Skip to content

[BCN] Handle missing Solana token ATA in txhistory#4173

Open
msalcala11 wants to merge 1 commit into
bitpay:masterfrom
msalcala11:fix-solana-history-error
Open

[BCN] Handle missing Solana token ATA in txhistory#4173
msalcala11 wants to merge 1 commit into
bitpay:masterfrom
msalcala11:fix-solana-history-error

Conversation

@msalcala11
Copy link
Copy Markdown
Contributor

@msalcala11 msalcala11 commented May 19, 2026

Description

Fixes a BitPay app txhistory failure observed with zero-balance Solana token wallets.

Zero-balance Solana token wallets can still have transaction history. A user may have received or sent a token before, then sent the balance back to zero or closed the associated token account. In that state, the wallet should still be able to show historical activity.

Observed failure mode: When the app fetched txhistory for one of these token wallets, BWS returned a plain-text Error getting ATA address response instead of an empty or historical transaction list.

Root cause: BWS forwards /v1/txhistory/ requests with tokenAddress to bitcore-node wallet transaction streaming. In the Solana token path, bitcore-node resolves the wallet address's associated token account before listing signatures. If there is no currently initialized ATA, getConfirmedAta throws and the stream fails.

The fix: This change keeps getConfirmedAta as the first lookup, so invalid mints and other non-missing-ATA failures keep their existing behavior. For the missing or uninitialized ATA case, it derives the deterministic ATA address and uses it to find any prior token-account activity. If prior activity exists, txhistory returns the corresponding transaction history even if the ATA was later closed.

Changelog

  • Fall back to the derived Solana ATA when SPL token txhistory has no currently initialized ATA.
  • Preserve existing error behavior for invalid mints and other non-missing-ATA failures.
  • Add regression coverage for SOL + tokenAddress + missing current ATA.

Testing Notes

From packages/bitcore-node, run:

npm run tsc && BCN_LOG_LEVEL=none npm exec -- mocha 'build/test/integration/solana/csp.test.js' --grep 'derived ATA'
npm run test:integration

@msalcala11 msalcala11 changed the title handle missing Solana token ATA in txhistory [BCN] Handle missing Solana token ATA in txhistory May 19, 2026
@msalcala11 msalcala11 force-pushed the fix-solana-history-error branch 29 times, most recently from 80ab6fd to 03b5dc1 Compare May 20, 2026 20:41
@msalcala11 msalcala11 force-pushed the fix-solana-history-error branch 4 times, most recently from 7d469b0 to 18e0943 Compare May 20, 2026 22:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Solana SPL token txhistory streaming when the associated token account (ATA) is currently missing/uninitialized (e.g., closed after balance returned to zero), by falling back to the deterministically derived ATA so prior token-account activity can still be discovered.

Changes:

  • Add missing-ATA detection and fallback from getConfirmedAta to deriveAta when streaming address/wallet transactions for SPL tokens.
  • Introduce a helper for identifying “missing ATA” errors.
  • Add an integration regression test covering the missing-current-ATA streaming path.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/bitcore-node/src/providers/chain-state/svm/api/csp.ts Adds missing-ATA error detection and falls back to derived ATA for token txhistory streaming.
packages/bitcore-node/test/integration/solana/csp.test.ts Adds a regression test for token txhistory streaming when the current ATA is not initialized.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +39 to +42
function isMissingAtaError(err: any): boolean {
const message = err?.message || '';
return message === 'Missing ATA' || message.includes('ATA not initialized');
}
Comment on lines +225 to +226
const tokenAddress = '11111111111111111111111111111112';
const derivedAtaAddress = 'derivedTokenAccountAddress';
Comment on lines +224 to +230
it('should stream empty SPL token history from derived ATA when current ATA is not initialized', async () => {
const tokenAddress = '11111111111111111111111111111112';
const derivedAtaAddress = 'derivedTokenAccountAddress';
const chunks: string[] = [];
const connection = {
getSignaturesForAddress: sandbox.stub().returns({ send: sandbox.stub().resolves([]) })
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants