@arkade-os/sdk 0.5.0-rc.9 → 0.5.1

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.
Files changed (94) hide show
  1. package/README.md +232 -51
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +5 -5
  4. package/dist/adapters/expo.d.ts +5 -5
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/{asyncStorageTaskQueue-DZYrAWN8.d.ts → asyncStorageTaskQueue-CdWheMqT.d.ts} +1 -1
  7. package/dist/{asyncStorageTaskQueue-ChKX-D51.d.cts → asyncStorageTaskQueue-DFt5LgW5.d.cts} +1 -1
  8. package/dist/{chunk-R4KRWX7R.js → chunk-3M22PJVB.js} +427 -1078
  9. package/dist/chunk-3M22PJVB.js.map +1 -0
  10. package/dist/{chunk-J2K7WWMJ.js → chunk-6MIGYYWB.js} +112 -243
  11. package/dist/chunk-6MIGYYWB.js.map +1 -0
  12. package/dist/{chunk-FQCMEAWN.js → chunk-FXVEOEYB.js} +32 -39
  13. package/dist/chunk-FXVEOEYB.js.map +1 -0
  14. package/dist/{chunk-7OL2P5TV.cjs → chunk-GQUFPTN7.cjs} +39 -46
  15. package/dist/chunk-GQUFPTN7.cjs.map +1 -0
  16. package/dist/{chunk-VMVHRKXM.cjs → chunk-GW42FS2X.cjs} +494 -1122
  17. package/dist/chunk-GW42FS2X.cjs.map +1 -0
  18. package/dist/{chunk-V4JZOFYT.cjs → chunk-HQNQ3CLQ.cjs} +124 -254
  19. package/dist/chunk-HQNQ3CLQ.cjs.map +1 -0
  20. package/dist/{chunk-PO2ZDZZC.cjs → chunk-JJ6QKTFZ.cjs} +12 -10
  21. package/dist/chunk-JJ6QKTFZ.cjs.map +1 -0
  22. package/dist/{chunk-3TCWQPAC.js → chunk-NKKJEA3Z.js} +5842 -4284
  23. package/dist/chunk-NKKJEA3Z.js.map +1 -0
  24. package/dist/{chunk-JFZBKPSV.js → chunk-QFB55EOZ.js} +541 -400
  25. package/dist/chunk-QFB55EOZ.js.map +1 -0
  26. package/dist/{chunk-PKD5VPYX.cjs → chunk-QKNSMVBW.cjs} +6143 -4565
  27. package/dist/chunk-QKNSMVBW.cjs.map +1 -0
  28. package/dist/{chunk-VTXMC4N7.cjs → chunk-XLHUGP3G.cjs} +548 -399
  29. package/dist/chunk-XLHUGP3G.cjs.map +1 -0
  30. package/dist/{chunk-Z3QM5XFY.js → chunk-XQRIY5K5.js} +7 -5
  31. package/dist/chunk-XQRIY5K5.js.map +1 -0
  32. package/dist/contracts/handlers/index.cjs +9 -9
  33. package/dist/contracts/handlers/index.d.cts +5 -5
  34. package/dist/contracts/handlers/index.d.ts +5 -5
  35. package/dist/contracts/handlers/index.js +2 -2
  36. package/dist/{delegate-CyBnNY9v.d.ts → delegate-BSbGQabI.d.ts} +1 -1
  37. package/dist/{delegate-Cyv2suFd.d.cts → delegate-CFCfrReG.d.cts} +1 -1
  38. package/dist/{index-BIL9boGL.d.ts → index-B3fRWO5i.d.cts} +1652 -2291
  39. package/dist/{index-BIL9boGL.d.cts → index-B3fRWO5i.d.ts} +1652 -2291
  40. package/dist/index-CzUVvIxA.d.ts +645 -0
  41. package/dist/index-Fpf4mQZr.d.cts +645 -0
  42. package/dist/index.cjs +399 -311
  43. package/dist/index.d.cts +957 -1124
  44. package/dist/index.d.ts +957 -1124
  45. package/dist/index.js +4 -4
  46. package/dist/repositories/realm/index.cjs +165 -103
  47. package/dist/repositories/realm/index.cjs.map +1 -1
  48. package/dist/repositories/realm/index.d.cts +18 -14
  49. package/dist/repositories/realm/index.d.ts +18 -14
  50. package/dist/repositories/realm/index.js +153 -91
  51. package/dist/repositories/realm/index.js.map +1 -1
  52. package/dist/repositories/sqlite/index.cjs +226 -184
  53. package/dist/repositories/sqlite/index.cjs.map +1 -1
  54. package/dist/repositories/sqlite/index.d.cts +22 -21
  55. package/dist/repositories/sqlite/index.d.ts +22 -21
  56. package/dist/repositories/sqlite/index.js +218 -176
  57. package/dist/repositories/sqlite/index.js.map +1 -1
  58. package/dist/{taskRunner-Cu4uO1to.d.ts → taskRunner-CdfoCMaw.d.ts} +1 -1
  59. package/dist/{taskRunner-DxpSuKmh.d.cts → taskRunner-Dk6oDAtd.d.cts} +1 -1
  60. package/dist/wallet/expo/background.cjs +14 -14
  61. package/dist/wallet/expo/background.cjs.map +1 -1
  62. package/dist/wallet/expo/background.d.cts +10 -16
  63. package/dist/wallet/expo/background.d.ts +10 -16
  64. package/dist/wallet/expo/background.js +6 -6
  65. package/dist/wallet/expo/background.js.map +1 -1
  66. package/dist/wallet/expo/index.cjs +19 -14
  67. package/dist/wallet/expo/index.cjs.map +1 -1
  68. package/dist/wallet/expo/index.d.cts +8 -6
  69. package/dist/wallet/expo/index.d.ts +8 -6
  70. package/dist/wallet/expo/index.js +10 -5
  71. package/dist/wallet/expo/index.js.map +1 -1
  72. package/dist/wallet-BQHNgc_v.d.ts +1874 -0
  73. package/dist/wallet-D9dvXu-K.d.cts +1874 -0
  74. package/dist/worker/expo/index.cjs +9 -9
  75. package/dist/worker/expo/index.d.cts +6 -6
  76. package/dist/worker/expo/index.d.ts +6 -6
  77. package/dist/worker/expo/index.js +5 -5
  78. package/package.json +10 -11
  79. package/dist/chunk-3TCWQPAC.js.map +0 -1
  80. package/dist/chunk-7OL2P5TV.cjs.map +0 -1
  81. package/dist/chunk-FQCMEAWN.js.map +0 -1
  82. package/dist/chunk-J2K7WWMJ.js.map +0 -1
  83. package/dist/chunk-JFZBKPSV.js.map +0 -1
  84. package/dist/chunk-PKD5VPYX.cjs.map +0 -1
  85. package/dist/chunk-PO2ZDZZC.cjs.map +0 -1
  86. package/dist/chunk-R4KRWX7R.js.map +0 -1
  87. package/dist/chunk-V4JZOFYT.cjs.map +0 -1
  88. package/dist/chunk-VMVHRKXM.cjs.map +0 -1
  89. package/dist/chunk-VTXMC4N7.cjs.map +0 -1
  90. package/dist/chunk-Z3QM5XFY.js.map +0 -1
  91. package/dist/hdWalletCapable-D1ImQqlu.d.cts +0 -2214
  92. package/dist/hdWalletCapable-DvumVrKW.d.ts +0 -2214
  93. package/dist/index-DleNQcz5.d.cts +0 -850
  94. package/dist/index-QVhQgYvU.d.ts +0 -850
@@ -1,11 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var btcSigner = require('@scure/btc-signer');
4
- var bip68 = require('bip68');
5
3
  var utils_js = require('@scure/btc-signer/utils.js');
6
4
  var base = require('@scure/base');
7
5
  var script_js = require('@scure/btc-signer/script.js');
6
+ var bip68 = require('bip68');
7
+ var btcSigner = require('@scure/btc-signer');
8
8
  var payment_js = require('@scure/btc-signer/payment.js');
9
+ var P = require('micro-packed');
9
10
  var psbt_js = require('@scure/btc-signer/psbt.js');
10
11
  var secp256k1_js = require('@noble/curves/secp256k1.js');
11
12
 
@@ -28,191 +29,13 @@ function _interopNamespace(e) {
28
29
  }
29
30
 
30
31
  var bip68__namespace = /*#__PURE__*/_interopNamespace(bip68);
