Skip to content

fix(sdk-coin-sol): account for tx fee in MAX withdraw (COIN-88)#8676

Closed
bitgo-ai-agent-dev[bot] wants to merge 2 commits into
masterfrom
COIN-88-sol-max-spendable-fee-fix
Closed

fix(sdk-coin-sol): account for tx fee in MAX withdraw (COIN-88)#8676
bitgo-ai-agent-dev[bot] wants to merge 2 commits into
masterfrom
COIN-88-sol-max-spendable-fee-fix

Conversation

@bitgo-ai-agent-dev
Copy link
Copy Markdown

Summary

  • Sol.getMaximumSpendable(walletAddress) queries the Solana node for balance, builds a representative transfer, gets the fee via getFeeForMessage, and returns balance - fee
  • Added optional getMaximumSpendable hook on BaseCoin/IBaseCoin (defaults to undefined → server API fallback)
  • wallet.ts sweep() now calls baseCoin.getMaximumSpendable() first; if it returns a value, that is used as the sweep amount instead of the server-side /maximumSpendable endpoint

Root cause

The server-side /maximumSpendable API for SOL returns balance − reserved_rent but does not subtract the transaction fee. Because the Solana fee payer pays the fee on top of the transfer amount, submitting maximumSpendable as the transfer amount leaves ~fee_amount of SOL stranded in the wallet — too small to send because sending it would also require paying a fee.

Test plan

  • yarn run unit-test --scope @bitgo/sdk-coin-sol — 588 passing, 0 failing
  • New tests in modules/sdk-coin-sol/test/unit/sol.ts under describe('getMaximumSpendable') cover: normal case (balance − fee), zero-balance wallet, balance smaller than fee (returns 0)
  • TypeScript type-checks clean (tsc --noEmit --skipLibCheck) on both sdk-coin-sol and sdk-core

🤖 Generated with Claude Code

The Solana fee payer is charged the transaction fee on top of the
transfer amount.  The server-side maximumSpendable API was returning
balance minus the rent-exempt reserve without subtracting the
transaction fee, so submitting that amount left an unsendable dust
residue equal to approximately one transaction fee.

Add Sol.getMaximumSpendable() which queries the Solana node for the
current balance, builds a representative transfer, fetches the fee via
getFeeForMessage, and returns balance - fee.  Add an optional
getMaximumSpendable hook on BaseCoin/IBaseCoin so any coin can supply
its own computation.  Update wallet.ts sweep() to use the coin-level
result when available, falling back to the BitGo API.

Ticket: COIN-88

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@bitgo-ai-agent-dev bitgo-ai-agent-dev Bot requested review from a team as code owners May 4, 2026 12:35
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 4, 2026

@bitgo-ai-agent-dev bitgo-ai-agent-dev Bot force-pushed the COIN-88-sol-max-spendable-fee-fix branch from 9c11474 to 6468395 Compare May 4, 2026 12:35
@bitgo-ai-agent-dev bitgo-ai-agent-dev Bot force-pushed the COIN-88-sol-max-spendable-fee-fix branch from 8c5ea01 to 2409f3f Compare May 4, 2026 13:08
Copy link
Copy Markdown
Contributor

@pritam-gembali pritam-gembali left a comment

Choose a reason for hiding this comment

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

this fix shouldn't be client side. it should be server side on maxSpendable API

@barathcj barathcj closed this May 5, 2026
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