DEV Community

Cover image for Solana DEV #02: Retrieve all Deposit transactions of your wallet
Tin Chung
Tin Chung

Posted on

Solana DEV #02: Retrieve all Deposit transactions of your wallet

If you use Phantom wallet to pay for transactions on Solana blockchain, you may recognize that every time you send SOL or SPL tokens to another address, that transaction will be recorded and listed on Phantom wallet interface.

Phantom deposit transaction interface

At first, I thought that it is just similar to any other data fetched by using getProgramAccounts with filtering stuffs. However, it does not work that way.

Fetching signatures and transactions

To fetch all deposit transactions of one address, you must get all signatures of that address by using the method getSignaturesForAddress

const signatureInfos = await connection.getSignaturesForAddress(vaultAddress);
Enter fullscreen mode Exit fullscreen mode

And then map the info to get only transaction signatures

const signatures = signatureInfos.map(sig => sig.signature);
const transactions = await connection.getParsedTransactions(signatures);
Enter fullscreen mode Exit fullscreen mode

This approach has a very big problem. It does not allow you to filter out fetched signatures like what you usually do with getProgramAccounts. And in that way, it will just fetch a bulk load of transactions from your address as your address have other wallet interaction beside receive and send coins. To make it more efficient, I try to filter out success signatures from the return data

const filteredSignatureInfos = signatureInfos.filter(sig => !sig.err && !sig.memo);
Enter fullscreen mode Exit fullscreen mode

But unlucky, if your wallet has around 300 or more transactions, the RPC won't allow you to fetch as there's a rate limit. I don't know if there are any other better approaches but this is the one that I found.

How to improve the approach?

This might not be an acceptable answer but there's a few ways that you can improve the case.

  • Trying to separate a vault from a wallet. A vault will be a PDA that use the wallet address as a seed. In that way, all transactions that the vault includes will be related to tokens and native SOL only. Even the most traffic vault can only have around 50-100 transactions.
  • Using cache database, partition and event listener: This technique is commonly used in tradition backend development. If you have around 300 transactions for an address, try to partition those into smaller parts: 50 transactions per each. Cache those data and then only update the database if there is a new data coming (use onAccountChange).

Filtering transactions

There will be two types of transactions that you may want to fetch to display a similar result from Phantom: Native SOL deposit transactions and SPL tokens deposit transactions. If you use getParsedTransactions like what I did above, all the data is already converted into human readable language. The raw transactions using getTransactions return only hexadecimal data. I wrote these two methods so that you can reuse it, it's quite simple because all data is parsed already.

// Filter SPL token deposit transaction
isSplTokenDepositTx(tx: any): boolean {
  const ixs = tx.transaction.message.instructions;
  const ix: any = ixs[ixs.length - 1];
  return (
    ix.programId.equals(TOKEN_PROGRAM_ID) &&
    (ix.parsed.type === 'transfer' || ix.parsed.type === 'transferChecked')
  );
}

// Filter Native SOL deposit transaction
isSolDepositTx(tx: any): boolean {
  const ix: any = tx.transaction.message.instructions[0];
  return ix.programId.equals(SYSTEM_PROGRAM_ID) && ix.parsed.type === 'transfer';
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)