Add fluent setters postConditionMode()/postConditions() to
AbstractContractBuilder, and restore them in initBuilder from the
deserialized tx so a re-build (the fee re-build via factory.from) does
not drop them.
The PoX-5 register-for-bond contract call moves the staker's STX; with
@stacks/transactions defaulting PostConditionMode to Deny and no
post-conditions declared, the tx aborts on-chain with
abort_by_post_condition. Wallet Platform now sets Deny + an STX
post-condition (SI-1936).
Ticket: SI-1936
Context
PoX-5
register-for-bond(TXN 2) moves the staker's STX (it locksamount-ustx). Wallet Platform built the contract call with no post-condition mode/conditions;@stacks/transactionsdefaultsPostConditionModetoDeny, so the STX movement is "unchecked" and the tx aborts on-chain withabort_by_post_condition(SIP-005). SI-1936.Change
modules/sdk-coin-stx/src/lib/abstractContractBuilder.ts:postConditionMode(mode)andpostConditions(postConditions);initBuilder: restore_postConditionMode/_postConditionsfrom the deserialized tx —toJson()doesn't carry them, so without this the fee re-build (buildTransactionWithFee→factory.from(hex)) would silently drop them.modules/sdk-coin-stx/test/unit/transactionBuilder/pox5Builder.ts: assert the register-for-bond tx carriesDeny+ the STX post-condition, and that they survive the re-build.Why the SDK
WP builds via
factory.getContractBuilder(); the builder holds_postConditionMode/_postConditionsbut exposed no public setter, so WP couldn't set them. This adds the minimal surface.Commits
654ef00e24Tests
pox5Builderunit test: register-for-bond withDeny+makeStandardSTXPostCondition(...)→ built tx has the mode + 1 post-condition, and the re-built (fee) tx preserves them.Verification
npx tsc -p tsconfig.json --noEmit→ exit 0;eslint --quietclean.sdk-coin-stxunit suite.Review follow-ups
Rationale — post-conditions (
DenyvsAllow)What "empty" means
"Empty" = no post-conditions; it's not a mode by itself — the outcome depends on the mode:
Under
Denyyou must declare the movement; if you want empty you must useAllow. The real choice isAllow+ empty (sandbox) vsDeny+ post-condition (this work).Why
Deny+ post-condition (impact by scenario)register-for-bondmoves the staker's 100,000,000 uSTX.Deny+makeStandardSTXPostCondition(staker, LessEqual, 100000000)= "the network must confirm the staker lost at most 100,000,000 STX — nothing else."Allow+ emptyDeny+ PCCustody moves user funds →
Deny+ PC cryptographically constrains the tx to move at most the staked amount. Trade-off (E): the bound must be exact — whether the tx fee counts is the one thing to confirm on the wire (evidence says no; the node cited only the 100,000,000 stake).Related
Deny+ STX post-condition on the register build) follows once this publishes a@bitgo-beta/sdk-coin-stxbeta.