diff --git a/providers/apis/defi/raydium/README.md b/providers/apis/defi/raydium/README.md new file mode 100644 index 000000000..4d145aa9e --- /dev/null +++ b/providers/apis/defi/raydium/README.md @@ -0,0 +1,17 @@ +# Raydium Provider + +The Raydium provider fetches prices from the Raydium dex via JSON-RPC requests to Solana nodes. + +## How It Works + +For each ticker (i.e. RAY/SOL), we query 4 accounts: + +* BaseTokenVault +* QuoteTokenVault +* AMMInfo +* OpenOrders + +To calculate the price, we need to get the base and quote token balances, subtract PNL feels, and add the value of open orders. + +With the above values, we calculate the price by dividing quote / base and multiplying by the scaling factor. + diff --git a/providers/apis/defi/raydium/price_fetcher.go b/providers/apis/defi/raydium/price_fetcher.go index 3f17090f6..b388baa77 100644 --- a/providers/apis/defi/raydium/price_fetcher.go +++ b/providers/apis/defi/raydium/price_fetcher.go @@ -159,7 +159,11 @@ func (pf *APIPriceFetcher) Fetch( tickers []oracletypes.ProviderTicker, ) oracletypes.PriceResponse { // get the accounts to query in order of the tickers given - expectedNumAccounts := len(tickers) * 4 + expectedNumAccounts := len(tickers) * 4 // for each ticker, we query 4 accounts (base, quote, amm, open orders) + + // accounts is a contiguous slice of solana.PublicKey. + // each ticker takes up 4 slots. this is functionally equivalent to [][]solana.PubKey, + // however, storing in one slice allows us query without rearranging the request data (i.e. converting [][] to []). accounts := make([]solana.PublicKey, expectedNumAccounts) for i, ticker := range tickers { @@ -188,7 +192,7 @@ func (pf *APIPriceFetcher) Fetch( defer cancel() accountsResp, err := pf.client.GetMultipleAccountsWithOpts(ctx, accounts, &rpc.GetMultipleAccountsOpts{ - Commitment: rpc.CommitmentFinalized, + Commitment: rpc.CommitmentConfirmed, // TODO(nikhil): Keep track of latest height queried as well? }) if err != nil { diff --git a/providers/apis/defi/raydium/price_fetcher_test.go b/providers/apis/defi/raydium/price_fetcher_test.go index b9f463503..f03421f4d 100644 --- a/providers/apis/defi/raydium/price_fetcher_test.go +++ b/providers/apis/defi/raydium/price_fetcher_test.go @@ -289,7 +289,7 @@ func TestProviderFetch(t *testing.T) { btcVaultPk, usdcVaultPk, usdcBtcAMMIDPk, usdcBtcOpenOrdersPk, ethVaultPk, usdtVaultPk, ethUsdtAMMIDPk, ETHUSDTOpenOrdersPk, }, &rpc.GetMultipleAccountsOpts{ - Commitment: rpc.CommitmentFinalized, + Commitment: rpc.CommitmentConfirmed, }).Return( &rpc.GetMultipleAccountsResult{}, nil, ).Once() @@ -323,7 +323,7 @@ func TestProviderFetch(t *testing.T) { btcVaultPk, usdcVaultPk, usdcBtcAMMIDPk, usdcBtcOpenOrdersPk, ethVaultPk, usdtVaultPk, ethUsdtAMMIDPk, ETHUSDTOpenOrdersPk, }, &rpc.GetMultipleAccountsOpts{ - Commitment: rpc.CommitmentFinalized, + Commitment: rpc.CommitmentConfirmed, }).Return( &rpc.GetMultipleAccountsResult{}, err, ).Once() @@ -421,7 +421,7 @@ func TestProviderFetch(t *testing.T) { ethVaultPk, usdtVaultPk, ethUsdtAMMIDPk, ETHUSDTOpenOrdersPk, mogVaultPk, solVaultPk, mogSolAMMIDPk, MOGSOLOpenOrdersPk, }, &rpc.GetMultipleAccountsOpts{ - Commitment: rpc.CommitmentFinalized, + Commitment: rpc.CommitmentConfirmed, }).Return( &rpc.GetMultipleAccountsResult{ Value: []*rpc.Account{ @@ -478,7 +478,7 @@ func TestProviderFetch(t *testing.T) { client.On("GetMultipleAccountsWithOpts", mock.Anything, []solana.PublicKey{ btcVaultPk, usdcVaultPk, usdcBtcAMMIDPk, usdcBtcOpenOrdersPk, }, &rpc.GetMultipleAccountsOpts{ - Commitment: rpc.CommitmentFinalized, + Commitment: rpc.CommitmentConfirmed, }).Return( &rpc.GetMultipleAccountsResult{ Value: []*rpc.Account{