@arkade-os/sdk 0.4.66 → 0.4.68

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 (80) hide show
  1. package/README.md +71 -15
  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-BZcIN7sA.d.cts → asyncStorageTaskQueue-B2CcXIHU.d.cts} +1 -1
  9. package/dist/{asyncStorageTaskQueue-B6SijMi3.d.ts → asyncStorageTaskQueue-DaZlVTbM.d.ts} +1 -1
  10. package/dist/{chunk-2JZGPXU4.js → chunk-33Q2RFET.js} +3 -3
  11. package/dist/{chunk-2JZGPXU4.js.map → chunk-33Q2RFET.js.map} +1 -1
  12. package/dist/{chunk-CYOI4PEA.js → chunk-45FKMOJH.js} +160 -114
  13. package/dist/chunk-45FKMOJH.js.map +1 -0
  14. package/dist/{chunk-J33ZEM3A.js → chunk-4CMXV5SF.js} +45 -14
  15. package/dist/chunk-4CMXV5SF.js.map +1 -0
  16. package/dist/{chunk-LL47QIHD.cjs → chunk-4KCVS4ZN.cjs} +10 -10
  17. package/dist/{chunk-LL47QIHD.cjs.map → chunk-4KCVS4ZN.cjs.map} +1 -1
  18. package/dist/{chunk-PXPPZF5K.cjs → chunk-6YUACVX4.cjs} +205 -159
  19. package/dist/chunk-6YUACVX4.cjs.map +1 -0
  20. package/dist/{chunk-ZIRFXBKL.cjs → chunk-EJOFL5WH.cjs} +47 -13
  21. package/dist/chunk-EJOFL5WH.cjs.map +1 -0
  22. package/dist/{chunk-R5POS3RS.js → chunk-G4I6PU5H.js} +4 -4
  23. package/dist/{chunk-R5POS3RS.js.map → chunk-G4I6PU5H.js.map} +1 -1
  24. package/dist/{chunk-55ZZ6RBL.js → chunk-GQ4NMQGR.js} +4 -4
  25. package/dist/{chunk-55ZZ6RBL.js.map → chunk-GQ4NMQGR.js.map} +1 -1
  26. package/dist/{chunk-IM6IKNSL.cjs → chunk-JGMSZIE4.cjs} +17 -17
  27. package/dist/{chunk-IM6IKNSL.cjs.map → chunk-JGMSZIE4.cjs.map} +1 -1
  28. package/dist/{chunk-3S3JZUEN.cjs → chunk-PJR63FTK.cjs} +17 -17
  29. package/dist/{chunk-3S3JZUEN.cjs.map → chunk-PJR63FTK.cjs.map} +1 -1
  30. package/dist/{chunk-DSC3G6QZ.js → chunk-VBHXBI7F.js} +1060 -185
  31. package/dist/chunk-VBHXBI7F.js.map +1 -0
  32. package/dist/{chunk-5E6IZNRG.cjs → chunk-WCJVKFAP.cjs} +1467 -581
  33. package/dist/chunk-WCJVKFAP.cjs.map +1 -0
  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-T-vgxMYZ.d.ts → delegate-AomVWxO_.d.ts} +1 -1
  39. package/dist/{delegate-YXupcWWJ.d.cts → delegate-Bffc5f54.d.cts} +1 -1
  40. package/dist/{wallet-CNibc3yJ.d.ts → hdWalletCapable-B5nRs3RH.d.cts} +318 -127
  41. package/dist/{wallet-DJN1QgFt.d.cts → hdWalletCapable-DZdIVa23.d.ts} +318 -127
  42. package/dist/{index-uUE_uQPn.d.ts → index-C7RZCfoY.d.cts} +222 -19
  43. package/dist/{index-uUE_uQPn.d.cts → index-C7RZCfoY.d.ts} +222 -19
  44. package/dist/{index-e7LYXk1d.d.cts → index-jouvy8FD.d.ts} +172 -99
  45. package/dist/{index-D_FgwLH9.d.ts → index-nfyQM33h.d.cts} +172 -99
  46. package/dist/index.cjs +326 -278
  47. package/dist/index.d.cts +295 -41
  48. package/dist/index.d.ts +295 -41
  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-BOVcIH1N.d.cts → taskRunner-D2vnpPBT.d.cts} +1 -1
  59. package/dist/{taskRunner-DNyD1kXG.d.ts → taskRunner-DuwK9t8O.d.ts} +1 -1
  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 +18 -14
  65. package/dist/wallet/expo/index.cjs.map +1 -1
  66. package/dist/wallet/expo/index.d.cts +7 -5
  67. package/dist/wallet/expo/index.d.ts +7 -5
  68. package/dist/wallet/expo/index.js +10 -6
  69. package/dist/wallet/expo/index.js.map +1 -1
  70. package/dist/worker/expo/index.cjs +9 -9
  71. package/dist/worker/expo/index.d.cts +4 -4
  72. package/dist/worker/expo/index.d.ts +4 -4
  73. package/dist/worker/expo/index.js +5 -5
  74. package/package.json +3 -3
  75. package/dist/chunk-5E6IZNRG.cjs.map +0 -1
  76. package/dist/chunk-CYOI4PEA.js.map +0 -1
  77. package/dist/chunk-DSC3G6QZ.js.map +0 -1
  78. package/dist/chunk-J33ZEM3A.js.map +0 -1
  79. package/dist/chunk-PXPPZF5K.cjs.map +0 -1
  80. package/dist/chunk-ZIRFXBKL.cjs.map +0 -1
