@bsv/wallet-toolbox-client 2.0.4 → 2.0.5-beta.0

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.
@@ -96,7 +96,6 @@ class WalletPermissionsManager {
96
96
  this.recentGrants = new Map();
97
97
  this.manifestCache = new Map();
98
98
  this.manifestFetchInProgress = new Map();
99
- this.groupedPermissionFlowTail = new Map();
100
99
  this.pactEstablishedCache = new Map();
101
100
  this.underlying = underlyingWallet;
102
101
  this.adminOriginator = this.normalizeOriginator(adminOriginator) || adminOriginator;
@@ -671,7 +670,6 @@ class WalletPermissionsManager {
671
670
  privileged,
672
671
  protocolID,
673
672
  counterparty,
674
- usageType,
675
673
  reason,
676
674
  renewal: true,
677
675
  previousToken: token
@@ -689,7 +687,6 @@ class WalletPermissionsManager {
689
687
  privileged,
690
688
  protocolID,
691
689
  counterparty,
692
- usageType,
693
690
  reason,
694
691
  renewal: false
695
692
  });
@@ -735,7 +732,6 @@ class WalletPermissionsManager {
735
732
  type: 'basket',
736
733
  originator,
737
734
  basket,
738
- usageType,
739
735
  reason,
740
736
  renewal: true,
741
737
  previousToken: token
@@ -751,7 +747,6 @@ class WalletPermissionsManager {
751
747
  type: 'basket',
752
748
  originator,
753
749
  basket,
754
- usageType,
755
750
  reason,
756
751
  renewal: false
757
752
  });
@@ -801,7 +796,6 @@ class WalletPermissionsManager {
801
796
  originator,
802
797
  privileged,
803
798
  certificate: { verifier, certType, fields },
804
- usageType,
805
799
  reason,
806
800
  renewal: true,
807
801
  previousToken: token
@@ -817,7 +811,6 @@ class WalletPermissionsManager {
817
811
  originator,
818
812
  privileged,
819
813
  certificate: { verifier, certType, fields },
820
- usageType,
821
814
  reason,
822
815
  renewal: false
823
816
  });
@@ -984,58 +977,47 @@ class WalletPermissionsManager {
984
977
  basketAccess: [],
985
978
  certificateAccess: []
986
979
  };
987
- const [spendingAuthorization, protocolPermissions, basketAccess, certificateAccess] = await Promise.all([
988
- (async () => {
989
- if (!groupPermissions.spendingAuthorization)
990
- return undefined;
991
- const hasAuth = await this.hasSpendingAuthorization({
992
- originator,
993
- satoshis: groupPermissions.spendingAuthorization.amount
994
- });
995
- return hasAuth ? undefined : groupPermissions.spendingAuthorization;
996
- })(),
997
- (async () => {
998
- const protocolChecks = await Promise.all((groupPermissions.protocolPermissions || []).map(async (p) => {
999
- const hasPerm = await this.hasProtocolPermission({
1000
- originator,
1001
- privileged: false,
1002
- protocolID: p.protocolID,
1003
- counterparty: p.counterparty || 'self'
1004
- });
1005
- return hasPerm ? null : p;
1006
- }));
1007
- return protocolChecks.filter(Boolean);
1008
- })(),
1009
- (async () => {
1010
- const basketChecks = await Promise.all((groupPermissions.basketAccess || []).map(async (b) => {
1011
- const hasAccess = await this.hasBasketAccess({
1012
- originator,
1013
- basket: b.basket
1014
- });
1015
- return hasAccess ? null : b;
1016
- }));
1017
- return basketChecks.filter(Boolean);
1018
- })(),
1019
- (async () => {
1020
- const certChecks = await Promise.all((groupPermissions.certificateAccess || []).map(async (c) => {
1021
- const hasAccess = await this.hasCertificateAccess({
1022
- originator,
1023
- privileged: false,
1024
- verifier: c.verifierPublicKey,
1025
- certType: c.type,
1026
- fields: c.fields
1027
- });
1028
- return hasAccess ? null : c;
1029
- }));
1030
- return certChecks.filter(Boolean);
1031
- })()
1032
- ]);
1033
- if (spendingAuthorization) {
1034
- permissionsToRequest.spendingAuthorization = spendingAuthorization;
1035
- }
1036
- permissionsToRequest.protocolPermissions = protocolPermissions;
1037
- permissionsToRequest.basketAccess = basketAccess;
1038
- permissionsToRequest.certificateAccess = certificateAccess;
980
+ if (groupPermissions.spendingAuthorization) {
981
+ const hasAuth = await this.hasSpendingAuthorization({
982
+ originator,
983
+ satoshis: groupPermissions.spendingAuthorization.amount
984
+ });
985
+ if (!hasAuth) {
986
+ permissionsToRequest.spendingAuthorization = groupPermissions.spendingAuthorization;
987
+ }
988
+ }
989
+ for (const p of groupPermissions.protocolPermissions || []) {
990
+ const hasPerm = await this.hasProtocolPermission({
991
+ originator,
992
+ privileged: false,
993
+ protocolID: p.protocolID,
994
+ counterparty: p.counterparty || 'self'
995
+ });
996
+ if (!hasPerm) {
997
+ permissionsToRequest.protocolPermissions.push(p);
998
+ }
999
+ }
1000
+ for (const b of groupPermissions.basketAccess || []) {
1001
+ const hasAccess = await this.hasBasketAccess({
1002
+ originator,
1003
+ basket: b.basket
1004
+ });
1005
+ if (!hasAccess) {
1006
+ permissionsToRequest.basketAccess.push(b);
1007
+ }
1008
+ }
1009
+ for (const c of groupPermissions.certificateAccess || []) {
1010
+ const hasAccess = await this.hasCertificateAccess({
1011
+ originator,
1012
+ privileged: false,
1013
+ verifier: c.verifierPublicKey,
1014
+ certType: c.type,
1015
+ fields: c.fields
1016
+ });
1017
+ if (!hasAccess) {
1018
+ permissionsToRequest.certificateAccess.push(c);
1019
+ }
1020
+ }
1039
1021
  return permissionsToRequest;
1040
1022
  }
