diff --git a/.changeset/twelve-cycles-grow.md b/.changeset/twelve-cycles-grow.md new file mode 100644 index 00000000000..6b6711b9539 --- /dev/null +++ b/.changeset/twelve-cycles-grow.md @@ -0,0 +1,5 @@ +--- +'@audius/sdk': patch +--- + +Fix getOrCreateUserBank failures due to low priority fees diff --git a/packages/common/src/services/audius-backend/solana.ts b/packages/common/src/services/audius-backend/solana.ts index b542e2aa19a..586c8f677f9 100644 --- a/packages/common/src/services/audius-backend/solana.ts +++ b/packages/common/src/services/audius-backend/solana.ts @@ -110,21 +110,15 @@ export const getTokenAccountInfo = async ( audiusBackendInstance: AudiusBackend, { tokenAccount, - mint = DEFAULT_MINT, commitment = 'processed' }: { tokenAccount: PublicKey - mint?: MintName commitment?: Commitment } ): Promise => { return ( await audiusBackendInstance.getAudiusLibs() - ).solanaWeb3Manager!.getTokenAccountInfo( - tokenAccount.toString(), - mint, - commitment - ) + ).solanaWeb3Manager!.getTokenAccountInfo(tokenAccount.toString(), commitment) } export const deriveUserBankPubkey = async ( diff --git a/packages/common/src/store/buy-usdc/utils.ts b/packages/common/src/store/buy-usdc/utils.ts index f8eff78ec85..b50e05781b1 100644 --- a/packages/common/src/store/buy-usdc/utils.ts +++ b/packages/common/src/store/buy-usdc/utils.ts @@ -1,12 +1,7 @@ import { PublicKey } from '@solana/web3.js' -import { channel, Channel } from 'redux-saga' -import { call, delay, select, take } from 'typed-redux-saga' +import { call, delay, select } from 'typed-redux-saga' -import { - createUserBankIfNeeded, - getTokenAccountInfo, - MintName -} from '~/services/audius-backend/solana' +import { getTokenAccountInfo, MintName } from '~/services/audius-backend/solana' import { IntKeys } from '~/services/remote-config' import { MAX_CONTENT_PRICE_CENTS, @@ -16,66 +11,38 @@ import { BUY_TOKEN_VIA_SOL_SLIPPAGE_BPS } from '~/services/remote-config/defaults' +import { getAccountUser } from '../account/selectors' import { getContext } from '../effects' -import { getFeePayer } from '../solana/selectors' const POLL_ACCOUNT_INFO_DELAY_MS = 1000 const POLL_ACCOUNT_INFO_RETRIES = 30 -// Create a channel to manage concurrent requests -let pendingUserBankCreation: Channel<{ - result?: Awaited> - error?: Error -}> | null = null - /** * Derives a USDC user bank for a given eth address, creating it if necessary. - * Defaults to the wallet of the current user. Uses a channel to manage concurrent - * requests so there is only one creation attempt in flight at a time. + * Defaults to the wallet of the current user. */ export function* getOrCreateUSDCUserBank(ethAddress?: string) { - // If there's already a pending operation, wait for its result - if (pendingUserBankCreation) { - const { result, error } = yield* take(pendingUserBankCreation) - if (error) throw error - if (!result) - throw new Error('No user bank returned from createUserBankIfNeeded') - return result - } - - // Create a new channel for this bank creation - pendingUserBankCreation = channel() - try { - const audiusBackendInstance = yield* getContext('audiusBackendInstance') - const { track } = yield* getContext('analytics') - const feePayerOverride = yield* select(getFeePayer) - - if (!feePayerOverride) { - throw new Error( - 'getOrCreateUSDCUserBank: unexpectedly no fee payer override' - ) + const audiusSdk = yield* getContext('audiusSdk') + const sdk = yield* call(audiusSdk) + let ethWallet = ethAddress + if (!ethWallet) { + const user = yield* select(getAccountUser) + if (!user?.wallet) { + throw new Error('Failed to create USDC user bank: No user wallet found.') } - - // Perform the bank creation - const result = yield* call(createUserBankIfNeeded, audiusBackendInstance, { - ethAddress, - feePayerOverride, - mint: 'usdc', - recordAnalytics: track - }) - - // Put the successful result on the channel - pendingUserBankCreation.put({ result }) - return result - } catch (error) { - // Put the error on the channel - pendingUserBankCreation.put({ error: error as Error }) - throw error - } finally { - // Close and cleanup the channel - pendingUserBankCreation.close() - pendingUserBankCreation = null + ethWallet = user.wallet } + const { userBank } = yield* call( + [ + sdk.services.claimableTokensClient, + sdk.services.claimableTokensClient.getOrCreateUserBank + ], + { + ethWallet, + mint: 'USDC' + } + ) + return userBank } /** Polls for the given token account info up to a maximum retry count. Useful diff --git a/packages/sdk/src/sdk/services/Solana/programs/ClaimableTokensClient/ClaimableTokensClient.ts b/packages/sdk/src/sdk/services/Solana/programs/ClaimableTokensClient/ClaimableTokensClient.ts index f90b29aaa72..f2345b73ab5 100644 --- a/packages/sdk/src/sdk/services/Solana/programs/ClaimableTokensClient/ClaimableTokensClient.ts +++ b/packages/sdk/src/sdk/services/Solana/programs/ClaimableTokensClient/ClaimableTokensClient.ts @@ -6,12 +6,12 @@ import { } from '@audius/spl' import { SendTransactionOptions } from '@solana/wallet-adapter-base' import { - TransactionMessage, VersionedTransaction, Secp256k1Program, PublicKey, Transaction, - SendTransactionError + SendTransactionError, + ComputeBudgetProgram } from '@solana/web3.js' import { productionConfig } from '../../../../config/production' @@ -152,18 +152,22 @@ export class ClaimableTokensClient { userBank, programId: this.programId }) - const confirmationStrategyArgs = + const computeBudgetLimitInstruction = + ComputeBudgetProgram.setComputeUnitLimit({ + units: 50000 + }) + const { blockhash, lastValidBlockHeight } = await this.client.connection.getLatestBlockhash() - const message = new TransactionMessage({ - payerKey: feePayer, - recentBlockhash: confirmationStrategyArgs.blockhash, - instructions: [createUserBankInstruction] - }).compileToLegacyMessage() - const transaction = new VersionedTransaction(message) + const transaction = await this.client.buildTransaction({ + instructions: [ + createUserBankInstruction, + computeBudgetLimitInstruction + ], + recentBlockhash: blockhash + }) const signature = await this.sendTransaction(transaction) - const confirmationStrategy = { ...confirmationStrategyArgs, signature } await this.client.connection.confirmTransaction( - confirmationStrategy, + { blockhash, lastValidBlockHeight, signature }, 'finalized' ) return { userBank, didExist: false }