@arkade-os/sdk 0.4.67 → 0.4.69

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 (78) hide show
  1. package/README.md +38 -0
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +2 -2
  4. package/dist/adapters/expo.d.ts +2 -2
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/adapters/indexedDB.cjs +5 -5
  7. package/dist/adapters/indexedDB.js +4 -4
  8. package/dist/{asyncStorageTaskQueue-Za-e_zMk.d.ts → asyncStorageTaskQueue-BgUJN-3X.d.ts} +2 -2
  9. package/dist/{asyncStorageTaskQueue-LTpeXYaD.d.cts → asyncStorageTaskQueue-Cstx6hS7.d.cts} +2 -2
  10. package/dist/{chunk-6TAQF6EV.js → chunk-2PPL3O7Z.js} +72 -120
  11. package/dist/chunk-2PPL3O7Z.js.map +1 -0
  12. package/dist/{chunk-2JV4VQ7C.cjs → chunk-5MLC2HU3.cjs} +17 -3
  13. package/dist/chunk-5MLC2HU3.cjs.map +1 -0
  14. package/dist/{chunk-MJUTO3PY.cjs → chunk-EBYCTLET.cjs} +832 -488
  15. package/dist/chunk-EBYCTLET.cjs.map +1 -0
  16. package/dist/{chunk-CO3KKSWM.cjs → chunk-GVHUHTRH.cjs} +17 -17
  17. package/dist/{chunk-CO3KKSWM.cjs.map → chunk-GVHUHTRH.cjs.map} +1 -1
  18. package/dist/{chunk-YDRZDZPP.cjs → chunk-HQ4DMGA4.cjs} +10 -10
  19. package/dist/{chunk-YDRZDZPP.cjs.map → chunk-HQ4DMGA4.cjs.map} +1 -1
  20. package/dist/{chunk-3WIWNE4P.js → chunk-L5SCQYHF.js} +16 -4
  21. package/dist/chunk-L5SCQYHF.js.map +1 -0
  22. package/dist/{chunk-MZFUZUTQ.js → chunk-MNMPGEK2.js} +4 -4
  23. package/dist/{chunk-MZFUZUTQ.js.map → chunk-MNMPGEK2.js.map} +1 -1
  24. package/dist/{chunk-AEWJU6NZ.js → chunk-TA7XLEP2.js} +411 -68
  25. package/dist/chunk-TA7XLEP2.js.map +1 -0
  26. package/dist/{chunk-OIZ2V2VD.cjs → chunk-WIFL5QYZ.cjs} +118 -166
  27. package/dist/chunk-WIFL5QYZ.cjs.map +1 -0
  28. package/dist/{chunk-EALWOVHK.js → chunk-XLWDX7QZ.js} +4 -4
  29. package/dist/{chunk-EALWOVHK.js.map → chunk-XLWDX7QZ.js.map} +1 -1
  30. package/dist/{chunk-R2YAMONM.cjs → chunk-XQPN5YP2.cjs} +17 -17
  31. package/dist/{chunk-R2YAMONM.cjs.map → chunk-XQPN5YP2.cjs.map} +1 -1
  32. package/dist/{chunk-X3VEMUVV.js → chunk-YG7T6LI3.js} +3 -3
  33. package/dist/{chunk-X3VEMUVV.js.map → chunk-YG7T6LI3.js.map} +1 -1
  34. package/dist/contracts/handlers/index.cjs +9 -9
  35. package/dist/contracts/handlers/index.d.cts +3 -3
  36. package/dist/contracts/handlers/index.d.ts +3 -3
  37. package/dist/contracts/handlers/index.js +2 -2
  38. package/dist/{delegate-cdmzb2f9.d.ts → delegate-BPdzTbwN.d.ts} +1 -1
  39. package/dist/{delegate-Bz2e2zXY.d.cts → delegate-DrwIar11.d.cts} +1 -1
  40. package/dist/{hdWalletCapable-Hi12xjCJ.d.ts → hdWalletCapable-D4WH35z0.d.cts} +49 -5
  41. package/dist/{hdWalletCapable-BSjuUYOO.d.cts → hdWalletCapable-DyxCiNVE.d.ts} +49 -5
  42. package/dist/{index-BiACuWaf.d.ts → index-BqhpAqqj.d.cts} +96 -119
  43. package/dist/{index-D2GjZxBr.d.cts → index-TZJvbIaA.d.ts} +96 -119
  44. package/dist/{index-DU5o_hz7.d.cts → index-dWRqYSdS.d.cts} +70 -2
  45. package/dist/{index-DU5o_hz7.d.ts → index-dWRqYSdS.d.ts} +70 -2
  46. package/dist/index.cjs +297 -289
  47. package/dist/index.d.cts +29 -8
  48. package/dist/index.d.ts +29 -8
  49. package/dist/index.js +4 -4
  50. package/dist/repositories/realm/index.cjs +19 -19
  51. package/dist/repositories/realm/index.d.cts +2 -2
  52. package/dist/repositories/realm/index.d.ts +2 -2
  53. package/dist/repositories/realm/index.js +5 -5
  54. package/dist/repositories/sqlite/index.cjs +18 -18
  55. package/dist/repositories/sqlite/index.d.cts +2 -2
  56. package/dist/repositories/sqlite/index.d.ts +2 -2
  57. package/dist/repositories/sqlite/index.js +5 -5
  58. package/dist/{taskRunner-BZJMLQ6g.d.cts → taskRunner-CzYKyJ9c.d.cts} +2 -2
  59. package/dist/{taskRunner-DATaRQus.d.ts → taskRunner-D2fnbqYw.d.ts} +2 -2
  60. package/dist/wallet/expo/background.cjs +14 -14
  61. package/dist/wallet/expo/background.d.cts +3 -3
  62. package/dist/wallet/expo/background.d.ts +3 -3
  63. package/dist/wallet/expo/background.js +6 -6
  64. package/dist/wallet/expo/index.cjs +14 -14
  65. package/dist/wallet/expo/index.d.cts +4 -4
  66. package/dist/wallet/expo/index.d.ts +4 -4
  67. package/dist/wallet/expo/index.js +5 -5
  68. package/dist/worker/expo/index.cjs +9 -9
  69. package/dist/worker/expo/index.d.cts +4 -4
  70. package/dist/worker/expo/index.d.ts +4 -4
  71. package/dist/worker/expo/index.js +5 -5
  72. package/package.json +1 -1
  73. package/dist/chunk-2JV4VQ7C.cjs.map +0 -1
  74. package/dist/chunk-3WIWNE4P.js.map +0 -1
  75. package/dist/chunk-6TAQF6EV.js.map +0 -1
  76. package/dist/chunk-AEWJU6NZ.js.map +0 -1
  77. package/dist/chunk-MJUTO3PY.cjs.map +0 -1
  78. package/dist/chunk-OIZ2V2VD.cjs.map +0 -1
