Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 62 additions & 34 deletions packages/wasm-utxo/cli/test/fixtures/psbt_bitcoin_fullsigned.txt

Large diffs are not rendered by default.

137 changes: 83 additions & 54 deletions packages/wasm-utxo/cli/test/fixtures/psbt_raw_bitcoin_fullsigned.txt

Large diffs are not rendered by default.

61 changes: 36 additions & 25 deletions packages/wasm-utxo/cli/test/fixtures/tx_bitcoin_fullsigned.txt
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
tx: None
├─ version: 1i32
├─ lock_time: 0u32
├─ txid: a341d563b6d62d3c078017ae60a72fae551f7381634871b2764422e9d4968061 (32 bytes)
├─ ntxid: 819e1ce50e5f92d52f3d6cfbb4084355392777d8b23b0bce674674577a940608 (32 bytes)
├─ wtxid: bfb14a40525fa2a173ce7fc0fb4f7fd7d89b07f5b0ea0073e77487de3c0b2d97 (32 bytes)
├─ txid: 895306f11e2bdb8d0ba6eca19c862ed0cab3391a3e02cffd8a02d386eea67e8b (32 bytes)
├─ ntxid: a8f0a1efb5a77f4fe2e40c379d3e122d3b30ac0b88aa80c6e70d3fd72a6cf736 (32 bytes)
├─ wtxid: d93620afa90de598a520acf58551308a9d141f16c276261dcbff2f57828d2c87 (32 bytes)
├─ inputs: 7u64
│ ├─ input_0: None
│ │ ├─ prev_txid: d99efae199fc4d54e5825a8e3368a395e9eb329915cfb5d88dc311507d184836 (32 bytes)
│ │ ├─ prev_txid: 7cce12effc2ea564c4227333fd305447e0de7b3ae7a5fcc751effff3ea1377e1 (32 bytes)
│ │ ├─ prev_vout: 0u32
│ │ ├─ sequence: 4294967295u32
│ │ └─ script_sig: 0047304402201e79545c011e34b1b872b4b057e66262d86881da6a7f853e7e57a9a4d12c6dc102201a538b2175c7b7161c76da18394220f354ae2729fcc1c902b74c59cd79e0153101483045022100dd31a25d0ebea90e67910168ef7c2b383ca26192cd5c8709f02980b7ca90472802203795c65ee0f073b80644d0c8ffa1d428457ae2af3df5b5d8117949781d10c462014c69522103f6f40764bd5d63f200a2778883acf75e96f15095c998263c087270d0c97e7e7f21035ffb7abc70159e0469f4b989a6d5e1785a2904169ff050b2f468fe5d3d5dbbf22103e1524d7f6fc57ab3eacbb659b787106780a475d1db483952c2310b7e9a38975b53ae (253 bytes)
│ │ └─ script_sig: 00473044022063f7d77b3e78d916fef10e0e3249730b0b364a07bd4d1de482e7dc3a6910e13402204925ac2db7e1e6a51970f288a12d88d8abfec4fc3b44686664f5a6d707e6b27101473044022068576594f32f0196dce83d0a2fadde3e3670ae4cee22295337c406374a14496602205858f9cbf54285930c2004045440956db1953a67d305ca3db0206ffd7e7d5343014c69522103f6f40764bd5d63f200a2778883acf75e96f15095c998263c087270d0c97e7e7f21035ffb7abc70159e0469f4b989a6d5e1785a2904169ff050b2f468fe5d3d5dbbf22103e1524d7f6fc57ab3eacbb659b787106780a475d1db483952c2310b7e9a38975b53ae (252 bytes)
│ ├─ input_1: None
│ │ ├─ prev_txid: 1ec9729a1b25373a30f0fe6e0879b31136a54f2f8c98618c46862748a08c5e78 (32 bytes)
│ │ ├─ prev_txid: b9c7b288fd6aa0d1415996e2a5dad9a4e070c129e179277f53e32f602f180646 (32 bytes)
│ │ ├─ prev_vout: 1u32
│ │ ├─ sequence: 4294967295u32
│ │ ├─ script_sig: 22002046d4800a1393330196085399ed4a1700b4c2fd38c52188c3a3a91f721f3c9600 (35 bytes)
│ │ └─ witness: 4u64
│ │ ├─ item_0: (0 bytes)
│ │ ├─ item_1: 304402205f760c27e7598a9e80a2adaf1d925c67d2e6c24aec773e5cce56d234159ab1e502201ce97d5659681ab881e10acc9c8021587f843a15336c3a8b6fb2efc053928b8501 (71 bytes)
│ │ ├─ item_2: 3045022100df41fbcbf3c7f77182627bcb7cd17973b8ca58c16b81de98e94c0293dcf33ac202206017171914fdfbc80f933ab3b5aae4e3d36e968757e6c0788ffbeaaebc68e21e01 (72 bytes)
│ │ ├─ item_1: 3045022100c3dddbc8b20f4aac003165182fb72357486da8a1538d151b06aca94f7894e169022050756f3949e780fd15e3a25baf7b3b3f674422c7ee8aff1d2f77a0f4d7f42ada01 (72 bytes)
│ │ ├─ item_2: 304402204f46d55ab3c78be2dd7b2df1a04aa929478c32445ea948923dc36f13eea30d23022054db1d0f3e7922e1ee1e7c3610b73c0297050c37cc4ac12e8ac63cb71dc314a501 (71 bytes)
│ │ └─ item_3: 522102a585f3fab49b5ef95346d932221a221bd55ec191f15533e0f270b3582574f0352102c4f7866cfd5996bc1068a96313ca15e9ccb5e984583a07340dddae7af014605b2102234531bc9119a36a7946e95aeb74915dd087c7b44f517b8eeeb73f89a0ff1a9953ae (105 bytes)
│ ├─ input_2: None
│ │ ├─ prev_txid: bb0dfbeba59bba69e3ce07a54346f804c543fa46d828ed539d11231adbaa8b7b (32 bytes)
│ │ ├─ prev_txid: 1f57d9560ae9071600b696533192dc17799164fd3fa12804a7f7eb4201c4d5dd (32 bytes)
│ │ ├─ prev_vout: 2u32
│ │ ├─ sequence: 4294967295u32
│ │ ├─ script_sig: (0 bytes)
│ │ └─ witness: 4u64
│ │ ├─ item_0: (0 bytes)
│ │ ├─ item_1: 3045022100d3b03fb77553144e14171c7b1b517a3bf33df87370b65e337f0a50844562261e0220585bc0913b56ad968161d343f321d77f5f94ff3cf62545932f1509239a15a38e01 (72 bytes)
│ │ ├─ item_2: 304402206441089c8c71a4926b49a5ab12bfaa86c4b64abbc519b3d217d68fe71bc43bee02203e17d0752c0b411e9477c22c2f4556a62da39e60095c6e0774bf42aa8f491b4d01 (71 bytes)
│ │ ├─ item_1: 304402207017fae20521ac634cfaf259714d370efcd196f83fb8d7c3133207900f27355902201e9b7f217987da96f77b3ba33e868987d13257cc03a05af959e34be2719fe1b501 (71 bytes)
│ │ ├─ item_2: 3045022100a9a571f171172962c80bf97099c0f1a809bec183af83dabe65bfc51ff1084548022047376a83e5d8bd5bfb07c5720bf90535d9a0ba5837172235132530387618b95901 (72 bytes)
│ │ └─ item_3: 522103519e572ab468560d1f8d0f87699d098308e166905f5dcae4390f060faa8f1ce32103a05bc26391221d685e18daaff36a1e95c34f99451253c16cd42650db278a79112102e80a08885c353676b820cdc290e6d81a0ac95a03e8abbf4bb7aeebfb70feb41853ae (105 bytes)
│ ├─ input_3: None
│ │ ├─ prev_txid: a662a5ffebf58bf3e65e53456c67c029cc154a2409740d8cd37fdee7559c5efd (32 bytes)
│ │ ├─ prev_txid: fc8fe5ff2a818c7661a4629809df2a1ffd60b6d16549fbf4882b54e7413ff8e6 (32 bytes)
│ │ ├─ prev_vout: 3u32
│ │ ├─ sequence: 4294967295u32
│ │ ├─ script_sig: (0 bytes)
│ │ └─ witness: 4u64
│ │ ├─ item_0: e7dab0d277ce7c41933136b44dcabef400f1d0e622a2255f9867d807bc8e0008cfd30766d36d736c8df7aa32917de59d0832b481c499f0917876134532306d45 (64 bytes)
│ │ ├─ item_1: 83b1bb7c6ce5868c8a723c4d350591894809b1335586f60cbfccc6dd4e28b8630a74637b1b242e5a389540db94f23bcbedee9c783830cb2afaff1f2763dbdb7b (64 bytes)
│ │ ├─ item_0: ce28402fd5d3544b9f3a8f21bc122c2147a9b17256458eb5b69b33c0ea5d2531b72108238a7493f2dd264221a87119b5343c16dcc48e941ba507243624f3d3c8 (64 bytes)
│ │ ├─ item_1: be30d2f4e624a99d258f9de83971d249611d1956908b64c8914fe2a347ecd9547b7b67aa6f544e9b5b21d265f7f2b83c67c40c1fc6e22deabbdc320ed1fc6080 (64 bytes)
│ │ ├─ item_2: 207373d723ce0a87f8fdd66843be12dae9d51939f68188d5ad96920bef5f51f496ad20aa88ca194fda43486504b86ac9b71f10fc41de7b1713874839427f74e78c2d5aac (68 bytes)
│ │ └─ item_3: c0bc17ea2bbf6ff46bd5c0c3780be2a63880eb7bb782b39ed86f29b99f4882994e1b178b1b55d3c6aac7b039e3422dfdb9c9d75d4d6fc908e9743e88b651e48d83 (65 bytes)
│ ├─ input_4: None
│ │ ├─ prev_txid: d394375cee23b3b9951488c0403529157a85b058edc0351546d9eb4807e8a1d3 (32 bytes)
│ │ ├─ prev_txid: 998804e6718d94c77eef1e8b3cd787bcc2dbfcbd6c009ab33043e7e500d5b49b (32 bytes)
│ │ ├─ prev_vout: 4u32
│ │ ├─ sequence: 4294967295u32
│ │ ├─ script_sig: (0 bytes)
│ │ └─ witness: 4u64
│ │ ├─ item_0: 4d8e50128b5c61dd449b352a6d6f3d611e163b0794c8c2d057d25401957bb07a70420e336e18f6b255d5b869570c087091c30c1a33f0cac0a40d90d0514c69a4 (64 bytes)
│ │ ├─ item_1: 0a1e013f6d57fb8b248b2b19b08b34c1a3cd5ff6de4acdf19dd4ce0e02d42154856dd569f4668f2abaccbb50ce81a9d2f53efdfb627c2cb14cf92c4189a35da7 (64 bytes)
│ │ ├─ item_0: 63fb7b832f6aa0f406554c195a96086b7e14468e4622b8e9976b3a83dca53a7c9152649a6d42d77c91d078eee2044e40c9ded9c90c0ee73f73930e38480f5063 (64 bytes)
│ │ ├─ item_1: 48ee7fb32dc07262ed7be7d907734df486ae6e54018d0b109518c7ae344366f72a234bdf28bce46a9fb1ef49e9292c26a4d1ce228936bf2824c38bf866ba371a (64 bytes)
│ │ ├─ item_2: 20643151ab03f3a97bb86d3592f12f8d25a8026d89cd47342fc1b49c5e2e63478bad20035c9d632db2ddb8f90cf3ccfc931822bcb1f24562b23ae041abf12e54bca64dac (68 bytes)
│ │ └─ item_3: c1a107a403f7a207e7b1f552d3fd3f55f64ae40e149d0d26f4868ad7faec949eb7637e37cac6e5f22347ab68e876b559117d9597ee7b37fb983c2ab9e51023c976 (65 bytes)
│ ├─ input_5: None
│ │ ├─ prev_txid: 0d2f7f3486edaefc6ab92c21f7caf90085c4de4adac491106fd8a0e4f563dea3 (32 bytes)
│ │ ├─ prev_txid: 02b23e9ffd550fa053f4c43e097b8114e463c8ba52c72b30d31d10cde853aabf (32 bytes)
│ │ ├─ prev_vout: 5u32
│ │ ├─ sequence: 4294967295u32
│ │ ├─ script_sig: (0 bytes)
│ │ └─ witness: 1u64
│ │ └─ item_0: 2ea4aeeef7c10765ed7bdce7ac429b7395e08cf55083df38384781054b0880e244fe8a2d847a8c334431322d0eeba4e34872ef6052e2044fff7fa8763ce0c20b (64 bytes)
│ │ └─ item_0: 0cfa38061dca7d6281adb9d2211757e54519b82cb27071e516ef86a7b8f8825988376fea2664afbdb2de6f9923f53dbbb7f5afd1f919f96c756e31da4342dec4 (64 bytes)
│ └─ input_6: None
│ ├─ prev_txid: 97441d99a8d66f124ab3c9de26b87bd00aeb1547051c842a88165c1b089ee902 (32 bytes)
│ ├─ prev_txid: 200d021345d40b204cc22a07ebad78da17159f34c2c656a2f4a51d68c6ca7754 (32 bytes)
│ ├─ prev_vout: 6u32
│ ├─ sequence: 4294967295u32
│ └─ script_sig: 483045022100d2a7abb6c0563c3000e37412a9b97f6352d17e40960456fe830d264f0474f8b6022038d5cdbe88a319de5d7b7db8f57d0a92524beb242729b46a617adb530f2fa0d00123210336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095ac (109 bytes)
└─ outputs: 5u64
│ └─ script_sig: 473044022066ba18beb6d351e087fe1203f4a0e47ddcc035882f9cd30a83e2d92febe9eff90220664396d8ebdcd04bef62a0781c1261279493b2ad88dc79eddc55f11e3ebcdb9d0123210336ef228ffe9b8efffba052c32d334660dd1f8366cf8fe44ae5aa672b6b629095ac (108 bytes)
└─ outputs: 8u64
├─ output_0: None
│ ├─ value: 900u64
│ ├─ script_pubkey: a914d909474404c124a3d04c3fbff61faa49cf43c58b87 (23 bytes)
Expand All @@ -79,7 +79,18 @@ tx: None
│ ├─ value: 900u64
│ ├─ script_pubkey: 5120b27227f5cadc056afea4b02b4b97b9a0151786234c26ad588dccf134e78931c6 (34 bytes)
│ └─ address: bc1pkfez0aw2mszk4l4ykq45h9ae5q230p3rfsn26kydencnfeufx8rq23ty2z
└─ output_4: None
├─ output_4: None
│ ├─ value: 900u64
│ ├─ script_pubkey: 51204f73b5561399eb397b5ab413e090cc0c48ff703a61afe47cf7d47a23d43b978b (34 bytes)
│ └─ address: bc1pfaem24snn84nj766ksf7pyxvp3y07up6vxh7gl8h63az84pmj79sehcc5d
├─ output_5: None
│ ├─ value: 900u64
│ ├─ script_pubkey: a9141e490a2a3641ffccc557aecddca67104f42978b387 (23 bytes)
│ └─ address: 34T9hBmUH9m7aCiJzk3BCPuLaGdGKRmWdL
├─ output_6: None
│ ├─ value: 900u64
│ ├─ script_pubkey: a914954288203f9697e25eaecb48d85b8a8608c385cf87 (23 bytes)
│ └─ address: 3FJEJqGMWCA8XUnK1jypEy7bu74YMCT8eE
└─ output_7: None
├─ value: 900u64
├─ script_pubkey: 51204f73b5561399eb397b5ab413e090cc0c48ff703a61afe47cf7d47a23d43b978b (34 bytes)
└─ address: bc1pfaem24snn84nj766ksf7pyxvp3y07up6vxh7gl8h63az84pmj79sehcc5d
└─ script_pubkey: 6a0f736574656320617374726f6e6f6d79 (17 bytes)
14 changes: 11 additions & 3 deletions packages/wasm-utxo/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ type-safe API over the raw WASM bindings.

