fix(sdk-coin-polyx): replace stale mainnet v8 material with live metadata#9354
Draft
nvrakesh06 wants to merge 1 commit into
Draft
fix(sdk-coin-polyx): replace stale mainnet v8 material with live metadata#9354nvrakesh06 wants to merge 1 commit into
nvrakesh06 wants to merge 1 commit into
Conversation
…data mainnetV8Material was a placeholder created before the mainnet v8 fork: it mirrored v7 metadata with only specVersion/txVersion bumped, so its call-index layout never matched the live v8 chain. Decoding a real, correctly-encoded mainnet transferWithMemo extrinsic against this placeholder misresolved the call as system.killStorage and threw, instead of routing to V8TransferBuilder. Every v8 builder (V8TransferBuilder, V8TokenTransferBuilder, V8RegisterDidBuilder, etc.) defaults to this same material in its constructor, so any caller that built or decoded a mainnet v8 transaction without first overriding .material() with live data hit the same corruption. Regenerated mainnetV8Material by fetching live runtime metadata directly from wss://mainnet-rpc.polymesh.network/ via @polkadot/api (bypassing substrate-api-sidecar, whose /runtime/metadata endpoint 500s on v8 metadata on sidecar versions < 20.10). Verified genesisHash is unchanged and that a fresh V8TransferBuilder build now round-trips through factory.from() using only the default bundled material, with no live material override required. Refs: CECHO-1781 Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
mainnetV8Material(modules/sdk-coin-polyx/src/resources/mainnetV8.ts) was a placeholder created before the Polymesh mainnet v8 fork (July 22, 2026). It mirrored v7 metadata with onlyspecVersion/txVersionbumped to v8 values — the actual pallet/call-index layout was never updated.Every v8 builder (
V8TransferBuilder,V8HexTransferBuilder,V8TokenTransferBuilder,V8RegisterDidBuilder,V8RegisterDidWithCDDBuilder,V8PreApproveAssetBuilder,V8BatchStakingBuilder,V8NominateBuilder,V8BondExtraBuilder,V8UnbondBuilder,V8WithdrawUnbondedBuilder,V8BatchUnstakingBuilder) defaults to this same bundled material in its constructor. This is also the materialTransactionBuilderFactory.tryGetV8Builder()falls back to internally when decoding. So any caller — direct SDK consumer, sandbox script, or future code — that builds/decodes a real mainnet v8 transaction without first overriding.material()with live data hits corrupted call-index resolution.This is a companion fix to #CECHO-1781 (the
getDummyTransferHex()v7→v8 re-encode inbitgo-microservices) and the relatedSI-1034specVersion-forwarding fix already on this repo — this PR fixes the underlying metadata shape, not just the specVersion number.Proof
Decoding a real, correctly-v8-encoded mainnet
transferWithMemoextrinsic using only the old bundledmainnetV8Material(no live override) — the exact fallback pathtryGetV8Builder()uses:It misresolves the call as
system.killStorageand throws, instead of routing toV8TransferBuilder.After regenerating
mainnetV8Materialwith live metadata fetched directly fromwss://mainnet-rpc.polymesh.network/(bypassingsubstrate-api-sidecar, whose/runtime/metadata500s on v8 metadata for sidecar versions < 20.10):genesisHashis unchanged (0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063) — confirms this is the correct chain.V8TransferBuilderbuild using only the default bundled material now correctly encodes call index0x0528.TransactionBuilderFactory.from(), again using only the default material (no live override), now correctly round-trips to aV8TransferBuilderinstead of throwing.specVersion 8000020; this snapshot was captured at that same spec version, at block height 24795900.Why this didn't break wallet-platform's production flows
I audited every real (non-dummy) build/decode call site in wallet-platform's
polyx.ts— fresh builds (PolyxFactory),getSignedTx,transactionToBuilder, the TSS-combine flow,extractMemoFromRawTx, and the sendQueue nonce-rebuild path. All of them fetch live metadata viagetOrFetchTransactionMetadata()(RPC-backed, not the SDK's bundled material) and call.material(liveMaterial)before building/decoding — enforced by an explicit@obligationcomment in the factory. So wallet-platform never actually exercised the bug in this PR. This PR closes the gap for anyone who calls the SDK directly without doing the same.Test plan
mochaunit suite insdk-coin-polyx— 252 passing, 2 pending (unchanged from before this change)genesisHashin new material matches the old placeholder's mainnet genesis hashMade with Cursor