@arkade-os/sdk 0.4.15 → 0.4.16

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 (197) hide show
  1. package/README.md +102 -96
  2. package/dist/cjs/arkfee/estimator.js +1 -1
  3. package/dist/cjs/arkfee/types.js +2 -1
  4. package/dist/cjs/arknote/index.js +43 -4
  5. package/dist/cjs/bip322/index.js +1 -1
  6. package/dist/cjs/contracts/arkcontract.js +1 -1
  7. package/dist/cjs/contracts/contractManager.js +40 -24
  8. package/dist/cjs/contracts/contractWatcher.js +29 -22
  9. package/dist/cjs/contracts/handlers/default.js +1 -1
  10. package/dist/cjs/contracts/handlers/delegate.js +1 -1
  11. package/dist/cjs/contracts/handlers/helpers.js +1 -1
  12. package/dist/cjs/extension/asset/assetGroup.js +92 -5
  13. package/dist/cjs/extension/asset/assetId.js +67 -3
  14. package/dist/cjs/extension/asset/assetInput.js +18 -0
  15. package/dist/cjs/extension/asset/assetOutput.js +15 -0
  16. package/dist/cjs/extension/asset/assetRef.js +66 -0
  17. package/dist/cjs/extension/asset/metadata.js +15 -0
  18. package/dist/cjs/extension/asset/packet.js +4 -1
  19. package/dist/cjs/extension/index.js +1 -1
  20. package/dist/cjs/forfeit.js +14 -0
  21. package/dist/cjs/identity/seedIdentity.js +2 -2
  22. package/dist/cjs/identity/singleKey.js +4 -0
  23. package/dist/cjs/intent/index.js +28 -12
  24. package/dist/cjs/providers/ark.js +3 -2
  25. package/dist/cjs/providers/delegator.js +20 -1
  26. package/dist/cjs/providers/expoArk.js +2 -2
  27. package/dist/cjs/providers/indexer.js +2 -2
  28. package/dist/cjs/providers/onchain.js +2 -1
  29. package/dist/cjs/repositories/realm/schemas.js +2 -2
  30. package/dist/cjs/repositories/realm/types.js +1 -1
  31. package/dist/cjs/script/address.js +37 -6
  32. package/dist/cjs/script/base.js +70 -1
  33. package/dist/cjs/script/default.js +3 -0
  34. package/dist/cjs/script/delegate.js +4 -0
  35. package/dist/cjs/script/tapscript.js +17 -2
  36. package/dist/cjs/script/vhtlc.js +35 -27
  37. package/dist/cjs/storage/fileSystem.js +1 -1
  38. package/dist/cjs/storage/inMemory.js +1 -1
  39. package/dist/cjs/storage/indexedDB.js +1 -1
  40. package/dist/cjs/storage/localStorage.js +1 -1
  41. package/dist/cjs/tree/validation.js +1 -1
  42. package/dist/cjs/utils/arkTransaction.js +5 -5
  43. package/dist/cjs/utils/bip21.js +16 -3
  44. package/dist/cjs/utils/syncCursors.js +4 -4
  45. package/dist/cjs/utils/transaction.js +1 -1
  46. package/dist/cjs/utils/transactionHistory.js +11 -11
  47. package/dist/cjs/utils/unknownFields.js +3 -3
  48. package/dist/cjs/wallet/asset-manager.js +4 -4
  49. package/dist/cjs/wallet/batch.js +5 -5
  50. package/dist/cjs/wallet/delegator.js +9 -8
  51. package/dist/cjs/wallet/expo/background.js +3 -3
  52. package/dist/cjs/wallet/expo/wallet.js +7 -7
  53. package/dist/cjs/wallet/index.js +43 -0
  54. package/dist/cjs/wallet/onchain.js +43 -5
  55. package/dist/cjs/wallet/ramps.js +44 -14
  56. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +22 -22
  57. package/dist/cjs/wallet/serviceWorker/wallet.js +28 -24
  58. package/dist/cjs/wallet/unroll.js +12 -8
  59. package/dist/cjs/wallet/utils.js +1 -1
  60. package/dist/cjs/wallet/vtxo-manager.js +122 -82
  61. package/dist/cjs/wallet/wallet.js +125 -67
  62. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +1 -1
  63. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +2 -2
  64. package/dist/cjs/worker/expo/taskRunner.js +3 -3
  65. package/dist/cjs/worker/messageBus.js +3 -0
  66. package/dist/esm/arkfee/estimator.js +1 -1
  67. package/dist/esm/arkfee/types.js +2 -1
  68. package/dist/esm/arknote/index.js +43 -4
  69. package/dist/esm/bip322/index.js +1 -1
  70. package/dist/esm/contracts/arkcontract.js +1 -1
  71. package/dist/esm/contracts/contractManager.js +40 -24
  72. package/dist/esm/contracts/contractWatcher.js +29 -22
  73. package/dist/esm/contracts/handlers/default.js +1 -1
  74. package/dist/esm/contracts/handlers/delegate.js +1 -1
  75. package/dist/esm/contracts/handlers/helpers.js +1 -1
  76. package/dist/esm/extension/asset/assetGroup.js +92 -5
  77. package/dist/esm/extension/asset/assetId.js +67 -3
  78. package/dist/esm/extension/asset/assetInput.js +18 -0
  79. package/dist/esm/extension/asset/assetOutput.js +15 -0
  80. package/dist/esm/extension/asset/assetRef.js +66 -0
  81. package/dist/esm/extension/asset/metadata.js +15 -0
  82. package/dist/esm/extension/asset/packet.js +4 -1
  83. package/dist/esm/extension/index.js +1 -1
  84. package/dist/esm/forfeit.js +14 -0
  85. package/dist/esm/identity/seedIdentity.js +2 -2
  86. package/dist/esm/identity/singleKey.js +4 -0
  87. package/dist/esm/index.js +1 -1
  88. package/dist/esm/intent/index.js +28 -12
  89. package/dist/esm/providers/ark.js +3 -2
  90. package/dist/esm/providers/delegator.js +20 -1
  91. package/dist/esm/providers/expoArk.js +2 -2
  92. package/dist/esm/providers/indexer.js +2 -2
  93. package/dist/esm/providers/onchain.js +2 -1
  94. package/dist/esm/repositories/realm/schemas.js +2 -2
  95. package/dist/esm/repositories/realm/types.js +1 -1
  96. package/dist/esm/script/address.js +37 -6
  97. package/dist/esm/script/base.js +70 -1
  98. package/dist/esm/script/default.js +3 -0
  99. package/dist/esm/script/delegate.js +4 -0
  100. package/dist/esm/script/tapscript.js +17 -2
  101. package/dist/esm/script/vhtlc.js +35 -27
  102. package/dist/esm/storage/fileSystem.js +1 -1
  103. package/dist/esm/storage/inMemory.js +1 -1
  104. package/dist/esm/storage/indexedDB.js +1 -1
  105. package/dist/esm/storage/localStorage.js +1 -1
  106. package/dist/esm/tree/validation.js +1 -1
  107. package/dist/esm/utils/arkTransaction.js +5 -5
  108. package/dist/esm/utils/bip21.js +16 -3
  109. package/dist/esm/utils/syncCursors.js +4 -4
  110. package/dist/esm/utils/transaction.js +1 -1
  111. package/dist/esm/utils/transactionHistory.js +11 -11
  112. package/dist/esm/utils/unknownFields.js +3 -3
  113. package/dist/esm/wallet/asset-manager.js +4 -4
  114. package/dist/esm/wallet/batch.js +5 -5
  115. package/dist/esm/wallet/delegator.js +9 -8
  116. package/dist/esm/wallet/expo/background.js +3 -3
  117. package/dist/esm/wallet/expo/wallet.js +7 -7
  118. package/dist/esm/wallet/index.js +43 -0
  119. package/dist/esm/wallet/onchain.js +43 -5
  120. package/dist/esm/wallet/ramps.js +44 -14
  121. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +22 -22
  122. package/dist/esm/wallet/serviceWorker/wallet.js +28 -24
  123. package/dist/esm/wallet/unroll.js +12 -8
  124. package/dist/esm/wallet/utils.js +1 -1
  125. package/dist/esm/wallet/vtxo-manager.js +121 -81
  126. package/dist/esm/wallet/wallet.js +125 -67
  127. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +1 -1
  128. package/dist/esm/worker/expo/processors/contractPollProcessor.js +2 -2
  129. package/dist/esm/worker/expo/taskRunner.js +3 -3
  130. package/dist/esm/worker/messageBus.js +3 -0
  131. package/dist/types/arkfee/estimator.d.ts +1 -1
  132. package/dist/types/arkfee/types.d.ts +2 -1
  133. package/dist/types/arknote/index.d.ts +44 -4
  134. package/dist/types/bip322/index.d.ts +1 -1
  135. package/dist/types/contracts/arkcontract.d.ts +1 -1
  136. package/dist/types/contracts/contractManager.d.ts +40 -63
  137. package/dist/types/contracts/contractWatcher.d.ts +39 -18
  138. package/dist/types/contracts/handlers/default.d.ts +1 -1
  139. package/dist/types/contracts/handlers/delegate.d.ts +1 -1
  140. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  141. package/dist/types/contracts/types.d.ts +36 -26
  142. package/dist/types/extension/asset/assetGroup.d.ts +92 -1
  143. package/dist/types/extension/asset/assetId.d.ts +67 -3
  144. package/dist/types/extension/asset/assetInput.d.ts +18 -0
  145. package/dist/types/extension/asset/assetOutput.d.ts +15 -0
  146. package/dist/types/extension/asset/assetRef.d.ts +66 -0
  147. package/dist/types/extension/asset/metadata.d.ts +15 -0
  148. package/dist/types/extension/asset/packet.d.ts +4 -1
  149. package/dist/types/extension/index.d.ts +1 -1
  150. package/dist/types/forfeit.d.ts +14 -0
  151. package/dist/types/identity/index.d.ts +16 -0
  152. package/dist/types/identity/seedIdentity.d.ts +8 -6
  153. package/dist/types/identity/singleKey.d.ts +4 -0
  154. package/dist/types/intent/index.d.ts +19 -6
  155. package/dist/types/providers/ark.d.ts +40 -2
  156. package/dist/types/providers/delegator.d.ts +54 -1
  157. package/dist/types/providers/expoArk.d.ts +2 -2
  158. package/dist/types/providers/indexer.d.ts +105 -2
  159. package/dist/types/providers/onchain.d.ts +62 -1
  160. package/dist/types/repositories/realm/schemas.d.ts +2 -2
  161. package/dist/types/repositories/realm/types.d.ts +2 -2
  162. package/dist/types/repositories/walletRepository.d.ts +16 -0
  163. package/dist/types/script/address.d.ts +35 -2
  164. package/dist/types/script/base.d.ts +66 -1
  165. package/dist/types/script/default.d.ts +3 -0
  166. package/dist/types/script/delegate.d.ts +4 -0
  167. package/dist/types/script/tapscript.d.ts +17 -2
  168. package/dist/types/script/vhtlc.d.ts +35 -27
  169. package/dist/types/storage/fileSystem.d.ts +1 -1
  170. package/dist/types/storage/inMemory.d.ts +1 -1
  171. package/dist/types/storage/index.d.ts +1 -1
  172. package/dist/types/storage/indexedDB.d.ts +1 -1
  173. package/dist/types/storage/localStorage.d.ts +1 -1
  174. package/dist/types/utils/arkTransaction.d.ts +3 -3
  175. package/dist/types/utils/bip21.d.ts +17 -0
  176. package/dist/types/utils/syncCursors.d.ts +4 -4
  177. package/dist/types/utils/transaction.d.ts +1 -1
  178. package/dist/types/utils/transactionHistory.d.ts +3 -3
  179. package/dist/types/utils/unknownFields.d.ts +5 -5
  180. package/dist/types/wallet/asset-manager.d.ts +3 -3
  181. package/dist/types/wallet/batch.d.ts +27 -7
  182. package/dist/types/wallet/delegator.d.ts +10 -0
  183. package/dist/types/wallet/expo/background.d.ts +4 -4
  184. package/dist/types/wallet/expo/wallet.d.ts +10 -10
  185. package/dist/types/wallet/index.d.ts +457 -25
  186. package/dist/types/wallet/onchain.d.ts +42 -4
  187. package/dist/types/wallet/ramps.d.ts +40 -10
  188. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +4 -4
  189. package/dist/types/wallet/serviceWorker/wallet.d.ts +71 -33
  190. package/dist/types/wallet/unroll.d.ts +8 -6
  191. package/dist/types/wallet/vtxo-manager.d.ts +146 -93
  192. package/dist/types/wallet/wallet.d.ts +91 -33
  193. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
  194. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
  195. package/dist/types/worker/expo/taskRunner.d.ts +6 -6
  196. package/dist/types/worker/messageBus.d.ts +5 -3
  197. package/package.json +1 -1