- Generated by `wasm-bindgen` from Rust code
- Exports classes with static methods (e.g., `AddressNamespace`, `UtxolibCompatNamespace`)
- Uses `snake_case` naming (Rust convention)
- Uses loose types (`any`, `string | null`) due to WASM-bindgen limitations

2. **Namespace Wrapper Files** (e.g., `address.ts`, `utxolibCompat.ts`, `fixedScriptWallet.ts`)

- Import the generated WASM namespace classes
- Define precise TypeScript types to replace `any` types
- Export individual functions that wrap the static WASM methods
- Convert `snake_case` WASM methods to `camelCase` (JavaScript convention)
- Re-export related types for convenience

3. **Shared Type Files** (e.g., `coinName.ts`, `triple.ts`)
Expand All @@ -42,8 +44,9 @@ type-safe API over the raw WASM bindings.
Given a WASM-generated class:

```typescript
// wasm/wasm_utxo.d.ts (generated)
// wasm/wasm_utxo.d.ts (generated by wasm-bindgen)
export class AddressNamespace {
// Note: snake_case naming from Rust
static to_output_script_with_coin(address: string, coin: string): Uint8Array;
static from_output_script_with_coin(
script: Uint8Array,
Expand All @@ -53,7 +56,7 @@ export class AddressNamespace {
}
```

