Skip to content

Commit c85396d

Browse files
authored
Merge pull request #281 from BitGo/veetragjain/cshld-770-add-support-for-sbtc-reclaim-transactions
feat(wasm-utxo): handle PayloadDrop in fromWasmNode converter
2 parents af61422 + 502e390 commit c85396d

3 files changed

Lines changed: 30 additions & 1 deletion

File tree

packages/wasm-utxo/js/ast/formatNode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ type Miniscript =
4646
| Wrap<{ hash256: string }>
4747
| Wrap<{ hash160: string }>
4848
| Wrap<{ older: number }>
49-
| Wrap<{ after: number }>;
49+
| Wrap<{ after: number }>
50+
| Wrap<{ payload_drop: string }>;
5051

5152
type TapTree = [TapTree, TapTree] | Miniscript;
5253

packages/wasm-utxo/js/ast/fromWasmNode.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ function fromUnknown(v: unknown): Node | Node[] {
114114
return node("multi", value);
115115
case "MultiA":
116116
return node("multi_a", value);
117+
case "PayloadDrop":
118+
return node("payload_drop", value);
117119

118120
case "Tree":
119121
if (!Array.isArray(value) || value.length !== 2) {

packages/wasm-utxo/test/sbtc.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as assert from "assert";
22
import * as crypto from "crypto";
33
import { Descriptor } from "../js/index.js";
4+
import { fromDescriptor, formatNode } from "../js/ast/index.js";
45
import { getDefaultXPubs, getUnspendableKey } from "../js/testutils/descriptor/descriptors.js";
56

67
// sBTC protocol uses two taproot script leaves:
@@ -245,4 +246,29 @@ describe("sBTC taproot descriptor", function () {
245246
assert.strictEqual(reclaimLeaf.AndV[0].Drop.Older.relLockTime, 1);
246247
});
247248
});
249+
250+
describe("fromDescriptor (wasm → JS AST)", function () {
251+
it("does not throw on a descriptor containing payload_drop", () => {
252+
assert.doesNotThrow(() => fromDescriptor(descriptor));
253+
});
254+
255+
it("emits a payload_drop node carrying the original hex payload", () => {
256+
const ast = fromDescriptor(descriptor);
257+
const formatted = formatNode(ast);
258+
assert.ok(
259+
formatted.includes(
260+
"payload_drop(0000000000013880051ad206838b7981a116c334e8cb1b950afb73eb54a5)",
261+
),
262+
`expected payload_drop(<hex>) in formatted AST, got: ${formatted}`,
263+
);
264+
});
265+
266+
it("round-trips the reclaim leaf via formatNode", () => {
267+
const ast = fromDescriptor(descriptor) as unknown as {
268+
tr: [string, [unknown, Parameters<typeof formatNode>[0]]];
269+
};
270+
const reclaimAst = ast.tr[1][1];
271+
assert.strictEqual(formatNode(reclaimAst), RECLAIM_LEAF);
272+
});
273+
});
248274
});

0 commit comments

Comments
 (0)