I am attempting to sell tokens immediately after purchasing them (in few seconds), but I am encountering an error when trying to retrieve the balance/token account for the swap. I have used both methods, getTokenAccountBalance and getTokenAccountsByOwner
, but I am consistently getting the same error ("cannot find token account" from baseMint or "failed to get token account balance" from tokeAccount).
I have observed that the code works fine if I set a longer delay for the sell-swap, such as 20 seconds or more. I suspect that this issue may be related to -> Finalized (MAX confirmations). So I cant getTokenBalance until Tx is completely Finalized, which takes over 10-15 seconds.
Is there any way to use RPC methods (e.x. to check token balance) before TX is finalized?
async function buy(
accountId: PublicKey,
accountData: LiquidityStateV4,
): Promise<void> {
const tokenAccount = existingTokenAccounts.get(
accountData.baseMint.toString(),
);
if (!tokenAccount) {
logger.error(`No token account found for mint: ${accountData.baseMint}`);
return;
}
logger.info(`CreatePoolKeys for ${accountId}`);
tokenAccount.poolKeys = createPoolKeys(
accountId,
accountData,
tokenAccount.market!,
);
logger.info(`Create Liquidity Pool for ${accountId}`);
const { innerTransaction, address } = Liquidity.makeSwapFixedInInstruction(
{
poolKeys: tokenAccount.poolKeys,
userKeys: {
tokenAccountIn: quoteTokenAssociatedAddress,
tokenAccountOut: tokenAccount.address,
owner: wallet.publicKey,
},
amountIn: quoteAmount.raw,
minAmountOut: 0,
},
tokenAccount.poolKeys.version,
);
logger.info(`Get latest blockhash for ${accountId}`);
const latestBlockhash = await solanaConnection.getLatestBlockhash({
commitment: commitment,
});
logger.info(`Create TransactionMessage for ${accountId}`);
const messageV0 = new TransactionMessage({
payerKey: wallet.publicKey,
recentBlockhash: latestBlockhash.blockhash,
instructions: [
ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 3000000 }),
createAssociatedTokenAccountIdempotentInstruction(
wallet.publicKey,
tokenAccount.address,
wallet.publicKey,
accountData.baseMint,
),
...innerTransaction.instructions,
],
}).compileToV0Message();
logger.info(`Sign TransactionMessage for ${accountId}`);
const transaction = new VersionedTransaction(messageV0);
transaction.sign([wallet, ...innerTransaction.signers]);
logger.info(`Send TransactionMessage for ${accountId}`);
const signature = await solanaConnection.sendRawTransaction(
transaction.serialize(),
{
maxRetries: 20,
skipPreflight: true,
},
);
setTimeout(() => sell(tokenAccount, accountData), 3000);
}
async function sell(
accountId: PublicKey,
accountData: LiquidityStateV4,
): Promise<void> {
const tokenAccount = existingTokenAccounts.get(accountData.baseMint.toString());
if (!tokenAccount) {
return;
}
try {
//ERROR appears in this line
const balanceResponse = (await solanaConnection.getTokenAccountBalance(tokenAccount.address)).value.amount;
if (balanceResponse !== null && Number(balanceResponse) > 0) {
////////////
throw new SolanaJSONRPCError(
^
SolanaJSONRPCError: failed to get token account balance: Invalid param: could not find account
at Connection.getTokenAccountBalance (C....\@solana\web3.js\src\connection.ts:3352:13)
at processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: -32602,
data: undefined
}