@@ -113,12 +113,12 @@ class ReadonlyWallet {
113
113
  const serverIsMainnet = info.network === "bitcoin";
114
114
  if (identityIsMainnet && !serverIsMainnet) {
115
115
  throw new Error(`Network mismatch: identity uses mainnet derivation (coin type 0) ` +
116
- `but Ark server is on ${info.network}. ` +
116
+ `but the Arkade server is on ${info.network}. ` +
117
117
  `Create identity with { isMainnet: false } to use testnet derivation.`);
118
118
  }
119
119
  if (!identityIsMainnet && serverIsMainnet) {
120
120
  throw new Error(`Network mismatch: identity uses testnet derivation (coin type 1) ` +
121
- `but Ark server is on mainnet. ` +
121
+ `but the Arkade server is on mainnet. ` +
122
122
  `Create identity with { isMainnet: true } or omit isMainnet (defaults to mainnet).`);
123
123
  }
124
124
  }
@@ -190,6 +190,12 @@ class ReadonlyWallet {
190
190
  delegatorProvider: config.delegatorProvider,
191
191
  };
192
192
  }
193
+ /**
194
+ * Create a readonly wallet for querying balances, addresses, and history.
195
+ *
196
+ * @param config - Readonly wallet configuration
197
+ * @returns A readonly wallet instance
198
+ */
193
199
  static async create(config) {
194
200
  const pubkey = await config.identity.xOnlyPublicKey();
195
201
  if (!pubkey) {
@@ -208,12 +214,17 @@ class ReadonlyWallet {
208
214
  get defaultContractScript() {
209
215
  return base_1.hex.encode(this.offchainTapscript.pkScript);
210
216
  }
217
+ /** Returns the wallet's Arkade address. */
211
218
  async getAddress() {
212
219
  return this.arkAddress.encode();
213
220
  }
221
+ /** Returns the onchain boarding address used to move funds into Arkade. */
214
222
  async getBoardingAddress() {
215
223
  return this.boardingTapscript.onchainAddress(this.network);
216
224
  }
225
+ /**
226
+ * Return the wallet's combined onchain and offchain balances.
227
+ */
217
228
  async getBalance() {
218
229
  const [boardingUtxos, vtxos] = await Promise.all([
219
230
  this.getBoardingUtxos(),
@@ -245,7 +256,7 @@ class ReadonlyWallet {
245
256
  .reduce((sum, coin) => sum + coin.value, 0);
246
257
  const totalBoarding = confirmed + unconfirmed;
247
258
  const totalOffchain = settled + preconfirmed + recoverable;
248
- // aggregate asset balances from spendable vtxos
259
+ // aggregate asset balances from spendable virtual outputs
249
260
  const assetBalances = new Map();
250
261
  for (const vtxo of vtxos) {
251
262
  if (!(0, _1.isSpendable)(vtxo))
@@ -275,11 +286,16 @@ class ReadonlyWallet {
275
286
  assets,
276
287
  };
277
288
  }
289
+ /**
290
+ * Return virtual outputs tracked by the wallet.
291
+ *
292
+ * @param filter - Optional flags controlling whether recoverable or unrolled VTXOs are included
293
+ */
278
294
  async getVtxos(filter) {
279
295
  const { isDelta, fetchedExtended, address } = await this.syncVtxos();
280
296
  const f = filter ?? { withRecoverable: true, withUnrolled: false };
281
297
  // For delta syncs, read the full merged set from cache so old
282
- // VTXOs that weren't in the delta are still returned.
298
+ // Virtual outputs that weren't in the delta are still returned.
283
299
  const vtxos = isDelta
284
300
  ? await this.walletRepository.getVtxos(address)
285
301
  : fetchedExtended;
@@ -294,8 +310,11 @@ class ReadonlyWallet {
294
310
  return !!(f.withUnrolled && vtxo.isUnrolled);
295
311
  });
296
312
  }
313
+ /**
314
+ * Return wallet transaction history derived from Arkade state and boarding transactions.
315
+ */
297
316
  async getTransactionHistory() {
298
- // Delta-sync VTXOs into cache, then build history from the cache.
317
+ // Delta-sync virtual outputs into cache, then build history from the cache.
299
318
  const { isDelta, fetchedExtended, address } = await this.syncVtxos();
300
319
  const allVtxos = isDelta
301
320
  ? await this.walletRepository.getVtxos(address)
@@ -307,7 +326,7 @@ class ReadonlyWallet {
307
326
  return (0, transactionHistory_1.buildTransactionHistory)(allVtxos, boardingTxs, commitmentsToIgnore, getTxCreatedAt);
308
327
  }
309
328
  /**
310
- * Delta-sync wallet VTXOs: fetch only changed VTXOs since the last
329
+ * Delta-sync wallet virtual outputs: fetch only changed virtual outputs since the last
311
330
  * cursor, or do a full bootstrap when no cursor exists. Upserts
312
331
  * the result into the cache and advances the sync cursors.
313
332
  *
@@ -380,21 +399,21 @@ class ReadonlyWallet {
380
399
  allVtxos.push(...response.vtxos);
381
400
  }
382
401
  }
383
- // Extend every fetched VTXO and upsert into the cache.
402
+ // Extend every fetched virtual output and upsert into the cache.
384
403
  const fetchedExtended = [];
385
404
  for (const vtxo of allVtxos) {
386
405
  const extended = extendWithScript(vtxo);
387
406
  if (extended)
388
407
  fetchedExtended.push(extended);
389
408
  }
390
- // Save VTXOs first, then advance cursors only on success.
409
+ // Save virtual outputs first, then advance cursors only on success.
391
410
  const cutoff = (0, syncCursors_1.cursorCutoff)(requestStartedAt);
392
411
  await this.walletRepository.saveVtxos(address, fetchedExtended);
393
412
  await (0, syncCursors_1.advanceSyncCursors)(this.walletRepository, Object.fromEntries(allScripts.map((s) => [s, cutoff])));
394
413
  // Delta-sync reconciliation: full re-fetch for delta scripts.
395
414
  //
396
- // The delta fetch (above) only returns VTXOs changed after the
397
- // cursor, so it can miss preconfirmed VTXOs that were consumed
415
+ // The delta fetch (above) only returns virtual outputs changed after the
416
+ // cursor, so it can miss preconfirmed virtual outputs that were consumed
398
417
  // by a round between syncs. Rather than layering targeted
399
418
  // queries (pendingOnly, spendableOnly) with pagination guards
400
419
  // and set algebra, we perform a single unfiltered re-fetch for
@@ -402,8 +421,8 @@ class ReadonlyWallet {
402
421
  // gives us complete, authoritative state in one call and keeps
403
422
  // the reconciliation logic simple.
404
423
  //
405
- // Any cached non-spent VTXO that is absent from the full
406
- // result set is marked spent; any VTXO whose state changed
424
+ // Any cached non-spent virtual output that is absent from the full
425
+ // result set is marked spent; any virtual output whose state changed
407
426
  // (e.g. preconfirmed → settled) is updated in place.
408
427
  if (hasDelta) {
409
428
  const { vtxos: fullVtxos, page: fullPage } = await this.indexerProvider.getVtxos({
@@ -412,7 +431,7 @@ class ReadonlyWallet {
412
431
  // Reconciliation is best-effort: if the response is
413
432
  // paginated we don't have a complete picture, so we skip
414
433
  // rather than act on partial data. Wallets with enough
415
- // VTXOs to exceed a single page rely solely on the
434
+ // virtual outputs to exceed a single page rely solely on the
416
435
  // cursor-based delta mechanism for state updates.
417
436
  const fullSetComplete = !fullPage || fullPage.total <= 1;
418
437
  if (fullSetComplete) {
@@ -429,7 +448,7 @@ class ReadonlyWallet {
429
448
  const outpoint = `${cached.txid}:${cached.vout}`;
430
449
  const fresh = fullOutpoints.get(outpoint);
431
450
  if (!fresh) {
432
- // Server no longer knows about this VTXO
451
+ // Server no longer knows about this virtual output
433
452
  // it was spent between syncs.
434
453
  reconciledExtended.push({
435
454
  ...cached,
@@ -462,12 +481,15 @@ class ReadonlyWallet {
462
481
  };
463
482
  }
464
483
  /**
465
- * Clear all VTXO sync cursors, forcing a full re-bootstrap on next sync.
484
+ * Clear all virtual output sync cursors, forcing a full re-bootstrap on next sync.
466
485
  * Useful for recovery after indexer reprocessing or debugging.
467
486
  */
468
487
  async clearSyncCursors() {
469
488
  await (0, syncCursors_1.clearSyncCursors)(this.walletRepository);
470
489
  }
490
+ /**
491
+ * Build a transaction history view for the wallet's boarding address.
492
+ */
471
493
  async getBoardingTxs() {
472
494
  const utxos = [];
473
495
  const commitmentsToIgnore = new Set();
@@ -538,16 +560,25 @@ class ReadonlyWallet {
538
560
  commitmentsToIgnore,
539
561
  };
540
562
  }
563
+ /**
564
+ * Fetch and cache onchain inputs (UTXOs) received at the boarding address.
565
+ */
541
566
  async getBoardingUtxos() {
542
567
  const boardingAddress = await this.getBoardingAddress();
543
568
  const boardingUtxos = await this.onchainProvider.getCoins(boardingAddress);
544
569
  const utxos = boardingUtxos.map((utxo) => {
545
570
  return (0, utils_1.extendCoin)(this, utxo);
546
571
  });
547
- // Save boardingUtxos using unified repository
572
+ // Save boarding inputs using unified repository
548
573
  await this.walletRepository.saveUtxos(boardingAddress, utxos);
549
574
  return utxos;
550
575
  }
576
+ /**
577
+ * Subscribe to onchain and offchain notifications for newly received funds.
578
+ *
579
+ * @param eventCallback - Callback invoked when matching funds are detected
580
+ * @returns A function that stops the subscriptions
581
+ */
551
582
  async notifyIncomingFunds(eventCallback) {
552
583
  const arkAddress = await this.getAddress();
553
584
  const boardingAddress = await this.getBoardingAddress();
@@ -558,11 +589,11 @@ class ReadonlyWallet {
558
589
  return tx.vout.findIndex((v) => v.scriptpubkey_address === boardingAddress);
559
590
  };
560
591
  onchainStopFunc = await this.onchainProvider.watchAddresses([boardingAddress], (txs) => {
561
- // find all utxos belonging to our boarding address
592
+ // find all onchain outputs belonging to our boarding address
562
593
  const coins = txs
563
594
  // filter txs where address is in output
564
595
  .filter((tx) => findVoutOnTx(tx) !== -1)
565
- // return utxo as Coin
596
+ // return boarding input as Coin
566
597
  .map((tx) => {
567
598
  const { txid, status } = tx;
568
599
  const vout = findVoutOnTx(tx);
@@ -587,8 +618,8 @@ class ReadonlyWallet {
587
618
  };
588
619
  // Handle subscription updates asynchronously without blocking.
589
620
  // Note: subscription covers all wallet scripts (default + delegate),
590
- // but we can't determine which script each VTXO belongs to from the
591
- // subscription event. VTXOs are extended with the current offchainTapscript;
621
+ // but we can't determine which script each virtual output belongs to from the
622
+ // subscription event. Virtual outputs are extended with the current offchainTapscript;
592
623
  // this is for notification/display only — not for spending.
593
624
  // For correct extension metadata, use getVtxos() which queries per-script.
594
625
  (async () => {
@@ -615,8 +646,9 @@ class ReadonlyWallet {
615
646
  };
616
647
  return stopFunc;
617
648
  }
649
+ /** Fetch Arkade transaction ids that are still pending final settlement. */
618
650
  async fetchPendingTxs() {
619
- // get non-swept VTXOs, rely on the indexer only in case DB doesn't have the right state
651
+ // get non-swept virtual outputs, rely on the indexer only in case DB doesn't have the right state
620
652
  const scripts = await this.getWalletScripts();
621
653
  let { vtxos } = await this.indexerProvider.getVtxos({
622
654
  scripts,
@@ -657,7 +689,7 @@ class ReadonlyWallet {
657
689
  }
658
690
  /**
659
691
  * Build a map of scriptHex → VtxoScript for all wallet contracts,
660
- * so VTXOs can be extended with the correct tapscript per contract.
692
+ * so virtual outputs can be extended with the correct tapscript per contract.
661
693
  */
662
694
  async getScriptMap() {
663
695
  const map = new Map();
@@ -770,7 +802,7 @@ class ReadonlyWallet {
770
802
  address: await this.getAddress(),
771
803
  state: "active",
772
804
  });
773
- // Also register the non-delegate version so old VTXOs remain visible
805
+ // Also register the non-delegate version so old virtual outputs remain visible
774
806
  const nonDelegateScript = new default_1.DefaultVtxo.Script({
775
807
  pubKey: delegateScript.options.pubKey,
776
808
  serverPubKey: delegateScript.options.serverPubKey,
@@ -808,6 +840,7 @@ class ReadonlyWallet {
808
840
  }
809
841
  return manager;
810
842
  }
843
+ /** Dispose wallet-owned managers and release background resources. */
811
844
  async dispose() {
812
845
  const manager = this._contractManager ??
813
846
  (this._contractManagerInitializing
@@ -817,30 +850,31 @@ class ReadonlyWallet {
817
850
  this._contractManager = undefined;
818
851
  this._contractManagerInitializing = undefined;
819
852
  }
853
+ /** Async-dispose hook that forwards to `dispose()`. */
820
854
  async [Symbol.asyncDispose]() {
821
855
  await this.dispose();
822
856
  }
823
857
  }
824
858
  exports.ReadonlyWallet = ReadonlyWallet;
825
859
  /**
826
- * Main wallet implementation for Bitcoin transactions with Ark protocol support.
827
- * The wallet does not store any data locally and relies on Ark and onchain
828
- * providers to fetch UTXOs and VTXOs.
860
+ * Main wallet implementation for Bitcoin transactions with Arkade protocol support.
861
+ * The wallet does not store any data locally and relies on Arkade and onchain
862
+ * providers to fetch onchain and virtual outputs.
829
863
  *
830
864
  * @example
831
865
  * ```typescript
832
866
  * // Create a wallet with URL configuration
833
867
  * const wallet = await Wallet.create({
834
- * identity: SingleKey.fromHex('your_private_key'),
835
- * arkServerUrl: 'https://ark.example.com',
868
+ * identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
869
+ * arkServerUrl: 'https://arkade.computer',
836
870
  * esploraUrl: 'https://mempool.space/api'
837
871
  * });
838
872
  *
839
873
  * // Or with custom provider instances (e.g., for Expo/React Native)
840
874
  * const wallet = await Wallet.create({
841
- * identity: SingleKey.fromHex('your_private_key'),
842
- * arkProvider: new ExpoArkProvider('https://ark.example.com'),
843
- * indexerProvider: new ExpoIndexerProvider('https://ark.example.com'),
875
+ * identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
876
+ * arkProvider: new ExpoArkProvider('https://arkade.computer'),
877
+ * indexerProvider: new ExpoIndexerProvider('https://arkade.computer'),
844
878
  * esploraUrl: 'https://mempool.space/api'
845
879
  * });
846
880
  *
@@ -849,9 +883,9 @@ exports.ReadonlyWallet = ReadonlyWallet;
849
883
  * const boardingAddress = await wallet.getBoardingAddress();
850
884
  *
851
885
  * // Send bitcoin
852
- * const txid = await wallet.sendBitcoin({
853
- * address: 'tb1...',
854
- * amount: 50000
886
+ * const txid = await wallet.send({
887
+ * address: 'ark1q...',
888
+ * amount: 50000,
855
889
  * });
856
890
  * ```
857
891
  */
@@ -880,7 +914,7 @@ class Wallet extends ReadonlyWallet {
880
914
  this.forfeitOutputScript = forfeitOutputScript;
881
915
  this.forfeitPubkey = forfeitPubkey;
882
916
  /**
883
- * Async mutex that serializes all operations submitting VTXOs to the Ark
917
+ * Async mutex that serializes all operations submitting VTXOs to the Arkade
884
918
  * server (`settle`, `send`, `sendBitcoin`). This prevents VtxoManager's
885
919
  * background renewal from racing with user-initiated transactions for the
886
920
  * same VTXO inputs.
@@ -960,6 +994,19 @@ class Wallet extends ReadonlyWallet {
960
994
  await super.dispose();
961
995
  }
962
996
  }
997
+ /**
998
+ * Create a full wallet and initialize its background managers.
999
+ *
1000
+ * @param config - Wallet configuration
1001
+ * @returns A wallet ready to query balances and send transactions
1002
+ * @example
1003
+ * ```typescript
1004
+ * const wallet = await Wallet.create({
1005
+ * identity,
1006
+ * arkServerUrl: 'https://arkade.computer',
1007
+ * });
1008
+ * ```
1009
+ */
963
1010
  static async create(config) {
964
1011
  const pubkey = await config.identity.xOnlyPublicKey();
965
1012
  if (!pubkey) {
@@ -991,7 +1038,7 @@ class Wallet extends ReadonlyWallet {
991
1038
  * @returns A readonly wallet with the same configuration but readonly identity
992
1039
  * @example
993
1040
  * ```typescript
994
- * const wallet = await Wallet.create({ identity: SingleKey.fromHex('...'), ... });
1041
+ * const wallet = await Wallet.create({ identity: MnemonicIdentity.fromMnemonic('abandon abandon...'), ... });
995
1042
  * const readonlyWallet = await wallet.toReadonly();
996
1043
  *
997
1044
  * // Can query balance and addresses
@@ -999,7 +1046,7 @@ class Wallet extends ReadonlyWallet {
999
1046
  * const address = await readonlyWallet.getAddress();
1000
1047
  *
1001
1048
  * // But cannot send transactions (type error)
1002
- * // readonlyWallet.sendBitcoin(...); // TypeScript error
1049
+ * // readonlyWallet.send(...); // TypeScript error
1003
1050
  * ```
1004
1051
  */
1005
1052
  async toReadonly() {
@@ -1009,19 +1056,22 @@ class Wallet extends ReadonlyWallet {
1009
1056
  : this.identity; // Identity extends ReadonlyIdentity, so this is safe
1010
1057
  return new ReadonlyWallet(readonlyIdentity, this.network, this.onchainProvider, this.indexerProvider, this.arkServerPublicKey, this.offchainTapscript, this.boardingTapscript, this.dustAmount, this.walletRepository, this.contractRepository, this.delegatorProvider, this.watcherConfig);
1011
1058
  }
1059
+ /** Returns the delegator manager when delegation support is configured. */
1012
1060
  async getDelegatorManager() {
1013
1061
  return this._delegatorManager;
1014
1062
  }
1015
1063
  /**
1016
- * @deprecated Use `send`
1017
- * @param params
1064
+ * Send bitcoin to an Arkade address.
1065
+ *
1066
+ * @deprecated Use `send`.
1067
+ * @param params - Send parameters
1018
1068
  */
1019
1069
  async sendBitcoin(params) {
1020
1070
  if (params.amount <= 0) {
1021
1071
  throw new Error("Amount must be positive");
1022
1072
  }
1023
1073
  if (!(0, arkTransaction_1.isValidArkAddress)(params.address)) {
1024
- throw new Error("Invalid Ark address " + params.address);
1074
+ throw new Error("Invalid Arkade address " + params.address);
1025
1075
  }
1026
1076
  if (params.selectedVtxos && params.selectedVtxos.length > 0) {
1027
1077
  return this._withTxLock(async () => {
@@ -1066,6 +1116,13 @@ class Wallet extends ReadonlyWallet {
1066
1116
  amount: params.amount,
1067
1117
  });
1068
1118
  }
1119
+ /**
1120
+ * Settle boarding inputs and/or virtual outputs into a finalized mainnet transaction.
1121
+ *
1122
+ * @param params - Optional settlement inputs and outputs. When omitted, the wallet settles all eligible funds.
1123
+ * @param eventCallback - Optional callback invoked for settlement stream events.
1124
+ * @returns The finalized Arkade transaction id
1125
+ */
1069
1126
  async settle(params, eventCallback) {
1070
1127
  return this._withTxLock(() => this._settleImpl(params, eventCallback));
1071
1128
  }
@@ -1083,7 +1140,7 @@ class Wallet extends ReadonlyWallet {
1083
1140
  }
1084
1141
  }
1085
1142
  }
1086
- // if no params are provided, use all non expired boarding utxos and offchain vtxos as inputs
1143
+ // if no params are provided, use all non-expired boarding inputs and offchain virtual outputs as inputs
1087
1144
  // and send all to the offchain address
1088
1145
  if (!params) {
1089
1146
  const { fees } = await this.arkProvider.getInfo();
@@ -1104,7 +1161,7 @@ class Wallet extends ReadonlyWallet {
1104
1161
  amount: BigInt(utxo.value),
1105
1162
  });
1106
1163
  if (inputFee.value >= utxo.value) {
1107
- // skip if fees are greater than the utxo value
1164
+ // skip if fees are greater than the boarding input value
1108
1165
  continue;
1109
1166
  }
1110
1167
  filteredBoardingUtxos.push(utxo);
@@ -1125,7 +1182,7 @@ class Wallet extends ReadonlyWallet {
1125
1182
  : new Date(),
1126
1183
  });
1127
1184
  if (inputFee.value >= vtxo.value) {
1128
- // skip if fees are greater than the vtxo value
1185
+ // skip if fees are greater than the virtual output value
1129
1186
  continue;
1130
1187
  }
1131
1188
  filteredVtxos.push(vtxo);
@@ -1216,7 +1273,7 @@ class Wallet extends ReadonlyWallet {
1216
1273
  const assetPacket = (0, asset_1.createAssetPacket)(assetInputs, recipients);
1217
1274
  outputs.push(extension_1.Extension.create([assetPacket]).txOut());
1218
1275
  }
1219
- // session holds the state of the musig2 signing process of the vtxo tree
1276
+ // session holds the state of the musig2 signing process of the virtual output tree
1220
1277
  let session;
1221
1278
  const signingPublicKeys = [];
1222
1279
  if (hasOffchainOutputs) {
@@ -1267,7 +1324,7 @@ class Wallet extends ReadonlyWallet {
1267
1324
  for (const input of inputs) {
1268
1325
  // check if the input is an offchain "virtual" coin
1269
1326
  const vtxo = vtxos.find((vtxo) => vtxo.txid === input.txid && vtxo.vout === input.vout);
1270
- // boarding utxo, we need to sign the settlement tx
1327
+ // boarding input, we need to sign the settlement tx
1271
1328
  if (!vtxo) {
1272
1329
  for (let i = 0; i < settlementPsbt.inputsLength; i++) {
1273
1330
  const settlementInput = settlementPsbt.getInput(i);
@@ -1345,11 +1402,12 @@ class Wallet extends ReadonlyWallet {
1345
1402
  }
1346
1403
  }
1347
1404
  /**
1348
- * @implements Batch.Handler interface.
1405
+ * Create a batch event handler for settlement flows.
1406
+ *
1349
1407
  * @param intentId - The intent ID.
1350
- * @param inputs - The inputs of the intent.
1351
- * @param session - The musig2 signing session, if not provided, the signing will be skipped.
1352
- * @param expectedRecipients - Expected recipients to validate in the vtxo tree.
1408
+ * @param inputs - Inputs used by the intent.
1409
+ * @param expectedRecipients - Expected recipients to validate in the virtual output tree.
1410
+ * @param session - Optional musig2 signing session. When omitted, signing steps are skipped.
1353
1411
  */
1354
1412
  createBatchHandler(intentId, inputs, expectedRecipients, session) {
1355
1413
  let sweepTapTreeRoot;
@@ -1363,7 +1421,7 @@ class Wallet extends ReadonlyWallet {
1363
1421
  for (const idHash of event.intentIdHashes) {
1364
1422
  if (idHash === intentIdHashStr) {
1365
1423
  if (!this.arkProvider) {
1366
- throw new Error("Ark provider not configured");
1424
+ throw new Error("Arkade provider not configured");
1367
1425
  }
1368
1426
  await this.arkProvider.confirmRegistration(intentId);
1369
1427
  skip = false;
@@ -1396,10 +1454,10 @@ class Wallet extends ReadonlyWallet {
1396
1454
  // not a cosigner, skip the signing
1397
1455
  return { skip: true };
1398
1456
  }
1399
- // validate the unsigned vtxo tree
1457
+ // validate the unsigned virtual output tree
1400
1458
  const commitmentTx = btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(event.unsignedCommitmentTx));
1401
1459
  (0, validation_1.validateVtxoTxGraph)(vtxoTree, commitmentTx, sweepTapTreeRoot);
1402
- // validate that all expected receivers are in the vtxo tree with correct amounts and assets
1460
+ // validate that all expected receivers are in the virtual output tree with correct amounts and assets
1403
1461
  if (expectedRecipients && expectedRecipients.length > 0) {
1404
1462
  (0, validation_2.validateBatchRecipients)(commitmentTx, vtxoTree.leaves(), expectedRecipients, this.network);
1405
1463
  }
@@ -1500,7 +1558,7 @@ class Wallet extends ReadonlyWallet {
1500
1558
  /**
1501
1559
  * Finalizes pending transactions by retrieving them from the server and finalizing each one.
1502
1560
  * Skips the server check entirely when no send was interrupted (no pending tx flag set).
1503
- * @param vtxos - Optional list of VTXOs to use instead of retrieving them from the server
1561
+ * @param vtxos - Optional list of virtual outputs to use instead of retrieving them from the server
1504
1562
  * @returns Array of transaction IDs that were finalized
1505
1563
  */
1506
1564
  async finalizePendingTxs(vtxos) {
@@ -1599,13 +1657,13 @@ class Wallet extends ReadonlyWallet {
1599
1657
  /**
1600
1658
  * Send BTC and/or assets to one or more recipients.
1601
1659
  *
1602
- * @param recipients - Array of recipients with their addresses, BTC amounts, and assets
1603
- * @returns Promise resolving to the ark transaction ID
1660
+ * @param args - Recipients with their addresses, BTC amounts, and assets
1661
+ * @returns Promise resolving to the Arkade transaction ID
1604
1662
  *
1605
1663
  * @example
1606
1664
  * ```typescript
1607
1665
  * const txid = await wallet.send({
1608
- * address: 'ark1...',
1666
+ * address: 'ark1q...',
1609
1667
  * amount: 1000, // (optional, default to dust) btc amount to send to the output
1610
1668
  * assets: [{ assetId: 'abc123...', amount: 50 }] // (optional) list of assets to send
1611
1669
  * });
@@ -1753,8 +1811,8 @@ class Wallet extends ReadonlyWallet {
1753
1811
  }
1754
1812
  /**
1755
1813
  * Build an offchain transaction from the given inputs and outputs,
1756
- * sign it, submit to the ark provider, and finalize.
1757
- * @returns The ark transaction id and server-signed checkpoint PSBTs (for bookkeeping)
1814
+ * sign it, submit to the Arkade provider, and finalize.
1815
+ * @returns The Arkade transaction id and server-signed checkpoint PSBTs (for bookkeeping)
1758
1816
  */
1759
1817
  async buildAndSubmitOffchainTx(inputs, outputs) {
1760
1818
  const offchainTx = (0, arkTransaction_1.buildOffchainTx)(inputs.map((input) => {
@@ -1813,7 +1871,7 @@ class Wallet extends ReadonlyWallet {
1813
1871
  }
1814
1872
  return { arkTxid, signedCheckpointTxs };
1815
1873
  }
1816
- // mark vtxo spent and save change vtxo if any
1874
+ // mark virtual outputs as spent, save change outputs if any
1817
1875
  async updateDbAfterOffchainTx(inputs, arkTxid, signedCheckpointTxs, sentAmount, changeAmount, changeVout, changeAssets) {
1818
1876
  try {
1819
1877
  const spentVtxos = [];
@@ -1861,7 +1919,7 @@ class Wallet extends ReadonlyWallet {
1861
1919
  }
1862
1920
  const createdAt = Date.now();
1863
1921
  const addr = this.arkAddress.encode();
1864
- // Only save a change VTXO for preconfirmed coins (those with a batchExpiry).
1922
+ // Only save a change virtual output for preconfirmed coins (those with a batchExpiry).
1865
1923
  // Inputs without a batchExpiry are already settled/unrolled and don't need tracking.
1866
1924
  let changeVtxo;
1867
1925
  if (changeAmount > 0n && batchExpiry !== Number.MAX_SAFE_INTEGER) {
@@ -1905,7 +1963,7 @@ class Wallet extends ReadonlyWallet {
1905
1963
  console.warn("error saving offchain tx to repository", e);
1906
1964
  }
1907
1965
  }
1908
- // mark vtxo spent & settled, remove boarding utxo
1966
+ // mark virtual outputs as spent/settled, remove boarding inputs
1909
1967
  async updateDbAfterSettle(inputs, commitmentTxid) {
1910
1968
  try {
1911
1969
  const addr = this.arkAddress.encode();
@@ -1916,7 +1974,7 @@ class Wallet extends ReadonlyWallet {
1916
1974
  const isVtxo = (input) => "virtualStatus" in input;
1917
1975
  for (const input of inputs) {
1918
1976
  if (isVtxo(input)) {
1919
- // vtxo = mark it settled
1977
+ // virtual output = mark it settled
1920
1978
  const vtxo = (0, utils_1.extendVirtualCoin)(this, input);
1921
1979
  if (vtxo.arkTxId) {
1922
1980
  inputArkTxIds.add(vtxo.arkTxId);
@@ -1932,7 +1990,7 @@ class Wallet extends ReadonlyWallet {
1932
1990
  });
1933
1991
  }
1934
1992
  else {
1935
- // boarding utxo = remove it
1993
+ // boarding input = remove it
1936
1994
  boardingUtxoToRemove.add(`${input.txid}:${input.vout}`);
1937
1995
  }
1938
1996
  }
@@ -1957,13 +2015,13 @@ class Wallet extends ReadonlyWallet {
1957
2015
  exports.Wallet = Wallet;
1958
2016
  Wallet.MIN_FEE_RATE = 1; // sats/vbyte
1959
2017
  /**
1960
- * Select virtual coins to reach a target amount, prioritizing those closer to expiry
1961
- * @param coins List of virtual coins to select from
2018
+ * Select virtual outputs to reach a target amount, prioritizing those closer to expiry
2019
+ * @param coins List of virtual outputs to select from
1962
2020
  * @param targetAmount Target amount to reach in satoshis
1963
- * @returns Selected coins and change amount
2021
+ * @returns Selected virtual outputs and change amount
1964
2022
  */
1965
2023
  function selectVirtualCoins(coins, targetAmount) {
1966
- // Sort VTXOs by expiry (ascending) and amount (descending)
2024
+ // Sort virtual outputs by expiry (ascending) and amount (descending)
1967
2025
  const sortedCoins = [...coins].sort((a, b) => {
1968
2026
  // First sort by expiry if available
1969
2027
  const expiryA = a.virtualStatus.batchExpiry || Number.MAX_SAFE_INTEGER;
@@ -52,7 +52,7 @@ class AsyncStorageTaskQueue {
52
52
  // ── Config persistence (for background handler rehydration) ──────
53
53
  /**
54
54
  * Persist a config blob alongside the queue data.
55
- * Used by {@link ExpoWallet.setup} to store the wallet parameters
55
+ * Used by @see ExpoWallet.setup to store the wallet parameters
56
56
  * that the background handler needs to reconstruct providers.
57
57
  */
58
58
  async persistConfig(config) {
@@ -6,7 +6,7 @@ exports.CONTRACT_POLL_TASK_TYPE = "contract-poll";
6
6
  * Polls the indexer for the latest VTXO state of every contract and
7
7
  * persists the results to the wallet repository.
8
8
  *
9
- * Replicates the polling subset of {@link ContractManager.initialize}:
9
+ * Replicates the polling subset of @see ContractManager.initialize:
10
10
  * 1. Load all contracts from the contract repository.
11
11
  * 2. Mark expired active contracts as inactive.
12
12
  * 3. Paginated fetch of spendable VTXOs from the indexer.
@@ -29,7 +29,7 @@ exports.contractPollProcessor = {
29
29
  contract.state = "inactive";
30
30
  await contractRepository.saveContract(contract);
31
31
  }
32
- // Paginated fetch of spendable VTXOs
32
+ // Paginated fetch of spendable virtual outputs
33
33
  const pageSize = 100;
34
34
  let pageIndex = 0;
35
35
  let hasMore = true;
@@ -8,7 +8,7 @@ const utils_1 = require("../../wallet/utils");
8
8
  *
9
9
  * For each task in the inbox:
10
10
  * 1. Find the processor whose `taskType` matches `task.type`.
11
- * 2. Execute it, producing a {@link TaskResult}.
11
+ * 2. Execute it, producing a @see TaskResult.
12
12
  * 3. Push the result to the outbox and remove the task from the inbox.
13
13
  *
14
14
  * Tasks with no matching processor produce a `"noop"` result.
@@ -57,8 +57,8 @@ async function runTasks(queue, processors, deps) {
57
57
  return results;
58
58
  }
59
59
  /**
60
- * Build the {@link TaskDependencies} needed by task processors
61
- * (e.g. {@link import("./processors").contractPollProcessor}).
60
+ * Build the @see TaskDependencies needed by task processors
61
+ * (e.g. `src/worker/expo/processors/contractPollProcessor.ts`)
62
62
  *
63
63
  * This is the same construction that `defineExpoBackgroundTask` does
64
64
  * internally, extracted so that consumers with custom schedulers
@@ -10,6 +10,7 @@ const wallet_1 = require("../wallet/wallet");
10
10
  const base_1 = require("@scure/base");
11
11
  const errors_1 = require("./errors");
12
12
  class MessageBus {
13
+ /** Create the service-worker message bus with repositories and handler configuration. */
13
14
  constructor(walletRepository, contractRepository, { messageHandlers, tickIntervalMs = 10000, messageTimeoutMs = 30000, debug = false, buildServices, }) {
14
15
  this.walletRepository = walletRepository;
15
16
  this.contractRepository = contractRepository;
@@ -25,6 +26,7 @@ class MessageBus {
25
26
  this.debug = debug;
26
27
  this.buildServicesFn = buildServices ?? this.buildServices.bind(this);
27
28
  }
29
+ /** Start the message bus and attach service-worker event listeners. */
28
30
  async start() {
29
31
  if (this.running)
30
32
  return;
@@ -45,6 +47,7 @@ class MessageBus {
45
47
  }
46
48
  });
47
49
  }
50
+ /** Stop the message bus, cancel ticks, and stop all registered handlers. */
48
51
  async stop() {
49
52
  if (this.debug)
50
53
  console.log("MessageBus stopping");
@@ -1,7 +1,7 @@
1
1
  import { IntentOffchainInputEnv, IntentOnchainInputEnv, IntentOutputEnv, } from "./celenv.js";
2
2
  import { FeeAmount, } from "./types.js";
3
3
  /**
4
- * Estimator evaluates CEL expressions to calculate fees for Ark intents
4
+ * Estimator evaluates CEL expressions to calculate fees for Arkade intents
5
5
  */
6
6
  export class Estimator {
7
7
  /**