package/README.md CHANGED
@@ -215,6 +215,29 @@ await wallet.send({ address: 'ark1q...', amount: 1000 })
215
215
 
216
216
  Identities without `signMultiple` continue to work unchanged — each checkpoint is signed individually via `sign()`.
217
217
 
218
+ ### Ark Provider Caching
219
+
220
+ `RestArkProvider.getInfo()` fetches current Arkade server parameters on every call. Wrap it
221
+ with `CachingArkProvider` when you reuse that response for fee, signer, or limit lookups:
222
+
223
+ ```typescript
224
+ import { CachingArkProvider, RestArkProvider, Wallet } from '@arkade-os/sdk'
225
+
226
+ const arkProvider = new CachingArkProvider(
227
+ new RestArkProvider('https://arkade.computer'),
228
+ 60_000, // optional TTL in milliseconds; defaults to 60 seconds
229
+ )
230
+
231
+ const wallet = await Wallet.create({ identity, arkProvider })
232
+ ```
233
+
234
+ Only `getInfo()` is cached; all other Ark provider methods pass through. The cache expires
235
+ after the TTL and updates when the inner provider reports server-info changes, including
236
+ signer rotation. Wrapping `RestArkProvider` preserves its `serverUrl`, so `Wallet.create`
237
+ can still derive the default indexer URL. Expired refresh failures propagate;
238
+ wallet boot fallback lives in the persisted ArkInfo snapshot. Call `dispose()` if the
239
+ inner provider outlives the wrapper, to drop its server-info subscription.
240
+
218
241
  ### Onchain Providers
219
242
 
220
243
  Wallets read onchain state (UTXOs, transactions, fee rates, chain tip) through an `OnchainProvider`. The SDK ships with two implementations and a single transport-agnostic interface so you can swap them without touching wallet code.
@@ -226,6 +249,8 @@ Wallets read onchain state (UTXOs, transactions, fee rates, chain tip) through a
226
249
 
227
250
  If you don't pass a provider explicitly, `OnchainWallet` and `Wallet.create({ ... })` both default to `EsploraProvider` pointing at the URL in `ESPLORA_URL[networkName]`.
228
251
 
252
+ > **New:** the interface also requires `getRawTransaction(txid): Promise<Uint8Array>`, the raw wire bytes of a transaction. Emulator v0.0.7+ demands the previous transaction of every input a covenant spend or intent proof carries, and a boarding or commitment parent has no off-chain source. Both shipped providers implement it; a custom `OnchainProvider` has to add it.
253
+
229
254
  #### Default URLs
230
255
 