32
+ var P__namespace = /*#__PURE__*/_interopNamespace(P);
31
33
 
32
34
  var __defProp = Object.defineProperty;
33
35
  var __export = (target, all) => {
34
36
  for (var name in all)
35
37
  __defProp(target, name, { get: all[name], enumerable: true });
36
38
  };
37
- var Transaction = class extends btcSigner.Transaction {
38
- static ARK_TX_OPTS = {
39
- allowUnknown: true,
40
- allowUnknownOutputs: true,
41
- allowUnknownInputs: true
42
- };
43
- constructor(opts) {
44
- super(withArkOpts(opts));
45
- }
46
- static fromPSBT(psbt_, opts) {
47
- return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
48
- }
49
- static fromRaw(raw, opts) {
50
- return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
51
- }
52
- };
53
- function withArkOpts(opts) {
54
- return { ...Transaction.ARK_TX_OPTS, ...opts };
55
- }
56
- function formatSighash(type) {
57
- return `0x${type.toString(16).padStart(2, "0")}`;
58
- }
59
- function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
60
- for (let i = 0; i < tx.inputsLength; i++) {
61
- const declared = tx.getInput(i).sighashType;
62
- if (declared === void 0) continue;
63
- if (!allowedSighashTypes.includes(declared)) {
64
- throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
65
- }
66
- }
67
- }
68
- function timelockToSequence(timelock) {
69
- return bip68__namespace.encode(
70
- timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
71
- );
72
- }
73
- function sequenceToTimelock(sequence) {
74
- const decoded = bip68__namespace.decode(sequence);
75
- if ("blocks" in decoded && decoded.blocks !== void 0) {
76
- return { type: "blocks", value: BigInt(decoded.blocks) };
77
- }
78
- if ("seconds" in decoded && decoded.seconds !== void 0) {
79
- return { type: "seconds", value: BigInt(decoded.seconds) };
80
- }
81
- throw new Error(`Invalid BIP68 sequence: ${sequence}`);
82
- }
83
- var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
84
- ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
85
- ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
86
- ArkPsbtFieldKey2["Cosigner"] = "cosigner";
87
- ArkPsbtFieldKey2["ConditionWitness"] = "condition";
88
- ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
89
- ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
90
- return ArkPsbtFieldKey2;
91
- })(ArkPsbtFieldKey || {});
92
- var ArkPsbtFieldKeyType = 222;
93
- function setArkPsbtField(tx, inputIndex, coder, value) {
94
- tx.updateInput(inputIndex, {
95
- unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
96
- });
97
- }
98
- function getArkPsbtFields(tx, inputIndex, coder) {
99
- const unknown = tx.getInput(inputIndex)?.unknown ?? [];
100
- const fields = [];
101
- for (const u of unknown) {
102
- const v = coder.decode(u);
103
- if (v !== null) fields.push(v);
104
- }
105
- return fields;
106
- }
107
- var VtxoTaprootTree = {
108
- key: "taptree" /* VtxoTaprootTree */,
109
- encode: (value) => [
110
- {
111
- type: ArkPsbtFieldKeyType,
112
- key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
113
- },
114
- value
115
- ],
116
- decode: (value) => nullIfCatch(() => {
117
- if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
118
- return value[1];
119
- })
120
- };
121
- var ConditionWitness = {
122
- key: "condition" /* ConditionWitness */,
123
- encode: (value) => [
124
- {
125
- type: ArkPsbtFieldKeyType,
126
- key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
127
- },
128
- btcSigner.RawWitness.encode(value)
129
- ],
130
- decode: (value) => nullIfCatch(() => {
131
- if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
132
- return btcSigner.RawWitness.decode(value[1]);
133
- })
134
- };
135
- var PrevArkTxField = {
136
- key: "prevarktx" /* PrevArkTx */,
137
- encode: (value) => [
138
- {
139
- type: ArkPsbtFieldKeyType,
140
- key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
141
- },
142
- value
143
- ],
144
- decode: (value) => nullIfCatch(() => {
145
- if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
146
- return value[1];
147
- })
148
- };
149
- var PrevoutTxField = {
150
- key: "prevouttx" /* PrevoutTx */,
151
- encode: (value) => [
152
- {
153
- type: ArkPsbtFieldKeyType,
154
- key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
155
- },
156
- value
157
- ],
158
- decode: (value) => nullIfCatch(() => {
159
- if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
160
- return value[1];
161
- })
162
- };
163
- var CosignerPublicKey = {
164
- key: "cosigner" /* Cosigner */,
165
- encode: (value) => [
166
- {
167
- type: ArkPsbtFieldKeyType,
168
- key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
169
- },
170
- value.key
171
- ],
172
- decode: (unknown) => nullIfCatch(() => {
173
- if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
174
- return {
175
- index: unknown[0].key[unknown[0].key.length - 1],
176
- key: unknown[1]
177
- };
178
- })
179
- };
180
- var VtxoTreeExpiry = {
181
- key: "expiry" /* VtxoTreeExpiry */,
182
- encode: (value) => [
183
- {
184
- type: ArkPsbtFieldKeyType,
185
- key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
186
- },
187
- btcSigner.ScriptNum(6, true).encode(value.value === 0n ? 0n : value.value)
188
- ],
189
- decode: (unknown) => nullIfCatch(() => {
190
- if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
191
- const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
192
- if (!v) return null;
193
- return sequenceToTimelock(Number(v));
194
- })
195
- };
196
- var encodedPsbtFieldKey = Object.fromEntries(
197
- Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
198
- );
199
- var nullIfCatch = (fn) => {
200
- try {
201
- return fn();
202
- } catch {
203
- return null;
204
- }
205
- };
206
- function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
207
- if (key.type !== ArkPsbtFieldKeyType) return false;
208
- const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
209
- if (key.key.length < expected.length) return false;
210
- if (!prefixOnly && key.key.length !== expected.length) return false;
211
- for (let i = 0; i < expected.length; i++) {
212
- if (key.key[i] !== expected[i]) return false;
213
- }
214
- return true;
215
- }
216
39
  var getNetwork = (network) => {
217
40
  const found = networks[network];
218
41
  if (!found) throw new Error(`Unsupported network: ${network}`);
@@ -243,6 +66,7 @@ function withArkPrefix(network, prefix, name) {
243
66
  };
244
67
  }
245
68
  var DEFAULT_ARKADE_SERVER_URL = "https://arkade.computer";
69
+ var DEFAULT_ARKADE_EMULATOR_URL = "https://emulator.arkade.computer";
246
70
  var DEFAULT_NETWORK = networks.bitcoin;
247
71
  var DEFAULT_NETWORK_NAME = "bitcoin";
248
72
  var COMPRESSED_PUBKEY = /^0[23][0-9a-f]{64}$/;
@@ -349,6 +173,26 @@ var ArkAddress = class _ArkAddress {
349
173
  return script_js.Script.encode(["RETURN", this.vtxoTaprootKey]);
350
174
  }
351
175
  };
176
+ function timelockToSequence(timelock) {
177
+ return bip68__namespace.encode(
178
+ timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
179
+ );
180
+ }
181
+ function sequenceToTimelock(sequence) {
182
+ const decoded = bip68__namespace.decode(sequence);
183
+ if ("blocks" in decoded && decoded.blocks !== void 0) {
184
+ return { type: "blocks", value: BigInt(decoded.blocks) };
185
+ }
186
+ if ("seconds" in decoded && decoded.seconds !== void 0) {
187
+ return { type: "seconds", value: BigInt(decoded.seconds) };
188
+ }
189
+ throw new Error(`Invalid BIP68 sequence: ${sequence}`);
190
+ }
191
+ function sequenceToCanonicalTimelock(sequence) {
192
+ if (sequence < 0n || sequence >= 0x80000000n) return void 0;
193
+ const timelock = sequenceToTimelock(Number(sequence));
194
+ return BigInt(timelockToSequence(timelock)) === sequence ? timelock : void 0;
195
+ }
352
196
  var MinimalScriptNum = btcSigner.ScriptNum(void 0, true);
353
197
  function decodeTapscript(script) {
354
198
  const types = [
@@ -596,6 +440,16 @@ exports.CSVMultisigTapscript = void 0;
596
440
  }
597
441
  CSVMultisigTapscript2.isScriptValid = isScriptValid;
598
442
  })(exports.CSVMultisigTapscript || (exports.CSVMultisigTapscript = {}));