We create a wrapper module:
We create a wrapper module that provides better types and camelCase naming:

```typescript
// address.ts
Expand All @@ -62,7 +65,9 @@ import type { CoinName } from "./coinName";

export type AddressFormat = "default" | "cashaddr";

// Wrapper provides camelCase naming and precise types
export function toOutputScriptWithCoin(address: string, coin: CoinName): Uint8Array {
// Calls snake_case WASM method
return AddressNamespace.to_output_script_with_coin(address, coin);
}

Expand All @@ -71,6 +76,7 @@ export function fromOutputScriptWithCoin(
coin: CoinName,
format?: AddressFormat,
): string {
// Calls snake_case WASM method
return AddressNamespace.from_output_script_with_coin(script, coin, format);
}
```
Expand All @@ -85,5 +91,7 @@ export * as address from "./address";
### Benefits

- **Type Safety**: Replace loose `any` and `string` types with precise union types
- **Better DX**: IDE autocomplete works better with concrete types
- **Idiomatic Naming**: Each layer uses its native convention (`snake_case` in Rust, `camelCase` in JavaScript)
- **Better DX**: IDE autocomplete works better with concrete types and familiar naming
- **Maintainability**: Centralized type definitions prevent duplication
- **Clear Separation**: WASM bindings stay pure to Rust conventions, TypeScript handles JS conventions
27 changes: 21 additions & 6 deletions packages/wasm-utxo/js/fixedScriptWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ type ReplayProtection =
export type ScriptId = { chain: number; index: number };

