@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.
- package/out/src/Wallet.d.ts.map +1 -1
- package/out/src/Wallet.js +0 -7
- package/out/src/Wallet.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +0 -13
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +133 -349
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/sdk/validationHelpers.d.ts +303 -0
- package/out/src/sdk/validationHelpers.d.ts.map +1 -0
- package/out/src/sdk/validationHelpers.js +632 -0
- package/out/src/sdk/validationHelpers.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js +0 -24
- package/out/src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.js.map +1 -1
- package/out/src/utility/ReaderUint8Array.d.ts +28 -0
- package/out/src/utility/ReaderUint8Array.d.ts.map +1 -0
- package/out/src/utility/ReaderUint8Array.js +166 -0
- package/out/src/utility/ReaderUint8Array.js.map +1 -0
- package/out/tsconfig.client.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
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
|
|
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
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
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
|
|
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
|
-
|
|
1228
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
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
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
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
|
-
|
|
2859
|
-
|
|
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
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
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
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
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
|
-
|
|
3461
|
-
//
|
|
3462
|
-
|
|
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;
|