443
+ function isConditionScriptValid(script) {
444
+ const asm = btcSigner.Script.decode(script);
445
+ if (asm.length < 1) {
446
+ return new Error(`Invalid script: too short (expected at least 1)`);
447
+ }
448
+ if (asm.lastIndexOf("VERIFY") === -1) {
449
+ return new Error("Invalid script: missing VERIFY operation");
450
+ }
451
+ return true;
452
+ }
599
453
  exports.ConditionCSVMultisigTapscript = void 0;
600
454
  ((ConditionCSVMultisigTapscript2) => {
601
455
  function encode2(params) {
@@ -620,7 +474,7 @@ exports.ConditionCSVMultisigTapscript = void 0;
620
474
  throw isValid;
621
475
  }
622
476
  const asm = btcSigner.Script.decode(script);
623
- let verifyIndex = getVerifyIndex(asm);
477
+ const verifyIndex = asm.lastIndexOf("VERIFY");
624
478
  if (verifyIndex === -1) {
625
479
  throw Error("Invalid script: missing VERIFY operation");
626
480
  }
@@ -655,26 +509,8 @@ exports.ConditionCSVMultisigTapscript = void 0;
655
509
  return tapscript.type === "condition-csv-multisig" /* ConditionCSVMultisig */;
656
510
  }
657
511
  ConditionCSVMultisigTapscript2.is = is;
658
- function getVerifyIndex(asm) {
659
- let verifyIndex = -1;
660
- for (let i = asm.length - 1; i >= 0; i--) {
661
- if (asm[i] === "VERIFY") {
662
- verifyIndex = i;
663
- return verifyIndex;
664
- }
665
- }
666
- return verifyIndex;
667
- }
668
512
  function isScriptValid(script) {
669
- const asm = btcSigner.Script.decode(script);
670
- if (asm.length < 1) {
671
- return new Error(`Invalid script: too short (expected at least 1)`);
672
- }
673
- let verifyIndex = getVerifyIndex(asm);
674
- if (verifyIndex === -1) {
675
- return new Error("Invalid script: missing VERIFY operation");
676
- }
677
- return true;
513
+ return isConditionScriptValid(script);
678
514
  }
679
515
  ConditionCSVMultisigTapscript2.isScriptValid = isScriptValid;
680
516
  })(exports.ConditionCSVMultisigTapscript || (exports.ConditionCSVMultisigTapscript = {}));
@@ -702,7 +538,7 @@ exports.ConditionMultisigTapscript = void 0;
702
538
  throw isValid;
703
539
  }
704
540
  const asm = btcSigner.Script.decode(script);
705
- let verifyIndex = getVerifyIndex(asm);
541
+ const verifyIndex = asm.lastIndexOf("VERIFY");
706
542
  if (verifyIndex === -1) {
707
543
  throw Error("Invalid script: missing VERIFY operation");
708
544
  }
@@ -737,26 +573,8 @@ exports.ConditionMultisigTapscript = void 0;
737
573
  return tapscript.type === "condition-multisig" /* ConditionMultisig */;
738
574
  }
739
575
  ConditionMultisigTapscript2.is = is;
740
- function getVerifyIndex(asm) {
741
- let verifyIndex = -1;
742
- for (let i = asm.length - 1; i >= 0; i--) {
743
- if (asm[i] === "VERIFY") {
744
- verifyIndex = i;
745
- return verifyIndex;
746
- }
747
- }
748
- return verifyIndex;
749
- }
750
576
  function isScriptValid(script) {
751
- const asm = btcSigner.Script.decode(script);
752
- if (asm.length < 1) {
753
- return new Error(`Invalid script: too short (expected at least 1)`);
754
- }
755
- let verifyIndex = getVerifyIndex(asm);
756
- if (verifyIndex === -1) {
757
- return new Error("Invalid script: missing VERIFY operation");
758
- }
759
- return true;
577
+ return isConditionScriptValid(script);
760
578
  }
761
579
  ConditionMultisigTapscript2.isScriptValid = isScriptValid;
762
580
  })(exports.ConditionMultisigTapscript || (exports.ConditionMultisigTapscript = {}));
@@ -881,7 +699,25 @@ function assembleBtcdTaprootTree(scripts) {
881
699
  }
882
700
  return branches[0];
883
701
  }
884
- var TapTreeCoder = psbt_js.PSBTOutput.tapTree[2];
702
+ function btcdLeafLayout(count) {
703
+ const placeholders = Array.from({ length: count }, () => new Uint8Array());
704
+ const indexOf = new Map(placeholders.map((script, index) => [script, index]));
705
+ const layout = [];
706
+ const walk = (node, depth) => {
707
+ if (Array.isArray(node)) {
708
+ walk(node[0], depth + 1);
709
+ walk(node[1], depth + 1);
710
+ } else {
711
+ layout.push({ index: indexOf.get(node.script), depth });
712
+ }
713
+ };
714
+ walk(assembleBtcdTaprootTree(placeholders), 0);
715
+ return layout;
716
+ }
717
+ var TapTreeCoder = P__namespace.array(
718
+ null,
719
+ P__namespace.struct({ depth: P__namespace.U8, version: P__namespace.U8, script: script_js.VarBytes })
720
+ );
885
721
  function scriptFromTapLeafScript(leaf) {
886
722
  return leaf[1].subarray(0, leaf[1].length - 1);
887
723
  }