package/README.md CHANGED
@@ -346,6 +346,39 @@ if (incomingFunds.type === "vtxo") {
346
346
  }
347
347
  ```
348
348
 
349
+ #### Cancelling a wait
350
+
351
+ `waitForIncomingFunds` is **a live subscription, not a one-shot query**. It opens an onchain address watcher plus an indexer stream and holds them until it settles. Cancel it whenever you might not await it to completion — pass a `timeoutMs`, or an `AbortSignal`:
352
+
353
+ ```typescript
354
+ const controller = new AbortController()
355
+
356
+ try {
357
+ const funds = await waitForIncomingFunds(wallet, { signal: controller.signal })
358
+ } catch (error) {
359
+ if ((error as Error).name !== "AbortError") throw error
360
+ // cancelled — watchers already released
361
+ }
362
+
363
+ // or bound the wait directly
364
+ await waitForIncomingFunds(wallet, { timeoutMs: 30_000 })
365
+ ```
366
+
367
+ Do **not** `Promise.race` an uncancelled call against a timer:
368
+
369
+ ```typescript
370
+ // WRONG: race abandons the loser without stopping it. Repeat this on a
371
+ // polling loop and the subscriptions stack until the process exits.
372
+ await Promise.race([sleep(15_000), waitForIncomingFunds(wallet)])
373
+
374
+ // Right: the signal tears the watcher down when the timer wins.
375
+ await waitForIncomingFunds(wallet, { timeoutMs: 15_000 }).catch(() => null)
376
+ ```
377
+
378
+ If you want a plain polling loop, use your own timer plus `wallet.getBalance()` — it observes new funds on the next cycle. If you want to keep a watcher across many iterations, call `wallet.notifyIncomingFunds(cb)` **once** and hold its `stop()` function, rather than resubscribing per tick.
379
+
380
+ Concurrent watchers over the same address set share a single Esplora subscription, so a duplicated or leaked watcher no longer multiplies explorer traffic. That is a safety net, not a licence to skip `stop()`.
381
+
349
382
  ### Onboarding
350
383
 
351
384
  Onboarding allows you to swap onchain funds into virtual outputs:
@@ -574,6 +607,11 @@ const expiringVtxos = await manager.getExpiringVtxos()
574
607
  const urgentlyExpiring = await manager.getExpiringVtxos(60_000)
575
608
  ```
576
609
 
