Skip to content

feat(sdk-coin-stx): register tstxsignet staking-testnet coin - #9843

Merged
akarath merged 2 commits into
masterfrom
cshld-1849-tstxsignet
Sep 29, 2026
Merged

akarath merged 2 commits into
masterfrom
cshld-1849-tstxsignet

Conversation

@ralph-bitgo

@ralph-bitgo ralph-bitgo Bot commented Sep 29, 2026

Copy link
Copy Markdown

What

  • statics: tstxsignet — the Stacks Foundation staking-testnet (chain ID 1280, private Bitcoin signet burnchain) — registered as a testnet-only coin, mirroring the tbtcstxsignet BTC-side pair from feat(sdk-coin-btc): register tbtcstxsignet #9832. New StxSignet network (chain ID 1280, tx version 0x80, PoX-5 boot and sBTC deployer contracts, both verified live against the node) under Networks.test.stxSignet, plus optional chainId / transactionVersion on the StacksNetwork interface.
  • sdk-coin-stx: new toStacksNetwork() applies a statics-declared chain identity on top of the stock @stacks/network object; TransactionBuilder uses it instead of the two-branch mainnet/testnet ternary. New Tstxsignet extends Stx coin class resolves the staking-testnet RPC.
  • Three hardcoded two-network maps fixed (they assumed only stx/tstx exist): statics getSip10TokenConfig now switches on the network name (same pattern as the Erc20 config), SDK Sip10Token resolves its base coin via tokenConfig.coin (same as Erc20Token), and the ofc stx addressCoin default is derived from the token name.
  • sdk-core environments.ts: stxSignetNodeUrl: 'https://api.staking-testnet.hiro.so' on testnet-derived environments; the tstxsignet coin throws a clear error in environments without it.
  • Registration: sdk-coin-stx register.ts, bitgo coinFactory + coins index, and the account-lib builder map.

Why

BTC-backed STX PoX-5 staking must be testable end to end; the Foundation's staking-testnet bonds in ~4h vs ~8h on private-1, so it replaces private-1 as the e2e target (CSHLD-1840). This statics entry blocks the Wallet Platform, indexer (BitGo/indexer#9384) and IMS (BitGo/indexerdb-microservice#2350) slices.

The chain ID is bytes 1-4 of a serialized Stacks transaction and sits inside the SHA-512/256 sighash, so the existing tstx network object cannot serve this network — its node rejects those transactions with SignatureValidation: invalid chain ID 2147483648 (expected 1280). The chain identity therefore travels in statics instead of being implied by the network type.

Builds on the closed #9828 (chain-ID slice) and the merged #9832 (tbtcstxsignet).

stx/tstx declare neither new field, so their transactions stay byte-identical.

Test plan

  • New sdk-coin-stx/test/unit/network.ts: toStacksNetwork keeps the stock stx/tstx identities; a tstxsignet transfer serializes with prefix 80 00000500; a tstx transfer stays on 80 8000 0000
  • New statics tests: StxSignet declares chain ID 1280 / version 0x80 and the pox-5 + sBTC contracts; stock stx networks carry no declared chain identity
  • sdk-coin-stx suite: 204 passing / 0 failing — SIGNED_TRANSACTION and HOT_WALLET_TOKEN_RECOVERY_TX_HEX fixtures untouched
  • statics suite: 37,797 passing / 0 failing (incl. ofc addressCoin parity, cold features, token config)
  • bitgo coin tests: 146 passing; the 2 ofcErc20Tokens failures reproduce identically on clean master (test expects a not-yet-existing ofchype:hwhype statics coin)
  • Live acceptance gate: a signed tstxsignet transfer broadcast to https://api.staking-testnet.hiro.so/v2/transactions is rejected with NotEnoughFunds — fails only on funds, not on chain identity

Ticket: CSHLD-1849

Add the Stacks Foundation staking-testnet network (chain ID 1280 on a
private Bitcoin signet) as the testnet-only coin tstxsignet, so
BTC-backed PoX-5 staking can be tested end to end. Wallet Platform,
IMS and hsm-api all consume this statics entry, which blocks the rest
of the onboarding.

The chain ID is bytes 1-4 of a serialized Stacks transaction and sits
inside the SHA-512/256 sighash, so the existing tstx network object
cannot serve this network: its node rejects such transactions with
`SignatureValidation: invalid chain ID 2147483648 (expected 1280)`.

- statics: optional chainId/transactionVersion on StacksNetwork; new
  StxSignet network (chain ID 1280, tx version 0x80, pox-5 boot and
  sBTC deployer contracts, both verified live); tstxsignet coin entry.
- sdk-coin-stx: new toStacksNetwork() applies the statics-declared
  chain identity on top of the stock @stacks/network object;
  TransactionBuilder uses it instead of the two-branch ternary. New
  Tstxsignet coin class resolves the staking-testnet RPC.
- Fix the three two-network maps that assumed only stx/tstx exist:
  statics tokenConfig (network-name switch, Erc20 precedent), sdk
  Sip10Token (resolve via tokenConfig.coin), and the ofc stx
  addressCoin default (derived from the token name).
- sdk-core environments: stxSignetNodeUrl on testnet-derived envs.
- Register the coin: sdk-coin-stx register, bitgo coinFactory, and
  the account-lib builder map.

stx/tstx declare neither new field, so their transactions stay
byte-identical - asserted by unit tests and guarded by the existing
signed-transaction fixtures. A signed tstxsignet transfer broadcast to
the live node is rejected only on funds (NotEnoughFunds), not on chain
identity, which is the acceptance gate from the ticket.

Ticket: CSHLD-1849
Session-Id: 139c18c0-3fc6-4b25-908d-4aed0df6dba8
Task-Id: 6215e6c5-ee49-49ad-afb0-d12bb855dfdb
@linear-code

linear-code Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

CSHLD-1849

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Unit tests are failing on Node 26.x (Current release line, non-blocking). This is not an LTS version yet, so it does not block merge, but it signals an incompatibility to fix before Node 26.x becomes LTS.

View run

@akarath
akarath marked this pull request as ready for review September 29, 2026 11:08
@akarath
akarath requested review from a team as code owners September 29, 2026 11:08
…y switches

getCoinConstructor() and getTokenConstructor() in bitgo's coinFactory.ts, and
the web-demo's lazy coin loader, each had their own hardcoded stx/tstx
case list that registerCoinConstructors()/register.ts didn't drive. Add
tstxsignet to all three so the AMS dynamic-registration fallback path and
the demo app can resolve the new coin/token the same way tstx already does.

Ticket: CSHLD-1849
@akarath
akarath requested a review from a team as a code owner September 29, 2026 11:21
@akarath

akarath commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

@claude review this

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


Code Review Progress

  • Read and understand PR changes
  • Review core implementation files
  • Review network and configuration changes
  • Review test coverage
  • Check for security and architectural issues
  • Provide final review feedback

Starting code review of PR #9843...

@akarath
akarath merged commit fea1c02 into master Sep 29, 2026
26 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.

4 participants