@arkade-os/sdk 0.3.0-alpha.6 → 0.3.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VtxoScript = void 0;
4
4
  exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
5
+ const btc_signer_1 = require("@scure/btc-signer");
5
6
  const payment_js_1 = require("@scure/btc-signer/payment.js");
7
+ const psbt_js_1 = require("@scure/btc-signer/psbt.js");
6
8
  const utils_js_1 = require("@scure/btc-signer/utils.js");
7
- const address_1 = require("./address");
8
- const script_js_1 = require("@scure/btc-signer/script.js");
9
9
  const base_1 = require("@scure/base");
10
+ const address_1 = require("./address");
10
11
  const tapscript_1 = require("./tapscript");
12
+ const TapTreeCoder = psbt_js_1.PSBTOutput.tapTree[2];
11
13
  function scriptFromTapLeafScript(leaf) {
12
14
  return leaf[1].subarray(0, leaf[1].length - 1); // remove the version byte
13
15
  }
@@ -21,13 +23,14 @@ function scriptFromTapLeafScript(leaf) {
21
23
  */
22
24
  class VtxoScript {
23
25
  static decode(tapTree) {
24
- const leaves = decodeTaprootTree(tapTree);
25
- return new VtxoScript(leaves);
26
+ const leaves = TapTreeCoder.decode(tapTree);
27
+ const scripts = leaves.map((leaf) => leaf.script);
28
+ return new VtxoScript(scripts);
26
29
  }
27
30
  constructor(scripts) {
28
31
  this.scripts = scripts;
29
- const tapTree = (0, payment_js_1.taprootListToTree)(scripts.map((script) => ({ script, leafVersion: payment_js_1.TAP_LEAF_VERSION })));
30
- const payment = (0, payment_js_1.p2tr)(utils_js_1.TAPROOT_UNSPENDABLE_KEY, tapTree, undefined, true);
32
+ const tapTree = (0, btc_signer_1.taprootListToTree)(scripts.map((script) => ({ script, leafVersion: payment_js_1.TAP_LEAF_VERSION })));
33
+ const payment = (0, btc_signer_1.p2tr)(utils_js_1.TAPROOT_UNSPENDABLE_KEY, tapTree, undefined, true);
31
34
  if (!payment.tapLeafScript ||
32
35
  payment.tapLeafScript.length !== scripts.length) {
33
36
  throw new Error("invalid scripts");
@@ -36,17 +39,21 @@ class VtxoScript {
36
39
  this.tweakedPublicKey = payment.tweakedPubkey;
37
40
  }
38
41
  encode() {
39
- const tapTree = encodeTaprootTree(this.scripts);
42
+ const tapTree = TapTreeCoder.encode(this.scripts.map((script) => ({
43
+ depth: 1,
44
+ version: payment_js_1.TAP_LEAF_VERSION,
45
+ script,
46
+ })));
40
47
  return tapTree;
41
48
  }
42
49
  address(prefix, serverPubKey) {
43
50
  return new address_1.ArkAddress(serverPubKey, this.tweakedPublicKey, prefix);
44
51
  }
45
52
  get pkScript() {
46
- return script_js_1.Script.encode(["OP_1", this.tweakedPublicKey]);
53
+ return btc_signer_1.Script.encode(["OP_1", this.tweakedPublicKey]);
47
54
  }
48
55
  onchainAddress(network) {
49
- return (0, payment_js_1.Address)(network).encode({
56
+ return (0, btc_signer_1.Address)(network).encode({
50
57
  type: "tr",
51
58
  pubkey: this.tweakedPublicKey,
52
59
  });
@@ -80,89 +87,3 @@ class VtxoScript {
80
87
  }
81
88
  }
82
89
  exports.VtxoScript = VtxoScript;
83
- function decodeTaprootTree(tapTree) {
84
- let offset = 0;
85
- const scripts = [];
86
- // Read number of leaves
87
- const [numLeaves, numLeavesSize] = decodeCompactSizeUint(tapTree, offset);
88
- offset += numLeavesSize;
89
- // Read each leaf
90
- for (let i = 0; i < numLeaves; i++) {
91
- // Skip depth (1 byte)
92
- offset += 1;
93
- // Skip leaf version (1 byte)
94
- offset += 1;
95
- // Read script length
96
- const [scriptLength, scriptLengthSize] = decodeCompactSizeUint(tapTree, offset);
97
- offset += scriptLengthSize;
98
- // Read script content
99
- const script = tapTree.slice(offset, offset + scriptLength);
100
- scripts.push(script);
101
- offset += scriptLength;
102
- }
103
- return scripts;
104
- }
105
- function decodeCompactSizeUint(data, offset) {
106
- const firstByte = data[offset];
107
- if (firstByte < 0xfd) {
108
- return [firstByte, 1];
109
- }
110
- else if (firstByte === 0xfd) {
111
- const value = new DataView(data.buffer).getUint16(offset + 1, true);
112
- return [value, 3];
113
- }
114
- else if (firstByte === 0xfe) {
115
- const value = new DataView(data.buffer).getUint32(offset + 1, true);
116
- return [value, 5];
117
- }
118
- else {
119
- const value = Number(new DataView(data.buffer).getBigUint64(offset + 1, true));
120
- return [value, 9];
121
- }
122
- }
123
- function encodeTaprootTree(leaves) {
124
- const chunks = [];
125
- // Write number of leaves as compact size uint
126
- chunks.push(encodeCompactSizeUint(leaves.length));
127
- for (const tapscript of leaves) {
128
- // Write depth (always 1 for now)
129
- chunks.push(new Uint8Array([1]));
130
- // Write leaf version (0xc0 for tapscript)
131
- chunks.push(new Uint8Array([0xc0]));
132
- // Write script length and script
133
- chunks.push(encodeCompactSizeUint(tapscript.length));
134
- chunks.push(tapscript);
135
- }
136
- // Concatenate all chunks
137
- const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
138
- const result = new Uint8Array(totalLength);
139
- let offset = 0;
140
- for (const chunk of chunks) {
141
- result.set(chunk, offset);
142
- offset += chunk.length;
143
- }
144
- return result;
145
- }
146
- function encodeCompactSizeUint(value) {
147
- if (value < 0xfd) {
148
- return new Uint8Array([value]);
149
- }
150
- else if (value <= 0xffff) {
151
- const buffer = new Uint8Array(3);
152
- buffer[0] = 0xfd;
153
- new DataView(buffer.buffer).setUint16(1, value, true);
154
- return buffer;
155
- }
156
- else if (value <= 0xffffffff) {
157
- const buffer = new Uint8Array(5);
158
- buffer[0] = 0xfe;
159
- new DataView(buffer.buffer).setUint32(1, value, true);
160
- return buffer;
161
- }
162
- else {
163
- const buffer = new Uint8Array(9);
164
- buffer[0] = 0xff;
165
- new DataView(buffer.buffer).setBigUint64(1, BigInt(value), true);
166
- return buffer;
167
- }
168
- }
@@ -1,9 +1,11 @@
1
- import { Address, p2tr, TAP_LEAF_VERSION, taprootListToTree, } from "@scure/btc-signer/payment.js";
1
+ import { Script, Address, p2tr, taprootListToTree } from "@scure/btc-signer";
2
+ import { TAP_LEAF_VERSION } from "@scure/btc-signer/payment.js";
3
+ import { PSBTOutput } from "@scure/btc-signer/psbt.js";
2
4
  import { TAPROOT_UNSPENDABLE_KEY, } from "@scure/btc-signer/utils.js";
3
- import { ArkAddress } from './address.js';
4
- import { Script } from "@scure/btc-signer/script.js";
5
5
  import { hex } from "@scure/base";
6
+ import { ArkAddress } from './address.js';
6
7
  import { ConditionCSVMultisigTapscript, CSVMultisigTapscript, } from './tapscript.js';
8
+ const TapTreeCoder = PSBTOutput.tapTree[2];
7
9
  export function scriptFromTapLeafScript(leaf) {
8
10
  return leaf[1].subarray(0, leaf[1].length - 1); // remove the version byte
9
11
  }
@@ -17,8 +19,9 @@ export function scriptFromTapLeafScript(leaf) {
17
19
  */
18
20
  export class VtxoScript {
19
21
  static decode(tapTree) {
20
- const leaves = decodeTaprootTree(tapTree);
21
- return new VtxoScript(leaves);
22
+ const leaves = TapTreeCoder.decode(tapTree);
23
+ const scripts = leaves.map((leaf) => leaf.script);
24
+ return new VtxoScript(scripts);
22
25
  }
23
26
  constructor(scripts) {
24
27
  this.scripts = scripts;
@@ -32,7 +35,11 @@ export class VtxoScript {
32
35
  this.tweakedPublicKey = payment.tweakedPubkey;
33
36
  }
34
37
  encode() {
35
- const tapTree = encodeTaprootTree(this.scripts);
38
+ const tapTree = TapTreeCoder.encode(this.scripts.map((script) => ({
39
+ depth: 1,
40
+ version: TAP_LEAF_VERSION,
41
+ script,
42
+ })));
36
43
  return tapTree;
37
44
  }
38
45
  address(prefix, serverPubKey) {
@@ -75,89 +82,3 @@ export class VtxoScript {
75
82
  return paths;
76
83
  }
77
84
  }
78
- function decodeTaprootTree(tapTree) {
79
- let offset = 0;
80
- const scripts = [];
81
- // Read number of leaves
82
- const [numLeaves, numLeavesSize] = decodeCompactSizeUint(tapTree, offset);
83
- offset += numLeavesSize;
84
- // Read each leaf
85
- for (let i = 0; i < numLeaves; i++) {
86
- // Skip depth (1 byte)
87
- offset += 1;
88
- // Skip leaf version (1 byte)
89
- offset += 1;
90
- // Read script length
91
- const [scriptLength, scriptLengthSize] = decodeCompactSizeUint(tapTree, offset);
92
- offset += scriptLengthSize;
93
- // Read script content
94
- const script = tapTree.slice(offset, offset + scriptLength);
95
- scripts.push(script);
96
- offset += scriptLength;
97
- }
98
- return scripts;
99
- }
100
- function decodeCompactSizeUint(data, offset) {
101
- const firstByte = data[offset];
102
- if (firstByte < 0xfd) {
103
- return [firstByte, 1];
104
- }
105
- else if (firstByte === 0xfd) {
106
- const value = new DataView(data.buffer).getUint16(offset + 1, true);
107
- return [value, 3];
108
- }
109
- else if (firstByte === 0xfe) {
110
- const value = new DataView(data.buffer).getUint32(offset + 1, true);
111
- return [value, 5];
112
- }
113
- else {
114
- const value = Number(new DataView(data.buffer).getBigUint64(offset + 1, true));
115
- return [value, 9];
116
- }
117
- }
118
- function encodeTaprootTree(leaves) {
119
- const chunks = [];
120
- // Write number of leaves as compact size uint
121
- chunks.push(encodeCompactSizeUint(leaves.length));
122
- for (const tapscript of leaves) {
123
- // Write depth (always 1 for now)
124
- chunks.push(new Uint8Array([1]));
125
- // Write leaf version (0xc0 for tapscript)
126
- chunks.push(new Uint8Array([0xc0]));
127
- // Write script length and script
128
- chunks.push(encodeCompactSizeUint(tapscript.length));
129
- chunks.push(tapscript);
130
- }
131
- // Concatenate all chunks
132
- const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
133
- const result = new Uint8Array(totalLength);
134
- let offset = 0;
135
- for (const chunk of chunks) {
136
- result.set(chunk, offset);
137
- offset += chunk.length;
138
- }
139
- return result;
140
- }
141
- function encodeCompactSizeUint(value) {
142
- if (value < 0xfd) {
143
- return new Uint8Array([value]);
144
- }
145
- else if (value <= 0xffff) {
146
- const buffer = new Uint8Array(3);
147
- buffer[0] = 0xfd;
148
- new DataView(buffer.buffer).setUint16(1, value, true);
149
- return buffer;
150
- }
151
- else if (value <= 0xffffffff) {
152
- const buffer = new Uint8Array(5);
153
- buffer[0] = 0xfe;
154
- new DataView(buffer.buffer).setUint32(1, value, true);
155
- return buffer;
156
- }
157
- else {
158
- const buffer = new Uint8Array(9);
159
- buffer[0] = 0xff;
160
- new DataView(buffer.buffer).setBigUint64(1, BigInt(value), true);
161
- return buffer;
162
- }
163
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.3.0-alpha.6",
3
+ "version": "0.3.0-alpha.7",
4
4
  "description": "Bitcoin wallet SDK with Taproot and Ark integration",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",