610
+ A virtual output whose unilateral exit already happened is never offered for renewal, and the
611
+ exported `isVtxoExpiringSoon` answers `false` for it regardless of its batch expiry: "expiring
612
+ soon" is a renewal signal, and no batch can take an output that already lives onchain. Its remedy
613
+ is `Unroll.completeUnroll`, and its value shows up in `balance.unrolled`.
614
+
577
615
  #### Boarding Input Sweep
578
616
 
579
617
  When a boarding input's CSV timelock expires, it can no longer be onboarded into Arkade cooperatively. The sweep feature detects these expired UTXOs and builds a raw onchain transaction that spends them via the unilateral exit path back to a fresh boarding address, restarting the timelock.
@@ -1,19 +1,19 @@
1
1
  'use strict';
2
2
 
3
- var chunkR2YAMONM_cjs = require('../chunk-R2YAMONM.cjs');
4
- require('../chunk-CO3KKSWM.cjs');
5
- require('../chunk-2JV4VQ7C.cjs');
3
+ var chunkXQPN5YP2_cjs = require('../chunk-XQPN5YP2.cjs');
4
+ require('../chunk-GVHUHTRH.cjs');
5
+ require('../chunk-5MLC2HU3.cjs');
6
6
  require('../chunk-5BLDMQED.cjs');
7
7
 
8
8
 
9
9
 
10
10
  Object.defineProperty(exports, "ExpoArkProvider", {
11
11
  enumerable: true,
12
- get: function () { return chunkR2YAMONM_cjs.ExpoArkProvider; }
12
+ get: function () { return chunkXQPN5YP2_cjs.ExpoArkProvider; }
13
13
  });
14
14
  Object.defineProperty(exports, "ExpoIndexerProvider", {
15
15
  enumerable: true,
16
- get: function () { return chunkR2YAMONM_cjs.ExpoIndexerProvider; }
16
+ get: function () { return chunkXQPN5YP2_cjs.ExpoIndexerProvider; }
17
17
  });
18
18
  //# sourceMappingURL=expo.cjs.map
19
19
  //# sourceMappingURL=expo.cjs.map
@@ -1,5 +1,5 @@
1
- import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-DU5o_hz7.cjs';
2
- export { q as ArkProvider, r as IndexerProvider } from '../index-DU5o_hz7.cjs';
1
+ import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-dWRqYSdS.cjs';
2
+ export { q as ArkProvider, r as IndexerProvider } from '../index-dWRqYSdS.cjs';
3
3
  import '@scure/btc-signer/utils.js';
4
4
  import '@scure/btc-signer/transaction.js';
5
5
  import '@scure/btc-signer';
@@ -1,5 +1,5 @@
1
- import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-DU5o_hz7.js';
2
- export { q as ArkProvider, r as IndexerProvider } from '../index-DU5o_hz7.js';
1
+ import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-dWRqYSdS.js';
2
+ export { q as ArkProvider, r as IndexerProvider } from '../index-dWRqYSdS.js';
3
3
  import '@scure/btc-signer/utils.js';
4
4
  import '@scure/btc-signer/transaction.js';
5
5
  import '@scure/btc-signer';
@@ -1,6 +1,6 @@
1
- export { ExpoArkProvider, ExpoIndexerProvider } from '../chunk-MZFUZUTQ.js';
2
- import '../chunk-X3VEMUVV.js';
3
- import '../chunk-3WIWNE4P.js';
1
+ export { ExpoArkProvider, ExpoIndexerProvider } from '../chunk-MNMPGEK2.js';
2
+ import '../chunk-YG7T6LI3.js';
3
+ import '../chunk-L5SCQYHF.js';
4
4
  import '../chunk-NSBPE2FW.js';
5
5
  //# sourceMappingURL=expo.js.map
6
6
  //# sourceMappingURL=expo.js.map
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkMJUTO3PY_cjs = require('../chunk-MJUTO3PY.cjs');
4
- require('../chunk-CO3KKSWM.cjs');
5
- require('../chunk-OIZ2V2VD.cjs');
6
- require('../chunk-2JV4VQ7C.cjs');
3
+ var chunkEBYCTLET_cjs = require('../chunk-EBYCTLET.cjs');
4
+ require('../chunk-GVHUHTRH.cjs');
5
+ require('../chunk-WIFL5QYZ.cjs');
6
+ require('../chunk-5MLC2HU3.cjs');
7
7
  require('../chunk-5BLDMQED.cjs');
8
8
 
9
9
  // src/storage/indexedDB.ts