export type ParsedInput = {
address?: string;
address: string;
script: Uint8Array;
value: bigint;
scriptId: ScriptId | undefined;
scriptId: ScriptId | null;
};

export type ParsedOutput = {
address?: string;
address: string | null;
script: Uint8Array;
value: bigint;
scriptId?: ScriptId;
scriptId: ScriptId | null;
};

export type ParsedTransaction = {
Expand All @@ -90,7 +90,7 @@ export class BitGoPsbt {
* @returns A BitGoPsbt instance
*/
static fromBytes(bytes: Uint8Array, network: NetworkName): BitGoPsbt {
const wasm = WasmBitGoPsbt.fromBytes(bytes, network);
const wasm = WasmBitGoPsbt.from_bytes(bytes, network);
return new BitGoPsbt(wasm);
}

Expand All @@ -104,6 +104,21 @@ export class BitGoPsbt {
walletKeys: WalletKeys,
replayProtection: ReplayProtection,
): ParsedTransaction {
return this.wasm.parseTransactionWithWalletKeys(walletKeys, replayProtection);
return this.wasm.parse_transaction_with_wallet_keys(walletKeys, replayProtection);
}

/**
* Parse outputs with wallet keys to identify which outputs belong to a wallet
* with the given wallet keys.
*
* This is useful in cases where we want to identify outputs that belong to a different
* wallet than the inputs.
*
* @param walletKeys - The wallet keys to use for identification
* @returns Array of parsed outputs
* @note This method does NOT validate wallet inputs. It only parses outputs.
*/
parseOutputsWithWalletKeys(walletKeys: WalletKeys): ParsedOutput[] {
return this.wasm.parse_outputs_with_wallet_keys(walletKeys);
}
}
Loading