Skip to content

feat(sdk-coin-sui): add fundsInAddressBalance support to StakingBuilder (AddStake)#9324

Merged
abhijit0943 merged 1 commit into
masterfrom
SI-1053-add-fundsInAddressBalance-to-staking-builder
Jul 23, 2026
Merged

feat(sdk-coin-sui): add fundsInAddressBalance support to StakingBuilder (AddStake)#9324
abhijit0943 merged 1 commit into
masterfrom
SI-1053-add-fundsInAddressBalance-to-staking-builder

Conversation

@abhijit0943

@abhijit0943 abhijit0943 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What

  • Added fundsInAddressBalance(amount: string) method to StakingBuilder so wallets holding only address-balance SUI can stake
  • When fundsInAddressBalance > 0, AddStake PTB inserts redeem_funds(SUI) + mergeCoins(gas, [addrCoin]) before splitCoins + request_add_stake
  • StakingTransaction.toJson() now emits fundsInAddressBalance (from tx.expiration ?? { None: null } and tx.fundsInAddressBalance); getTxData() handles BalanceWithdrawal inputs and uses tx.expiration ?? { None: null }
  • StakingBuilder.initBuilder() restores _fundsInAddressBalance from deserialized BalanceWithdrawal input and restores _expiration if ValidDuring
  • StakingBuilder.buildSuiTransaction() passes expiration: this._expiration through to the returned SuiTransaction
  • Fixed utils.getStakeRequests() to only parse MoveCalls ending with ::sui_system::request_add_stake, preventing crash on redeem_funds MoveCall (no arguments[2])
  • Fixed utils.getWalrusStakeWithPoolRequests() with same target filter (::staking::stake_with_pool) for defensive parity
  • Fixed WalrusStakingBuilder to use WalrusStakingTransaction instead of StakingTransaction (fixes loadInputsAndOutputs calling the correct getWalrusStakeWithPoolRequests)
  • Removed now-unused StakingTransaction import from walrusStakingBuilder.ts

Why

  • Wallets holding only address-balance SUI (no Coin<SUI> objects) cannot stake because StakingBuilder sourced the stake amount exclusively from gas coin objects. This mirrors the fundsInAddressBalance path in TransferBuilder Path 2c.
  • StakingTransaction.toJson()/getTxData() previously hardcoded expiration: { None: null } — this would silently discard any ValidDuring expiration set by WP for Case 2 (addr-bal-only, empty gasData.payment). Fixed to use tx.expiration ?? { None: null }.
  • The getStakeRequests bug would cause a runtime crash when parsing a staking transaction that includes a redeem_funds MoveCall (no arguments[2]).

Test plan

  • New fundsInAddressBalance suite: mixed coin-objects + addr-bal command sequence, round-trip deserialization, multi-stake, default behavior unchanged
  • New Case 2 test: fundsInAddressBalance > 0 + gasData.payment = [] (addr-bal-only stake)
  • All 6 existing Sui Staking Builder tests still pass
  • All Walrus Staking Builder tests pass (fixed regression from getStakeRequests target filter)
  • 148 tests passing, 2 pre-existing failures unrelated to this change

Ticket: SI-1053

@linear-code

linear-code Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

SI-1053

@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the SI-1053-add-fundsInAddressBalance-to-staking-builder branch 3 times, most recently from cc4935d to c41dbb4 Compare July 22, 2026 10:26
…er (AddStake)

Wallets holding only address-balance SUI (no Coin<SUI> objects) could not
stake because StakingBuilder sourced the stake amount only from gas coin
objects (gasData.payment). This change teaches StakingBuilder the same
address-balance principal funding path as TransferBuilder Path 2c.

Changes:
- stakingBuilder.ts: add _fundsInAddressBalance field and
  fundsInAddressBalance(amount) setter; when > 0, insert
  redeem_funds(SUI) + mergeCoins(gas, [addrCoin]) before splitCoins +
  request_add_stake; return expiration: this._expiration instead of
  hardcoded None; restore both _fundsInAddressBalance and _expiration
  in initBuilder()
- stakingTransaction.ts: toJson() emits fundsInAddressBalance and uses
  tx.expiration ?? { None: null }; getTxData() handles BalanceWithdrawal
  inputs and uses tx.expiration ?? { None: null } (fixes ValidDuring
  being silently discarded, required for Case 2 / WP addr-bal-only stake)
- utils.ts: getStakeRequests() filters MoveCall targets to
  ::sui_system::request_add_stake (prevents crash on redeem_funds
  MoveCall with no arguments[2]); getWalrusStakeWithPoolRequests()
  gets matching filter on ::staking::stake_with_pool for defensive
  parity ahead of Walrus addr-bal support
- walrusStakingBuilder.ts: use WalrusStakingTransaction instead of
  StakingTransaction so loadInputsAndOutputs calls the correct
  getWalrusStakeWithPoolRequests (the getStakeRequests target filter
  would otherwise zero out Walrus stake I/O); remove now-unused
  StakingTransaction import
- stakingBuilder tests: fundsInAddressBalance suite covering mixed
  coin-objects + addr-bal command sequence, round-trip deserialization,
  multi-stake, Case 2 (addr-bal-only / empty payment), and unchanged
  default behavior

Ticket: SI-1053
Session-Id: 6c1e4b34-b84e-453f-ba38-703340b82bb0
Task-Id: df1f6ba5-a31c-4ff7-9b7d-26fc6422054f
@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the SI-1053-add-fundsInAddressBalance-to-staking-builder branch 2 times, most recently from dbcc0d1 to 0f0979b Compare July 22, 2026 10:33
Comment thread modules/sdk-coin-sui/src/lib/walrusStakingBuilder.ts
Comment thread modules/sdk-coin-sui/src/lib/utils.ts
@abhijit0943
abhijit0943 marked this pull request as ready for review July 23, 2026 05:58
@abhijit0943
abhijit0943 requested a review from a team as a code owner July 23, 2026 05:58
@abhijit0943
abhijit0943 merged commit e10119f into master Jul 23, 2026
28 checks passed
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.

3 participants