@@ -901,7 +737,7 @@ var VtxoScript = class _VtxoScript {
901
737
  constructor(scripts) {
902
738
  this.scripts = scripts;
903
739
  const tapTree = assembleBtcdTaprootTree(scripts);
904
- const payment = btcSigner.p2tr(btcSigner.TAPROOT_UNSPENDABLE_KEY, tapTree, void 0, true);
740
+ const payment = btcSigner.p2tr(btcSigner.taprootNumsKey(), tapTree, void 0, true);
905
741
  if (!payment.tapLeafScript || payment.tapLeafScript.length !== scripts.length) {
906
742
  throw new Error("invalid scripts");
907
743
  }
@@ -916,15 +752,46 @@ var VtxoScript = class _VtxoScript {
916
752
  /**
917
753
  * Decode a virtual output script from an encoded TapTree.
918
754
  *
755
+ * Leaves are normally read in construction order and their depths
756
+ * ignored: that covers the {@link encode} form (every depth 1) and the
757
+ * placeholder depths other writers use, such as arkd's. The exception is
758
+ * the BIP-371 form {@link toBIP371TapTree} writes, whose leaves are in the
759
+ * tree's DFS order: for some leaf counts (6, 7, 10, ...) that differs from
760
+ * construction order. A tree whose depths are exactly the shape
761
+ * `assembleBtcdTaprootTree` builds is that form, so its leaves are mapped
762
+ * back to construction order first. No construction-order writer produces
763
+ * that depth sequence when the two orders differ, so this never reorders
764
+ * a tree that decoded correctly before.
765
+ *
766
+ * Every leaf must carry the base tapscript version: the tree is rebuilt
767
+ * with {@link TAP_LEAF_VERSION} leaves, so any other version would
768
+ * silently derive a different taproot key.
769
+ *
919
770
  * @param tapTree - Encoded TapTree bytes
920
771
  * @returns Decoded virtual output script
921
772
  * @throws Error if the TapTree cannot be decoded into a valid script set
773
+ * or a leaf carries a version other than {@link TAP_LEAF_VERSION}
922
774
  * @see encode
923
775
  */
924
776
  static decode(tapTree) {
925
777
  const leaves = TapTreeCoder.decode(tapTree);
778
+ const foreign = leaves.find((leaf) => leaf.version !== payment_js.TAP_LEAF_VERSION);
779
+ if (foreign) {
780
+ throw new Error(`unsupported tap leaf version 0x${foreign.version.toString(16)}`);
781
+ }
926
782
  const scripts = leaves.map((leaf) => leaf.script);
927
- return new _VtxoScript(scripts);
783
+ if (leaves.every((leaf) => leaf.depth === 1)) {
784
+ return new _VtxoScript(scripts);
785
+ }
786
+ const layout = btcdLeafLayout(leaves.length);
787
+ if (layout.some((slot, i) => slot.depth !== leaves[i].depth)) {
788
+ return new _VtxoScript(scripts);
789
+ }
790
+ const ordered = new Array(leaves.length);
791
+ layout.forEach((slot, i) => {
792
+ ordered[slot.index] = scripts[i];
793
+ });
794
+ return new _VtxoScript(ordered);
928
795
  }
929
796
  /**
930
797
  * Encode the virtual output script to a TapTree byte representation.
@@ -1007,21 +874,323 @@ var VtxoScript = class _VtxoScript {
1007
874
  return paths;
1008
875
  }
1009
876
  };
1010
- function getSequence(tapLeafScript) {
1011
- let sequence = void 0;
877
+ function toBIP371TapTree(tapTree) {
878
+ const scripts = TapTreeCoder.decode(tapTree).map((leaf) => leaf.script);
879
+ const vtxoScript = new VtxoScript(scripts);
880
+ return vtxoScript.leaves.map((leaf) => ({
881
+ depth: leaf[0].merklePath.length,
882
+ version: payment_js.TAP_LEAF_VERSION,
883
+ script: scriptFromTapLeafScript(leaf)
884
+ }));
885
+ }
886
+ function getSequence(tapLeafScript) {
887
+ let sequence = void 0;
888
+ try {
889
+ const scriptWithLeafVersion = tapLeafScript[1];
890
+ const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
891
+ try {
892
+ const params = exports.CSVMultisigTapscript.decode(script).params;
893
+ sequence = timelockToSequence(params.timelock);
894
+ } catch {
895
+ const params = exports.CLTVMultisigTapscript.decode(script).params;
896
+ sequence = Number(params.absoluteTimelock);
897
+ }
898
+ } catch {
899
+ }
900
+ return sequence;
901
+ }
902
+ var Transaction = class extends btcSigner.Transaction {
903
+ static ARK_TX_OPTS = {
904
+ unknown: "ignore",
905
+ allowUnknownOutputs: true,
906
+ allowUnknownInputs: true
907
+ };
908
+ constructor(opts) {
909
+ super(withArkOpts(opts));
910
+ }
911
+ /**
912
+ * Decode a PSBT. PSBTs carrying a legacy `PSBT_OUT_TAP_TREE` (see
913
+ * {@link repairLegacyOutputTapTrees}) are repaired and decoded again
914
+ * instead of being rejected.
915
+ */
916
+ static fromPSBT(psbt_, opts) {
917
+ try {
918
+ return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
919
+ } catch (err) {
920
+ const repaired = repairLegacyOutputTapTrees(psbt_);
921
+ if (!repaired) throw err;
922
+ return btcSigner.Transaction.fromPSBT(repaired, withArkOpts(opts));
923
+ }
924
+ }
925
+ static fromRaw(raw, opts) {
926
+ return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
927
+ }
928
+ };
929
+ function withArkOpts(opts) {
930
+ return { ...Transaction.ARK_TX_OPTS, ...opts };
931
+ }
932
+ var PSBT_MAGIC = new Uint8Array([112, 115, 98, 116, 255]);
933
+ var PSBT_GLOBAL_UNSIGNED_TX = 0;
934
+ var PSBT_GLOBAL_INPUT_COUNT = 4;
935
+ var PSBT_OUT_TAP_TREE = 6;
936
+ function repairLegacyOutputTapTrees(psbt) {
937
+ let maps;
938
+ let inputsCount;
939
+ try {
940
+ maps = readPsbtMaps(psbt);
941
+ inputsCount = psbtInputsCount(maps[0]);
942
+ } catch {
943
+ return void 0;
944
+ }
945
+ let repaired = false;
946
+ for (const output of maps.slice(1 + inputsCount)) {
947
+ for (const kv of output) {
948
+ if (kv.key.length !== 1 || kv.key[0] !== PSBT_OUT_TAP_TREE) continue;
949
+ const value = legacyTapTreeToBIP371(kv.value);
950
+ if (!value) continue;
951
+ kv.value = value;
952
+ repaired = true;
953
+ }
954
+ }
955
+ return repaired ? writePsbtMaps(maps) : void 0;
956
+ }
957
+ function legacyTapTreeToBIP371(value) {
958
+ try {
959
+ psbt_js.PSBTOutput.tapTree[2].decode(value);
960
+ return void 0;
961
+ } catch {
962
+ }
963
+ let leaves;
964
+ try {
965
+ leaves = TapTreeCoder.decode(value);
966
+ } catch {
967
+ return void 0;
968
+ }
969
+ if (leaves.length === 0 || leaves.some((leaf) => leaf.depth !== 1)) return void 0;
970
+ try {
971
+ return TapTreeCoder.encode(toBIP371TapTree(value));
972
+ } catch {
973
+ return void 0;
974
+ }
975
+ }
976
+ function psbtInputsCount(global) {
977
+ for (const { key, value } of global) {
978
+ if (key.length !== 1) continue;
979
+ if (key[0] === PSBT_GLOBAL_UNSIGNED_TX) return btcSigner.RawTx.decode(value).inputs.length;
980
+ if (key[0] === PSBT_GLOBAL_INPUT_COUNT) return readCompactSize(value, 0)[0];
981
+ }
982
+ throw new Error("PSBT: missing input count");
983
+ }
984
+ function readPsbtMaps(psbt) {
985
+ for (let i = 0; i < PSBT_MAGIC.length; i++) {
986
+ if (psbt[i] !== PSBT_MAGIC[i]) throw new Error("PSBT: invalid magic");
987
+ }
988
+ const maps = [];
989
+ let pos = PSBT_MAGIC.length;
990
+ while (pos < psbt.length) {
991
+ const map = [];
992
+ for (; ; ) {
993
+ const [keyLen, afterKeyLen] = readCompactSize(psbt, pos);
994
+ pos = afterKeyLen;
995
+ if (keyLen === 0) break;
996
+ const key = readBytes(psbt, pos, keyLen);
997
+ pos += keyLen;
998
+ const [valueLen, afterValueLen] = readCompactSize(psbt, pos);
999
+ pos = afterValueLen;
1000
+ const value = readBytes(psbt, pos, valueLen);
1001
+ pos += valueLen;
1002
+ map.push({ key, value });
1003
+ }
1004
+ maps.push(map);
1005
+ }
1006
+ if (maps.length === 0) throw new Error("PSBT: missing global map");
1007
+ return maps;
1008
+ }
1009
+ function writePsbtMaps(maps) {
1010
+ const parts = [PSBT_MAGIC];
1011
+ for (const map of maps) {
1012
+ for (const { key, value } of map) {
1013
+ parts.push(writeCompactSize(key.length), key, writeCompactSize(value.length), value);
1014
+ }
1015
+ parts.push(new Uint8Array([0]));
1016
+ }
1017
+ return utils_js.concatBytes(...parts);
1018
+ }
1019
+ function readBytes(data, pos, len) {
1020
+ if (pos + len > data.length) throw new Error("PSBT: unexpected end of data");
1021
+ return data.slice(pos, pos + len);
1022
+ }
1023
+ function readCompactSize(data, pos) {
1024
+ const first = readBytes(data, pos, 1)[0];
1025
+ if (first < 253) return [first, pos + 1];
1026
+ const width = first === 253 ? 2 : first === 254 ? 4 : 8;
1027
+ const bytes = readBytes(data, pos + 1, width);
1028
+ let value = 0;
1029
+ for (let i = width - 1; i >= 0; i--) value = value * 256 + bytes[i];
1030
+ if (!Number.isSafeInteger(value)) throw new Error("PSBT: compact size too large");
1031
+ return [value, pos + 1 + width];
1032
+ }
1033
+ function writeCompactSize(value) {
1034
+ if (value < 253) return new Uint8Array([value]);
1035
+ const width = value <= 65535 ? 2 : value <= 4294967295 ? 4 : 8;
1036
+ const out = new Uint8Array(1 + width);
1037
+ out[0] = width === 2 ? 253 : width === 4 ? 254 : 255;
1038
+ for (let i = 0, v = value; i < width; i++, v = Math.floor(v / 256)) out[1 + i] = v % 256;
1039
+ return out;
1040
+ }
1041
+ function formatSighash(type) {
1042
+ return `0x${type.toString(16).padStart(2, "0")}`;
1043
+ }
1044
+ function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
1045
+ for (let i = 0; i < tx.inputsLength; i++) {
1046
+ const declared = tx.getInput(i).sighashType;
1047
+ if (declared === void 0) continue;
1048
+ if (!allowedSighashTypes.includes(declared)) {
1049
+ throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
1050
+ }
1051
+ }
1052
+ }
1053
+
1054
+ // src/utils/time.ts
1055
+ function assertNonNegativeMs(name, ms) {
1056
+ if (ms !== void 0 && (!Number.isSafeInteger(ms) || ms < 0)) {
1057
+ throw new Error(`${name} must be a non-negative safe integer`);
1058
+ }
1059
+ }
1060
+ var MAX_TIMER_MS = 2 ** 31 - 1;
1061
+ function assertTimerMs(name, ms) {
1062
+ assertNonNegativeMs(name, ms);
1063
+ if (ms !== void 0 && ms > MAX_TIMER_MS) {
1064
+ throw new Error(`${name} must not exceed ${MAX_TIMER_MS} milliseconds`);
1065
+ }
1066
+ }
1067
+ var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
1068
+ ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
1069
+ ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
1070
+ ArkPsbtFieldKey2["Cosigner"] = "cosigner";
1071
+ ArkPsbtFieldKey2["ConditionWitness"] = "condition";
1072
+ ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
1073
+ ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
1074
+ return ArkPsbtFieldKey2;
1075
+ })(ArkPsbtFieldKey || {});
1076
+ var ArkPsbtFieldKeyType = 222;
1077
+ function setArkPsbtField(tx, inputIndex, coder, value) {
1078
+ tx.updateInput(inputIndex, {
1079
+ unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
1080
+ });
1081
+ }
1082
+ function getArkPsbtFields(tx, inputIndex, coder) {
1083
+ const unknown = tx.getInput(inputIndex)?.unknown ?? [];
1084
+ return unknown.map((u) => coder.decode(u)).filter((v) => v !== null);
1085
+ }
1086
+ var VtxoTaprootTree = {
1087
+ key: "taptree" /* VtxoTaprootTree */,
1088
+ encode: (value) => [
1089
+ {
1090
+ type: ArkPsbtFieldKeyType,
1091
+ key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
1092
+ },
1093
+ value
1094
+ ],
1095
+ decode: (value) => nullIfCatch(() => {
1096
+ if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
1097
+ return value[1];
1098
+ })
1099
+ };
1100
+ var ConditionWitness = {
1101
+ key: "condition" /* ConditionWitness */,
1102
+ encode: (value) => [
1103
+ {
1104
+ type: ArkPsbtFieldKeyType,
1105
+ key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
1106
+ },
1107
+ btcSigner.RawWitness.encode(value)
1108
+ ],
1109
+ decode: (value) => nullIfCatch(() => {
1110
+ if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
1111
+ return btcSigner.RawWitness.decode(value[1]);
1112
+ })
1113
+ };
1114
+ var PrevArkTxField = {
1115
+ key: "prevarktx" /* PrevArkTx */,
1116
+ encode: (value) => [
1117
+ {
1118
+ type: ArkPsbtFieldKeyType,
1119
+ key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
1120
+ },
1121
+ value
1122
+ ],
1123
+ decode: (value) => nullIfCatch(() => {
1124
+ if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
1125
+ return value[1];
1126
+ })
1127
+ };
1128
+ var PrevoutTxField = {
1129
+ key: "prevouttx" /* PrevoutTx */,
1130
+ encode: (value) => [
1131
+ {
1132
+ type: ArkPsbtFieldKeyType,
1133
+ key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
1134
+ },
1135
+ value
1136
+ ],
1137
+ decode: (value) => nullIfCatch(() => {
1138
+ if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
1139
+ return value[1];
1140
+ })
1141
+ };
1142
+ var CosignerPublicKey = {
1143
+ key: "cosigner" /* Cosigner */,
1144
+ encode: (value) => [
1145
+ {
1146
+ type: ArkPsbtFieldKeyType,
1147
+ key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
1148
+ },
1149
+ value.key
1150
+ ],
1151
+ decode: (unknown) => nullIfCatch(() => {
1152
+ if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
1153
+ return {
1154
+ index: unknown[0].key[unknown[0].key.length - 1],
1155
+ key: unknown[1]
1156
+ };
1157
+ })
1158
+ };
1159
+ var VtxoTreeExpiry = {
1160
+ key: "expiry" /* VtxoTreeExpiry */,
1161
+ encode: (value) => [
1162
+ {
1163
+ type: ArkPsbtFieldKeyType,
1164
+ key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
1165
+ },
1166
+ btcSigner.ScriptNum(6, true).encode(value.value)
1167
+ ],
1168
+ decode: (unknown) => nullIfCatch(() => {
1169
+ if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
1170
+ const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
1171
+ if (!v) return null;
1172
+ return sequenceToTimelock(Number(v));
1173
+ })
1174
+ };
1175
+ var encodedPsbtFieldKey = Object.fromEntries(
1176
+ Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
1177
+ );
1178
+ var nullIfCatch = (fn) => {
1012
1179
  try {
1013
- const scriptWithLeafVersion = tapLeafScript[1];
1014
- const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
1015
- try {
1016
- const params = exports.CSVMultisigTapscript.decode(script).params;
1017
- sequence = timelockToSequence(params.timelock);
1018
- } catch {
1019
- const params = exports.CLTVMultisigTapscript.decode(script).params;
1020
- sequence = Number(params.absoluteTimelock);
1021
- }
1180
+ return fn();
1022
1181
  } catch {
1182
+ return null;
1023
1183
  }
1024
- return sequence;
1184
+ };
1185
+ function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
1186
+ if (key.type !== ArkPsbtFieldKeyType) return false;
1187
+ const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
1188
+ if (key.key.length < expected.length) return false;
1189
+ if (!prefixOnly && key.key.length !== expected.length) return false;
1190
+ for (let i = 0; i < expected.length; i++) {
1191
+ if (key.key[i] !== expected[i]) return false;
1192
+ }
1193
+ return true;
1025
1194
  }
