precious-void / raydium-swap

Swap example using the Raydium SDK
127 stars 42 forks source link

After I do run the program, the program returns the txid normally but when I go to check it, it's an empty transaction #7

Closed xiaozhu001 closed 1 month ago

xiaozhu001 commented 7 months ago

After I do run the program, the program returns the txid normally but when I go to check it, it's an empty transaction

precious-void commented 7 months ago

@xiaozhu001 that is an expected behavior. Transaction id is a hash, it doesn't confirm the transaction has actually landed. Currently, in my implementation there is no confirmation check implemented. You can use connection.confirmTransaction method to wait for transaction result.

Allen-Taylor commented 6 months ago

I'm using a modified version of your code (thank you by the way) and I am running into the same issues with the blank txn hashes.

You can confirmTransaction like you said but it is just going to hang until it times out which is terrible for trading.

I'm using a QuickNode RPC, I can imagine it is worse if you are using a public RPC.

You could try and use:

const web3 = require('@solana/web3.js'); web3.sendAndConfirmTransaction()

If your txn isn't getting picked up it could be the priority fee is set way too low as well.

precious-void commented 6 months ago

@xiaozhu001 @Allen-Taylor welcome to solana 😅

Allen-Taylor commented 6 months ago

@xiaozhu001 @Allen-Taylor welcome to solana 😅

Yeah right?

What is the RPC method to see if the cluster even is processing the transaction. Not even confirm/finalized, just that hasn't been dropped.

https://github.com/StrataFoundation/strata/blob/ab288abb1892161bfae21b955fbc160311ac4eee/packages/spl-utils/src/transaction.ts#L287

These guys have a sendAndConfirmWithRetry function that could be interesting. However they are using raw txns.

I still haven't found a good solution.

precious-void commented 6 months ago

@Allen-Taylor you can do the same, get the raw transaction by calling transaction.serialize()

Allen-Taylor commented 6 months ago

@Allen-Taylor you can do the same, get the raw transaction by calling transaction.serialize()

I think you have to sign before serializing.

I'm finding checking balance is actually faster than confirming. Your balance will update 2 or 3 seconds before the actual confirmation goes through.

Handling the dropped transaction is a pain though. 25 seconds is a good estimated timeout.

kaiyes commented 6 months ago

So you are saying instead of using raydiumSwap.sendVersionedTransactionwe should use either web3.sendAndConfirmTransaction() or connection.confirmTransaction ?

Thanks for the repo by the way. Got me furthest.

Screenshot 2024-04-17 at 4 01 09 PM
Allen-Taylor commented 6 months ago

I think it is recommended to use get signature statuses for the versioned transactions.

https://solana.com/docs/rpc/http/getsignaturestatuses

Unfortunately, just because there is a signature doesn't mean it was picked up by the cluster.

If speed is a concern, I recommend checking the token balance of the wallet along with the signature status. From my experience, the wallet updates 1 or 2 seconds before the status shows success. If the token balance changes you can assume that the buy or sell went through successfully.

kaiyes commented 6 months ago

Thanks @Allen-Taylor. that's what I'm doing right now.

But checking sol balance isn't that bulletproof. I'm almost always seeing the balance unchanged even after waiting a minute. Hence looking for a way to check for transaction confirmation

Screenshot 2024-04-17 at 6 43 12 PM
Allen-Taylor commented 6 months ago

You should use the get signature statuses method then.

Do you need an example of the function?

kaiyes commented 6 months ago

@Allen-Taylor that will be very kind of you. Thank you

Allen-Taylor commented 6 months ago

sorry I misspoke. it is supposed to be getTransaction.


export async function confirmTxn(transactionId: string): Promise<boolean | null> {
const RPC = "your RPC"
try {
  const response = await axios.post<any>(RPC, {
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransaction',
    params: [transactionId, { maxSupportedTransactionVersion: 0 }],
  }, {
    headers: {
      'Content-Type': 'application/json',
    },
  });

  if (!response.data) {
    return null; 
  }

  if (!response.data.result || !response.data.result.meta) {
    throw new Error('Invalid response structure');
  }

  const { err, status } = response.data.result.meta;

  if (status.Ok === null) {
    return true;
  } else {
    return false;
  }
} catch (error) {
  return null; 
}
}
kaiyes commented 6 months ago

Thanks @Allen-Taylor . I moved to jupiter for swapping. Has an api you can call. Works great.

https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/index.ts

Allen-Taylor commented 6 months ago

Thanks @Allen-Taylor . I moved to jupiter for swapping. Has an api you can call. Works great.

https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/index.ts

Yeah Jupiter works great, but if you are trading low liquidity pairs it doesn't work. Jupiter doesn't work for new pairs.

umaid56 commented 5 months ago

Hi @Allen-Taylor

I stuck for a while with the same issue, the program returns the txid normally but when I go to check it, it's an empty.

What should I do for this? can sendAndConfirmTransaction will be enough for this.

Allen-Taylor commented 5 months ago

Hi @Allen-Taylor

I stuck for a while with the same issue, the program returns the txid normally but when I go to check it, it's an empty.

What should I do for this? can sendAndConfirmTransaction will be enough for this.

The issue is mostly related to which RPC you are using. Any of the public RPCs are going to be unreliable. Since I have moved to a better quality RPC, I don't have this issue.

Unfortunately, the best way is to set the retries to 0 and spam the txn hash until the block hash expired. A txn hash can be picked up only once, so you don't have to worry about duplicate transactions.

umaid56 commented 5 months ago

First of all thanks for your reply Currently, I set the retries to 20 and use quick node RPC.

Allen-Taylor commented 5 months ago

First of all thanks for your reply Currently, I set the retries to 20 and use quick node RPC.

I did not have good experience with Quick Node. Try a different RPC provider.

umaid56 commented 5 months ago

I guess Quick Node is the best of all. Do you recommend any other?

Allen-Taylor commented 5 months ago

Alchemy or Helius.

NotArchon commented 5 months ago

What are you guys setting the priority fee to?

zerofill commented 5 months ago

Priority fee max is 5000000 lamports. .005 sol. I just leave it at that or auto. When I set priority fees.