@bsv/wallet-toolbox-mobile 2.4.2 → 2.4.4
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/out/src/CWIStyleWalletManager.d.ts +52 -5
- package/out/src/CWIStyleWalletManager.d.ts.map +1 -1
- package/out/src/CWIStyleWalletManager.js +500 -128
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/Wallet.d.ts +8 -0
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +23 -9
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletAuthenticationManager.d.ts +20 -6
- package/out/src/WalletAuthenticationManager.d.ts.map +1 -1
- package/out/src/WalletAuthenticationManager.js +214 -34
- package/out/src/WalletAuthenticationManager.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +15 -0
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +76 -28
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/index.mobile.d.ts +1 -0
- package/out/src/index.mobile.d.ts.map +1 -1
- package/out/src/index.mobile.js +1 -0
- package/out/src/index.mobile.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +4 -3
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts +13 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.d.ts.map +1 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js +24 -0
- package/out/src/monitor/tasks/TaskCleanupActionBatches.js.map +1 -0
- package/out/src/sdk/ActionBatch.interfaces.d.ts +105 -0
- package/out/src/sdk/ActionBatch.interfaces.d.ts.map +1 -0
- package/out/src/sdk/ActionBatch.interfaces.js +3 -0
- package/out/src/sdk/ActionBatch.interfaces.js.map +1 -0
- package/out/src/sdk/WalletStorage.interfaces.d.ts +18 -1
- package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
- package/out/src/sdk/index.d.ts +1 -0
- package/out/src/sdk/index.d.ts.map +1 -1
- package/out/src/sdk/index.js +1 -0
- package/out/src/sdk/index.js.map +1 -1
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts +28 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js +313 -0
- package/out/src/signer/actionBatch/ActionBatchPlanner.js.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts +33 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.d.ts.map +1 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js +693 -0
- package/out/src/signer/actionBatch/ActionBatchWorkspace.js.map +1 -0
- package/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.js +2 -1
- package/out/src/signer/methods/buildSignableTransaction.js.map +1 -1
- package/out/src/signer/methods/createAction.d.ts.map +1 -1
- package/out/src/signer/methods/createAction.js +4 -1
- package/out/src/signer/methods/createAction.js.map +1 -1
- package/out/src/storage/StorageProvider.d.ts +28 -0
- package/out/src/storage/StorageProvider.d.ts.map +1 -1
- package/out/src/storage/StorageProvider.js +49 -0
- package/out/src/storage/StorageProvider.js.map +1 -1
- package/out/src/storage/WalletStorageManager.d.ts +8 -0
- package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
- package/out/src/storage/WalletStorageManager.js +24 -0
- package/out/src/storage/WalletStorageManager.js.map +1 -1
- package/out/src/storage/methods/actionBatch.d.ts +14 -0
- package/out/src/storage/methods/actionBatch.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatch.js +644 -0
- package/out/src/storage/methods/actionBatch.js.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts +12 -0
- package/out/src/storage/methods/actionBatchBlobs.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchBlobs.js +121 -0
- package/out/src/storage/methods/actionBatchBlobs.js.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts +15 -0
- package/out/src/storage/methods/actionBatchValidation.d.ts.map +1 -0
- package/out/src/storage/methods/actionBatchValidation.js +310 -0
- package/out/src/storage/methods/actionBatchValidation.js.map +1 -0
- package/out/src/storage/methods/actionPlanning.d.ts +12 -0
- package/out/src/storage/methods/actionPlanning.d.ts.map +1 -0
- package/out/src/storage/methods/actionPlanning.js +48 -0
- package/out/src/storage/methods/actionPlanning.js.map +1 -0
- package/out/src/storage/methods/createAction.d.ts.map +1 -1
- package/out/src/storage/methods/createAction.js +9 -25
- package/out/src/storage/methods/createAction.js.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.d.ts +9 -0
- package/out/src/storage/remoting/StorageClientBase.d.ts.map +1 -1
- package/out/src/storage/remoting/StorageClientBase.js +36 -1
- package/out/src/storage/remoting/StorageClientBase.js.map +1 -1
- package/out/src/storage/schema/tables/TableActionBatch.d.ts +24 -0
- package/out/src/storage/schema/tables/TableActionBatch.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TableActionBatch.js +3 -0
- package/out/src/storage/schema/tables/TableActionBatch.js.map +1 -0
- package/out/src/storage/schema/tables/index.d.ts +1 -0
- package/out/src/storage/schema/tables/index.d.ts.map +1 -1
- package/out/src/storage/schema/tables/index.js +1 -0
- package/out/src/storage/schema/tables/index.js.map +1 -1
- package/out/src/utility/actionBatchDigest.d.ts +9 -0
- package/out/src/utility/actionBatchDigest.d.ts.map +1 -0
- package/out/src/utility/actionBatchDigest.js +48 -0
- package/out/src/utility/actionBatchDigest.js.map +1 -0
- package/out/src/utility/beefForTxids.d.ts +9 -0
- package/out/src/utility/beefForTxids.d.ts.map +1 -0
- package/out/src/utility/beefForTxids.js +35 -0
- package/out/src/utility/beefForTxids.js.map +1 -0
- package/out/src/wab-client/WABClient.d.ts +36 -90
- package/out/src/wab-client/WABClient.d.ts.map +1 -1
- package/out/src/wab-client/WABClient.js +103 -151
- package/out/src/wab-client/WABClient.js.map +1 -1
- package/out/src/wab-client/WABTransport.d.ts +53 -0
- package/out/src/wab-client/WABTransport.d.ts.map +1 -0
- package/out/src/wab-client/WABTransport.js +300 -0
- package/out/src/wab-client/WABTransport.js.map +1 -0
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts +10 -10
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js +16 -21
- package/out/src/wab-client/auth-method-interactors/AuthMethodInteractor.js.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts +2 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.d.ts.map +1 -1
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js +14 -0
- package/out/src/wab-client/auth-method-interactors/TwilioPhoneInteractor.js.map +1 -1
- package/package.json +8 -3
|
@@ -91,6 +91,14 @@ class WalletPermissionsManager {
|
|
|
91
91
|
/** Cache recently confirmed permissions to avoid repeated lookups. */
|
|
92
92
|
permissionCache = new Map();
|
|
93
93
|
recentGrants = new Map();
|
|
94
|
+
/**
|
|
95
|
+
* Token mints currently being written on-chain, keyed by permission cache
|
|
96
|
+
* key. A granted permission is only cached once its token finishes minting
|
|
97
|
+
* (network seconds); ensures arriving in that window await the in-flight
|
|
98
|
+
* mint instead of re-prompting the user for a permission they just granted.
|
|
99
|
+
* Stored promises never reject.
|
|
100
|
+
*/
|
|
101
|
+
mintsInFlight = new Map();
|
|
94
102
|
manifestCache = new Map();
|
|
95
103
|
manifestFetchInProgress = new Map();
|
|
96
104
|
static MANIFEST_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
@@ -391,26 +399,45 @@ class WalletPermissionsManager {
|
|
|
391
399
|
}
|
|
392
400
|
this.activeRequests.delete(params.requestID);
|
|
393
401
|
// 3) If `ephemeral !== true`, we create or renew an on-chain token
|
|
394
|
-
if (!params.ephemeral) {
|
|
395
|
-
const request = matching.request;
|
|
396
|
-
if (request.renewal) {
|
|
397
|
-
// renewal => spend the old token, produce a new one
|
|
398
|
-
await this.renewPermissionOnChain(request.previousToken, request, params.expiry || 0, // default: never expires
|
|
399
|
-
params.amount);
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
// brand-new permission token
|
|
403
|
-
await this.createPermissionOnChain(request, params.expiry || 0, // default: never expires
|
|
404
|
-
params.amount);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
402
|
// Only cache non-ephemeral permissions
|
|
408
403
|
// Ephemeral permissions should not be cached as they are one-time authorizations
|
|
409
404
|
if (!params.ephemeral) {
|
|
405
|
+
const request = matching.request;
|
|
410
406
|
const expiry = params.expiry || 0; // default: never expires
|
|
411
|
-
const key = this.buildRequestKey(
|
|
407
|
+
const key = this.buildRequestKey(request);
|
|
408
|
+
// Several first-contact prompts for the same permission can stack up
|
|
409
|
+
// before any token exists (e.g. one per usage type). Granting them all
|
|
410
|
+
// should yield ONE token: if an identical non-renewal grant just minted
|
|
411
|
+
// (or is minting), don't mint a duplicate. Spending authorizations are
|
|
412
|
+
// excluded — their tokens carry amounts, so every grant is honored.
|
|
413
|
+
let skipDuplicateMint = !request.renewal &&
|
|
414
|
+
request.type !== 'spending' &&
|
|
415
|
+
(this.isPermissionCached(key) || this.isRecentlyGranted(key) || this.mintsInFlight.has(key));
|
|
416
|
+
if (skipDuplicateMint) {
|
|
417
|
+
const inFlight = this.mintsInFlight.get(key);
|
|
418
|
+
if (inFlight != null) {
|
|
419
|
+
await inFlight;
|
|
420
|
+
// The awaited mint may have failed; only skip if it landed.
|
|
421
|
+
skipDuplicateMint = this.isPermissionCached(key) || this.isRecentlyGranted(key);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (!skipDuplicateMint) {
|
|
425
|
+
const mint = request.renewal
|
|
426
|
+
? this.renewPermissionOnChain(request.previousToken, request, expiry, params.amount)
|
|
427
|
+
: this.createPermissionOnChain(request, expiry, params.amount);
|
|
428
|
+
// Publish the in-flight mint so concurrent ensures for the same
|
|
429
|
+
// permission wait for it instead of re-prompting (stored promise
|
|
430
|
+
// never rejects; failures still propagate to this caller below).
|
|
431
|
+
this.mintsInFlight.set(key, mint.then(() => { }, () => { }));
|
|
432
|
+
try {
|
|
433
|
+
await mint;
|
|
434
|
+
}
|
|
435
|
+
finally {
|
|
436
|
+
this.mintsInFlight.delete(key);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
412
439
|
this.cachePermission(key, expiry);
|
|
413
|
-
this.markRecentGrant(
|
|
440
|
+
this.markRecentGrant(request);
|
|
414
441
|
}
|
|
415
442
|
}
|
|
416
443
|
/**
|
|
@@ -426,8 +453,12 @@ class WalletPermissionsManager {
|
|
|
426
453
|
throw new Error('Request ID not found.');
|
|
427
454
|
}
|
|
428
455
|
// 2) Reject all matching requests, deleting the entry
|
|
456
|
+
// Denials carry the canonical machine-readable code so applications can
|
|
457
|
+
// distinguish user denial from other failures (matches denyActiveRequest).
|
|
458
|
+
const err = new Error('Permission denied.');
|
|
459
|
+
err.code = 'ERR_PERMISSION_DENIED';
|
|
429
460
|
for (const x of matching.pending) {
|
|
430
|
-
x.reject(
|
|
461
|
+
x.reject(err);
|
|
431
462
|
}
|
|
432
463
|
this.activeRequests.delete(requestID);
|
|
433
464
|
}
|
|
@@ -673,7 +704,7 @@ class WalletPermissionsManager {
|
|
|
673
704
|
if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID))
|
|
674
705
|
return true;
|
|
675
706
|
const cacheKey = this.buildRequestKey({ type: 'protocol', originator, privileged, protocolID, counterparty });
|
|
676
|
-
if (
|
|
707
|
+
if (await this.hasRecentOrPendingGrant(cacheKey))
|
|
677
708
|
return true;
|
|
678
709
|
// 4) Attempt to find a valid token in the internal basket
|
|
679
710
|
const token = await this.findProtocolToken(originator, privileged, protocolID, counterparty, /* includeExpired= */ true, lookupValues);
|
|
@@ -713,7 +744,7 @@ class WalletPermissionsManager {
|
|
|
713
744
|
if (!this.isBasketUsageRequired(usageType))
|
|
714
745
|
return true;
|
|
715
746
|
const cacheKey = this.buildRequestKey({ type: 'basket', originator, basket });
|
|
716
|
-
if (
|
|
747
|
+
if (await this.hasRecentOrPendingGrant(cacheKey))
|
|
717
748
|
return true;
|
|
718
749
|
const token = await this.findBasketToken(originator, basket, true, lookupValues);
|
|
719
750
|
if (token == null) {
|
|
@@ -762,10 +793,7 @@ class WalletPermissionsManager {
|
|
|
762
793
|
privileged,
|
|
763
794
|
certificate: { verifier, certType, fields }
|
|
764
795
|
});
|
|
765
|
-
if (this.
|
|
766
|
-
return true;
|
|
767
|
-
}
|
|
768
|
-
if (this.isRecentlyGranted(cacheKey)) {
|
|
796
|
+
if (await this.hasRecentOrPendingGrant(cacheKey)) {
|
|
769
797
|
return true;
|
|
770
798
|
}
|
|
771
799
|
const token = await this.findCertificateToken(originator, privileged, verifier, certType, fields,
|
|
@@ -816,7 +844,10 @@ class WalletPermissionsManager {
|
|
|
816
844
|
return true;
|
|
817
845
|
}
|
|
818
846
|
const cacheKey = this.buildRequestKey({ type: 'spending', originator, spending: { satoshis } });
|
|
819
|
-
|
|
847
|
+
// Spending keys are amount-scoped. The recent-grant window this adds sits
|
|
848
|
+
// inside the pre-existing permissionCache window grantPermission already
|
|
849
|
+
// wrote for spending, so accounting exposure is unchanged.
|
|
850
|
+
if (await this.hasRecentOrPendingGrant(cacheKey)) {
|
|
820
851
|
return true;
|
|
821
852
|
}
|
|
822
853
|
const token = await this.findSpendingToken(originator, lookupValues);
|
|
@@ -1025,11 +1056,13 @@ class WalletPermissionsManager {
|
|
|
1025
1056
|
(async () => {
|
|
1026
1057
|
if (groupPermissions.spendingAuthorization == null)
|
|
1027
1058
|
return undefined;
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1059
|
+
// A standing authorization is a grant regardless of how much of the
|
|
1060
|
+
// monthly allowance has been used — exhaustion is handled by renewal
|
|
1061
|
+
// at spend time. Checking remaining headroom here re-requests (and,
|
|
1062
|
+
// if approved, re-mints) spending after any monthly usage.
|
|
1063
|
+
const { normalized, lookupValues } = this.prepareOriginator(originator);
|
|
1064
|
+
const token = await this.findSpendingToken(normalized, lookupValues);
|
|
1065
|
+
return token != null ? undefined : groupPermissions.spendingAuthorization;
|
|
1033
1066
|
})(),
|
|
1034
1067
|
(async () => {
|
|
1035
1068
|
const protocolChecks = await Promise.all((groupPermissions.protocolPermissions || []).map(async (p) => {
|
|
@@ -3553,6 +3586,21 @@ class WalletPermissionsManager {
|
|
|
3553
3586
|
return true;
|
|
3554
3587
|
return false;
|
|
3555
3588
|
}
|
|
3589
|
+
/**
|
|
3590
|
+
* Whether the permission is satisfied without consulting on-chain tokens:
|
|
3591
|
+
* cached, recently granted, or — when the user just granted it and its
|
|
3592
|
+
* token is still minting — after the in-flight mint settles. Spares the
|
|
3593
|
+
* user a duplicate prompt for a grant they already made moments ago.
|
|
3594
|
+
*/
|
|
3595
|
+
async hasRecentOrPendingGrant(cacheKey) {
|
|
3596
|
+
if (this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey))
|
|
3597
|
+
return true;
|
|
3598
|
+
const inFlight = this.mintsInFlight.get(cacheKey);
|
|
3599
|
+
if (inFlight == null)
|
|
3600
|
+
return false;
|
|
3601
|
+
await inFlight;
|
|
3602
|
+
return this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey);
|
|
3603
|
+
}
|
|
3556
3604
|
/**
|
|
3557
3605
|
* Returns true if we have a cached record that the permission identified by
|
|
3558
3606
|
* `key` is valid and unexpired.
|