1026
1195
 
1027
1196
  // src/providers/eventSource.ts
@@ -1049,11 +1218,15 @@ function resolveEventSource(override) {
1049
1218
  }
1050
1219
 
1051
1220
  // package.json
1052
- var version = "0.5.0-rc.9";
1221
+ var version = "0.5.1";
1053
1222
 
1054
1223
  // src/utils/fetch.ts
1055
1224
  var buildVersion = "0.9.9";
1056
1225
  var sdkVersion = `ts-sdk/${version}`;
1226
+ var ARKADE_VERSION_HEADERS = {
1227
+ "X-Build-Version": buildVersion,
1228
+ "X-SDK-VERSION": sdkVersion
1229
+ };
1057
1230
  var FetchError = class extends Error {
1058
1231
  /** The request URL that failed, when derivable from the `fetch` input. */
1059
1232
  url;
@@ -1102,27 +1275,12 @@ function baseFetch(input, init) {
1102
1275
  }
1103
1276
  function fetch(input, init) {
1104
1277
  const headers = new Headers(init?.headers);
1105
- headers.set("X-Build-Version", buildVersion);
1106
- headers.set("X-SDK-VERSION", sdkVersion);
1278
+ for (const [name, value] of Object.entries(ARKADE_VERSION_HEADERS)) headers.set(name, value);
1107
1279
  return baseFetch(input, { ...init, headers });
1108
1280
  }
1109
1281
  function describeRequest(input, init) {
1110
- let url;
1111
- if (typeof input === "string") {
1112
- url = input;
1113
- } else if (input instanceof URL) {
1114
- url = input.href;
1115
- } else {
1116
- url = input.url;
1117
- }
1118
- let method;
1119
- if (init?.method !== void 0) {
1120
- method = init.method;
1121
- } else if (input instanceof Request) {
1122
- method = input.method;
1123
- } else {
1124
- method = "GET";
1125
- }
1282
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1283
+ const method = init?.method !== void 0 ? init.method : input instanceof Request ? input.method : "GET";
1126
1284
  return { url, method };
1127
1285
  }
1128
1286
 
@@ -1146,15 +1304,13 @@ var ArkErrorName = {
1146
1304
  INVALID_TX_FILTER: "INVALID_TX_FILTER",
1147
1305
  TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED",
1148
1306
  /**
1149
- * A CLTV closure was spent before its absolute locktime matured. Raised only by
1150
- * `submitTx` (never `finalizeTx`), with metadata
1151
- * `{ locktime, current_locktime, type: "height" | "time" }`.
1152
- *
1153
- * Self-healing, so defer and retry rather than fail: the server matures a
1154
- * seconds-locktime against the **chain tip block's timestamp**, not its wall clock,
1155
- * so a spend attempted promptly at maturity is rejected until a later block lands.
1307
+ * A CLTV closure was spent before its absolute locktime matured. `submitTx` only, with
1308
+ * metadata `{ locktime, current_locktime, type: "height" | "time" }`. Self-healing, so defer
1309
+ * and retry: the server matures a seconds-locktime against the **chain tip block's
1310
+ * timestamp**, not wall clock, so a prompt spend is rejected until a later block lands.
1156
1311
  */
1157
- FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED"
1312
+ FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED",
1313
+ INVALID_INTENT_PROOF: "INVALID_INTENT_PROOF"
1158
1314
  };
1159
1315
  function isArkError(error, name) {
1160
1316
  return error instanceof ArkError && (name === void 0 || error.name === name);
@@ -1230,8 +1386,8 @@ exports.Intent = void 0;
1230
1386
  }
1231
1387
  if (ins.length == 0) throw new Error("intent proof requires at least one input");
1232
1388
  const inputs = ins.map(prepareCoinAsIntentProofInput);
1233
- if (!validateInputs(inputs)) ;
1234
- if (!validateOutputs(outputs)) ;
1389
+ validateInputs(inputs);
1390
+ validateOutputs(outputs);
1235
1391
  const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
1236
1392
  return craftToSignTx(toSpend, inputs, outputs, message);
1237
1393
  }