231
256
  The SDK ships with reachable defaults for each network — bitcoin, signet, and mutinynet point at Ark Labs–operated deployments; testnet falls back to mempool.space; regtest assumes a local [arkade-regtest](https://github.com/ArkLabsHQ/arkade-regtest) stack (esplora API on `http://localhost:3000/api`).
@@ -345,21 +370,27 @@ console.log('Gated by a contract:', balance.gated) // swap escrow, chiefly
345
370
  console.log('Locked by an in-flight intent:', balance.intentLocked)
346
371
  console.log('Recoverable:', balance.recoverable)
347
372
  console.log('Awaiting recovery:', balance.pendingRecovery)
373
+ console.log('Unilaterally exited:', balance.unrolled)
348
374
  ```
349
375
 
350
376
  `settled` and `preconfirmed` are the owned offchain buckets this relationship is
351
- about — `recoverable` and `pendingRecovery` are the wallet's funds too, just held
352
- under a different predicate. `available` is what generic spending will actually
353
- pick, and the difference between the two is accounted for exactly:
377
+ about — `recoverable`, `pendingRecovery` and `unrolled` are the wallet's funds
378
+ too, just held under a different predicate. `available` is what generic spending
379
+ will actually pick, and the difference between the two is accounted for exactly:
354
380
 
355
381
  ```text
356
382
  settled + preconfirmed === available + gated + intentLocked
357
383
  ```
358
384
 
385
+ `unrolled` holds virtual outputs whose unilateral exit already happened: they sit
386
+ onchain behind their CSV timelock, so nothing offchain can move them and
387
+ `Unroll.completeUnroll` is the only thing that will. They are never `available` and
388
+ never `recoverable` — but they are still your money, so they still count in `total`.
389
+
359
390
  To show "your money, minus what is tied up", subtract from `settled + preconfirmed`
360
- — **not from `total`**, which also contains `boarding.total`, `recoverable` and
361
- `pendingRecovery`. Those are still your funds, so subtracting a bucket from `total`
362
- silently drops them from the figure.
391
+ — **not from `total`**, which also contains `boarding.total`, `recoverable`,
392
+ `pendingRecovery` and `unrolled`. Those are still your funds, so subtracting a bucket
393
+ from `total` silently drops them from the figure.
363
394
 
364
395
  ```typescript
365
396
 
@@ -543,6 +574,11 @@ const expiringVtxos = await manager.getExpiringVtxos()
543
574
  const urgentlyExpiring = await manager.getExpiringVtxos(60_000)
544
575
  ```
545
576
 
577
+ A virtual output whose unilateral exit already happened is never offered for renewal, and the
578
+ exported `isVtxoExpiringSoon` answers `false` for it regardless of its batch expiry: "expiring
579
+ soon" is a renewal signal, and no batch can take an output that already lives onchain. Its remedy
580
+ is `Unroll.completeUnroll`, and its value shows up in `balance.unrolled`.
581
+
546
582
  #### Boarding Input Sweep
547
583
 
548
584
  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.
@@ -747,12 +783,7 @@ const onchainWallet = await OnchainWallet.create(onchainIdentity, 'regtest');
747
783
 
748
784
  // Unroll a specific virtual output
749
785
  const vtxo = { txid: 'your_vtxo_txid', vout: 0 };
750
- const session = await Unroll.Session.create(
751
- vtxo,
752
- onchainWallet,
753
- onchainWallet.provider,
754
- wallet.indexerProvider
755
- );
786
+ const session = await Unroll.sessionFor(wallet, vtxo, onchainWallet);
756
787
 
757
788
  // Iterate through the unrolling steps
758
789
  for await (const step of session) {
@@ -770,6 +801,24 @@ for await (const step of session) {
770
801
  }
771
802
  ```
772
803
 
804
+ `Unroll.sessionFor` is `Session.create` with the wallet's explorer, indexer and
805
+ virtual-tx cache filled in, plus the exit observer wired: at `StepType.DONE` it re-reads
806
+ the outpoint from the indexer, so the value moves into the `unrolled` balance bucket
807
+ without waiting for a sync that would never bring it. Nothing else would tell the wallet
808
+ — delta sync filters on creation time, so it never sees a status change on an older
809
+ virtual output.
810
+
811
+ That re-read is a prompt rather than a guarantee: `StepType.DONE` means your Esplora
812
+ endpoint saw the exit confirm, and the Arkade indexer may not have marked the output
813
+ `isUnrolled` yet. The session fires once, so a re-read that lands early simply leaves the
814
+ wallet where it would have been anyway, and the next thing to refresh that outpoint picks
815
+ the exit up. `UnilateralExit` fires twice per virtual output — branch-confirmed and
816
+ sweep-confirmed — and by the sweep the exit has been onchain for at least the CSV delay.
817
+
818
+ If you hold no `Wallet` — driving an exit from providers alone — build the session with
819
+ the lower-level `Unroll.Session.create(vtxo, bumper, explorer, indexer,
820
+ virtualTxRepository?, onExitObserved?)`, whose last two parameters are optional.
821
+
773
822
  The unrolling process works by:
774
823
 
775
824
  - Traversing the transaction chain from the root (most recent) to the leaf (oldest)
@@ -819,9 +868,10 @@ await Unroll.completeUnroll(
819
868
 
820
869
  ### Unilateral Exit Packages (pre-signed)
821
870
 
822
- `Unroll.Session` requires the wallet (keys + indexer access) to stay online for the whole
823
- multi-day exit. `UnilateralExit` removes that requirement: it pre-signs **every** transaction
824
- needed to unroll a VTXO's offchain transaction chain onchain **and** sweep each matured output
871
+ `Unroll.sessionFor` (and the `Unroll.Session` it builds) requires the wallet keys plus
872
+ indexer access — to stay online for the whole multi-day exit. `UnilateralExit` removes that
873
+ requirement: it pre-signs **every** transaction needed to unroll a VTXO's offchain
874
+ transaction chain onchain **and** sweep each matured output
825
875
  to an address you solely control, then emits a versioned JSON package that anything with an
826
876
  Esplora-compatible endpoint can execute — no keys, no Arkade infrastructure.
827
877
 
@@ -858,6 +908,12 @@ for await (const event of executor) {
858
908
  }
859
909
  ```
860
910
 
911
+ Where the executing machine does hold the `Wallet`, `UnilateralExit.execute(wallet, pkg, opts?)`
912
+ returns the same executor with the exit observer already wired, so the repository re-reads each
913
+ branch as it confirms and again as its sweep does — picking the exit up as it lands, indexer lag
914
+ permitting. The same prompt-not-guarantee caveat as `Unroll.sessionFor` above applies, with the
915
+ sweep-confirm re-read as its own retry.
916
+
861
917
  Every exit terminates in a **sweep**. Unrolling only lands a VTXO back onchain still encumbered
862
918
  by its Arkade script; the funds become yours unilaterally only once a sweep spends that output
863
919
  through the CSV-timelocked exit path to `sweepAddress`. So the package always pairs each exited
@@ -1,19 +1,19 @@
1
1
  'use strict';
2
2
 
3
- var chunkIM6IKNSL_cjs = require('../chunk-IM6IKNSL.cjs');
4
- require('../chunk-3S3JZUEN.cjs');
5
- require('../chunk-ZIRFXBKL.cjs');
3
+ var chunkJGMSZIE4_cjs = require('../chunk-JGMSZIE4.cjs');
4
+ require('../chunk-PJR63FTK.cjs');
5
+ require('../chunk-EJOFL5WH.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 chunkIM6IKNSL_cjs.ExpoArkProvider; }
12
+ get: function () { return chunkJGMSZIE4_cjs.ExpoArkProvider; }
13
13
  });
14
14
  Object.defineProperty(exports, "ExpoIndexerProvider", {
15
15
  enumerable: true,
16
- get: function () { return chunkIM6IKNSL_cjs.ExpoIndexerProvider; }
16
+ get: function () { return chunkJGMSZIE4_cjs.ExpoIndexerProvider; }
17
17
  });
18
18
  //# sourceMappingURL=expo.cjs.map
19
19
  //# sourceMappingURL=expo.cjs.map
@@ -1,5 +1,5 @@
1
- import { l as RestArkProvider, i as SettlementEvent, T as TxNotificationEvent, m as RestIndexerProvider, n as SubscriptionResponse } from '../index-uUE_uQPn.cjs';
2
- export { o as ArkProvider, p as IndexerProvider } from '../index-uUE_uQPn.cjs';
1
+ import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-C7RZCfoY.cjs';
2
+ export { q as ArkProvider, r as IndexerProvider } from '../index-C7RZCfoY.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 { l as RestArkProvider, i as SettlementEvent, T as TxNotificationEvent, m as RestIndexerProvider, n as SubscriptionResponse } from '../index-uUE_uQPn.js';
2
- export { o as ArkProvider, p as IndexerProvider } from '../index-uUE_uQPn.js';
1
+ import { n as RestArkProvider, k as SettlementEvent, T as TxNotificationEvent, o as RestIndexerProvider, p as SubscriptionResponse } from '../index-C7RZCfoY.js';
2
+ export { q as ArkProvider, r as IndexerProvider } from '../index-C7RZCfoY.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-R5POS3RS.js';
2
- import '../chunk-2JZGPXU4.js';
3
- import '../chunk-J33ZEM3A.js';
1
+ export { ExpoArkProvider, ExpoIndexerProvider } from '../chunk-G4I6PU5H.js';
2
+ import '../chunk-33Q2RFET.js';
3
+ import '../chunk-4CMXV5SF.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 chunk5E6IZNRG_cjs = require('../chunk-5E6IZNRG.cjs');
4
- require('../chunk-3S3JZUEN.cjs');
5
- require('../chunk-PXPPZF5K.cjs');
6
- require('../chunk-ZIRFXBKL.cjs');
3
+ var chunkWCJVKFAP_cjs = require('../chunk-WCJVKFAP.cjs');
4
+ require('../chunk-PJR63FTK.cjs');
5
+ require('../chunk-6YUACVX4.cjs');
6
+ require('../chunk-EJOFL5WH.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 = chunk5E6IZNRG_cjs.DB_VERSION) {
14
+ constructor(dbName, version = chunkWCJVKFAP_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-DSC3G6QZ.js';
2
- import '../chunk-2JZGPXU4.js';
3
- import '../chunk-CYOI4PEA.js';
4
- import '../chunk-J33ZEM3A.js';
1
+ import { DB_VERSION } from '../chunk-VBHXBI7F.js';
2
+ import '../chunk-33Q2RFET.js';
3
+ import '../chunk-45FKMOJH.js';
4
+ import '../chunk-4CMXV5SF.js';
5
5
  import '../chunk-NSBPE2FW.js';
6
6
 
7
7
  // src/storage/indexedDB.ts
@@ -1,4 +1,4 @@
1
- import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-BOVcIH1N.cjs';
1
+ import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-D2vnpPBT.cjs';
2
2
 
3
3
  /**
4
4
  * Minimal async key-value storage interface.
@@ -1,4 +1,4 @@
1
- import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-DNyD1kXG.js';
1
+ import { a as TaskQueue, c as TaskItem, d as TaskResult } from './taskRunner-DuwK9t8O.js';
2
2
 
3
3
  /**
4
4
  * Minimal async key-value storage interface.
@@ -1,4 +1,4 @@
1
- import { DEFAULT_ARKADE_SERVER_URL, eventSourceIterator, resolveEventSource, convertVtxo, isFetchTimeoutError, isEventSourceError, isEventSourceUnavailableError, rateGate, baseFetch, toProviderUnavailable, ProviderUnavailableError, throwIfHttpUnavailable } from './chunk-J33ZEM3A.js';
1
+ import { DEFAULT_ARKADE_SERVER_URL, eventSourceIterator, resolveEventSource, convertVtxo, isFetchTimeoutError, isEventSourceError, isEventSourceUnavailableError, rateGate, baseFetch, toProviderUnavailable, ProviderUnavailableError, throwIfHttpUnavailable } from './chunk-4CMXV5SF.js';
2
2
  import { __export } from './chunk-NSBPE2FW.js';
3
3
  import { hex } from '@scure/base';
4
4
  import { schnorr } from '@noble/curves/secp256k1.js';
@@ -1954,5 +1954,5 @@ var Response;
1954
1954
  })(Response || (Response = {}));
1955
1955
 
1956
1956
  export { AssetGroup, AssetId, AssetInput, AssetOutput, AssetRef, BufferReader, BufferWriter, ChainTxType, DEFAULT_VTXO_PAGE_SIZE, IndexerTxType, Metadata, Packet, RestIndexerProvider, asset_exports };
1957
- //# sourceMappingURL=chunk-2JZGPXU4.js.map
1958
- //# sourceMappingURL=chunk-2JZGPXU4.js.map
1957
+ //# sourceMappingURL=chunk-33Q2RFET.js.map
1958
+ //# sourceMappingURL=chunk-33Q2RFET.js.map