@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
@@ -108,12 +108,12 @@ export class ReadonlyWallet {
108
108
  const serverIsMainnet = info.network === "bitcoin";
109
109
  if (identityIsMainnet && !serverIsMainnet) {
110
110
  throw new Error(`Network mismatch: identity uses mainnet derivation (coin type 0) ` +
111
- `but Ark server is on ${info.network}. ` +
111
+ `but the Arkade server is on ${info.network}. ` +
112
112
  `Create identity with { isMainnet: false } to use testnet derivation.`);
113
113
  }
114
114
  if (!identityIsMainnet && serverIsMainnet) {
115
115
  throw new Error(`Network mismatch: identity uses testnet derivation (coin type 1) ` +
116
- `but Ark server is on mainnet. ` +
116
+ `but the Arkade server is on mainnet. ` +
117
117
  `Create identity with { isMainnet: true } or omit isMainnet (defaults to mainnet).`);
118
118
  }
119
119
  }
@@ -185,6 +185,12 @@ export class ReadonlyWallet {
185
185
  delegatorProvider: config.delegatorProvider,
186
186
  };
187
187
  }
188
+ /**
189
+ * Create a readonly wallet for querying balances, addresses, and history.
190
+ *
191
+ * @param config - Readonly wallet configuration
192
+ * @returns A readonly wallet instance
193
+ */
188
194
  static async create(config) {
189
195
  const pubkey = await config.identity.xOnlyPublicKey();
190
196
  if (!pubkey) {
@@ -203,12 +209,17 @@ export class ReadonlyWallet {
203
209
  get defaultContractScript() {
204
210
  return hex.encode(this.offchainTapscript.pkScript);
205
211
  }
212
+ /** Returns the wallet's Arkade address. */
206
213
  async getAddress() {
207
214
  return this.arkAddress.encode();
208
215
  }
216
+ /** Returns the onchain boarding address used to move funds into Arkade. */
209
217
  async getBoardingAddress() {
210
218
  return this.boardingTapscript.onchainAddress(this.network);
211
219
  }
220
+ /**
221
+ * Return the wallet's combined onchain and offchain balances.
222
+ */
212
223
  async getBalance() {
213
224
  const [boardingUtxos, vtxos] = await Promise.all([
214
225
  this.getBoardingUtxos(),
@@ -240,7 +251,7 @@ export class ReadonlyWallet {
240
251
  .reduce((sum, coin) => sum + coin.value, 0);
241
252
  const totalBoarding = confirmed + unconfirmed;
242
253
  const totalOffchain = settled + preconfirmed + recoverable;
243
- // aggregate asset balances from spendable vtxos
254
+ // aggregate asset balances from spendable virtual outputs
244
255
  const assetBalances = new Map();
245
256
  for (const vtxo of vtxos) {
246
257
  if (!isSpendable(vtxo))
@@ -270,11 +281,16 @@ export class ReadonlyWallet {
270
281
  assets,
271
282
  };
272
283
  }
284
+ /**
285
+ * Return virtual outputs tracked by the wallet.
286
+ *
287
+ * @param filter - Optional flags controlling whether recoverable or unrolled VTXOs are included
288
+ */
273
289
  async getVtxos(filter) {
274
290
  const { isDelta, fetchedExtended, address } = await this.syncVtxos();
275
291
  const f = filter ?? { withRecoverable: true, withUnrolled: false };
276
292
  // For delta syncs, read the full merged set from cache so old
277
- // VTXOs that weren't in the delta are still returned.
293
+ // Virtual outputs that weren't in the delta are still returned.
278
294
  const vtxos = isDelta
279
295
  ? await this.walletRepository.getVtxos(address)
280
296
  : fetchedExtended;
@@ -289,8 +305,11 @@ export class ReadonlyWallet {
289
305
  return !!(f.withUnrolled && vtxo.isUnrolled);
290
306
  });
291
307
  }
308
+ /**
309
+ * Return wallet transaction history derived from Arkade state and boarding transactions.
310
+ */
292
311
  async getTransactionHistory() {
293
- // Delta-sync VTXOs into cache, then build history from the cache.
312
+ // Delta-sync virtual outputs into cache, then build history from the cache.
294
313
  const { isDelta, fetchedExtended, address } = await this.syncVtxos();
295
314
  const allVtxos = isDelta
296
315
  ? await this.walletRepository.getVtxos(address)
@@ -302,7 +321,7 @@ export class ReadonlyWallet {
302
321
  return buildTransactionHistory(allVtxos, boardingTxs, commitmentsToIgnore, getTxCreatedAt);
303
322
  }
304
323
  /**
305
- * Delta-sync wallet VTXOs: fetch only changed VTXOs since the last
324
+ * Delta-sync wallet virtual outputs: fetch only changed virtual outputs since the last
306
325
  * cursor, or do a full bootstrap when no cursor exists. Upserts
307
326
  * the result into the cache and advances the sync cursors.
308
327
  *
@@ -375,21 +394,21 @@ export class ReadonlyWallet {
375
394
  allVtxos.push(...response.vtxos);
376
395
  }
377
396
  }
378
- // Extend every fetched VTXO and upsert into the cache.
397
+ // Extend every fetched virtual output and upsert into the cache.
379
398
  const fetchedExtended = [];
380
399
  for (const vtxo of allVtxos) {
381
400
  const extended = extendWithScript(vtxo);
382
401
  if (extended)
383
402
  fetchedExtended.push(extended);
384
403
  }
385
- // Save VTXOs first, then advance cursors only on success.
404
+ // Save virtual outputs first, then advance cursors only on success.
386
405
  const cutoff = cursorCutoff(requestStartedAt);
387
406
  await this.walletRepository.saveVtxos(address, fetchedExtended);
388
407
  await advanceSyncCursors(this.walletRepository, Object.fromEntries(allScripts.map((s) => [s, cutoff])));
389
408
  // Delta-sync reconciliation: full re-fetch for delta scripts.
390
409
  //
391
- // The delta fetch (above) only returns VTXOs changed after the
392
- // cursor, so it can miss preconfirmed VTXOs that were consumed
410
+ // The delta fetch (above) only returns virtual outputs changed after the
411
+ // cursor, so it can miss preconfirmed virtual outputs that were consumed
393
412
  // by a round between syncs. Rather than layering targeted
394
413
  // queries (pendingOnly, spendableOnly) with pagination guards
395
414
  // and set algebra, we perform a single unfiltered re-fetch for
@@ -397,8 +416,8 @@ export class ReadonlyWallet {
397
416
  // gives us complete, authoritative state in one call and keeps
398
417
  // the reconciliation logic simple.
399
418
  //
400
- // Any cached non-spent VTXO that is absent from the full
401
- // result set is marked spent; any VTXO whose state changed
419
+ // Any cached non-spent virtual output that is absent from the full
420
+ // result set is marked spent; any virtual output whose state changed
402
421
  // (e.g. preconfirmed → settled) is updated in place.
403
422
  if (hasDelta) {
404
423
  const { vtxos: fullVtxos, page: fullPage } = await this.indexerProvider.getVtxos({
@@ -407,7 +426,7 @@ export class ReadonlyWallet {
407
426
  // Reconciliation is best-effort: if the response is
408
427
  // paginated we don't have a complete picture, so we skip
409
428
  // rather than act on partial data. Wallets with enough
410
- // VTXOs to exceed a single page rely solely on the
429
+ // virtual outputs to exceed a single page rely solely on the
411
430
  // cursor-based delta mechanism for state updates.
412
431
  const fullSetComplete = !fullPage || fullPage.total <= 1;
413
432
  if (fullSetComplete) {
@@ -424,7 +443,7 @@ export class ReadonlyWallet {
424
443
  const outpoint = `${cached.txid}:${cached.vout}`;
425
444
  const fresh = fullOutpoints.get(outpoint);
426
445
  if (!fresh) {
427
- // Server no longer knows about this VTXO
446
+ // Server no longer knows about this virtual output
428
447
  // it was spent between syncs.
429
448
  reconciledExtended.push({
430
449
  ...cached,
@@ -457,12 +476,15 @@ export class ReadonlyWallet {
457
476
  };
458
477
  }
459
478
  /**
460
- * Clear all VTXO sync cursors, forcing a full re-bootstrap on next sync.
479
+ * Clear all virtual output sync cursors, forcing a full re-bootstrap on next sync.
461
480
  * Useful for recovery after indexer reprocessing or debugging.
462
481
  */
463
482
  async clearSyncCursors() {
464
483
  await clearSyncCursors(this.walletRepository);
465
484
  }
485
+ /**
486
+ * Build a transaction history view for the wallet's boarding address.
487
+ */
466
488
  async getBoardingTxs() {
467
489
  const utxos = [];
468
490
  const commitmentsToIgnore = new Set();
@@ -533,16 +555,25 @@ export class ReadonlyWallet {
533
555
  commitmentsToIgnore,
534
556
  };
535
557
  }
558
+ /**
559
+ * Fetch and cache onchain inputs (UTXOs) received at the boarding address.
560
+ */
536
561
  async getBoardingUtxos() {
537
562
  const boardingAddress = await this.getBoardingAddress();
538
563
  const boardingUtxos = await this.onchainProvider.getCoins(boardingAddress);
539
564
  const utxos = boardingUtxos.map((utxo) => {
540
565
  return extendCoin(this, utxo);
541
566
  });
542
- // Save boardingUtxos using unified repository
567
+ // Save boarding inputs using unified repository
543
568
  await this.walletRepository.saveUtxos(boardingAddress, utxos);
544
569
  return utxos;
545
570
  }
571
+ /**
572
+ * Subscribe to onchain and offchain notifications for newly received funds.
573
+ *
574
+ * @param eventCallback - Callback invoked when matching funds are detected
575
+ * @returns A function that stops the subscriptions
576
+ */
546
577
  async notifyIncomingFunds(eventCallback) {
547
578
  const arkAddress = await this.getAddress();
548
579
  const boardingAddress = await this.getBoardingAddress();
@@ -553,11 +584,11 @@ export class ReadonlyWallet {
553
584
  return tx.vout.findIndex((v) => v.scriptpubkey_address === boardingAddress);
554
585
  };
555
586
  onchainStopFunc = await this.onchainProvider.watchAddresses([boardingAddress], (txs) => {
556
- // find all utxos belonging to our boarding address
587
+ // find all onchain outputs belonging to our boarding address
557
588
  const coins = txs
558
589
  // filter txs where address is in output
559
590
  .filter((tx) => findVoutOnTx(tx) !== -1)
560
- // return utxo as Coin
591
+ // return boarding input as Coin
561
592
  .map((tx) => {
562
593
  const { txid, status } = tx;
563
594
  const vout = findVoutOnTx(tx);
@@ -582,8 +613,8 @@ export class ReadonlyWallet {
582
613
  };
583
614
  // Handle subscription updates asynchronously without blocking.
584
615
  // Note: subscription covers all wallet scripts (default + delegate),
585
- // but we can't determine which script each VTXO belongs to from the
586
- // subscription event. VTXOs are extended with the current offchainTapscript;
616
+ // but we can't determine which script each virtual output belongs to from the
617
+ // subscription event. Virtual outputs are extended with the current offchainTapscript;
587
618
  // this is for notification/display only — not for spending.
588
619
  // For correct extension metadata, use getVtxos() which queries per-script.
589
620
  (async () => {
@@ -610,8 +641,9 @@ export class ReadonlyWallet {
610
641
  };
611
642
  return stopFunc;
612
643
  }
644
+ /** Fetch Arkade transaction ids that are still pending final settlement. */
613
645
  async fetchPendingTxs() {
614
- // get non-swept VTXOs, rely on the indexer only in case DB doesn't have the right state
646
+ // get non-swept virtual outputs, rely on the indexer only in case DB doesn't have the right state
615
647
  const scripts = await this.getWalletScripts();
616
648
  let { vtxos } = await this.indexerProvider.getVtxos({
617
649
  scripts,
@@ -652,7 +684,7 @@ export class ReadonlyWallet {
652
684
  }
653
685
  /**
654
686
  * Build a map of scriptHex → VtxoScript for all wallet contracts,
655
- * so VTXOs can be extended with the correct tapscript per contract.
687
+ * so virtual outputs can be extended with the correct tapscript per contract.
656
688
  */
657
689
  async getScriptMap() {
658
690
  const map = new Map();
@@ -765,7 +797,7 @@ export class ReadonlyWallet {
765
797
  address: await this.getAddress(),
766
798
  state: "active",
767
799
  });
768
- // Also register the non-delegate version so old VTXOs remain visible
800
+ // Also register the non-delegate version so old virtual outputs remain visible
769
801
  const nonDelegateScript = new DefaultVtxo.Script({
770
802
  pubKey: delegateScript.options.pubKey,
771
803
  serverPubKey: delegateScript.options.serverPubKey,
@@ -803,6 +835,7 @@ export class ReadonlyWallet {
803
835
  }
804
836
  return manager;
805
837
  }
838
+ /** Dispose wallet-owned managers and release background resources. */
806
839
  async dispose() {
807
840
  const manager = this._contractManager ??
808
841
  (this._contractManagerInitializing
@@ -812,29 +845,30 @@ export class ReadonlyWallet {
812
845
  this._contractManager = undefined;
813
846
  this._contractManagerInitializing = undefined;
814
847
  }
848
+ /** Async-dispose hook that forwards to `dispose()`. */
815
849
  async [Symbol.asyncDispose]() {
816
850
  await this.dispose();
817
851
  }
818
852
  }
819
853
  /**
820
- * Main wallet implementation for Bitcoin transactions with Ark protocol support.
821
- * The wallet does not store any data locally and relies on Ark and onchain
822
- * providers to fetch UTXOs and VTXOs.
854
+ * Main wallet implementation for Bitcoin transactions with Arkade protocol support.
855
+ * The wallet does not store any data locally and relies on Arkade and onchain
856
+ * providers to fetch onchain and virtual outputs.
823
857
  *
824
858
  * @example
825
859
  * ```typescript
826
860
  * // Create a wallet with URL configuration
827
861
  * const wallet = await Wallet.create({
828
- * identity: SingleKey.fromHex('your_private_key'),
829
- * arkServerUrl: 'https://ark.example.com',
862
+ * identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
863
+ * arkServerUrl: 'https://arkade.computer',
830
864
  * esploraUrl: 'https://mempool.space/api'
831
865
  * });
832
866
  *
833
867
  * // Or with custom provider instances (e.g., for Expo/React Native)
834
868
  * const wallet = await Wallet.create({
835
- * identity: SingleKey.fromHex('your_private_key'),
836
- * arkProvider: new ExpoArkProvider('https://ark.example.com'),
837
- * indexerProvider: new ExpoIndexerProvider('https://ark.example.com'),
869
+ * identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
870
+ * arkProvider: new ExpoArkProvider('https://arkade.computer'),
871
+ * indexerProvider: new ExpoIndexerProvider('https://arkade.computer'),
838
872
  * esploraUrl: 'https://mempool.space/api'
839
873
  * });
840
874
  *
@@ -843,9 +877,9 @@ export class ReadonlyWallet {
843
877
  * const boardingAddress = await wallet.getBoardingAddress();
844
878
  *
845
879
  * // Send bitcoin
846
- * const txid = await wallet.sendBitcoin({
847
- * address: 'tb1...',
848
- * amount: 50000
880
+ * const txid = await wallet.send({
881
+ * address: 'ark1q...',
882
+ * amount: 50000,
849
883
  * });
850
884
  * ```
851
885
  */
@@ -874,7 +908,7 @@ export class Wallet extends ReadonlyWallet {
874
908
  this.forfeitOutputScript = forfeitOutputScript;
875
909
  this.forfeitPubkey = forfeitPubkey;
876
910
  /**
877
- * Async mutex that serializes all operations submitting VTXOs to the Ark
911
+ * Async mutex that serializes all operations submitting VTXOs to the Arkade
878
912
  * server (`settle`, `send`, `sendBitcoin`). This prevents VtxoManager's
879
913
  * background renewal from racing with user-initiated transactions for the
880
914
  * same VTXO inputs.
@@ -954,6 +988,19 @@ export class Wallet extends ReadonlyWallet {
954
988
  await super.dispose();
955
989
  }
956
990
  }
991
+ /**
992
+ * Create a full wallet and initialize its background managers.
993
+ *
994
+ * @param config - Wallet configuration
995
+ * @returns A wallet ready to query balances and send transactions
996
+ * @example
997
+ * ```typescript
998
+ * const wallet = await Wallet.create({
999
+ * identity,
1000
+ * arkServerUrl: 'https://arkade.computer',
1001
+ * });
1002
+ * ```
1003
+ */
957
1004
  static async create(config) {
958
1005
  const pubkey = await config.identity.xOnlyPublicKey();
959
1006
  if (!pubkey) {
@@ -985,7 +1032,7 @@ export class Wallet extends ReadonlyWallet {
985
1032
  * @returns A readonly wallet with the same configuration but readonly identity
986
1033
  * @example
987
1034
  * ```typescript
988
- * const wallet = await Wallet.create({ identity: SingleKey.fromHex('...'), ... });
1035
+ * const wallet = await Wallet.create({ identity: MnemonicIdentity.fromMnemonic('abandon abandon...'), ... });
989
1036
  * const readonlyWallet = await wallet.toReadonly();
990
1037
  *
991
1038
  * // Can query balance and addresses
@@ -993,7 +1040,7 @@ export class Wallet extends ReadonlyWallet {
993
1040
  * const address = await readonlyWallet.getAddress();
994
1041
  *
995
1042
  * // But cannot send transactions (type error)
996
- * // readonlyWallet.sendBitcoin(...); // TypeScript error
1043
+ * // readonlyWallet.send(...); // TypeScript error
997
1044
  * ```
998
1045
  */
999
1046
  async toReadonly() {
@@ -1003,19 +1050,22 @@ export class Wallet extends ReadonlyWallet {
1003
1050
  : this.identity; // Identity extends ReadonlyIdentity, so this is safe
1004
1051
  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);
1005
1052
  }
1053
+ /** Returns the delegator manager when delegation support is configured. */
1006
1054
  async getDelegatorManager() {
1007
1055
  return this._delegatorManager;
1008
1056
  }
1009
1057
  /**
1010
- * @deprecated Use `send`
1011
- * @param params
1058
+ * Send bitcoin to an Arkade address.
1059
+ *
1060
+ * @deprecated Use `send`.
1061
+ * @param params - Send parameters
1012
1062
  */
1013
1063
  async sendBitcoin(params) {
1014
1064
  if (params.amount <= 0) {
1015
1065
  throw new Error("Amount must be positive");
1016
1066
  }
1017
1067
  if (!isValidArkAddress(params.address)) {
1018
- throw new Error("Invalid Ark address " + params.address);
1068
+ throw new Error("Invalid Arkade address " + params.address);
1019
1069
  }
1020
1070
  if (params.selectedVtxos && params.selectedVtxos.length > 0) {
1021
1071
  return this._withTxLock(async () => {
@@ -1060,6 +1110,13 @@ export class Wallet extends ReadonlyWallet {
1060
1110
  amount: params.amount,
1061
1111
  });
1062
1112
  }
1113
+ /**
1114
+ * Settle boarding inputs and/or virtual outputs into a finalized mainnet transaction.
1115
+ *
1116
+ * @param params - Optional settlement inputs and outputs. When omitted, the wallet settles all eligible funds.
1117
+ * @param eventCallback - Optional callback invoked for settlement stream events.
1118
+ * @returns The finalized Arkade transaction id
1119
+ */
1063
1120
  async settle(params, eventCallback) {
1064
1121
  return this._withTxLock(() => this._settleImpl(params, eventCallback));
1065
1122
  }
@@ -1077,7 +1134,7 @@ export class Wallet extends ReadonlyWallet {
1077
1134
  }
1078
1135
  }
1079
1136
  }
1080
- // if no params are provided, use all non expired boarding utxos and offchain vtxos as inputs
1137
+ // if no params are provided, use all non-expired boarding inputs and offchain virtual outputs as inputs
1081
1138
  // and send all to the offchain address
1082
1139
  if (!params) {
1083
1140
  const { fees } = await this.arkProvider.getInfo();
@@ -1098,7 +1155,7 @@ export class Wallet extends ReadonlyWallet {
1098
1155
  amount: BigInt(utxo.value),
1099
1156
  });
1100
1157
  if (inputFee.value >= utxo.value) {
1101
- // skip if fees are greater than the utxo value
1158
+ // skip if fees are greater than the boarding input value
1102
1159
  continue;
1103
1160
  }
1104
1161
  filteredBoardingUtxos.push(utxo);
@@ -1119,7 +1176,7 @@ export class Wallet extends ReadonlyWallet {
1119
1176
  : new Date(),
1120
1177
  });
1121
1178
  if (inputFee.value >= vtxo.value) {
1122
- // skip if fees are greater than the vtxo value
1179
+ // skip if fees are greater than the virtual output value
1123
1180
  continue;
1124
1181
  }
1125
1182
  filteredVtxos.push(vtxo);
@@ -1210,7 +1267,7 @@ export class Wallet extends ReadonlyWallet {
1210
1267
  const assetPacket = createAssetPacket(assetInputs, recipients);
1211
1268
  outputs.push(Extension.create([assetPacket]).txOut());
1212
1269
  }
1213
- // session holds the state of the musig2 signing process of the vtxo tree
1270
+ // session holds the state of the musig2 signing process of the virtual output tree
1214
1271
  let session;
1215
1272
  const signingPublicKeys = [];
1216
1273
  if (hasOffchainOutputs) {
@@ -1261,7 +1318,7 @@ export class Wallet extends ReadonlyWallet {
1261
1318
  for (const input of inputs) {
1262
1319
  // check if the input is an offchain "virtual" coin
1263
1320
  const vtxo = vtxos.find((vtxo) => vtxo.txid === input.txid && vtxo.vout === input.vout);
1264
- // boarding utxo, we need to sign the settlement tx
1321
+ // boarding input, we need to sign the settlement tx
1265
1322
  if (!vtxo) {
1266
1323
  for (let i = 0; i < settlementPsbt.inputsLength; i++) {
1267
1324
  const settlementInput = settlementPsbt.getInput(i);
@@ -1339,11 +1396,12 @@ export class Wallet extends ReadonlyWallet {
1339
1396
  }
1340
1397
  }
1341
1398
  /**
1342
- * @implements Batch.Handler interface.
1399
+ * Create a batch event handler for settlement flows.
1400
+ *
1343
1401
  * @param intentId - The intent ID.
1344
- * @param inputs - The inputs of the intent.
1345
- * @param session - The musig2 signing session, if not provided, the signing will be skipped.
1346
- * @param expectedRecipients - Expected recipients to validate in the vtxo tree.
1402
+ * @param inputs - Inputs used by the intent.
1403
+ * @param expectedRecipients - Expected recipients to validate in the virtual output tree.
1404
+ * @param session - Optional musig2 signing session. When omitted, signing steps are skipped.
1347
1405
  */
1348
1406
  createBatchHandler(intentId, inputs, expectedRecipients, session) {
1349
1407
  let sweepTapTreeRoot;
@@ -1357,7 +1415,7 @@ export class Wallet extends ReadonlyWallet {
1357
1415
  for (const idHash of event.intentIdHashes) {
1358
1416
  if (idHash === intentIdHashStr) {
1359
1417
  if (!this.arkProvider) {
1360
- throw new Error("Ark provider not configured");
1418
+ throw new Error("Arkade provider not configured");
1361
1419
  }
1362
1420
  await this.arkProvider.confirmRegistration(intentId);
1363
1421
  skip = false;
@@ -1390,10 +1448,10 @@ export class Wallet extends ReadonlyWallet {
1390
1448
  // not a cosigner, skip the signing
1391
1449
  return { skip: true };
1392
1450
  }
1393
- // validate the unsigned vtxo tree
1451
+ // validate the unsigned virtual output tree
1394
1452
  const commitmentTx = Transaction.fromPSBT(base64.decode(event.unsignedCommitmentTx));
1395
1453
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
1396
- // validate that all expected receivers are in the vtxo tree with correct amounts and assets
1454
+ // validate that all expected receivers are in the virtual output tree with correct amounts and assets
1397
1455
  if (expectedRecipients && expectedRecipients.length > 0) {
1398
1456
  validateBatchRecipients(commitmentTx, vtxoTree.leaves(), expectedRecipients, this.network);
1399
1457
  }
@@ -1494,7 +1552,7 @@ export class Wallet extends ReadonlyWallet {
1494
1552
  /**
1495
1553
  * Finalizes pending transactions by retrieving them from the server and finalizing each one.
1496
1554
  * Skips the server check entirely when no send was interrupted (no pending tx flag set).
1497
- * @param vtxos - Optional list of VTXOs to use instead of retrieving them from the server
1555
+ * @param vtxos - Optional list of virtual outputs to use instead of retrieving them from the server
1498
1556
  * @returns Array of transaction IDs that were finalized
1499
1557
  */
1500
1558
  async finalizePendingTxs(vtxos) {
@@ -1593,13 +1651,13 @@ export class Wallet extends ReadonlyWallet {
1593
1651
  /**
1594
1652
  * Send BTC and/or assets to one or more recipients.
1595
1653
  *
1596
- * @param recipients - Array of recipients with their addresses, BTC amounts, and assets
1597
- * @returns Promise resolving to the ark transaction ID
1654
+ * @param args - Recipients with their addresses, BTC amounts, and assets
1655
+ * @returns Promise resolving to the Arkade transaction ID
1598
1656
  *
1599
1657
  * @example
1600
1658
  * ```typescript
1601
1659
  * const txid = await wallet.send({
1602
- * address: 'ark1...',
1660
+ * address: 'ark1q...',
1603
1661
  * amount: 1000, // (optional, default to dust) btc amount to send to the output
1604
1662
  * assets: [{ assetId: 'abc123...', amount: 50 }] // (optional) list of assets to send
1605
1663
  * });
@@ -1747,8 +1805,8 @@ export class Wallet extends ReadonlyWallet {
1747
1805
  }
1748
1806
  /**
1749
1807
  * Build an offchain transaction from the given inputs and outputs,
1750
- * sign it, submit to the ark provider, and finalize.
1751
- * @returns The ark transaction id and server-signed checkpoint PSBTs (for bookkeeping)
1808
+ * sign it, submit to the Arkade provider, and finalize.
1809
+ * @returns The Arkade transaction id and server-signed checkpoint PSBTs (for bookkeeping)
1752
1810
  */
1753
1811
  async buildAndSubmitOffchainTx(inputs, outputs) {
1754
1812
  const offchainTx = buildOffchainTx(inputs.map((input) => {
@@ -1807,7 +1865,7 @@ export class Wallet extends ReadonlyWallet {
1807
1865
  }
1808
1866
  return { arkTxid, signedCheckpointTxs };
1809
1867
  }
1810
- // mark vtxo spent and save change vtxo if any
1868
+ // mark virtual outputs as spent, save change outputs if any
1811
1869
  async updateDbAfterOffchainTx(inputs, arkTxid, signedCheckpointTxs, sentAmount, changeAmount, changeVout, changeAssets) {
1812
1870
  try {
1813
1871
  const spentVtxos = [];
@@ -1855,7 +1913,7 @@ export class Wallet extends ReadonlyWallet {
1855
1913
  }
1856
1914
  const createdAt = Date.now();
1857
1915
  const addr = this.arkAddress.encode();
1858
- // Only save a change VTXO for preconfirmed coins (those with a batchExpiry).
1916
+ // Only save a change virtual output for preconfirmed coins (those with a batchExpiry).
1859
1917
  // Inputs without a batchExpiry are already settled/unrolled and don't need tracking.
1860
1918
  let changeVtxo;
1861
1919
  if (changeAmount > 0n && batchExpiry !== Number.MAX_SAFE_INTEGER) {
@@ -1899,7 +1957,7 @@ export class Wallet extends ReadonlyWallet {
1899
1957
  console.warn("error saving offchain tx to repository", e);
1900
1958
  }
1901
1959
  }
1902
- // mark vtxo spent & settled, remove boarding utxo
1960
+ // mark virtual outputs as spent/settled, remove boarding inputs
1903
1961
  async updateDbAfterSettle(inputs, commitmentTxid) {
1904
1962
  try {
1905
1963
  const addr = this.arkAddress.encode();
@@ -1910,7 +1968,7 @@ export class Wallet extends ReadonlyWallet {
1910
1968
  const isVtxo = (input) => "virtualStatus" in input;
1911
1969
  for (const input of inputs) {
1912
1970
  if (isVtxo(input)) {
1913
- // vtxo = mark it settled
1971
+ // virtual output = mark it settled
1914
1972
  const vtxo = extendVirtualCoin(this, input);
1915
1973
  if (vtxo.arkTxId) {
1916
1974
  inputArkTxIds.add(vtxo.arkTxId);
@@ -1926,7 +1984,7 @@ export class Wallet extends ReadonlyWallet {
1926
1984
  });
1927
1985
  }
1928
1986
  else {
1929
- // boarding utxo = remove it
1987
+ // boarding input = remove it
1930
1988
  boardingUtxoToRemove.add(`${input.txid}:${input.vout}`);
1931
1989
  }
1932
1990
  }
@@ -1950,13 +2008,13 @@ export class Wallet extends ReadonlyWallet {
1950
2008
  }
1951
2009
  Wallet.MIN_FEE_RATE = 1; // sats/vbyte
1952
2010
  /**
1953
- * Select virtual coins to reach a target amount, prioritizing those closer to expiry
1954
- * @param coins List of virtual coins to select from
2011
+ * Select virtual outputs to reach a target amount, prioritizing those closer to expiry
2012
+ * @param coins List of virtual outputs to select from
1955
2013
  * @param targetAmount Target amount to reach in satoshis
1956
- * @returns Selected coins and change amount
2014
+ * @returns Selected virtual outputs and change amount
1957
2015
  */
1958
2016
  export function selectVirtualCoins(coins, targetAmount) {
1959
- // Sort VTXOs by expiry (ascending) and amount (descending)
2017
+ // Sort virtual outputs by expiry (ascending) and amount (descending)
1960
2018
  const sortedCoins = [...coins].sort((a, b) => {
1961
2019
  // First sort by expiry if available
1962
2020
  const expiryA = a.virtualStatus.batchExpiry || Number.MAX_SAFE_INTEGER;
@@ -49,7 +49,7 @@ export class AsyncStorageTaskQueue {
49
49
  // ── Config persistence (for background handler rehydration) ──────
50
50
  /**
51
51
  * Persist a config blob alongside the queue data.
52
- * Used by {@link ExpoWallet.setup} to store the wallet parameters
52
+ * Used by @see ExpoWallet.setup to store the wallet parameters
53
53
  * that the background handler needs to reconstruct providers.
54
54
  */
55
55
  async persistConfig(config) {
@@ -3,7 +3,7 @@ export const CONTRACT_POLL_TASK_TYPE = "contract-poll";
3
3
  * Polls the indexer for the latest VTXO state of every contract and
4
4
  * persists the results to the wallet repository.
5
5
  *
6
- * Replicates the polling subset of {@link ContractManager.initialize}:
6
+ * Replicates the polling subset of @see ContractManager.initialize:
7
7
  * 1. Load all contracts from the contract repository.
8
8
  * 2. Mark expired active contracts as inactive.
9
9
  * 3. Paginated fetch of spendable VTXOs from the indexer.
@@ -26,7 +26,7 @@ export const contractPollProcessor = {
26
26
  contract.state = "inactive";
27
27
  await contractRepository.saveContract(contract);
28
28
  }
29
- // Paginated fetch of spendable VTXOs
29
+ // Paginated fetch of spendable virtual outputs
30
30
  const pageSize = 100;
31
31
  let pageIndex = 0;
32
32
  let hasMore = true;
@@ -4,7 +4,7 @@ import { getRandomId, extendVirtualCoin, extendVtxoFromContract, } from '../../w
4
4
  *
5
5
  * For each task in the inbox:
6
6
  * 1. Find the processor whose `taskType` matches `task.type`.
7
- * 2. Execute it, producing a {@link TaskResult}.
7
+ * 2. Execute it, producing a @see TaskResult.
8
8
  * 3. Push the result to the outbox and remove the task from the inbox.
9
9
  *
10
10
  * Tasks with no matching processor produce a `"noop"` result.
@@ -53,8 +53,8 @@ export async function runTasks(queue, processors, deps) {
53
53
  return results;
54
54
  }
55
55
  /**
56
- * Build the {@link TaskDependencies} needed by task processors
57
- * (e.g. {@link import("./processors").contractPollProcessor}).
56
+ * Build the @see TaskDependencies needed by task processors
57
+ * (e.g. `src/worker/expo/processors/contractPollProcessor.ts`)
58
58
  *
59
59
  * This is the same construction that `defineExpoBackgroundTask` does
60
60
  * internally, extracted so that consumers with custom schedulers
@@ -7,6 +7,7 @@ import { ReadonlyWallet, Wallet } from '../wallet/wallet.js';
7
7
  import { hex } from "@scure/base";
8
8
  import { MessageBusNotInitializedError, ServiceWorkerTimeoutError, } from './errors.js';
9
9
  export class MessageBus {
10
+ /** Create the service-worker message bus with repositories and handler configuration. */
10
11
  constructor(walletRepository, contractRepository, { messageHandlers, tickIntervalMs = 10000, messageTimeoutMs = 30000, debug = false, buildServices, }) {
11
12
  this.walletRepository = walletRepository;
12
13
  this.contractRepository = contractRepository;
@@ -22,6 +23,7 @@ export class MessageBus {
22
23
  this.debug = debug;
23
24
  this.buildServicesFn = buildServices ?? this.buildServices.bind(this);
24
25
  }
26
+ /** Start the message bus and attach service-worker event listeners. */
25
27
  async start() {
26
28
  if (this.running)
27
29
  return;
@@ -42,6 +44,7 @@ export class MessageBus {
42
44
  }
43
45
  });
44
46
  }
47
+ /** Stop the message bus, cancel ticks, and stop all registered handlers. */
45
48
  async stop() {
46
49
  if (this.debug)
47
50
  console.log("MessageBus stopping");
@@ -1,6 +1,6 @@
1
1
  import { IntentFeeConfig, OffchainInput, OnchainInput, FeeOutput, FeeAmount } from "./types.js";
2
2
  /**
3
- * Estimator evaluates CEL expressions to calculate fees for Ark intents
3
+ * Estimator evaluates CEL expressions to calculate fees for Arkade intents
4
4
  */
5
5
  export declare class Estimator {
6
6
  readonly config: IntentFeeConfig;