@@ -1286,7 +1442,6 @@ var OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btcSigner.OP.RETURN]);
1286
1442
  var ZERO_32 = new Uint8Array(32).fill(0);
1287
1443
  var MAX_INDEX = 4294967295;
1288
1444
  var TAG_INTENT_PROOF = "ark-intent-proof-message";
1289
- var PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 9;
1290
1445
  function validateInput(input) {
1291
1446
  if (input.index === void 0) throw new Error("intent proof input requires index");
1292
1447
  if (input.txid === void 0) throw new Error("intent proof input requires txid");
@@ -1296,7 +1451,6 @@ function validateInput(input) {
1296
1451
  }
1297
1452
  function validateInputs(inputs) {
1298
1453
  inputs.forEach(validateInput);
1299
- return true;
1300
1454
  }
1301
1455
  function validateOutput(output) {
1302
1456
  if (output.amount === void 0) throw new Error("intent proof output requires amount");
@@ -1305,7 +1459,6 @@ function validateOutput(output) {
1305
1459
  }
1306
1460
  function validateOutputs(outputs) {
1307
1461
  outputs.forEach(validateOutput);
1308
- return true;
1309
1462
  }
1310
1463
  function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
1311
1464
  const messageHash = hashMessage(message, tag);
@@ -1333,8 +1486,9 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
1333
1486
  version: 2,
1334
1487
  lockTime: 0
1335
1488
  });
1489
+ const { unknown: _, ...toSpendInput } = firstInput;
1336
1490
  tx.addInput({
1337
- ...firstInput,
1491
+ ...toSpendInput,
1338
1492
  txid: toSpend.id,
1339
1493
  index: 0,
1340
1494
  witnessUtxo: {
@@ -1368,14 +1522,7 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
1368
1522
  script: output.script
1369
1523
  });
1370
1524
  }
1371
- const global = tx.global;
1372
- global.unknown = [
1373
- ...global.unknown ?? [],
1374
- [
1375
- { type: PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE, key: new Uint8Array() },
1376
- new TextEncoder().encode(message)
1377
- ]
1378
- ];
1525
+ tx.global.genericSignedMessage = new TextEncoder().encode(message);
1379
1526
  return tx;
1380
1527
  }
