@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.
- package/README.md +102 -96
- package/dist/cjs/arkfee/estimator.js +1 -1
- package/dist/cjs/arkfee/types.js +2 -1
- package/dist/cjs/arknote/index.js +43 -4
- package/dist/cjs/bip322/index.js +1 -1
- package/dist/cjs/contracts/arkcontract.js +1 -1
- package/dist/cjs/contracts/contractManager.js +40 -24
- package/dist/cjs/contracts/contractWatcher.js +29 -22
- package/dist/cjs/contracts/handlers/default.js +1 -1
- package/dist/cjs/contracts/handlers/delegate.js +1 -1
- package/dist/cjs/contracts/handlers/helpers.js +1 -1
- package/dist/cjs/extension/asset/assetGroup.js +92 -5
- package/dist/cjs/extension/asset/assetId.js +67 -3
- package/dist/cjs/extension/asset/assetInput.js +18 -0
- package/dist/cjs/extension/asset/assetOutput.js +15 -0
- package/dist/cjs/extension/asset/assetRef.js +66 -0
- package/dist/cjs/extension/asset/metadata.js +15 -0
- package/dist/cjs/extension/asset/packet.js +4 -1
- package/dist/cjs/extension/index.js +1 -1
- package/dist/cjs/forfeit.js +14 -0
- package/dist/cjs/identity/seedIdentity.js +2 -2
- package/dist/cjs/identity/singleKey.js +4 -0
- package/dist/cjs/intent/index.js +28 -12
- package/dist/cjs/providers/ark.js +3 -2
- package/dist/cjs/providers/delegator.js +20 -1
- package/dist/cjs/providers/expoArk.js +2 -2
- package/dist/cjs/providers/indexer.js +2 -2
- package/dist/cjs/providers/onchain.js +2 -1
- package/dist/cjs/repositories/realm/schemas.js +2 -2
- package/dist/cjs/repositories/realm/types.js +1 -1
- package/dist/cjs/script/address.js +37 -6
- package/dist/cjs/script/base.js +70 -1
- package/dist/cjs/script/default.js +3 -0
- package/dist/cjs/script/delegate.js +4 -0
- package/dist/cjs/script/tapscript.js +17 -2
- package/dist/cjs/script/vhtlc.js +35 -27
- package/dist/cjs/storage/fileSystem.js +1 -1
- package/dist/cjs/storage/inMemory.js +1 -1
- package/dist/cjs/storage/indexedDB.js +1 -1
- package/dist/cjs/storage/localStorage.js +1 -1
- package/dist/cjs/tree/validation.js +1 -1
- package/dist/cjs/utils/arkTransaction.js +5 -5
- package/dist/cjs/utils/bip21.js +16 -3
- package/dist/cjs/utils/syncCursors.js +4 -4
- package/dist/cjs/utils/transaction.js +1 -1
- package/dist/cjs/utils/transactionHistory.js +11 -11
- package/dist/cjs/utils/unknownFields.js +3 -3
- package/dist/cjs/wallet/asset-manager.js +4 -4
- package/dist/cjs/wallet/batch.js +5 -5
- package/dist/cjs/wallet/delegator.js +9 -8
- package/dist/cjs/wallet/expo/background.js +3 -3
- package/dist/cjs/wallet/expo/wallet.js +7 -7
- package/dist/cjs/wallet/index.js +43 -0
- package/dist/cjs/wallet/onchain.js +43 -5
- package/dist/cjs/wallet/ramps.js +44 -14
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +22 -22
- package/dist/cjs/wallet/serviceWorker/wallet.js +28 -24
- package/dist/cjs/wallet/unroll.js +12 -8
- package/dist/cjs/wallet/utils.js +1 -1
- package/dist/cjs/wallet/vtxo-manager.js +122 -82
- package/dist/cjs/wallet/wallet.js +125 -67
- package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +1 -1
- package/dist/cjs/worker/expo/processors/contractPollProcessor.js +2 -2
- package/dist/cjs/worker/expo/taskRunner.js +3 -3
- package/dist/cjs/worker/messageBus.js +3 -0
- package/dist/esm/arkfee/estimator.js +1 -1
- package/dist/esm/arkfee/types.js +2 -1
- package/dist/esm/arknote/index.js +43 -4
- package/dist/esm/bip322/index.js +1 -1
- package/dist/esm/contracts/arkcontract.js +1 -1
- package/dist/esm/contracts/contractManager.js +40 -24
- package/dist/esm/contracts/contractWatcher.js +29 -22
- package/dist/esm/contracts/handlers/default.js +1 -1
- package/dist/esm/contracts/handlers/delegate.js +1 -1
- package/dist/esm/contracts/handlers/helpers.js +1 -1
- package/dist/esm/extension/asset/assetGroup.js +92 -5
- package/dist/esm/extension/asset/assetId.js +67 -3
- package/dist/esm/extension/asset/assetInput.js +18 -0
- package/dist/esm/extension/asset/assetOutput.js +15 -0
- package/dist/esm/extension/asset/assetRef.js +66 -0
- package/dist/esm/extension/asset/metadata.js +15 -0
- package/dist/esm/extension/asset/packet.js +4 -1
- package/dist/esm/extension/index.js +1 -1
- package/dist/esm/forfeit.js +14 -0
- package/dist/esm/identity/seedIdentity.js +2 -2
- package/dist/esm/identity/singleKey.js +4 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/intent/index.js +28 -12
- package/dist/esm/providers/ark.js +3 -2
- package/dist/esm/providers/delegator.js +20 -1
- package/dist/esm/providers/expoArk.js +2 -2
- package/dist/esm/providers/indexer.js +2 -2
- package/dist/esm/providers/onchain.js +2 -1
- package/dist/esm/repositories/realm/schemas.js +2 -2
- package/dist/esm/repositories/realm/types.js +1 -1
- package/dist/esm/script/address.js +37 -6
- package/dist/esm/script/base.js +70 -1
- package/dist/esm/script/default.js +3 -0
- package/dist/esm/script/delegate.js +4 -0
- package/dist/esm/script/tapscript.js +17 -2
- package/dist/esm/script/vhtlc.js +35 -27
- package/dist/esm/storage/fileSystem.js +1 -1
- package/dist/esm/storage/inMemory.js +1 -1
- package/dist/esm/storage/indexedDB.js +1 -1
- package/dist/esm/storage/localStorage.js +1 -1
- package/dist/esm/tree/validation.js +1 -1
- package/dist/esm/utils/arkTransaction.js +5 -5
- package/dist/esm/utils/bip21.js +16 -3
- package/dist/esm/utils/syncCursors.js +4 -4
- package/dist/esm/utils/transaction.js +1 -1
- package/dist/esm/utils/transactionHistory.js +11 -11
- package/dist/esm/utils/unknownFields.js +3 -3
- package/dist/esm/wallet/asset-manager.js +4 -4
- package/dist/esm/wallet/batch.js +5 -5
- package/dist/esm/wallet/delegator.js +9 -8
- package/dist/esm/wallet/expo/background.js +3 -3
- package/dist/esm/wallet/expo/wallet.js +7 -7
- package/dist/esm/wallet/index.js +43 -0
- package/dist/esm/wallet/onchain.js +43 -5
- package/dist/esm/wallet/ramps.js +44 -14
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +22 -22
- package/dist/esm/wallet/serviceWorker/wallet.js +28 -24
- package/dist/esm/wallet/unroll.js +12 -8
- package/dist/esm/wallet/utils.js +1 -1
- package/dist/esm/wallet/vtxo-manager.js +121 -81
- package/dist/esm/wallet/wallet.js +125 -67
- package/dist/esm/worker/expo/asyncStorageTaskQueue.js +1 -1
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +2 -2
- package/dist/esm/worker/expo/taskRunner.js +3 -3
- package/dist/esm/worker/messageBus.js +3 -0
- package/dist/types/arkfee/estimator.d.ts +1 -1
- package/dist/types/arkfee/types.d.ts +2 -1
- package/dist/types/arknote/index.d.ts +44 -4
- package/dist/types/bip322/index.d.ts +1 -1
- package/dist/types/contracts/arkcontract.d.ts +1 -1
- package/dist/types/contracts/contractManager.d.ts +40 -63
- package/dist/types/contracts/contractWatcher.d.ts +39 -18
- package/dist/types/contracts/handlers/default.d.ts +1 -1
- package/dist/types/contracts/handlers/delegate.d.ts +1 -1
- package/dist/types/contracts/handlers/helpers.d.ts +1 -1
- package/dist/types/contracts/types.d.ts +36 -26
- package/dist/types/extension/asset/assetGroup.d.ts +92 -1
- package/dist/types/extension/asset/assetId.d.ts +67 -3
- package/dist/types/extension/asset/assetInput.d.ts +18 -0
- package/dist/types/extension/asset/assetOutput.d.ts +15 -0
- package/dist/types/extension/asset/assetRef.d.ts +66 -0
- package/dist/types/extension/asset/metadata.d.ts +15 -0
- package/dist/types/extension/asset/packet.d.ts +4 -1
- package/dist/types/extension/index.d.ts +1 -1
- package/dist/types/forfeit.d.ts +14 -0
- package/dist/types/identity/index.d.ts +16 -0
- package/dist/types/identity/seedIdentity.d.ts +8 -6
- package/dist/types/identity/singleKey.d.ts +4 -0
- package/dist/types/intent/index.d.ts +19 -6
- package/dist/types/providers/ark.d.ts +40 -2
- package/dist/types/providers/delegator.d.ts +54 -1
- package/dist/types/providers/expoArk.d.ts +2 -2
- package/dist/types/providers/indexer.d.ts +105 -2
- package/dist/types/providers/onchain.d.ts +62 -1
- package/dist/types/repositories/realm/schemas.d.ts +2 -2
- package/dist/types/repositories/realm/types.d.ts +2 -2
- package/dist/types/repositories/walletRepository.d.ts +16 -0
- package/dist/types/script/address.d.ts +35 -2
- package/dist/types/script/base.d.ts +66 -1
- package/dist/types/script/default.d.ts +3 -0
- package/dist/types/script/delegate.d.ts +4 -0
- package/dist/types/script/tapscript.d.ts +17 -2
- package/dist/types/script/vhtlc.d.ts +35 -27
- package/dist/types/storage/fileSystem.d.ts +1 -1
- package/dist/types/storage/inMemory.d.ts +1 -1
- package/dist/types/storage/index.d.ts +1 -1
- package/dist/types/storage/indexedDB.d.ts +1 -1
- package/dist/types/storage/localStorage.d.ts +1 -1
- package/dist/types/utils/arkTransaction.d.ts +3 -3
- package/dist/types/utils/bip21.d.ts +17 -0
- package/dist/types/utils/syncCursors.d.ts +4 -4
- package/dist/types/utils/transaction.d.ts +1 -1
- package/dist/types/utils/transactionHistory.d.ts +3 -3
- package/dist/types/utils/unknownFields.d.ts +5 -5
- package/dist/types/wallet/asset-manager.d.ts +3 -3
- package/dist/types/wallet/batch.d.ts +27 -7
- package/dist/types/wallet/delegator.d.ts +10 -0
- package/dist/types/wallet/expo/background.d.ts +4 -4
- package/dist/types/wallet/expo/wallet.d.ts +10 -10
- package/dist/types/wallet/index.d.ts +457 -25
- package/dist/types/wallet/onchain.d.ts +42 -4
- package/dist/types/wallet/ramps.d.ts +40 -10
- package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +4 -4
- package/dist/types/wallet/serviceWorker/wallet.d.ts +71 -33
- package/dist/types/wallet/unroll.d.ts +8 -6
- package/dist/types/wallet/vtxo-manager.d.ts +146 -93
- package/dist/types/wallet/wallet.d.ts +91 -33
- package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
- package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
- package/dist/types/worker/expo/taskRunner.d.ts +6 -6
- package/dist/types/worker/messageBus.d.ts +5 -3
- 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
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
397
|
-
// cursor, so it can miss preconfirmed
|
|
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
|
|
406
|
-
// result set is marked spent; any
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
591
|
-
// subscription event.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
827
|
-
* The wallet does not store any data locally and relies on
|
|
828
|
-
* providers to fetch
|
|
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:
|
|
835
|
-
* arkServerUrl: 'https://
|
|
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:
|
|
842
|
-
* arkProvider: new ExpoArkProvider('https://
|
|
843
|
-
* indexerProvider: new ExpoIndexerProvider('https://
|
|
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.
|
|
853
|
-
* address: '
|
|
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
|
|
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:
|
|
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.
|
|
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
|
-
*
|
|
1017
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
1405
|
+
* Create a batch event handler for settlement flows.
|
|
1406
|
+
*
|
|
1349
1407
|
* @param intentId - The intent ID.
|
|
1350
|
-
* @param inputs -
|
|
1351
|
-
* @param
|
|
1352
|
-
* @param
|
|
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("
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1603
|
-
* @returns Promise resolving to the
|
|
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: '
|
|
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
|
|
1757
|
-
* @returns The
|
|
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
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
|
1961
|
-
* @param coins List of virtual
|
|
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
|
|
2021
|
+
* @returns Selected virtual outputs and change amount
|
|
1964
2022
|
*/
|
|
1965
2023
|
function selectVirtualCoins(coins, targetAmount) {
|
|
1966
|
-
// Sort
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
61
|
-
* (e.g.
|
|
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
|
|
4
|
+
* Estimator evaluates CEL expressions to calculate fees for Arkade intents
|
|
5
5
|
*/
|
|
6
6
|
export class Estimator {
|
|
7
7
|
/**
|