Skip to content

fix(sdk-coin-sui): wire ValidDuring through Walrus withdraw builder - #9410

Merged
abhijit0943 merged 2 commits into
masterfrom
si-1139-wire-validduring-through-walruswithdrawstake-builder
Aug 4, 2026
Merged

fix(sdk-coin-sui): wire ValidDuring through Walrus withdraw builder#9410
abhijit0943 merged 2 commits into
masterfrom
si-1139-wire-validduring-through-walruswithdrawstake-builder

Conversation

@ralph-bitgo

@ralph-bitgo ralph-bitgo Bot commented Aug 4, 2026

Copy link
Copy Markdown

What

  • WalrusWithdrawStakeBuilder.buildSuiTransaction() now includes expiration: this._expiration in the built SuiTransaction, instead of omitting the field entirely.
  • WalrusWithdrawStakeBuilder.initBuilder() now restores _expiration from the decoded raw transaction's expiration field (skipping the None default), mirroring StakingBuilder/WalrusStakingBuilder.
  • WalrusWithdrawStakeTransaction.toJson() / getTxData() now use tx.expiration ?? { None: null } instead of unconditionally hardcoding { None: null }.
  • Added unit tests covering ValidDuring serialize + round-trip restore for both the request-withdraw and withdraw builders, plus a regression test asserting the default ({ None: null }) expiration is preserved when .expiration() is never called.

Why

WalrusWithdrawStakeBuilder / WalrusWithdrawStakeTransaction (used by Walrus undelegate + withdraw) hardcoded expiration: { None: null }, so wallet-platform's calls to txBuilder.expiration(ValidDuring) were silently dropped on serialize in the published @bitgo-beta/sdk-coin-sui SDK. StakingBuilder / WalrusStakingBuilder already pass expiration: this._expiration — this brings the withdraw/request-withdraw path in line with that pattern so ValidDuring expirations survive build and serialize/deserialize round-trips.

Test plan

  • yarn unit-test in modules/sdk-coin-sui — all existing + new tests pass
  • New tests assert toJson().expiration.ValidDuring is set after builder.expiration(ValidDuring) and survives toBroadcastFormat()from(raw)build() round-trip, for both WalrusRequestWithdrawStake and WalrusWithdrawStake transaction types
  • New test asserts the default ({ None: null }) expiration is unaffected when .expiration() is never called

Follow-up

  • Publishing @bitgo-beta/sdk-coin-sui beta is a separate manual workflow_dispatch step (.github/workflows/publish.yml), not included in this PR.
  • Wallet-platform rebuild of ValidDuring for undelegate/withdraw/unstake is tracked in SI-1140.

Ticket: SI-1139

WalrusWithdrawStakeBuilder and WalrusWithdrawStakeTransaction hardcoded
expiration: { None: null } in buildSuiTransaction / getTxData / toJson,
so a ValidDuring expiration set via txBuilder.expiration(...) was silently
dropped on serialize. StakingBuilder / walrusStakingBuilder already pass
expiration: this._expiration - this brings the withdraw/request-withdraw
path in line with that pattern:

- restore _expiration from decoded txData in initBuilder (skip when None)
- include expiration: this._expiration when building the SuiTransaction
- use tx.expiration ?? { None: null } in toJson/getTxData instead of
  always hardcoding None

Wallet-platform calls txBuilder.expiration(ValidDuring) for Walrus
undelegate/withdraw but the published SDK drops it on serialize, so
signed transactions built by consumers cannot include a ValidDuring
expiration for these transaction types.

Ticket: SI-1139
Session-Id: ea36d793-6db6-41ea-a197-79d9cdfe8539
Task-Id: 6a79f435-03d5-48ac-bf4f-74622ff15c3b
Add an assertion that toJson().expiration stays { None: null } when
.expiration() is never called on WalrusWithdrawStakeBuilder, both
before and after a raw round-trip.

Flagged by automated test-adequacy review after the ValidDuring wiring
commit: the new expiration ?? { None: null } fallback path had no
test guarding the default (no-expiration-set) case, so a regression
there would have slipped through silently.

Ticket: SI-1139
Session-Id: ea36d793-6db6-41ea-a197-79d9cdfe8539
Task-Id: 6a79f435-03d5-48ac-bf4f-74622ff15c3b
@linear-code

linear-code Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

SI-1139

@bitgo-ai-agent-dev
bitgo-ai-agent-dev Bot force-pushed the si-1139-wire-validduring-through-walruswithdrawstake-builder branch from 4d2e8b3 to ae164b9 Compare August 4, 2026 10:38
@ralph-bitgo
ralph-bitgo Bot force-pushed the si-1139-wire-validduring-through-walruswithdrawstake-builder branch from ae164b9 to 886a7be Compare August 4, 2026 10:38

@ashutoshkumar-6 ashutoshkumar-6 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: wire ValidDuring through Walrus withdraw builder

Verdict: APPROVE

Summary: Correct, minimal fix matching the existing StakingBuilder / WalrusStakingBuilder / WalrusStakingTransaction pattern. buildSuiTransaction now passes this._expiration, initBuilder restores non-None expiration, and toJson/getTxData use tx.expiration ?? { None: null } so BCS serialize (getDataBytesgetTxData) and from(raw) round-trips work. Tests cover ValidDuring for request-withdraw + withdraw, plus the default None regression.

Low

  • severity: low
    file: modules/sdk-coin-sui/src/lib/unstakingTransaction.ts
    line: ~78 / ~365
    issue: Native SUI UnstakingTransaction still hardcodes expiration: { None: null } (same bug class). Out of SI-1139 scope (Walrus only), but SI-1140 mentions undelegate/withdraw/unstake — confirm whether WP also needs ValidDuring on native WithdrawStake.
    suggestion: Track as a follow-up if WP applies ValidDuring to SUI unstake rebuilds; otherwise ignore.

@abhijit0943
abhijit0943 marked this pull request as ready for review August 4, 2026 11:17
@abhijit0943
abhijit0943 requested a review from a team as a code owner August 4, 2026 11:17
@abhijit0943
abhijit0943 merged commit 6956225 into master Aug 4, 2026
25 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.

2 participants