1381
1528
  function hashMessage(message, tag = TAG_INTENT_PROOF) {
@@ -1425,6 +1572,7 @@ function eventSourceIterator(eventSource) {
1425
1572
  cleanedUp = true;
1426
1573
  eventSource.removeEventListener("message", messageHandler);
1427
1574
  eventSource.removeEventListener("error", errorHandler);
1575
+ eventSource.removeEventListener("failure", failureHandler);
1428
1576
  };
1429
1577
  const close = () => {
1430
1578
  if (closed) return;
@@ -1451,10 +1599,8 @@ function eventSourceIterator(eventSource) {
1451
1599
  messageQueue.push(event);
1452
1600
  }
1453
1601
  };
1454
- const errorHandler = () => {
1602
+ const rejectWith = (error) => {
1455
1603
  if (closed) return;
1456
- const error = new Error("EventSource error");
1457
- error.name = "EventSourceError";
1458
1604
  if (errorResolve) {
1459
1605
  const reject = errorResolve;
1460
1606
  messageResolve = null;
@@ -1464,8 +1610,11 @@ function eventSourceIterator(eventSource) {
1464
1610
  errorQueue.push(error);
1465
1611
  }
1466
1612
  };
1613
+ const errorHandler = () => rejectWith(eventSourceError("EventSource error"));
1614
+ const failureHandler = (event) => rejectWith(streamFailureError(event.data));
1467
1615
  eventSource.addEventListener("message", messageHandler);
1468
1616
  eventSource.addEventListener("error", errorHandler);
1617
+ eventSource.addEventListener("failure", failureHandler);
1469
1618
  const gen = (async function* () {
1470
1619
  try {
1471
1620
  while (!closed) {
@@ -1503,6 +1652,20 @@ function eventSourceIterator(eventSource) {
1503
1652
  };
1504
1653
  return managed;
1505
1654
  }
1655
+ function eventSourceError(message) {
1656
+ const error = new Error(message);
1657
+ error.name = "EventSourceError";
1658
+ return error;
1659
+ }
1660
+ function streamFailureError(data) {
1661
+ let message = String(data);
1662
+ try {
1663
+ const parsed = typeof data === "string" ? JSON.parse(data) : data;
1664
+ if (typeof parsed?.message === "string") message = parsed.message;
1665
+ } catch {
1666
+ }
1667
+ return eventSourceError(`EventSource failure: ${message}`);
1668
+ }
1506
1669
  function isEventSourceError(error) {
1507
1670
  return error instanceof Error && error.name === "EventSourceError";
1508
1671
  }
@@ -1512,7 +1675,7 @@ var DEFAULT_MAX_CONCURRENT = 6;
1512
1675
  var DEFAULT_COOLDOWN_MS = 5e3;
1513
1676
  var MAX_COOLDOWN_MS = 6e4;
1514
1677
  var DEFAULT_JITTER_MS = 500;
1515
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1678
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, MAX_TIMER_MS)));
1516
1679
  function parseRetryAfterMs(header) {
1517
1680
  if (header === null || header === void 0) return void 0;
1518
1681
  const trimmed = header.trim();
@@ -1545,6 +1708,9 @@ var OriginRateGate = class {
1545
1708
  maxCooldownMs;
1546
1709
  jitterMs;
1547
1710
  constructor(options) {
1711
+ assertNonNegativeMs("defaultCooldownMs", options?.defaultCooldownMs);
1712
+ assertNonNegativeMs("maxCooldownMs", options?.maxCooldownMs);
1713
+ assertNonNegativeMs("jitterMs", options?.jitterMs);
1548
1714
  this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
1549
1715
  this.defaultCooldownMs = options?.defaultCooldownMs ?? DEFAULT_COOLDOWN_MS;
1550
1716
  this.maxCooldownMs = options?.maxCooldownMs ?? MAX_COOLDOWN_MS;
@@ -1750,6 +1916,20 @@ var RestArkProvider = class {
1750
1916
  "Arkade server reported a configuration digest mismatch; server info was refreshed. Rebuild and retry the request under the new server info."
1751
1917
  );
1752
1918
  }
1919
+ async postJson(url, body, failureMessage) {
1920
+ const response = await this.authedFetch(url, {
1921
+ method: "POST",
1922
+ headers: {
1923
+ "Content-Type": "application/json"
1924
+ },
1925
+ body: JSON.stringify(body)
1926
+ });
1927
+ if (!response.ok) {
1928
+ const errorText = await response.text();
1929
+ handleError(errorText, failureMessage(errorText, response));
1930
+ }
1931
+ return response;
1932
+ }
1753
1933
  async getInfo() {
1754
1934
  const url = `${this.serverUrl}/v1/info`;
1755
1935
  const response = await rateGate.runHttp(
@@ -1815,20 +1995,14 @@ var RestArkProvider = class {
1815
1995
  }
1816
1996
  async submitTx(signedArkTx, checkpointTxs) {
1817
1997
  const url = `${this.serverUrl}/v1/tx/submit`;
1818
- const response = await this.authedFetch(url, {
1819
- method: "POST",
1820
- headers: {
1821
- "Content-Type": "application/json"
1822
- },
1823
- body: JSON.stringify({
1998
+ const response = await this.postJson(
1999
+ url,
2000
+ {
1824
2001
  signedArkTx,
1825
2002
  checkpointTxs
1826
- })
1827
- });
1828
- if (!response.ok) {
1829
- const errorText = await response.text();
1830
- handleError(errorText, `Failed to submit virtual transaction: ${errorText}`);
1831
- }
2003
+ },
2004
+ (errorText) => `Failed to submit virtual transaction: ${errorText}`
2005
+ );
1832
2006
  const data = await response.json();
1833
2007
  return {
1834
2008
  arkTxid: data.arkTxid,
@@ -1838,129 +2012,87 @@ var RestArkProvider = class {
1838
2012
  }
1839
2013
  async finalizeTx(arkTxid, finalCheckpointTxs) {
1840
2014
  const url = `${this.serverUrl}/v1/tx/finalize`;
1841
- const response = await this.authedFetch(url, {
1842
- method: "POST",
1843
- headers: {
1844
- "Content-Type": "application/json"
1845
- },
1846
- body: JSON.stringify({
2015
+ await this.postJson(
2016
+ url,
2017
+ {
1847
2018
  arkTxid,
1848
2019
  finalCheckpointTxs
1849
- })
1850
- });
1851
- if (!response.ok) {
1852
- const errorText = await response.text();
1853
- handleError(errorText, `Failed to finalize offchain transaction: ${errorText}`);
1854
- }
2020
+ },
2021
+ (errorText) => `Failed to finalize offchain transaction: ${errorText}`
2022
+ );
1855
2023
  }
1856
2024
  async registerIntent(intent) {
1857
2025
  const url = `${this.serverUrl}/v1/batch/registerIntent`;
1858
- const response = await this.authedFetch(url, {
1859
- method: "POST",
1860
- headers: {
1861
- "Content-Type": "application/json"
1862
- },
1863
- body: JSON.stringify({
2026
+ const response = await this.postJson(
2027
+ url,
2028
+ {
1864
2029
  intent: {
1865
2030
  proof: intent.proof,
1866
2031
  message: exports.Intent.encodeMessage(intent.message)
1867
2032
  }
1868
- })
1869
- });
1870
- if (!response.ok) {
1871
- const errorText = await response.text();
1872
- handleError(errorText, `Failed to register intent: ${errorText}`);
1873
- }
2033
+ },
2034
+ (errorText) => `Failed to register intent: ${errorText}`
2035
+ );
1874
2036
  const data = await response.json();
1875
2037
  return data.intentId;
1876
2038
  }
1877
2039
  async deleteIntent(intent) {
1878
2040
  const url = `${this.serverUrl}/v1/batch/deleteIntent`;
1879
- const response = await this.authedFetch(url, {
1880
- method: "POST",
1881
- headers: {
1882
- "Content-Type": "application/json"
1883
- },
1884
- body: JSON.stringify({
2041
+ await this.postJson(
2042
+ url,
2043
+ {
1885
2044
  intent: {
1886
2045
  proof: intent.proof,
1887
2046
  message: exports.Intent.encodeMessage(intent.message)
1888
2047
  }
1889
- })
1890
- });
1891
- if (!response.ok) {
1892
- const errorText = await response.text();
1893
- handleError(errorText, `Failed to delete intent: ${errorText}`);
1894
- }
2048
+ },
2049
+ (errorText) => `Failed to delete intent: ${errorText}`
2050
+ );
1895
2051
  }
1896
2052
  async confirmRegistration(intentId) {
1897
2053
  const url = `${this.serverUrl}/v1/batch/ack`;
1898
- const response = await this.authedFetch(url, {
1899
- method: "POST",
1900
- headers: {
1901
- "Content-Type": "application/json"
1902
- },
1903
- body: JSON.stringify({
2054
+ await this.postJson(
2055
+ url,
2056
+ {
1904
2057
  intentId
1905
- })
1906
- });
1907
- if (!response.ok) {
1908
- const errorText = await response.text();
1909
- handleError(errorText, `Failed to confirm registration: ${errorText}`);
1910
- }
2058
+ },
2059
+ (errorText) => `Failed to confirm registration: ${errorText}`
2060
+ );
1911
2061
  }
1912
2062
  async submitTreeNonces(batchId, pubkey, nonces) {
1913
2063
  const url = `${this.serverUrl}/v1/batch/tree/submitNonces`;
1914
- const response = await this.authedFetch(url, {
1915
- method: "POST",
1916
- headers: {
1917
- "Content-Type": "application/json"
1918
- },
1919
- body: JSON.stringify({
2064
+ await this.postJson(
2065
+ url,
2066
+ {
1920
2067
  batchId,
1921
2068
  pubkey,
1922
2069
  treeNonces: encodeMusig2Nonces(nonces)
1923
- })
1924
- });
1925
- if (!response.ok) {
1926
- const errorText = await response.text();
1927
- handleError(errorText, `Failed to submit tree nonces: ${errorText}`);
1928
- }
2070
+ },
2071
+ (errorText) => `Failed to submit tree nonces: ${errorText}`
2072
+ );
1929
2073
  }
1930
2074
  async submitTreeSignatures(batchId, pubkey, signatures) {
1931
2075
  const url = `${this.serverUrl}/v1/batch/tree/submitSignatures`;
1932
- const response = await this.authedFetch(url, {
1933
- method: "POST",
1934
- headers: {
1935
- "Content-Type": "application/json"
1936
- },
1937
- body: JSON.stringify({
2076
+ await this.postJson(
2077
+ url,
2078
+ {
1938
2079
  batchId,
1939
2080
  pubkey,
1940
2081
  treeSignatures: encodeMusig2Signatures(signatures)
1941
- })
1942
- });
1943
- if (!response.ok) {
1944
- const errorText = await response.text();
1945
- handleError(errorText, `Failed to submit tree signatures: ${errorText}`);
1946
- }
2082
+ },
2083
+ (errorText) => `Failed to submit tree signatures: ${errorText}`
2084
+ );
1947
2085
  }
1948
2086
  async submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
1949
2087
  const url = `${this.serverUrl}/v1/batch/submitForfeitTxs`;
1950
- const response = await this.authedFetch(url, {
1951
- method: "POST",
1952
- headers: {
1953
- "Content-Type": "application/json"
1954
- },
1955
- body: JSON.stringify({
2088
+ await this.postJson(
2089
+ url,
2090
+ {
1956
2091
  signedForfeitTxs,
1957
2092
  signedCommitmentTx
1958
- })
1959
- });
1960
- if (!response.ok) {
1961
- const errorText = await response.text();
1962
- handleError(errorText, `Failed to submit forfeit transactions: ${response.statusText}`);
1963
- }
2093
+ },
2094
+ (_, res) => `Failed to submit forfeit transactions: ${res.statusText}`
2095
+ );
1964
2096
  }
1965
2097
  getEventStream(signal, topics) {
1966
2098
  const url = `${this.serverUrl}/v1/batch/events`;
@@ -2083,22 +2215,16 @@ var RestArkProvider = class {
2083
2215
  }
2084
2216
  async getPendingTxs(intent) {
2085
2217
  const url = `${this.serverUrl}/v1/tx/pending`;
2086
- const response = await this.authedFetch(url, {
2087
- method: "POST",
2088
- headers: {
2089
- "Content-Type": "application/json"
2090
- },
2091
- body: JSON.stringify({
2218
+ const response = await this.postJson(
2219
+ url,
2220
+ {
2092
2221
  intent: {
2093
2222
  proof: intent.proof,
2094
2223
  message: exports.Intent.encodeMessage(intent.message)
2095
2224
  }
2096
- })
2097
- });
2098
- if (!response.ok) {
2099
- const errorText = await response.text();
2100
- handleError(errorText, `Failed to get pending transactions: ${errorText}`);
2101
- }
2225
+ },
2226
+ (errorText) => `Failed to get pending transactions: ${errorText}`
2227
+ );
2102
2228
  const data = await response.json();
2103
2229
  return data.pendingTxs;
2104
2230
  }
@@ -2364,11 +2490,16 @@ async function getNormalizedVtxos(provider, opts) {
2364
2490
  const { vtxos, page } = await provider.getVtxos(opts);
2365
2491
  return { vtxos: vtxos.map(normalizeVtxo), page };
2366
2492
  }
2493
+ var SCRIPT_CHUNK_CONCURRENCY = 4;
2367
2494
  async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
2368
2495
  const { pageSize = DEFAULT_PAGE_SIZE, ...filters } = opts;
2369
2496
  const all = [];
2497
+ const chunks = [];
2370
2498
  for (let i = 0; i < scripts.length; i += SCRIPT_QUERY_CHUNK_SIZE) {
2371
- const chunk = scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE);
2499
+ chunks.push(scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE));
2500
+ }
2501
+ const fetchChunk = async (chunk) => {
2502
+ const result = [];
2372
2503
  let pageIndex = 0;
2373
2504
  let hasMore = true;
2374
2505
  while (hasMore) {
@@ -2378,11 +2509,18 @@ async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
2378
2509
  pageIndex,
2379
2510
  pageSize
2380
2511
  });
2381
- all.push(...vtxos);
2512
+ result.push(...vtxos);
2382
2513
  hasMore = page ? vtxos.length === pageSize : false;
2383
2514
  pageIndex++;
2384
2515
  if (hasMore) await new Promise((r) => setTimeout(r, 500));
2385
2516
  }
2517
+ return result;
2518
+ };
2519
+ for (let i = 0; i < chunks.length; i += SCRIPT_CHUNK_CONCURRENCY) {
2520
+ const batch = await Promise.all(
2521
+ chunks.slice(i, i + SCRIPT_CHUNK_CONCURRENCY).map(fetchChunk)
2522
+ );
2523
+ for (const result of batch) all.push(...result);
2386
2524
  }
2387
2525
  return all;
2388
2526
  }
@@ -2405,7 +2543,7 @@ async function fetchVtxoCreatedAtByTxid(provider, txids) {
2405
2543
  }
2406
2544
  return createdAt;
2407
2545
  }
2408
- function hasTerminalSpend(vtxo) {
2546
+ function isVtxoSpent(vtxo) {
2409
2547
  const n = normalizeVtxo(vtxo);
2410
2548
  return !!n.isSpent || !!n.spentBy || !!n.settledBy;
2411
2549
  }
@@ -2416,15 +2554,19 @@ function isPastExpiry(vtxo, now) {
2416
2554
  }
2417
2555
  function canSpendOffchain(vtxo, now) {
2418
2556
  const n = normalizeVtxo(vtxo);
2419
- return !hasTerminalSpend(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
2557
+ return !isVtxoSpent(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
2420
2558
  }
2421
2559
  function canRecoverOnchain(vtxo, now) {
2422
2560
  const n = normalizeVtxo(vtxo);
2423
- return !hasTerminalSpend(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
2561
+ return !isVtxoSpent(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
2424
2562
  }
2425
2563
  function canSweepOnchain(vtxo) {
2426
2564
  const n = normalizeVtxo(vtxo);
2427
- return !hasTerminalSpend(n) && !!n.isUnrolled;
2565
+ return !isVtxoSpent(n) && !!n.isUnrolled;
2566
+ }
2567
+ function requiresForfeit(vtxo) {
2568
+ const n = normalizeVtxo(vtxo);
2569
+ return !n.isSwept && !n.isUnrolled;
2428
2570
  }
2429
2571
  function toOffchainInputFeeParams(vtxo) {
2430
2572
  return {
@@ -2439,6 +2581,7 @@ function isVirtualCoin(input) {
2439
2581
  return typeof input === "object" && input !== null && typeof input.script === "string";
2440
2582
  }
2441
2583
 
2584
+ exports.ARKADE_VERSION_HEADERS = ARKADE_VERSION_HEADERS;
2442
2585
  exports.ArkAddress = ArkAddress;
2443
2586
  exports.ArkError = ArkError;
2444
2587
  exports.ArkErrorName = ArkErrorName;
@@ -2447,6 +2590,7 @@ exports.ArkPsbtFieldKeyType = ArkPsbtFieldKeyType;
2447
2590
  exports.BITCOIN_EMULATOR_PUBKEY = BITCOIN_EMULATOR_PUBKEY;
2448
2591
  exports.ConditionWitness = ConditionWitness;
2449
2592
  exports.CosignerPublicKey = CosignerPublicKey;
2593
+ exports.DEFAULT_ARKADE_EMULATOR_URL = DEFAULT_ARKADE_EMULATOR_URL;
2450
2594
  exports.DEFAULT_ARKADE_SERVER_URL = DEFAULT_ARKADE_SERVER_URL;
2451
2595
  exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
2452
2596
  exports.DEFAULT_NETWORK_NAME = DEFAULT_NETWORK_NAME;
@@ -2475,6 +2619,8 @@ exports.VtxoTreeExpiry = VtxoTreeExpiry;
2475
2619
  exports.__export = __export;
2476
2620
  exports.assembleBtcdTaprootTree = assembleBtcdTaprootTree;
2477
2621
  exports.assertAllowedSighashTypes = assertAllowedSighashTypes;
2622
+ exports.assertNonNegativeMs = assertNonNegativeMs;
2623
+ exports.assertTimerMs = assertTimerMs;
2478
2624
  exports.baseFetch = baseFetch;
2479
2625
  exports.buildVersion = buildVersion;
2480
2626
  exports.canRecoverOnchain = canRecoverOnchain;
@@ -2486,7 +2632,6 @@ exports.craftToSpendTx = craftToSpendTx;
2486
2632
  exports.decodeTapscript = decodeTapscript;
2487
2633
  exports.defaultEmulatorPubkey = defaultEmulatorPubkey;
2488
2634
  exports.eventSourceIterator = eventSourceIterator;
2489
- exports.fetch = fetch;
2490
2635
  exports.fetchVtxoCreatedAtByTxid = fetchVtxoCreatedAtByTxid;
2491
2636
  exports.formatSighash = formatSighash;
2492
2637
  exports.getAllNormalizedVtxos = getAllNormalizedVtxos;
@@ -2495,7 +2640,6 @@ exports.getConfiguredEventSource = getConfiguredEventSource;
2495
2640
  exports.getNetwork = getNetwork;
2496
2641
  exports.getNormalizedVtxos = getNormalizedVtxos;
2497
2642
  exports.getSequence = getSequence;
2498
- exports.hasTerminalSpend = hasTerminalSpend;
2499
2643
  exports.isArkError = isArkError;
2500
2644
  exports.isEventSourceError = isEventSourceError;
2501
2645
  exports.isEventSourceUnavailableError = isEventSourceUnavailableError;
@@ -2503,21 +2647,26 @@ exports.isFetchTimeoutError = isFetchTimeoutError;
2503
2647
  exports.isPastExpiry = isPastExpiry;
2504
2648
  exports.isRetryableProviderError = isRetryableProviderError;
2505
2649
  exports.isVirtualCoin = isVirtualCoin;
2650
+ exports.isVtxoSpent = isVtxoSpent;
2506
2651
  exports.maybeArkError = maybeArkError;
2507
2652
  exports.networkFromArkadeInfo = networkFromArkadeInfo;
2508
2653
  exports.networks = networks;
2509
2654
  exports.normalizeVtxo = normalizeVtxo;
2510
2655
  exports.rateGate = rateGate;
2656
+ exports.requiresForfeit = requiresForfeit;
2511
2657
  exports.resolveEmulatorPubkey = resolveEmulatorPubkey;
2512
2658
  exports.resolveEventSource = resolveEventSource;
2513
2659
  exports.resolveTimeHeight = resolveTimeHeight;
2514
2660
  exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
2515
2661
  exports.sdkVersion = sdkVersion;
2662
+ exports.sequenceToCanonicalTimelock = sequenceToCanonicalTimelock;
2516
2663
  exports.sequenceToTimelock = sequenceToTimelock;
2517
2664
  exports.setArkPsbtField = setArkPsbtField;
2665
+ exports.streamFailureError = streamFailureError;
2518
2666
  exports.throwIfHttpUnavailable = throwIfHttpUnavailable;
2519
2667
  exports.timelockToSequence = timelockToSequence;
2668
+ exports.toBIP371TapTree = toBIP371TapTree;
2520
2669
  exports.toOffchainInputFeeParams = toOffchainInputFeeParams;
2521
2670
  exports.toProviderUnavailable = toProviderUnavailable;
2522
- //# sourceMappingURL=chunk-VTXMC4N7.cjs.map
2523
- //# sourceMappingURL=chunk-VTXMC4N7.cjs.map
2671
+ //# sourceMappingURL=chunk-XLHUGP3G.cjs.map
2672
+ //# sourceMappingURL=chunk-XLHUGP3G.cjs.map