1041
1023
  hasAnyPermissionsToRequest(permissions) {
@@ -1116,16 +1098,18 @@ class WalletPermissionsManager {
1116
1098
  if (!((_a = counterpartyPermissions === null || counterpartyPermissions === void 0 ? void 0 : counterpartyPermissions.protocols) === null || _a === void 0 ? void 0 : _a.length)) {
1117
1099
  return null;
1118
1100
  }
1119
- const protocolChecks = await Promise.all(counterpartyPermissions.protocols.map(async (p) => {
1101
+ const protocolsToRequest = [];
1102
+ for (const p of counterpartyPermissions.protocols) {
1120
1103
  const hasPerm = await this.hasProtocolPermission({
1121
1104
  originator,
1122
1105
  privileged: false,
1123
1106
  protocolID: p.protocolID,
1124
1107
  counterparty
1125
1108
  });
1126
- return hasPerm ? null : p;
1127
- }));
1128
- const protocolsToRequest = protocolChecks.filter(Boolean);
1109
+ if (!hasPerm) {
1110
+ protocolsToRequest.push(p);
1111
+ }
1112
+ }
1129
1113
  if (protocolsToRequest.length === 0) {
1130
1114
  this.markPactEstablished(originator, counterparty);
1131
1115
  return null;
@@ -1217,22 +1201,21 @@ class WalletPermissionsManager {
1217
1201
  const permissionsToRequest = {
1218
1202
  protocolPermissions: []
1219
1203
  };
1220
- const protocolChecks = await Promise.all(manifestLevel2ForThisPeer.map(async (p) => {
1204
+ for (const p of manifestLevel2ForThisPeer) {
1221
1205
  const hasPerm = await this.hasProtocolPermission({
1222
1206
  originator,
1223
1207
  privileged,
1224
1208
  protocolID: p.protocolID,
1225
1209
  counterparty: p.counterparty
1226
1210
  });
1227
- return hasPerm
1228
- ? null
1229
- : {
1211
+ if (!hasPerm) {
1212
+ permissionsToRequest.protocolPermissions.push({
1230
1213
  protocolID: p.protocolID,
1231
1214
  counterparty: p.counterparty,
1232
1215
  description: p.description
1233
- };
1234
- }));
1235
- permissionsToRequest.protocolPermissions = protocolChecks.filter(Boolean);
1216
+ });
1217
+ }
1218
+ }
1236
1219
  if (!this.hasAnyPermissionsToRequest(permissionsToRequest)) {
1237
1220
  return null;
1238
1221
  }
@@ -1273,28 +1256,6 @@ class WalletPermissionsManager {
1273
1256
  const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest);
1274
1257
  return satisfied ? true : null;
1275
1258
  }
1276
- async withGroupedPermissionFlowLock(originator, fn) {
1277
- const priorTail = this.groupedPermissionFlowTail.get(originator) || Promise.resolve();
1278
- const safePriorTail = priorTail.catch(() => { });
1279
- let release;
1280
- const gate = new Promise(resolve => {
1281
- release = resolve;
1282
- });
1283
- const currentTail = safePriorTail.then(() => gate);
1284
- this.groupedPermissionFlowTail.set(originator, currentTail);
1285
- await safePriorTail;
1286
- try {
1287
- return await fn();
1288
- }
1289
- finally {
1290
- release === null || release === void 0 ? void 0 : release();
1291
- currentTail.finally(() => {
1292
- if (this.groupedPermissionFlowTail.get(originator) === currentTail) {
1293
- this.groupedPermissionFlowTail.delete(originator);
1294
- }
1295
- });
1296
- }
1297
- }
1298
1259
  async checkSpecificPermissionAfterGroupFlow(request) {
1299
1260
  var _a, _b, _c;
1300
1261
  switch (request.type) {
@@ -1429,14 +1390,6 @@ class WalletPermissionsManager {
1429
1390
  originator: normalizedOriginator,
1430
1391
  displayOriginator: (_c = (_a = r.displayOriginator) !== null && _a !== void 0 ? _a : (_b = r.previousToken) === null || _b === void 0 ? void 0 : _b.rawOriginator) !== null && _c !== void 0 ? _c : r.originator
1431
1392
  };
1432
- const key = this.buildActiveRequestKey(preparedRequest);
1433
- // If there's already a queue for the same resource, we piggyback on it
1434
- const existingQueue = this.activeRequests.get(key);
1435
- if (existingQueue && existingQueue.pending.length > 0) {
1436
- return new Promise((resolve, reject) => {
1437
- existingQueue.pending.push({ resolve, reject });
1438
- });
1439
- }
1440
1393
  const pactResult = await this.maybeRequestPact(preparedRequest);
1441
1394
  if (pactResult !== null) {
1442
1395
  return pactResult;
@@ -1445,73 +1398,51 @@ class WalletPermissionsManager {
1445
1398
  if (peerGroupResult !== null) {
1446
1399
  return peerGroupResult;
1447
1400
  }
1448
- const hadPendingGroupedFlowBefore = this.config.seekGroupedPermission && this.groupedPermissionFlowTail.has(preparedRequest.originator);
1449
- let groupResult = null;
1450
- if (this.config.seekGroupedPermission) {
1451
- groupResult = await this.withGroupedPermissionFlowLock(preparedRequest.originator, async () => {
1452
- return await this.maybeRequestGroupedPermissions(preparedRequest);
1453
- });
1454
- }
1455
- else {
1456
- groupResult = await this.maybeRequestGroupedPermissions(preparedRequest);
1457
- }
1401
+ const groupResult = await this.maybeRequestGroupedPermissions(preparedRequest);
1458
1402
  if (groupResult !== null) {
1459
1403
  return groupResult;
1460
1404
  }
1461
- if (this.config.seekGroupedPermission && hadPendingGroupedFlowBefore) {
1462
- const satisfiedAfterGroup = await this.checkSpecificPermissionAfterGroupFlow(preparedRequest);
1463
- if (satisfiedAfterGroup) {
1464
- return true;
1465
- }
1466
- }
1467
- const existingQueueAfterGroups = this.activeRequests.get(key);
1468
- if (existingQueueAfterGroups && existingQueueAfterGroups.pending.length > 0) {
1405
+ const key = this.buildRequestKey(preparedRequest);
1406
+ // If there's already a queue for the same resource, we piggyback on it
1407
+ const existingQueue = this.activeRequests.get(key);
1408
+ if (existingQueue && existingQueue.pending.length > 0) {
1469
1409
  return new Promise((resolve, reject) => {
1470
- existingQueueAfterGroups.pending.push({ resolve, reject });
1410
+ existingQueue.pending.push({ resolve, reject });
1471
1411
  });
1472
1412
  }
1413
+ // Otherwise, create a new queue with a single entry
1414
+ // Return a promise that resolves or rejects once the user grants/denies
1473
1415
  return new Promise(async (resolve, reject) => {
1474
1416
  this.activeRequests.set(key, {
1475
1417
  request: preparedRequest,
1476
1418
  pending: [{ resolve, reject }]
1477
1419
  });
1478
- try {
1479
- // Fire the relevant onXXXRequested event (which one depends on r.type)
1480
- switch (preparedRequest.type) {
1481
- case 'protocol':
1482
- await this.callEvent('onProtocolPermissionRequested', {
1483
- ...preparedRequest,
1484
- requestID: key
1485
- });
1486
- break;
1487
- case 'basket':
1488
- await this.callEvent('onBasketAccessRequested', {
1489
- ...preparedRequest,
1490
- requestID: key
1491
- });
1492
- break;
1493
- case 'certificate':
1494
- await this.callEvent('onCertificateAccessRequested', {
1495
- ...preparedRequest,
1496
- requestID: key
1497
- });
1498
- break;
1499
- case 'spending':
1500
- await this.callEvent('onSpendingAuthorizationRequested', {
1501
- ...preparedRequest,
1502
- requestID: key
1503
- });
1504
- break;
1505
- }
1506
- }
1507
- catch (e) {
1508
- const matching = this.activeRequests.get(key);
1509
- if (matching) {
1510
- for (const p of matching.pending) {
1511
- p.reject(e);
1512
- }
1513
- this.activeRequests.delete(key);
1514
- }
1420
+ // Fire the relevant onXXXRequested event (which one depends on r.type)
1421
+ switch (preparedRequest.type) {
1422
+ case 'protocol':
1423
+ await this.callEvent('onProtocolPermissionRequested', {
1424
+ ...preparedRequest,
1425
+ requestID: key
1426
+ });
1427
+ break;
1428
+ case 'basket':
1429
+ await this.callEvent('onBasketAccessRequested', {
1430
+ ...preparedRequest,
1431
+ requestID: key
1432
+ });
1433
+ break;
1434
+ case 'certificate':
1435
+ await this.callEvent('onCertificateAccessRequested', {
1436
+ ...preparedRequest,
1437
+ requestID: key
1438
+ });
1439
+ break;
1440
+ case 'spending':
1441
+ await this.callEvent('onSpendingAuthorizationRequested', {
1442
+ ...preparedRequest,
1443
+ requestID: key
1444
+ });
1445
+ break;
1515
1446
  }
1516
1447
  });
1517
1448
  }
@@ -2579,137 +2510,6 @@ class WalletPermissionsManager {
2579
2510
  return false;
2580
2511
  }
2581
2512
  }
2582
- async revokePermissions(oldTokens) {
2583
- return await this.revokePermissionTokensBestEffort(oldTokens);
2584
- }
2585
- async revokeAllForOriginator(originator, opts) {
2586
- const preparedOriginator = this.prepareOriginator(originator);
2587
- const include = {
2588
- protocol: true,
2589
- basket: true,
2590
- certificate: true,
2591
- spending: true,
2592
- ...(opts || {})
2593
- };
2594
- const [protocolTokens, basketTokens, certificateTokens, spendingTokens] = await Promise.all([
2595
- include.protocol ? this.listProtocolPermissions({ originator }) : Promise.resolve([]),
2596
- include.basket ? this.listBasketAccess({ originator }) : Promise.resolve([]),
2597
- include.certificate ? this.listCertificateAccess({ originator }) : Promise.resolve([]),
2598
- include.spending
2599
- ? this.listSpendingAuthorizations({ originator: preparedOriginator.normalized })
2600
- : Promise.resolve([])
2601
- ]);
2602
- const spendingTokenList = spendingTokens.length ? [spendingTokens[0]] : [];
2603
- const allTokens = [...protocolTokens, ...basketTokens, ...certificateTokens, ...spendingTokenList];
2604
- const seen = new Set();
2605
- const deduped = allTokens.filter(t => {
2606
- const key = `${t.txid}.${t.outputIndex}`;
2607
- if (seen.has(key))
2608
- return false;
2609
- seen.add(key);
2610
- return true;
2611
- });
2612
- return await this.revokePermissions(deduped);
2613
- }
2614
- async revokePermissionTokensBestEffort(items) {
2615
- const CHUNK = 15;
2616
- return this.runBestEffortBatches(items, CHUNK, async (chunk) => {
2617
- await this.revokePermissionTokensChunk(chunk);
2618
- return chunk;
2619
- });
2620
- }
2621
- async revokePermissionTokensChunk(oldTokens) {
2622
- if (!oldTokens.length)
2623
- return;
2624
- const inputBeef = new sdk_1.Beef();
2625
- for (const token of oldTokens) {
2626
- inputBeef.mergeBeef(sdk_1.Beef.fromBinary(token.tx));
2627
- }
2628
- const { signableTransaction } = await this.createAction({
2629
- description: `Revoke ${oldTokens.length} permissions`,
2630
- inputBEEF: inputBeef.toBinary(),
2631
- inputs: oldTokens.map((t, i) => ({
2632
- outpoint: `${t.txid}.${t.outputIndex}`,
2633
- unlockingScriptLength: 73,
2634
- inputDescription: `Consume old permission token #${i + 1}`
2635
- })),
2636
- options: {
2637
- acceptDelayedBroadcast: true,
2638
- randomizeOutputs: false,
2639
- signAndProcess: false
2640
- }
2641
- }, this.adminOriginator);
2642
- if (!(signableTransaction === null || signableTransaction === void 0 ? void 0 : signableTransaction.reference) || !signableTransaction.tx) {
2643
- throw new Error('Failed to create signable transaction');
2644
- }
2645
- const tx = sdk_1.Transaction.fromAtomicBEEF(signableTransaction.tx);
2646
- const normalizeTxid = (txid) => (txid !== null && txid !== void 0 ? txid : '').toLowerCase();
2647
- const reverseHexTxid = (txid) => {
2648
- const hex = normalizeTxid(txid);
2649
- if (!/^[0-9a-f]{64}$/.test(hex))
2650
- return hex;
2651
- const bytes = hex.match(/../g);
2652
- return bytes ? bytes.reverse().join('') : hex;
2653
- };
2654
- const matchesOutpointString = (outpoint, token) => {
2655
- const dot = outpoint.lastIndexOf('.');
2656
- const colon = outpoint.lastIndexOf(':');
2657
- const sep = dot > colon ? dot : colon;
2658
- if (sep === -1)
2659
- return false;
2660
- const txidPart = outpoint.slice(0, sep);
2661
- const indexPart = outpoint.slice(sep + 1);
2662
- const vout = Number(indexPart);
2663
- if (!Number.isFinite(vout))
2664
- return false;
2665
- return normalizeTxid(txidPart) === normalizeTxid(token.txid) && vout === token.outputIndex;
2666
- };
2667
- const findInputIndexForToken = (token) => {
2668
- return tx.inputs.findIndex((input) => {
2669
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
2670
- const txidCandidate = (_g = (_f = (_e = (_d = (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.sourceTXID) !== null && _a !== void 0 ? _a : input === null || input === void 0 ? void 0 : input.sourceTxid) !== null && _b !== void 0 ? _b : input === null || input === void 0 ? void 0 : input.sourceTxId) !== null && _c !== void 0 ? _c : input === null || input === void 0 ? void 0 : input.prevTxId) !== null && _d !== void 0 ? _d : input === null || input === void 0 ? void 0 : input.prevTxid) !== null && _e !== void 0 ? _e : input === null || input === void 0 ? void 0 : input.prevTXID) !== null && _f !== void 0 ? _f : input === null || input === void 0 ? void 0 : input.txid) !== null && _g !== void 0 ? _g : input === null || input === void 0 ? void 0 : input.txID;
2671
- const voutCandidate = (_l = (_k = (_j = (_h = input === null || input === void 0 ? void 0 : input.sourceOutputIndex) !== null && _h !== void 0 ? _h : input === null || input === void 0 ? void 0 : input.sourceOutput) !== null && _j !== void 0 ? _j : input === null || input === void 0 ? void 0 : input.outputIndex) !== null && _k !== void 0 ? _k : input === null || input === void 0 ? void 0 : input.vout) !== null && _l !== void 0 ? _l : input === null || input === void 0 ? void 0 : input.prevOutIndex;
2672
- if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {
2673
- const cand = normalizeTxid(txidCandidate);
2674
- const target = normalizeTxid(token.txid);
2675
- if (cand === target && voutCandidate === token.outputIndex)
2676
- return true;
2677
- if (cand === reverseHexTxid(token.txid) && voutCandidate === token.outputIndex)
2678
- return true;
2679
- }
2680
- const outpointCandidate = (_o = (_m = input === null || input === void 0 ? void 0 : input.outpoint) !== null && _m !== void 0 ? _m : input === null || input === void 0 ? void 0 : input.sourceOutpoint) !== null && _o !== void 0 ? _o : input === null || input === void 0 ? void 0 : input.prevOutpoint;
2681
- if (typeof outpointCandidate === 'string' && matchesOutpointString(outpointCandidate, token))
2682
- return true;
2683
- return false;
2684
- });
2685
- };
2686
- const inputsToSign = oldTokens.map(token => {
2687
- let permInputIndex = findInputIndexForToken(token);
2688
- if (permInputIndex === -1 && tx.inputs.length === 1) {
2689
- permInputIndex = 0;
2690
- }
2691
- if (permInputIndex === -1) {
2692
- throw new Error('Unable to locate permission token input for revocation.');
2693
- }
2694
- return { token, permInputIndex };
2695
- });
2696
- const pushdrop = new sdk_1.PushDrop(this.underlying);
2697
- const spends = {};
2698
- const signed = await this.mapWithConcurrency(inputsToSign, 8, async ({ token, permInputIndex }) => {
2699
- const unlocker = pushdrop.unlock(WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL, '1', 'self', 'all', false, 1, sdk_1.LockingScript.fromHex(token.outputScript));
2700
- const unlockingScript = await unlocker.sign(tx, permInputIndex);
2701
- return { permInputIndex, unlockingScriptHex: unlockingScript.toHex() };
2702
- });
2703
- for (const s of signed) {
2704
- spends[s.permInputIndex] = { unlockingScript: s.unlockingScriptHex };
2705
- }
2706
- const { txid } = await this.underlying.signAction({
2707
- reference: signableTransaction.reference,
2708
- spends
2709
- });
2710
- if (!txid)
2711
- throw new Error('Failed to finalize revoke transaction');
2712
- }
2713
2513
  /**
2714
2514
  * Revokes a permission token by spending it with no replacement output.
2715
2515
  * The manager builds a BRC-100 transaction that consumes the token, effectively invalidating it.
@@ -2844,28 +2644,22 @@ class WalletPermissionsManager {
2844
2644
  const originalDescription = args.description;
2845
2645
  const originalInputDescriptions = {};
2846
2646
  const originalOutputDescriptions = {};
2847
- const inputEncryptionTasks = (args.inputs || []).map(async (input, i) => {
2848
- if (!input.inputDescription)
2849
- return;
2850
- originalInputDescriptions[i] = input.inputDescription;
2851
- input.inputDescription = await this.maybeEncryptMetadata(input.inputDescription);
2852
- });
2853
- const outputEncryptionTasks = (args.outputs || []).map(async (output, i) => {
2854
- if (output.outputDescription) {
2855
- originalOutputDescriptions[i] = output.outputDescription;
2856
- output.outputDescription = await this.maybeEncryptMetadata(output.outputDescription);
2647
+ args.description = await this.maybeEncryptMetadata(args.description);
2648
+ for (let i = 0; i < (args.inputs || []).length; i++) {
2649
+ if (args.inputs[i].inputDescription) {
2650
+ originalInputDescriptions[i] = args.inputs[i].inputDescription;
2651
+ args.inputs[i].inputDescription = await this.maybeEncryptMetadata(args.inputs[i].inputDescription);
2857
2652
  }
2858
- if (output.customInstructions) {
2859
- output.customInstructions = await this.maybeEncryptMetadata(output.customInstructions);
2653
+ }
2654
+ for (let i = 0; i < (args.outputs || []).length; i++) {
2655
+ if (args.outputs[i].outputDescription) {
2656
+ originalOutputDescriptions[i] = args.outputs[i].outputDescription;
2657
+ args.outputs[i].outputDescription = await this.maybeEncryptMetadata(args.outputs[i].outputDescription);
2860
2658
  }
2861
- });
2862
- await Promise.all([
2863
- (async () => {
2864
- args.description = await this.maybeEncryptMetadata(args.description);
2865
- })(),
2866
- ...inputEncryptionTasks,
2867
- ...outputEncryptionTasks
2868
- ]);
2659
+ if (args.outputs[i].customInstructions) {
2660
+ args.outputs[i].customInstructions = await this.maybeEncryptMetadata(args.outputs[i].customInstructions);
2661
+ }
2662
+ }
2869
2663
  /**
2870
2664
  * 6) Call the underlying wallet's createAction.
2871
2665
  * - If P-modules are involved, chain request transformations through them first
@@ -3441,45 +3235,43 @@ class WalletPermissionsManager {
3441
3235
  let [_, originator] = args;
3442
3236
  if (this.config.seekGroupedPermission && originator) {
3443
3237
  const { normalized: normalizedOriginator } = this.prepareOriginator(originator);
3444
- const normalized = normalizedOriginator;
3445
- await this.withGroupedPermissionFlowLock(normalized, async () => {
3446
- // 1. Fetch manifest.json from the originator
3447
- const groupPermissions = await this.fetchManifestGroupPermissions(normalized);
3448
- if (groupPermissions) {
3449
- // 2. Filter out already-granted permissions
3450
- const permissionsToRequest = await this.filterAlreadyGrantedPermissions(normalized, groupPermissions);
3451
- // 3. If any permissions are left to request, start the flow
3452
- if (this.hasAnyPermissionsToRequest(permissionsToRequest)) {
3453
- const key = `group:${normalized}`;
3454
- if (this.activeRequests.has(key)) {
3455
- // Another call is already waiting, piggyback on it
3456
- await new Promise((resolve, reject) => {
3457
- this.activeRequests.get(key).pending.push({ resolve, reject });
3238
+ originator = normalizedOriginator;
3239
+ // 1. Fetch manifest.json from the originator
3240
+ const groupPermissions = await this.fetchManifestGroupPermissions(originator);
3241
+ if (groupPermissions) {
3242
+ // 2. Filter out already-granted permissions
3243
+ const permissionsToRequest = await this.filterAlreadyGrantedPermissions(originator, groupPermissions);
3244
+ // 3. If any permissions are left to request, start the flow
3245
+ if (this.hasAnyPermissionsToRequest(permissionsToRequest)) {
3246
+ const key = `group:${originator}`;
3247
+ if (this.activeRequests.has(key)) {
3248
+ // Another call is already waiting, piggyback on it
3249
+ await new Promise((resolve, reject) => {
3250
+ this.activeRequests.get(key).pending.push({ resolve, reject });
3251
+ });
3252
+ }
3253
+ else {
3254
+ // This is the first call, create a new request
3255
+ try {
3256
+ await new Promise(async (resolve, reject) => {
3257
+ this.activeRequests.set(key, {
3258
+ request: { originator: originator, permissions: permissionsToRequest },
3259
+ pending: [{ resolve, reject }]
3260
+ });
3261
+ await this.callEvent('onGroupedPermissionRequested', {
3262
+ requestID: key,
3263
+ originator,
3264
+ permissions: permissionsToRequest
3265
+ });
3458
3266
  });
3459
3267
  }
3460
- else {
3461
- // This is the first call, create a new request
3462
- try {
3463
- await new Promise(async (resolve, reject) => {
3464
- this.activeRequests.set(key, {
3465
- request: { originator: normalized, permissions: permissionsToRequest },
3466
- pending: [{ resolve, reject }]
3467
- });
3468
- await this.callEvent('onGroupedPermissionRequested', {
3469
- requestID: key,
3470
- originator: normalized,
3471
- permissions: permissionsToRequest
3472
- });
3473
- });
3474
- }
3475
- catch (e) {
3476
- // Permission was denied, re-throw to stop execution
3477
- throw e;
3478
- }
3268
+ catch (e) {
3269
+ // Permission was denied, re-throw to stop execution
3270
+ throw e;
3479
3271
  }
3480
3272
  }
3481
3273
  }
3482
- });
3274
+ }
3483
3275
  }
3484
3276
  // Finally, after handling grouped permissions, call the underlying method.
3485
3277
  return this.underlying.waitForAuthentication(...args);
@@ -3682,14 +3474,6 @@ class WalletPermissionsManager {
3682
3474
  return `spend:${normalizedOriginator}:${(_e = r.spending) === null || _e === void 0 ? void 0 : _e.satoshis}`;
3683
3475
  }
3684
3476
  }
3685
- buildActiveRequestKey(r) {
3686
- var _a;
3687
- const base = this.buildRequestKey(r);
3688
- if (r.type === 'protocol' || r.type === 'basket' || r.type === 'certificate') {
3689
- return `${base}:${(_a = r.usageType) !== null && _a !== void 0 ? _a : ''}`;
3690
- }
3691
- return base;
3692
- }
3693
3477
  }
3694
3478
  exports.WalletPermissionsManager = WalletPermissionsManager;
3695
3479
  WalletPermissionsManager.MANIFEST_CACHE_TTL_MS = 5 * 60 * 1000;