Repository navigation
fix(sdk-coin-stx): stringify Response Clarity args to JSON-safe values - #9963
Merged
shubham-damkondwar merged 1 commit intoOct 14, 2026
Conversation
Contributor
Contributor
|
|
stringifyCv normalised only Int/UInt/OptionalSome/Tuple/List, so the ResponseOk/ResponseErr wrapping register-for-bond's lockup reached toJson() with native BigInt values. JSON.stringify then threw, and the policy service, which receives this via fast-safe-stringify, rejected the whole payload and returned 400 — blocking the PoX-5 register leg. Handle ResponseOk/ResponseErr by recursing into the wrapped value, as is already done for OptionalSome. Tests pin the real staging register-for-bond args (btc ResponseOk / sbtc ResponseErr): the built tx toJson() and explainTransaction().contractFunctionArgs are JSON-serialisable, and the fee re-build stays byte-identical. STX-only; no change for other txs. Ticket: SI-1922
Doddanna17
force-pushed
the
doddannab/si-1922-sdk-coin-stx-stringifycv-leaks-bigint-in-register-for-bond
branch
from
October 14, 2026 11:38
80bc569 to
69cbffa
Compare
Doddanna17
marked this pull request as ready for review
October 14, 2026 11:55
Contributor
Contributor
|
Claude finished @shubham-damkondwar's task —— View job STX Clarity Value Serialization Fix - Code Review ✅Todo List:
Review SummaryThis PR successfully fixes a critical BigInt serialization issue in STX Clarity values. The implementation is solid, well-tested, and ready for merge. Core Fix Analysis (
|
shubham-damkondwar
approved these changes
Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
PoX-5 BTC+STX paired-bond staking, TXN 2 = Stacks
pox-5.register-for-bond, signed by the user's custody STX wallet (onchain multisig). staking-service sends the 5 Clarity args as hex; Wallet Platform decodes them and builds the contract call. The register leg currently fails at WP policy evaluation — policy-service returns400 Unexpected exception while parsing JSON content: '[unable to serialize, circular reference is too complex to analyze]'— so no pending approval is created and the register row is retried forever.Change
modules/sdk-coin-stx/src/lib/utils.ts—stringifyCvnow handlesClarityType.ResponseOk/ClarityType.ResponseErrby recursing into the wrapped value (same shape as the existingOptionalSomecase).modules/sdk-coin-stx/test/unit/registerForBondRealArgs.ts— fixture with the real stagingregister-for-bondargs captured from the failing request (btc lockupResponseOk).modules/sdk-coin-stx/test/unit/util.ts—stringifyCvcases forResponseOk/ResponseErr.modules/sdk-coin-stx/test/unit/transactionBuilder/pox5Builder.ts— register-for-bond (btcResponseOk+ sbtcResponseErr)toJson()isJSON.stringify-able; the real-args fixture pins the nested uints as strings and the fee re-build as byte-identical.modules/sdk-coin-stx/test/unit/stx.ts— the second consumer:explainTransaction().contractFunctionArgsisJSON.stringify-able for the real args.Why recurse in place (not
cvToJSON/cvToValue)register-for-bond arg 4 (the btc lockup) is
ResponseOk(tuple { outputs (list …), staker-unlock-bytes }); the sbtc variant isResponseErr(uint).stringifyCv'sdefault: return cvreturned it raw, so the nested uints stayed native BigInt intxInfo. WP sendshalfSigned.txInfoin the policy body via superagent, whoseapplication/jsonserializer isfast-safe-stringify; whenJSON.stringifythrows (TypeError: Do not know how to serialize a BigInt) that library replaces the whole body with the placeholder string, which policy-service cannot parse. It is not a circular reference —fast-safe-stringifyreplaces a real cycle with[Circular].cvToJSONwas rejected: it emits string type names (arg 4 becomes(response (tuple …) UnknownType)), soserializeCVthrows and the fee re-build (buildTransactionWithFee→factory.from→initBuilder) breaks;cvToValuedrops the Clarity type. Recursing in place keepsserializeCVbyte-identical (the existing byte-identical re-build test still passes).Scope
ResponseOk/ResponseErrare produced only byPox5Builder.registerForBond, so onlyregister-for-bond(btc + sbtc)toJson()/explainTransaction().contractFunctionArgschange. All other STX transactions and every other coin are unchanged, andserializeCV/toBroadcastFormatbytes are unchanged — so pending approval, serialization and HSM signing are unaffected.Commits
69cbffae70Tests
sdk-coin-stxunit suite (util + pox5Builder + stx):stringifyCvResponseOk/ResponseErrcases,ResponseOk) + sbtc (ResponseErr)JSON.stringify(tx.toJson())succeeds,toJson()+explainTransaction().contractFunctionArgsare JSON-serialisable, fee re-build byte-identical,Verification
npx tsc -p tsconfig.json --noEmit→ exit 0 (module).npx eslint --quiet <changed files>→ clean.mochain this checkout is currently blocked by an unrelated env failure (a partialtsc -bdestabiliseddist/, producing ansdk-coresrc-load io-ts error and pre-existing type errors in other modules) — this is not caused by the change.Review follow-ups
Related
@bitgo-beta/account-libin Wallet Platform — it has no directsdk-coin-stxdependency; it comes via account-lib, which pinssdk-coin-stx 1.1.1-beta.2310.bg_stx_signalready signs register-for-bond); TSSsignablePayload/hash (SI-1904/1905/1906 parked — custody is onchain multisig).