Skip to content

Commit 40b3425

Browse files
committed
feat: add WASM-based DOT transaction parsing via @bitgo/wasm-dot
Integrates @bitgo/wasm-dot into sdk-coin-dot for WASM-based transaction parsing using Rust/subxt, replacing the JS txwrapper-polkadot path for tdot (testnet) signed transactions. ## what changed - **wasmParser.ts**: new module with `explainDotTransaction()` and `toJsonFromWasm()` that parse DOT extrinsics via WASM and map to BitGoJS TransactionExplanation / TxData formats. handles transfers, staking (bond, unbond, withdraw, chill, payout), proxy (add/remove), batch (nested + atomic), and transferAll. - **transaction.ts toJson()**: signed tdot transactions now use the WASM path (`toJsonFromWasm`), which handles metadata-aware signed extension parsing (e.g. Westend's AuthorizeCall, StorageWeightReclaim). unsigned transactions still use the legacy txwrapper path. - **webpack config**: added ESM alias for @bitgo/wasm-dot so browser builds use the fetch-based WASM loader instead of fs.readFileSync. - **tests**: 72+ new test lines in dot.ts covering WASM explain for transfers and staking. 511-line byte comparison test suite validating WASM builder output matches legacy txwrapper output byte-for-byte across all transaction types (transfer, stake, unstake, withdraw, chill, proxy, batch). - **withdrawUnstakedBuilder test fix**: numSlashingSpans assertion updated from string to number to match actual type. ## scope WASM path is only active for tdot signed transactions, gated by `this._coinConfig.name === 'tdot' && this._signedTransaction`. mainnet dot remains on the legacy path until validation is complete. BTC-0 TICKET: BTC-0
1 parent fe561c2 commit 40b3425

File tree

10 files changed

+997
-13
lines changed

10 files changed

+997
-13
lines changed

modules/sdk-coin-dot/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@bitgo/sdk-core": "^36.33.2",
4444
"@bitgo/sdk-lib-mpc": "^10.9.0",
4545
"@bitgo/statics": "^58.29.0",
46+
"@bitgo/wasm-dot": "^1.1.2",
4647
"@polkadot/api": "14.1.1",
4748
"@polkadot/api-augment": "14.1.1",
4849
"@polkadot/keyring": "13.5.6",

modules/sdk-coin-dot/src/dot.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@ export interface TransactionPrebuild {
5858
transaction: Interface.TxData;
5959
}
6060

61-
export interface ExplainTransactionOptions {
62-
txPrebuild: TransactionPrebuild;
63-
publicKey: string;
64-
feeInfo: {
65-
fee: string;
66-
};
67-
}
68-
6961
export interface VerifiedTransactionParameters {
7062
txHex: string;
7163
prv: string;

modules/sdk-coin-dot/src/lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ export { TransactionBuilderFactory } from './transactionBuilderFactory';
1616
export { SingletonRegistry } from './singletonRegistry';
1717
export { NativeTransferBuilder } from './nativeTransferBuilder';
1818
export { RemoveProxyBuilder } from './proxyBuilder';
19+
export { explainDotTransaction } from './wasmParser';
20+
export type { ExplainDotTransactionParams, DotWasmExplanation, DotInput } from './wasmParser';
1921
export { Interface, Utils };

modules/sdk-coin-dot/src/lib/transaction.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
} from './iface';
3939
import { getAddress, getDelegateAddress } from './iface_utils';
4040
import utils from './utils';
41+
import { toJsonFromWasm } from './wasmParser';
4142
import BigNumber from 'bignumber.js';
4243
import { Vec } from '@polkadot/types';
4344
import { PalletConstantMetadataV14 } from '@polkadot/types/interfaces';
@@ -161,6 +162,20 @@ export class Transaction extends BaseTransaction {
161162
if (!this._dotTransaction) {
162163
throw new InvalidTransactionError('Empty transaction');
163164
}
165+
166+
// WASM path for signed tdot transactions — validates WASM parsing against production.
167+
// Only for signed txs because toBroadcastFormat() returns the signed extrinsic (parseable).
168+
// Unsigned txs return a signing payload (different format), so they use the legacy path.
169+
if (this._coinConfig.name === 'tdot' && this._signedTransaction) {
170+
return toJsonFromWasm({
171+
txHex: this._signedTransaction,
172+
material: utils.getMaterial(this._coinConfig),
173+
senderAddress: this._sender,
174+
coinConfigName: this._coinConfig.name,
175+
referenceBlock: this._dotTransaction.blockHash,
176+
blockNumber: Number(this._dotTransaction.blockNumber),
177+
});
178+
}
164179
const decodedTx = decode(this._dotTransaction, {
165180
metadataRpc: this._dotTransaction.metadataRpc,
166181
registry: this._registry,

0 commit comments

Comments
 (0)