@@ -11,7 +11,7 @@ var IndexedDBStorageAdapter = class {
11
11
  dbName;
12
12
  version;
13
13
  db = null;
14
- constructor(dbName, version = chunkMJUTO3PY_cjs.DB_VERSION) {
14
+ constructor(dbName, version = chunkEBYCTLET_cjs.DB_VERSION) {
15
15
  this.dbName = dbName;
16
16
  this.version = version;
17
17
  }
@@ -1,7 +1,7 @@
1
- import { DB_VERSION } from '../chunk-AEWJU6NZ.js';
2
- import '../chunk-X3VEMUVV.js';
3
- import '../chunk-6TAQF6EV.js';
4
- import '../chunk-3WIWNE4P.js';
1
+ import { DB_VERSION } from '../chunk-TA7XLEP2.js';
2
+ import '../chunk-YG7T6LI3.js';
3
+ import '../chunk-2PPL3O7Z.js';
4
+ import '../chunk-L5SCQYHF.js';
5
5
  import '../chunk-NSBPE2FW.js';
6
6
 
7
7
  // src/storage/indexedDB.ts
@@ -1,4 +1,4 @@
1
- import { c as TaskQueue, b as TaskItem, d as TaskResult } from './taskRunner-DATaRQus.js';
1
+ import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-D2fnbqYw.js';
2
2
 
3
3
  /**
4
4
  * Minimal async key-value storage interface.
@@ -46,4 +46,4 @@ declare class AsyncStorageTaskQueue implements TaskQueue {
46
46
  private writeList;
47
47
  }
48
48
 
49
- export { type AsyncStorageLike as A, AsyncStorageTaskQueue as a };
49
+ export { AsyncStorageTaskQueue as A, type AsyncStorageLike as a };
@@ -1,4 +1,4 @@
1
- import { c as TaskQueue, b as TaskItem, d as TaskResult } from './taskRunner-BZJMLQ6g.cjs';
1
+ import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-CzYKyJ9c.cjs';
2
2
 
3
3
  /**
4
4
  * Minimal async key-value storage interface.
@@ -46,4 +46,4 @@ declare class AsyncStorageTaskQueue implements TaskQueue {
46
46
  private writeList;
47
47
  }
48
48
 
49
- export { type AsyncStorageLike as A, AsyncStorageTaskQueue as a };
49
+ export { AsyncStorageTaskQueue as A, type AsyncStorageLike as a };
@@ -1,4 +1,4 @@
1
- import { VtxoScript, MultisigTapscript, CSVMultisigTapscript, timelockToSequence, sequenceToTimelock, ConditionMultisigTapscript, CLTVMultisigTapscript, ConditionCSVMultisigTapscript, SCRIPT_QUERY_CHUNK_SIZE, getNormalizedVtxos, DEFAULT_PAGE_SIZE } from './chunk-3WIWNE4P.js';
1
+ import { VtxoScript, MultisigTapscript, CSVMultisigTapscript, timelockToSequence, sequenceToTimelock, ConditionMultisigTapscript, CLTVMultisigTapscript, ConditionCSVMultisigTapscript, SCRIPT_QUERY_CHUNK_SIZE, getNormalizedVtxos, DEFAULT_PAGE_SIZE } from './chunk-L5SCQYHF.js';
2
2
  import { __export } from './chunk-NSBPE2FW.js';
3
3
  import { hex } from '@scure/base';
4
4
  import { networks, expand } from '@bitcoinerlab/descriptors-scure';
@@ -1504,41 +1504,30 @@ var VHTLC;
1504
1504
  ];
1505
1505
  let arkadeScriptNic;
1506
1506
  let nonInteractiveClaimScript;
1507
- if (options.nonInteractiveClaim) {
1508
- arkadeScriptNic = enforcePayToMaybeAsset(
1509
- options.nonInteractiveClaim.receiverPkScript,
1510
- options.asset,
1511
- options.nonInteractiveClaim.strict
1512
- );
1507
+ let arkadeScriptNir;
1508
+ let nonInteractiveRefundScript;
1509
+ let nonInteractiveRefundWithoutReceiverScript;
1510
+ const covenants = options.nonInteractiveParameters;
1511
+ if (covenants) {
1512
+ arkadeScriptNic = enforcePayToMaybeAsset(covenants.receiverPkScript, options.asset);
1513
1513
  nonInteractiveClaimScript = ConditionMultisigTapscript.encode({
1514
1514
  conditionScript,
1515
1515
  pubkeys: [
1516
1516
  server,
1517
- computeArkadeScriptPublicKey(
1518
- options.nonInteractiveClaim.emulatorPubkey,
1519
- arkadeScriptNic
1520
- )
1517
+ computeArkadeScriptPublicKey(covenants.emulatorPubkey, arkadeScriptNic)
1521
1518
  ]
1522
1519
  }).script;
1523
1520
  scripts.push(nonInteractiveClaimScript);
1524
- }
1525
- let arkadeScriptNir;
1526
- let nonInteractiveRefundScript;
1527
- let nonInteractiveRefundWithoutReceiverScript;
1528
- if (options.nonInteractiveRefund) {
1529
- arkadeScriptNir = enforcePayToMaybeAsset(
1530
- options.nonInteractiveRefund.senderPkScript,
1531
- options.asset
1532
- );
1521
+ arkadeScriptNir = enforcePayToMaybeAsset(covenants.senderPkScript, options.asset);
1533
1522
  const nirCosigner = computeArkadeScriptPublicKey(
1534
- options.nonInteractiveRefund.emulatorPubkey,
1523
+ covenants.emulatorPubkey,
1535
1524
  arkadeScriptNir
1536
1525
  );
1537
1526
  nonInteractiveRefundScript = MultisigTapscript.encode({
1538
1527
  pubkeys: [server, receiver, nirCosigner]
1539
1528
  }).script;
1540
1529
  scripts.push(nonInteractiveRefundScript);
1541
- if (options.nonInteractiveRefund.withoutReceiver) {
1530
+ if (covenants.legacy !== "preTimelockedRefund") {
1542
1531
  nonInteractiveRefundWithoutReceiverScript = CLTVMultisigTapscript.encode({
1543
1532
  absoluteTimelock: refundLocktime,
1544
1533
  pubkeys: [server, nirCosigner]
@@ -1703,47 +1692,25 @@ var VHTLC;
1703
1692
  if (!preimageHash || preimageHash.length !== 20) {
1704
1693
  throw new Error("preimage hash must be 20 bytes");
1705
1694
  }
1706
- if (options.asset !== void 0 && !options.nonInteractiveClaim && !options.nonInteractiveRefund) {
1707
- throw new Error(
1708
- "asset has no effect without nonInteractiveClaim or nonInteractiveRefund"
1709
- );
1695
+ if (options.asset !== void 0 && !options.nonInteractiveParameters) {
1696
+ throw new Error("asset has no effect without nonInteractiveParameters");
1710
1697
  }
1711
- const strict = options.nonInteractiveClaim?.strict;
1712
- if (strict !== void 0) {
1713
- if (strict.amount <= 0n) {
1714
- throw new Error(`strict claim amount must be positive, got ${strict.amount}`);
1715
- }
1716
- if (options.asset !== void 0 && strict.assetAmount === void 0) {
1717
- throw new Error(
1718
- "strict claim needs assetAmount when the contract is denominated in an asset: bounding only the sats would leave the asset amount unenforced"
1719
- );
1720
- }
1721
- if (options.asset === void 0 && strict.assetAmount !== void 0) {
1722
- throw new Error("strict claim assetAmount has no effect without asset");
1723
- }
1724
- if (strict.assetAmount !== void 0 && strict.assetAmount <= 0n) {
1725
- throw new Error(
1726
- `strict claim assetAmount must be positive, got ${strict.assetAmount}`
1727
- );
1728
- }
1729
- }
1730
- if (options.nonInteractiveClaim) {
1731
- const { emulatorPubkey, receiverPkScript } = options.nonInteractiveClaim;
1698
+ if (options.nonInteractiveParameters) {
1699
+ const { emulatorPubkey, receiverPkScript, senderPkScript, legacy } = options.nonInteractiveParameters;
1732
1700
  if (!emulatorPubkey || emulatorPubkey.length !== 32 && emulatorPubkey.length !== 33) {
1733
1701
  throw new Error("Invalid public key length (emulator)");
1734
1702
  }
1735
1703
  if (!receiverPkScript || !isP2trPkScript(receiverPkScript)) {
1736
1704
  throw new Error("Invalid P2TR script");
1737
1705
  }
1738
- }
1739
- if (options.nonInteractiveRefund) {
1740
- const { emulatorPubkey, senderPkScript } = options.nonInteractiveRefund;
1741
- if (!emulatorPubkey || emulatorPubkey.length !== 32 && emulatorPubkey.length !== 33) {
1742
- throw new Error("Invalid public key length (emulator)");
1743
- }
1744
1706
  if (!senderPkScript || !isP2trPkScript(senderPkScript)) {
1745
1707
  throw new Error("Invalid P2TR script");
1746
1708
  }
1709
+ if (legacy !== void 0 && legacy !== "preTimelockedRefund") {
1710
+ throw new Error(
1711
+ `nonInteractiveParameters.legacy must be "preTimelockedRefund" when set, got ${JSON.stringify(legacy)}`
1712
+ );
1713
+ }
1747
1714
  }
1748
1715
  if (!receiver || receiver.length !== 32) {
1749
1716
  throw new Error("Invalid public key length (receiver)");
@@ -1795,7 +1762,7 @@ function preimageConditionScriptV2(preimageHash) {
1795
1762
  function isP2trPkScript(pkScript) {
1796
1763
  return pkScript.length === 34 && pkScript[0] === 81 && pkScript[1] === 32;
1797
1764
  }
1798
- function satClause(destinationPkScript, quotedSats) {
1765
+ function satClause(destinationPkScript) {
1799
1766
  return [
1800
1767
  "PUSHCURRENTINPUTINDEX",
1801
1768
  "DUP",
@@ -1805,21 +1772,18 @@ function satClause(destinationPkScript, quotedSats) {
1805
1772
  destinationPkScript.subarray(2),
1806
1773
  "EQUALVERIFY",
1807
1774
  "INSPECTOUTPUTVALUE",
1808
- // `DUP` because the output value is needed twice: once against the
1809
- // quote, once against the input.
1810
- ...quotedSats === void 0 ? [] : ["DUP", quotedSats, "GREATERTHANOREQUAL", "VERIFY"],
1811
1775
  "PUSHCURRENTINPUTINDEX",
1812
1776
  "INSPECTINPUTVALUE",
1813
1777
  "GREATERTHANOREQUAL"
1814
1778
  ];
1815
1779
  }
1816
- function enforcePayTo(destinationPkScript, quotedSats) {
1780
+ function enforcePayTo(destinationPkScript) {
1817
1781
  if (!isP2trPkScript(destinationPkScript)) {
1818
1782
  throw new Error("invalid P2TR script");
1819
1783
  }
1820
- return ArkadeScript.encode(satClause(destinationPkScript, quotedSats));
1784
+ return ArkadeScript.encode(satClause(destinationPkScript));
1821
1785
  }
1822
- function enforcePayToAsset(destinationPkScript, asset, strict) {
1786
+ function enforcePayToAsset(destinationPkScript, asset) {
1823
1787
  if (!isP2trPkScript(destinationPkScript)) {
1824
1788
  throw new Error("invalid P2TR script");
1825
1789
  }
@@ -1843,10 +1807,6 @@ function enforcePayToAsset(destinationPkScript, asset, strict) {
1843
1807
  "INSPECTOUTASSETLOOKUP",
1844
1808
  "VERIFY",
1845
1809
  // PRESENT on the output, not merely "zero of it"
1846
- // The quoted bound, when the caller opted in — added to the input
1847
- // comparison below, not substituted for it. `DUP` because the output's
1848
- // asset amount is needed twice.
1849
- ...strict?.assetAmount === void 0 ? [] : ["DUP", strict.assetAmount, "GREATERTHANOREQUAL", "VERIFY"],
1850
1810
  "PUSHCURRENTINPUTINDEX",
1851
1811
  inspectionTxid,
1852
1812
  asset.groupIndex,
@@ -1861,11 +1821,11 @@ function enforcePayToAsset(destinationPkScript, asset, strict) {
1861
1821
  1,
1862
1822
  "EQUALVERIFY",
1863
1823
  // ...then the sat covenant, the same tokens `enforcePayTo` emits.
1864
- ...satClause(destinationPkScript, strict?.amount)
1824
+ ...satClause(destinationPkScript)
1865
1825
  ]);
1866
1826
  }
1867
- function enforcePayToMaybeAsset(destinationPkScript, asset, strict) {
1868
- return asset === void 0 ? enforcePayTo(destinationPkScript, strict?.amount) : enforcePayToAsset(destinationPkScript, asset, strict);
1827
+ function enforcePayToMaybeAsset(destinationPkScript, asset) {
1828
+ return asset === void 0 ? enforcePayTo(destinationPkScript) : enforcePayToAsset(destinationPkScript, asset);
1869
1829
  }
1870
1830
 
1871
1831
  // src/contracts/handlers/vhtlc.ts
@@ -2137,6 +2097,7 @@ var VHTLCV2ContractHandler = {
2137
2097
  return new VHTLC.ScriptV2(typed);
2138
2098
  },
2139
2099
  serializeParams(params) {
2100
+ const covenants = params.nonInteractiveParameters;
2140
2101
  return {
2141
2102
  sender: hex.encode(params.sender),
2142
2103
  receiver: hex.encode(params.receiver),
@@ -2148,39 +2109,31 @@ var VHTLCV2ContractHandler = {
2148
2109
  refundNoReceiverDelay: timelockToSequence(
2149
2110
  params.unilateralRefundWithoutReceiverDelay
2150
2111
  ).toString(),
2112
+ // The on-disk keys keep their per-leaf names even though the typed
2113
+ // param is ONE group: rows written by older SDKs carry exactly
2114
+ // these keys, and changing the storage encoding would orphan them.
2115
+ // The group maps onto them without loss — one emulator key serves
2116
+ // both covenant destinations by construction (see the option's doc
2117
+ // on VHTLC.Options), so the two emulator-key columns always hold
2118
+ // the same value on a row written from here.
2119
+ //
2151
2120
  // Spread rather than written as `undefined`: a `Record<string,
2152
2121
  // string>` round-tripped through a repository must not gain keys
2153
2122
  // whose value is the string "undefined".
2154
- ...params.nonInteractiveClaim && {
2155
- nonInteractiveClaimReceiverPkScript: hex.encode(
2156
- params.nonInteractiveClaim.receiverPkScript
2157
- ),
2158
- nonInteractiveClaimEmulatorPubkey: hex.encode(
2159
- params.nonInteractiveClaim.emulatorPubkey
2160
- ),
2161
- // The opt-in quoted bound. Dropping it re-derives the DEFAULT
2162
- // claim covenant a strictly weaker one and registration dies
2163
- // at `upsertContractRow` with an opaque `Script mismatch`. Same
2164
- // silent-drop class as the asset keys above.
2165
- ...params.nonInteractiveClaim.strict && {
2166
- strictClaimAmount: params.nonInteractiveClaim.strict.amount.toString(),
2167
- ...params.nonInteractiveClaim.strict.assetAmount !== void 0 && {
2168
- strictClaimAssetAmount: params.nonInteractiveClaim.strict.assetAmount.toString()
2169
- }
2170
- }
2171
- },
2172
- ...params.nonInteractiveRefund && {
2173
- nonInteractiveRefundSenderPkScript: hex.encode(
2174
- params.nonInteractiveRefund.senderPkScript
2175
- ),
2176
- nonInteractiveRefundEmulatorPubkey: hex.encode(
2177
- params.nonInteractiveRefund.emulatorPubkey
2178
- ),
2179
- // Spread rather than a "false"/"undefined" string: a dropped
2180
- // flag re-derives the EIGHT-leaf script, a different pkScript,
2181
- // and registration dies at `upsertContractRow` with an opaque
2182
- // `Script mismatch`. Same silent-drop class as the asset keys.
2183
- ...params.nonInteractiveRefund.withoutReceiver && {
2123
+ ...covenants && {
2124
+ nonInteractiveClaimReceiverPkScript: hex.encode(covenants.receiverPkScript),
2125
+ nonInteractiveClaimEmulatorPubkey: hex.encode(covenants.emulatorPubkey),
2126
+ nonInteractiveRefundSenderPkScript: hex.encode(covenants.senderPkScript),
2127
+ nonInteractiveRefundEmulatorPubkey: hex.encode(covenants.emulatorPubkey),
2128
+ // The legacy marker is precisely the ABSENCE of this key: a
2129
+ // row carrying it re-derives the full suite (nine leaves), a
2130
+ // row lacking it the pre-timelocked-refund eight the same
2131
+ // encoding older SDKs wrote for eight-leaf rows, so those rows
2132
+ // read back unchanged. Spread rather than a "false"/"undefined"
2133
+ // string: a dropped flag re-derives the EIGHT-leaf script, a
2134
+ // different pkScript, and registration dies at
2135
+ // `upsertContractRow` with an opaque `Script mismatch`.
2136
+ ...covenants.legacy === void 0 && {
2184
2137
  nonInteractiveRefundWithoutReceiver: "1"
2185
2138
  }
2186
2139
  },
@@ -2212,19 +2165,29 @@ var VHTLCV2ContractHandler = {
2212
2165
  "nonInteractiveRefundEmulatorPubkey",
2213
2166
  "nonInteractiveRefund"
2214
2167
  );
2168
+ if (claim === void 0 !== (refund === void 0)) {
2169
+ throw new Error(
2170
+ "emulator covenant params are all-or-nothing: the claim keys (nonInteractiveClaim*) and the refund keys (nonInteractiveRefund*) must both be present or both absent \u2014 a row carrying one side was written for a leaf subset this handler no longer derives"
2171
+ );
2172
+ }
2173
+ if (claim && refund && hex.encode(claim.emulatorPubkey) !== hex.encode(refund.emulatorPubkey)) {
2174
+ throw new Error(
2175
+ "emulator covenant params name two different emulator pubkeys: the suite derives both covenant cosigners from ONE key, so this row cannot be rebuilt as a group"
2176
+ );
2177
+ }
2215
2178
  if (params.assetTxid === void 0 !== (params.assetGroupIndex === void 0)) {
2216
2179
  throw new Error(
2217
2180
  "asset params are incomplete: assetTxid and assetGroupIndex must both be present or both absent"
2218
2181
  );
2219
2182
  }
2220
- if (params.strictClaimAssetAmount !== void 0 && params.strictClaimAmount === void 0) {
2183
+ if (params.strictClaimAmount !== void 0 || params.strictClaimAssetAmount !== void 0) {
2221
2184
  throw new Error(
2222
- "strictClaimAssetAmount without strictClaimAmount: reading this as 'not strict' would re-derive the default claim covenant, which is weaker than the row asked for"
2185
+ "strict claim params on a stored row: the strict claim bound was removed and this row's lockup cannot be re-derived without it \u2014 restore it with the SDK version that wrote it"
2223
2186
  );
2224
2187
  }
2225
2188
  if (params.nonInteractiveRefundWithoutReceiver !== void 0 && !refund) {
2226
2189
  throw new Error(
2227
- "nonInteractiveRefundWithoutReceiver without the nonInteractiveRefund keys it extends: reading this as 'not set' would re-derive a script without the leaf"
2190
+ "nonInteractiveRefundWithoutReceiver without the emulator covenant keys it extends: reading this as 'not set' would re-derive a script without the leaf"
2228
2191
  );
2229
2192
  }
2230
2193
  if (params.nonInteractiveRefundWithoutReceiver !== void 0 && params.nonInteractiveRefundWithoutReceiver !== "1") {
@@ -2248,26 +2211,15 @@ var VHTLCV2ContractHandler = {
2248
2211
  unilateralRefundWithoutReceiverDelay: sequenceToTimelock(
2249
2212
  Number(params.refundNoReceiverDelay)
2250
2213
  ),
2251
- ...claim && {
2252
- nonInteractiveClaim: {
2214
+ ...claim && refund && {
2215
+ nonInteractiveParameters: {
2253
2216
  receiverPkScript: claim.destination,
2254
- emulatorPubkey: claim.emulatorPubkey,
2255
- ...params.strictClaimAmount !== void 0 && {
2256
- strict: {
2257
- amount: BigInt(params.strictClaimAmount),
2258
- ...params.strictClaimAssetAmount !== void 0 && {
2259
- assetAmount: BigInt(params.strictClaimAssetAmount)
2260
- }
2261
- }
2262
- }
2263
- }
2264
- },
2265
- ...refund && {
2266
- nonInteractiveRefund: {
2267
2217
  senderPkScript: refund.destination,
2268
- emulatorPubkey: refund.emulatorPubkey,
2269
- ...params.nonInteractiveRefundWithoutReceiver === "1" && {
2270
- withoutReceiver: true
2218
+ emulatorPubkey: claim.emulatorPubkey,
2219
+ // Absence of the flag IS the legacy marker — the same
2220
+ // encoding older SDKs wrote for eight-leaf rows.
2221
+ ...params.nonInteractiveRefundWithoutReceiver !== "1" && {
2222
+ legacy: "preTimelockedRefund"
2271
2223
  }
2272
2224
  }
2273
2225
  }
@@ -3036,5 +2988,5 @@ contractHandlers.register(BoardingContractHandler);
3036
2988
  contractHandlers.register(ArkadeContractHandler);
3037
2989
 
3038
2990
  export { ARKADE_OP, ARKADE_OPCODES, ARKADE_OPCODE_NAMES, ARKADE_OPCODE_VALUES, ARKADE_OPS, ArkadeContractHandler, ArkadeProgramScript, ArkadeScript, BoardingContractHandler, DefaultContractHandler, DefaultVtxo, DelegateContractHandler, DelegateVtxo, OPCODE_NAMES, OPCODE_VALUES, SUPPORTED_PROGRAM_VERSION, VHTLC, VHTLCContractHandler, VHTLCV2ContractHandler, WALLET_RECEIVE_SOURCE, arkadeScriptHash, arkadeWitnessHash, asmToBytes, bignum_exports, bytesToASM, computeArkadeScriptPublicKey, contractHandlers, deriveDescriptorLeafCompressedPubKey, deriveDescriptorLeafPubKey, descriptorIsOurs, deserializeArkadeContractParams, fromASM, getOpcodeName, getOpcodeValue, identityDescriptor, inputName, isCltvSatisfied, isCsvSpendable, isMainnetDescriptor, normalizeToDescriptor, parseArtifact, parseHDDescriptor, resolveAsm, serializeArkadeContractParams, speculativeReceiveMetadata, stringifyArtifact, toASM, toXOnly, validateProgram, witnessRefToBytes };
3039
- //# sourceMappingURL=chunk-6TAQF6EV.js.map
3040
- //# sourceMappingURL=chunk-6TAQF6EV.js.map
2991
+ //# sourceMappingURL=chunk-2PPL3O7Z.js.map
2992
+ //# sourceMappingURL=chunk-2PPL3O7Z.js.map