Skip to content

Commit b8f8c91

Browse files
committed
feat: compute hash from witness control-block
1 parent 9947571 commit b8f8c91

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

src/payments/p2tr.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,14 @@ function p2tr(a, opts) {
7373
lazy.prop(o, 'hash', () => {
7474
if (a.hash) return a.hash;
7575
if (a.scriptsTree) return (0, merkle_1.computeMastRoot)(a.scriptsTree);
76-
// todo: compute from witness
76+
const w = _witness();
77+
if (w && w.length > 1) {
78+
const controlBlock = w[w.length - 1];
79+
const leafVersion = controlBlock[0] & 0b11111110;
80+
const script = w[w.length - 2];
81+
const tapLeafHash = (0, types_1.leafHash)(script, leafVersion);
82+
return (0, types_1.rootHash)(controlBlock, tapLeafHash);
83+
}
7784
return null;
7885
});
7986
lazy.prop(o, 'output', () => {

test/fixtures/p2tr.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,10 @@
106106
"expected": {
107107
"name": "p2tr",
108108
"internalPubkey": "a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a36",
109-
"pubkey": "a44784d6b2d0159ca57f52e3e6023a4f1960d22c089d019f3656d9e23926dcc9",
110-
"address": "bc1p53rcf44j6q2eeftl2t37vq36fuvkp53vpzwsr8ek2mv7ywfxmnysdul78t",
111-
"output": "OP_1 a44784d6b2d0159ca57f52e3e6023a4f1960d22c089d019f3656d9e23926dcc9",
109+
"pubkey": "1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
110+
"hash": "c5c62d7fc595ba5fbe61602eb1a29e2e4763408fe1e2b161beb7cb3c71ebcad9",
111+
"address": "bc1pr6lghypk80gf025lx5kgkgv3fcvgd0qfl608psylx0hj624a7j7qay80rv",
112+
"output": "OP_1 1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
112113
"signature": null,
113114
"input": null,
114115
"witness": [
@@ -133,9 +134,10 @@
133134
"expected": {
134135
"name": "p2tr",
135136
"internalPubkey": "a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a36",
136-
"pubkey": "a44784d6b2d0159ca57f52e3e6023a4f1960d22c089d019f3656d9e23926dcc9",
137-
"address": "bc1p53rcf44j6q2eeftl2t37vq36fuvkp53vpzwsr8ek2mv7ywfxmnysdul78t",
138-
"output": "OP_1 a44784d6b2d0159ca57f52e3e6023a4f1960d22c089d019f3656d9e23926dcc9",
137+
"pubkey": "1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
138+
"hash": "c5c62d7fc595ba5fbe61602eb1a29e2e4763408fe1e2b161beb7cb3c71ebcad9",
139+
"address": "bc1pr6lghypk80gf025lx5kgkgv3fcvgd0qfl608psylx0hj624a7j7qay80rv",
140+
"output": "OP_1 1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
139141
"signature": null,
140142
"input": null,
141143
"witness": [

ts_src/payments/p2tr.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,14 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
6969
lazy.prop(o, 'hash', () => {
7070
if (a.hash) return a.hash;
7171
if (a.scriptsTree) return computeMastRoot(a.scriptsTree)
72-
// todo: compute from witness
72+
const w = _witness()
73+
if (w && w.length > 1) {
74+
const controlBlock = w[w.length - 1];
75+
const leafVersion = controlBlock[0] & 0b11111110;
76+
const script = w[w.length - 2];
77+
const tapLeafHash = leafHash(script, leafVersion)
78+
return rootHash(controlBlock, tapLeafHash)
79+
}
7380
return null
7481
});
7582
lazy.prop(o, 'output', () => {
@@ -186,10 +193,9 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
186193
if (!internalPubkeyPoint)
187194
throw new TypeError('Invalid internalPubkey for p2tr witness');
188195

189-
190196
const leafVersion = controlBlock[0] & 0b11111110;
191197
const script = witness[witness.length - 2];
192-
198+
193199
const tapLeafHash = leafHash(script, leafVersion)
194200
const hash = rootHash(controlBlock, tapLeafHash)
195201

0 commit comments

Comments
 (0)