@bsv/wallet-toolbox 1.4.3 → 1.4.5
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/docs/client.md +225 -79
- package/docs/monitor.md +32 -1
- package/docs/wallet.md +225 -79
- package/mobile/out/src/WalletPermissionsManager.d.ts +60 -1
- package/mobile/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/mobile/out/src/WalletPermissionsManager.js +223 -15
- package/mobile/out/src/WalletPermissionsManager.js.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/mobile/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/mobile/package-lock.json +2 -2
- package/mobile/package.json +1 -1
- package/out/src/CWIStyleWalletManager.js +1 -1
- package/out/src/CWIStyleWalletManager.js.map +1 -1
- package/out/src/WalletPermissionsManager.d.ts +60 -1
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +222 -15
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/__tests/WalletPermissionsManager.initialization.test.js.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskCheckNoSends.js.map +1 -1
- package/out/src/sdk/CertOps.d.ts +66 -0
- package/out/src/sdk/CertOps.d.ts.map +1 -0
- package/out/src/sdk/CertOps.js +198 -0
- package/out/src/sdk/CertOps.js.map +1 -0
- package/out/src/sdk/StorageSyncReader.d.ts +121 -0
- package/out/src/sdk/StorageSyncReader.d.ts.map +1 -0
- package/out/src/sdk/StorageSyncReader.js +3 -0
- package/out/src/sdk/StorageSyncReader.js.map +1 -0
- package/out/src/sdk/StorageSyncReaderWriter.d.ts +89 -0
- package/out/src/sdk/StorageSyncReaderWriter.d.ts.map +1 -0
- package/out/src/sdk/StorageSyncReaderWriter.js +3 -0
- package/out/src/sdk/StorageSyncReaderWriter.js.map +1 -0
- package/out/src/services/__tests/ARC.test.d.ts +2 -0
- package/out/src/services/__tests/ARC.test.d.ts.map +1 -0
- package/out/src/services/__tests/ARC.test.js +104 -0
- package/out/src/services/__tests/ARC.test.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts +98 -0
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js +38 -0
- package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +1 -0
- package/out/src/storage/methods/listActions.d.ts +5 -0
- package/out/src/storage/methods/listActions.d.ts.map +1 -0
- package/out/src/storage/methods/listActions.js +228 -0
- package/out/src/storage/methods/listActions.js.map +1 -0
- package/out/src/storage/methods/listOutputs.d.ts +5 -0
- package/out/src/storage/methods/listOutputs.d.ts.map +1 -0
- package/out/src/storage/methods/listOutputs.js +295 -0
- package/out/src/storage/methods/listOutputs.js.map +1 -0
- package/out/src/storage/schema/entities/Certificate.d.ts +43 -0
- package/out/src/storage/schema/entities/Certificate.d.ts.map +1 -0
- package/out/src/storage/schema/entities/Certificate.js +162 -0
- package/out/src/storage/schema/entities/Certificate.js.map +1 -0
- package/out/src/storage/schema/entities/CertificateField.d.ts +32 -0
- package/out/src/storage/schema/entities/CertificateField.d.ts.map +1 -0
- package/out/src/storage/schema/entities/CertificateField.js +114 -0
- package/out/src/storage/schema/entities/CertificateField.js.map +1 -0
- package/out/src/storage/schema/entities/Commission.d.ts +37 -0
- package/out/src/storage/schema/entities/Commission.d.ts.map +1 -0
- package/out/src/storage/schema/entities/Commission.js +130 -0
- package/out/src/storage/schema/entities/Commission.js.map +1 -0
- package/out/src/storage/schema/entities/Output.d.ts +67 -0
- package/out/src/storage/schema/entities/Output.d.ts.map +1 -0
- package/out/src/storage/schema/entities/Output.js +281 -0
- package/out/src/storage/schema/entities/Output.js.map +1 -0
- package/out/src/storage/schema/entities/OutputBasket.d.ts +35 -0
- package/out/src/storage/schema/entities/OutputBasket.d.ts.map +1 -0
- package/out/src/storage/schema/entities/OutputBasket.js +133 -0
- package/out/src/storage/schema/entities/OutputBasket.js.map +1 -0
- package/out/src/storage/schema/entities/OutputTag.d.ts +31 -0
- package/out/src/storage/schema/entities/OutputTag.d.ts.map +1 -0
- package/out/src/storage/schema/entities/OutputTag.js +104 -0
- package/out/src/storage/schema/entities/OutputTag.js.map +1 -0
- package/out/src/storage/schema/entities/OutputTagMap.d.ts +28 -0
- package/out/src/storage/schema/entities/OutputTagMap.d.ts.map +1 -0
- package/out/src/storage/schema/entities/OutputTagMap.js +101 -0
- package/out/src/storage/schema/entities/OutputTagMap.js.map +1 -0
- package/out/src/storage/schema/entities/ProvenTx.d.ts +84 -0
- package/out/src/storage/schema/entities/ProvenTx.d.ts.map +1 -0
- package/out/src/storage/schema/entities/ProvenTx.js +286 -0
- package/out/src/storage/schema/entities/ProvenTx.js.map +1 -0
- package/out/src/storage/schema/entities/ProvenTxReq.d.ts +135 -0
- package/out/src/storage/schema/entities/ProvenTxReq.d.ts.map +1 -0
- package/out/src/storage/schema/entities/ProvenTxReq.js +532 -0
- package/out/src/storage/schema/entities/ProvenTxReq.js.map +1 -0
- package/out/src/storage/schema/entities/SyncState.d.ts +66 -0
- package/out/src/storage/schema/entities/SyncState.d.ts.map +1 -0
- package/out/src/storage/schema/entities/SyncState.js +284 -0
- package/out/src/storage/schema/entities/SyncState.js.map +1 -0
- package/out/src/storage/schema/entities/Transaction.d.ts +67 -0
- package/out/src/storage/schema/entities/Transaction.d.ts.map +1 -0
- package/out/src/storage/schema/entities/Transaction.js +264 -0
- package/out/src/storage/schema/entities/Transaction.js.map +1 -0
- package/out/src/storage/schema/entities/TxLabel.d.ts +31 -0
- package/out/src/storage/schema/entities/TxLabel.d.ts.map +1 -0
- package/out/src/storage/schema/entities/TxLabel.js +104 -0
- package/out/src/storage/schema/entities/TxLabel.js.map +1 -0
- package/out/src/storage/schema/entities/TxLabelMap.d.ts +28 -0
- package/out/src/storage/schema/entities/TxLabelMap.d.ts.map +1 -0
- package/out/src/storage/schema/entities/TxLabelMap.js +103 -0
- package/out/src/storage/schema/entities/TxLabelMap.js.map +1 -0
- package/out/src/storage/schema/entities/User.d.ts +29 -0
- package/out/src/storage/schema/entities/User.d.ts.map +1 -0
- package/out/src/storage/schema/entities/User.js +100 -0
- package/out/src/storage/schema/entities/User.js.map +1 -0
- package/out/src/storage/schema/tables/Certificate.d.ts +20 -0
- package/out/src/storage/schema/tables/Certificate.d.ts.map +1 -0
- package/out/src/storage/schema/tables/Certificate.js +3 -0
- package/out/src/storage/schema/tables/Certificate.js.map +1 -0
- package/out/src/storage/schema/tables/CertificateField.d.ts +12 -0
- package/out/src/storage/schema/tables/CertificateField.d.ts.map +1 -0
- package/out/src/storage/schema/tables/CertificateField.js +3 -0
- package/out/src/storage/schema/tables/CertificateField.js.map +1 -0
- package/out/src/storage/schema/tables/Commission.d.ts +13 -0
- package/out/src/storage/schema/tables/Commission.d.ts.map +1 -0
- package/out/src/storage/schema/tables/Commission.js +3 -0
- package/out/src/storage/schema/tables/Commission.js.map +1 -0
- package/out/src/storage/schema/tables/MonitorEvent.d.ts +9 -0
- package/out/src/storage/schema/tables/MonitorEvent.d.ts.map +1 -0
- package/out/src/storage/schema/tables/MonitorEvent.js +3 -0
- package/out/src/storage/schema/tables/MonitorEvent.js.map +1 -0
- package/out/src/storage/schema/tables/Output.d.ts +36 -0
- package/out/src/storage/schema/tables/Output.d.ts.map +1 -0
- package/out/src/storage/schema/tables/Output.js +31 -0
- package/out/src/storage/schema/tables/Output.js.map +1 -0
- package/out/src/storage/schema/tables/OutputBasket.d.ts +12 -0
- package/out/src/storage/schema/tables/OutputBasket.d.ts.map +1 -0
- package/out/src/storage/schema/tables/OutputBasket.js +3 -0
- package/out/src/storage/schema/tables/OutputBasket.js.map +1 -0
- package/out/src/storage/schema/tables/OutputTag.d.ts +10 -0
- package/out/src/storage/schema/tables/OutputTag.d.ts.map +1 -0
- package/out/src/storage/schema/tables/OutputTag.js +3 -0
- package/out/src/storage/schema/tables/OutputTag.js.map +1 -0
- package/out/src/storage/schema/tables/OutputTagMap.d.ts +9 -0
- package/out/src/storage/schema/tables/OutputTagMap.d.ts.map +1 -0
- package/out/src/storage/schema/tables/OutputTagMap.js +3 -0
- package/out/src/storage/schema/tables/OutputTagMap.js.map +1 -0
- package/out/src/storage/schema/tables/ProvenTx.d.ts +14 -0
- package/out/src/storage/schema/tables/ProvenTx.d.ts.map +1 -0
- package/out/src/storage/schema/tables/ProvenTx.js +3 -0
- package/out/src/storage/schema/tables/ProvenTx.js.map +1 -0
- package/out/src/storage/schema/tables/ProvenTxReq.d.ts +64 -0
- package/out/src/storage/schema/tables/ProvenTxReq.d.ts.map +1 -0
- package/out/src/storage/schema/tables/ProvenTxReq.js +3 -0
- package/out/src/storage/schema/tables/ProvenTxReq.js.map +1 -0
- package/out/src/storage/schema/tables/SyncState.d.ts +18 -0
- package/out/src/storage/schema/tables/SyncState.d.ts.map +1 -0
- package/out/src/storage/schema/tables/SyncState.js +3 -0
- package/out/src/storage/schema/tables/SyncState.js.map +1 -0
- package/out/src/storage/schema/tables/Transaction.d.ts +37 -0
- package/out/src/storage/schema/tables/Transaction.d.ts.map +1 -0
- package/out/src/storage/schema/tables/Transaction.js +21 -0
- package/out/src/storage/schema/tables/Transaction.js.map +1 -0
- package/out/src/storage/schema/tables/TxLabel.d.ts +10 -0
- package/out/src/storage/schema/tables/TxLabel.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TxLabel.js +3 -0
- package/out/src/storage/schema/tables/TxLabel.js.map +1 -0
- package/out/src/storage/schema/tables/TxLabelMap.d.ts +9 -0
- package/out/src/storage/schema/tables/TxLabelMap.d.ts.map +1 -0
- package/out/src/storage/schema/tables/TxLabelMap.js +3 -0
- package/out/src/storage/schema/tables/TxLabelMap.js.map +1 -0
- package/out/src/storage/schema/tables/User.d.ts +16 -0
- package/out/src/storage/schema/tables/User.d.ts.map +1 -0
- package/out/src/storage/schema/tables/User.js +3 -0
- package/out/src/storage/schema/tables/User.js.map +1 -0
- package/out/test/Wallet/action/abortAction.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/action/abortAction.test.js.map +1 -1
- package/out/test/Wallet/action/createAction.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/action/createAction.test.js.map +1 -1
- package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts.map +1 -1
- package/out/test/{wallet → Wallet}/action/createAction2.test.js.map +1 -1
- package/out/test/Wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js.map +1 -1
- package/out/test/Wallet/action/internalizeAction.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/action/internalizeAction.test.js.map +1 -1
- package/out/test/Wallet/action/relinquishOutput.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js.map +1 -1
- package/out/test/Wallet/construct/Wallet.constructor.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js.map +1 -1
- package/out/test/Wallet/list/listActions.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/list/listActions.test.js.map +1 -1
- package/out/test/Wallet/list/listActions2.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/list/listActions2.test.js.map +1 -1
- package/out/test/Wallet/list/listCertificates.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/list/listCertificates.test.js.map +1 -1
- package/out/test/Wallet/list/listOutputs.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/list/listOutputs.test.js.map +1 -1
- package/out/test/Wallet/local/localWalletMethods.d.ts +28 -0
- package/out/test/Wallet/local/localWalletMethods.d.ts.map +1 -0
- package/out/test/Wallet/local/localWalletMethods.js +281 -0
- package/out/test/Wallet/local/localWalletMethods.js.map +1 -0
- package/out/test/Wallet/support/opers1.man.test.d.ts +2 -0
- package/out/test/Wallet/support/opers1.man.test.d.ts.map +1 -0
- package/out/test/Wallet/support/opers1.man.test.js +202 -0
- package/out/test/Wallet/support/opers1.man.test.js.map +1 -0
- package/out/test/Wallet/sync/Wallet.sync.test.d.ts.map +1 -0
- package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js.map +1 -1
- package/out/tsconfig.all.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/CWIStyleWalletManager.ts +1 -1
- package/src/WalletPermissionsManager.ts +317 -26
- package/src/__tests/WalletPermissionsManager.initialization.test.ts +1 -1
- package/src/monitor/tasks/TaskCheckNoSends.ts +0 -1
- package/src/monitor/tasks/TaskNewHeader.ts +1 -1
- package/out/test/wallet/action/abortAction.test.d.ts.map +0 -1
- package/out/test/wallet/action/createAction.test.d.ts.map +0 -1
- package/out/test/wallet/action/createActionToGenerateBeefs.man.test.d.ts.map +0 -1
- package/out/test/wallet/action/internalizeAction.test.d.ts.map +0 -1
- package/out/test/wallet/action/relinquishOutput.test.d.ts.map +0 -1
- package/out/test/wallet/construct/Wallet.constructor.test.d.ts.map +0 -1
- package/out/test/wallet/list/listActions.test.d.ts.map +0 -1
- package/out/test/wallet/list/listActions2.test.d.ts.map +0 -1
- package/out/test/wallet/list/listCertificates.test.d.ts.map +0 -1
- package/out/test/wallet/list/listOutputs.test.d.ts.map +0 -1
- package/out/test/wallet/sync/Wallet.sync.test.d.ts.map +0 -1
- /package/out/test/{wallet → Wallet}/action/abortAction.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/abortAction.test.js +0 -0
- /package/out/test/{wallet → Wallet}/action/createAction.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/createAction.test.js +0 -0
- /package/out/test/{wallet → Wallet}/action/createAction2.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/createAction2.test.js +0 -0
- /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.js +0 -0
- /package/out/test/{wallet → Wallet}/action/internalizeAction.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/internalizeAction.test.js +0 -0
- /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/action/relinquishOutput.test.js +0 -0
- /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/construct/Wallet.constructor.test.js +0 -0
- /package/out/test/{wallet → Wallet}/list/listActions.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/list/listActions.test.js +0 -0
- /package/out/test/{wallet → Wallet}/list/listActions2.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/list/listActions2.test.js +0 -0
- /package/out/test/{wallet → Wallet}/list/listCertificates.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/list/listCertificates.test.js +0 -0
- /package/out/test/{wallet → Wallet}/list/listOutputs.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/list/listOutputs.test.js +0 -0
- /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.d.ts +0 -0
- /package/out/test/{wallet → Wallet}/sync/Wallet.sync.test.js +0 -0
- /package/test/{wallet → Wallet}/action/abortAction.test.ts +0 -0
- /package/test/{wallet → Wallet}/action/createAction.test.ts +0 -0
- /package/test/{wallet → Wallet}/action/createAction2.test.ts +0 -0
- /package/test/{wallet → Wallet}/action/createActionToGenerateBeefs.man.test.ts +0 -0
- /package/test/{wallet → Wallet}/action/internalizeAction.test.ts +0 -0
- /package/test/{wallet → Wallet}/action/relinquishOutput.test.ts +0 -0
- /package/test/{wallet → Wallet}/construct/Wallet.constructor.test.ts +0 -0
- /package/test/{wallet → Wallet}/list/listActions.test.ts +0 -0
- /package/test/{wallet → Wallet}/list/listActions2.test.ts +0 -0
- /package/test/{wallet → Wallet}/list/listCertificates.test.ts +0 -0
- /package/test/{wallet → Wallet}/list/listOutputs.test.ts +0 -0
- /package/test/{wallet → Wallet}/sync/Wallet.sync.test.ts +0 -0
package/package.json
CHANGED
|
@@ -1870,7 +1870,7 @@ export class CWIStyleWalletManager implements WalletInterface {
|
|
|
1870
1870
|
while (!this.authenticated || !this.underlying) {
|
|
1871
1871
|
await new Promise(resolve => setTimeout(resolve, 100))
|
|
1872
1872
|
}
|
|
1873
|
-
return {
|
|
1873
|
+
return await this.underlying.waitForAuthentication({}, originator)
|
|
1874
1874
|
}
|
|
1875
1875
|
|
|
1876
1876
|
async getHeight(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetHeightResult> {
|
|
@@ -11,8 +11,77 @@ import {
|
|
|
11
11
|
import { validateCreateActionArgs } from './sdk'
|
|
12
12
|
|
|
13
13
|
////// TODO: ADD SUPPORT FOR ADMIN COUNTERPARTIES BASED ON WALLET STORAGE
|
|
14
|
+
////// PROHIBITION OF SPECIAL OPERATIONS IS ALSO CRITICAL.
|
|
14
15
|
////// !!!!!!!! SECURITY-CRITICAL ADDITION — DO NOT USE UNTIL IMPLEMENTED.
|
|
15
16
|
|
|
17
|
+
function deepEqual(object1: any, object2: any): boolean {
|
|
18
|
+
if (object1 === null || object1 === undefined || object2 === null || object2 === undefined) {
|
|
19
|
+
return object1 === object2
|
|
20
|
+
}
|
|
21
|
+
const keys1 = Object.keys(object1)
|
|
22
|
+
const keys2 = Object.keys(object2)
|
|
23
|
+
|
|
24
|
+
if (keys1.length !== keys2.length) {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (const key of keys1) {
|
|
29
|
+
const val1 = object1[key]
|
|
30
|
+
const val2 = object2[key]
|
|
31
|
+
const areObjects = isObject(val1) && isObject(val2)
|
|
32
|
+
if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isObject(object: any): boolean {
|
|
41
|
+
return object != null && typeof object === 'object'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Describes a group of permissions that can be requested together.
|
|
46
|
+
* This structure is based on BRC-73.
|
|
47
|
+
*/
|
|
48
|
+
export interface GroupedPermissions {
|
|
49
|
+
description?: string
|
|
50
|
+
spendingAuthorization?: {
|
|
51
|
+
amount: number
|
|
52
|
+
description: string
|
|
53
|
+
}
|
|
54
|
+
protocolPermissions?: Array<{
|
|
55
|
+
protocolID: WalletProtocol
|
|
56
|
+
counterparty?: string
|
|
57
|
+
description: string
|
|
58
|
+
}>
|
|
59
|
+
basketAccess?: Array<{
|
|
60
|
+
basket: string
|
|
61
|
+
description: string
|
|
62
|
+
}>
|
|
63
|
+
certificateAccess?: Array<{
|
|
64
|
+
type: string
|
|
65
|
+
fields: string[]
|
|
66
|
+
verifierPublicKey: string
|
|
67
|
+
description: string
|
|
68
|
+
}>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The object passed to the UI when a grouped permission is requested.
|
|
73
|
+
*/
|
|
74
|
+
export interface GroupedPermissionRequest {
|
|
75
|
+
originator: string
|
|
76
|
+
requestID: string
|
|
77
|
+
permissions: GroupedPermissions
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Signature for functions that handle a grouped permission request event.
|
|
82
|
+
*/
|
|
83
|
+
export type GroupedPermissionEventHandler = (request: GroupedPermissionRequest) => void | Promise<void>
|
|
84
|
+
|
|
16
85
|
/**
|
|
17
86
|
* Describes a single requested permission that the user must either grant or deny.
|
|
18
87
|
*
|
|
@@ -146,6 +215,7 @@ export interface WalletPermissionsManagerCallbacks {
|
|
|
146
215
|
onBasketAccessRequested?: PermissionEventHandler[]
|
|
147
216
|
onCertificateAccessRequested?: PermissionEventHandler[]
|
|
148
217
|
onSpendingAuthorizationRequested?: PermissionEventHandler[]
|
|
218
|
+
onGroupedPermissionRequested?: GroupedPermissionEventHandler[]
|
|
149
219
|
}
|
|
150
220
|
|
|
151
221
|
/**
|
|
@@ -255,6 +325,11 @@ export interface PermissionsManagerConfig {
|
|
|
255
325
|
*/
|
|
256
326
|
seekSpendingPermissions?: boolean
|
|
257
327
|
|
|
328
|
+
/**
|
|
329
|
+
* If true, triggers a grouped permission request flow based on the originator's `manifest.json`.
|
|
330
|
+
*/
|
|
331
|
+
seekGroupedPermission?: boolean
|
|
332
|
+
|
|
258
333
|
/**
|
|
259
334
|
* If false, permissions are checked without regard for whether we are in
|
|
260
335
|
* privileged mode. Privileged status is ignored with respect to whether
|
|
@@ -300,7 +375,8 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
300
375
|
onProtocolPermissionRequested: [],
|
|
301
376
|
onBasketAccessRequested: [],
|
|
302
377
|
onCertificateAccessRequested: [],
|
|
303
|
-
onSpendingAuthorizationRequested: []
|
|
378
|
+
onSpendingAuthorizationRequested: [],
|
|
379
|
+
onGroupedPermissionRequested: []
|
|
304
380
|
}
|
|
305
381
|
|
|
306
382
|
/**
|
|
@@ -316,9 +392,9 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
316
392
|
private activeRequests: Map<
|
|
317
393
|
string,
|
|
318
394
|
{
|
|
319
|
-
request: PermissionRequest
|
|
395
|
+
request: PermissionRequest | { originator: string; permissions: GroupedPermissions }
|
|
320
396
|
pending: Array<{
|
|
321
|
-
resolve: (val:
|
|
397
|
+
resolve: (val: any) => void
|
|
322
398
|
reject: (err: any) => void
|
|
323
399
|
}>
|
|
324
400
|
}
|
|
@@ -366,6 +442,7 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
366
442
|
seekCertificateListingPermissions: true,
|
|
367
443
|
encryptWalletMetadata: true,
|
|
368
444
|
seekSpendingPermissions: true,
|
|
445
|
+
seekGroupedPermission: true,
|
|
369
446
|
differentiatePrivilegedOperations: true,
|
|
370
447
|
...config // override with user-specified config
|
|
371
448
|
}
|
|
@@ -382,8 +459,11 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
382
459
|
* @param handler A function that handles the event
|
|
383
460
|
* @returns A numeric ID you can use to unbind later
|
|
384
461
|
*/
|
|
385
|
-
public bindCallback(
|
|
386
|
-
|
|
462
|
+
public bindCallback(
|
|
463
|
+
eventName: keyof WalletPermissionsManagerCallbacks,
|
|
464
|
+
handler: PermissionEventHandler | GroupedPermissionEventHandler
|
|
465
|
+
): number {
|
|
466
|
+
const arr = this.callbacks[eventName]! as any[]
|
|
387
467
|
arr.push(handler)
|
|
388
468
|
return arr.length - 1
|
|
389
469
|
}
|
|
@@ -469,18 +549,19 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
469
549
|
|
|
470
550
|
// 3) If `ephemeral !== true`, we create or renew an on-chain token
|
|
471
551
|
if (!params.ephemeral) {
|
|
472
|
-
|
|
552
|
+
const request = matching.request as PermissionRequest
|
|
553
|
+
if (!request.renewal) {
|
|
473
554
|
// brand-new permission token
|
|
474
555
|
await this.createPermissionOnChain(
|
|
475
|
-
|
|
556
|
+
request,
|
|
476
557
|
params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30, // default 30-day expiry
|
|
477
558
|
params.amount
|
|
478
559
|
)
|
|
479
560
|
} else {
|
|
480
561
|
// renewal => spend the old token, produce a new one
|
|
481
562
|
await this.renewPermissionOnChain(
|
|
482
|
-
|
|
483
|
-
|
|
563
|
+
request.previousToken!,
|
|
564
|
+
request,
|
|
484
565
|
params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30,
|
|
485
566
|
params.amount
|
|
486
567
|
)
|
|
@@ -489,7 +570,7 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
489
570
|
|
|
490
571
|
// Update the cache regardless of ephemeral status
|
|
491
572
|
const expiry = params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30
|
|
492
|
-
const key = this.buildRequestKey(matching.request)
|
|
573
|
+
const key = this.buildRequestKey(matching.request as PermissionRequest)
|
|
493
574
|
this.cachePermission(key, expiry)
|
|
494
575
|
}
|
|
495
576
|
|
|
@@ -513,6 +594,123 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
513
594
|
this.activeRequests.delete(requestID)
|
|
514
595
|
}
|
|
515
596
|
|
|
597
|
+
/**
|
|
598
|
+
* Grants a previously requested grouped permission.
|
|
599
|
+
* @param params.requestID The ID of the request being granted.
|
|
600
|
+
* @param params.granted A subset of the originally requested permissions that the user has granted.
|
|
601
|
+
* @param params.expiry An optional expiry time (in seconds) for the new permission tokens.
|
|
602
|
+
*/
|
|
603
|
+
public async grantGroupedPermission(params: {
|
|
604
|
+
requestID: string
|
|
605
|
+
granted: Partial<GroupedPermissions>
|
|
606
|
+
expiry?: number
|
|
607
|
+
}): Promise<void> {
|
|
608
|
+
const matching = this.activeRequests.get(params.requestID)
|
|
609
|
+
if (!matching) {
|
|
610
|
+
throw new Error('Request ID not found.')
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const originalRequest = matching.request as { originator: string; permissions: GroupedPermissions }
|
|
614
|
+
const { originator, permissions: requestedPermissions } = originalRequest
|
|
615
|
+
|
|
616
|
+
// --- Validation: Ensure granted permissions are a subset of what was requested ---
|
|
617
|
+
if (
|
|
618
|
+
params.granted.spendingAuthorization &&
|
|
619
|
+
!deepEqual(params.granted.spendingAuthorization, requestedPermissions.spendingAuthorization)
|
|
620
|
+
) {
|
|
621
|
+
throw new Error('Granted spending authorization does not match the original request.')
|
|
622
|
+
}
|
|
623
|
+
if (
|
|
624
|
+
params.granted.protocolPermissions?.some(
|
|
625
|
+
g => !requestedPermissions.protocolPermissions?.find(r => deepEqual(r, g))
|
|
626
|
+
)
|
|
627
|
+
) {
|
|
628
|
+
throw new Error('Granted protocol permissions are not a subset of the original request.')
|
|
629
|
+
}
|
|
630
|
+
if (params.granted.basketAccess?.some(g => !requestedPermissions.basketAccess?.find(r => deepEqual(r, g)))) {
|
|
631
|
+
throw new Error('Granted basket access permissions are not a subset of the original request.')
|
|
632
|
+
}
|
|
633
|
+
if (
|
|
634
|
+
params.granted.certificateAccess?.some(g => !requestedPermissions.certificateAccess?.find(r => deepEqual(r, g)))
|
|
635
|
+
) {
|
|
636
|
+
throw new Error('Granted certificate access permissions are not a subset of the original request.')
|
|
637
|
+
}
|
|
638
|
+
// --- End Validation ---
|
|
639
|
+
|
|
640
|
+
const expiry = params.expiry || Math.floor(Date.now() / 1000) + 3600 * 24 * 30 // 30-day default
|
|
641
|
+
|
|
642
|
+
if (params.granted.spendingAuthorization) {
|
|
643
|
+
await this.createPermissionOnChain(
|
|
644
|
+
{
|
|
645
|
+
type: 'spending',
|
|
646
|
+
originator,
|
|
647
|
+
spending: { satoshis: params.granted.spendingAuthorization.amount },
|
|
648
|
+
reason: params.granted.spendingAuthorization.description
|
|
649
|
+
},
|
|
650
|
+
0, // No expiry for spending tokens
|
|
651
|
+
params.granted.spendingAuthorization.amount
|
|
652
|
+
)
|
|
653
|
+
}
|
|
654
|
+
for (const p of params.granted.protocolPermissions || []) {
|
|
655
|
+
await this.createPermissionOnChain(
|
|
656
|
+
{
|
|
657
|
+
type: 'protocol',
|
|
658
|
+
originator,
|
|
659
|
+
privileged: false, // No privileged protocols allowed in groups for added security.
|
|
660
|
+
protocolID: p.protocolID,
|
|
661
|
+
counterparty: p.counterparty || 'self',
|
|
662
|
+
reason: p.description
|
|
663
|
+
},
|
|
664
|
+
expiry
|
|
665
|
+
)
|
|
666
|
+
}
|
|
667
|
+
for (const b of params.granted.basketAccess || []) {
|
|
668
|
+
await this.createPermissionOnChain(
|
|
669
|
+
{ type: 'basket', originator, basket: b.basket, reason: b.description },
|
|
670
|
+
expiry
|
|
671
|
+
)
|
|
672
|
+
}
|
|
673
|
+
for (const c of params.granted.certificateAccess || []) {
|
|
674
|
+
await this.createPermissionOnChain(
|
|
675
|
+
{
|
|
676
|
+
type: 'certificate',
|
|
677
|
+
originator,
|
|
678
|
+
privileged: false, // No certificates on the privileged identity are allowed as part of groups.
|
|
679
|
+
certificate: {
|
|
680
|
+
verifier: c.verifierPublicKey,
|
|
681
|
+
certType: c.type,
|
|
682
|
+
fields: c.fields
|
|
683
|
+
},
|
|
684
|
+
reason: c.description
|
|
685
|
+
},
|
|
686
|
+
expiry
|
|
687
|
+
)
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Resolve all pending promises for this request
|
|
691
|
+
for (const p of matching.pending) {
|
|
692
|
+
p.resolve(true)
|
|
693
|
+
}
|
|
694
|
+
this.activeRequests.delete(params.requestID)
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Denies a previously requested grouped permission.
|
|
699
|
+
* @param requestID The ID of the request being denied.
|
|
700
|
+
*/
|
|
701
|
+
public async denyGroupedPermission(requestID: string): Promise<void> {
|
|
702
|
+
const matching = this.activeRequests.get(requestID)
|
|
703
|
+
if (!matching) {
|
|
704
|
+
throw new Error('Request ID not found.')
|
|
705
|
+
}
|
|
706
|
+
const err = new Error('The user has denied the request for permission.')
|
|
707
|
+
;(err as any).code = 'ERR_PERMISSION_DENIED'
|
|
708
|
+
for (const p of matching.pending) {
|
|
709
|
+
p.reject(err)
|
|
710
|
+
}
|
|
711
|
+
this.activeRequests.delete(requestID)
|
|
712
|
+
}
|
|
713
|
+
|
|
516
714
|
/* ---------------------------------------------------------------------
|
|
517
715
|
* 3) THE "ENSURE" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT
|
|
518
716
|
* --------------------------------------------------------------------- */
|
|
@@ -2127,22 +2325,6 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
2127
2325
|
...signResult,
|
|
2128
2326
|
signableTransaction: undefined
|
|
2129
2327
|
}
|
|
2130
|
-
|
|
2131
|
-
// const userWantedImmediate = args.options?.signAndProcess !== false
|
|
2132
|
-
// const weOverrode =
|
|
2133
|
-
// modifiedOptions.signAndProcess === false &&
|
|
2134
|
-
// args.options?.signAndProcess !== false
|
|
2135
|
-
|
|
2136
|
-
// // Check if all inputs already have valid unlockingScripts (no partial signatures needed)
|
|
2137
|
-
const allInputsHaveScripts = tx.inputs.every(i => i.unlockingScript)
|
|
2138
|
-
|
|
2139
|
-
// // If user wanted immediate broadcast and we forcibly suppressed it, we can finalize now by calling signAction with no additional scripts:
|
|
2140
|
-
// if (allInputsHaveScripts && userWantedImmediate && weOverrode) {
|
|
2141
|
-
|
|
2142
|
-
// }
|
|
2143
|
-
|
|
2144
|
-
// // Otherwise, return the partial transaction so the caller can do signAction.
|
|
2145
|
-
// return createResult
|
|
2146
2328
|
}
|
|
2147
2329
|
|
|
2148
2330
|
public async signAction(
|
|
@@ -2526,6 +2708,115 @@ export class WalletPermissionsManager implements WalletInterface {
|
|
|
2526
2708
|
public async waitForAuthentication(
|
|
2527
2709
|
...args: Parameters<WalletInterface['waitForAuthentication']>
|
|
2528
2710
|
): ReturnType<WalletInterface['waitForAuthentication']> {
|
|
2711
|
+
const [_, originator] = args
|
|
2712
|
+
if (this.config.seekGroupedPermission && originator) {
|
|
2713
|
+
// 1. Fetch manifest.json from the originator
|
|
2714
|
+
let groupPermissions: GroupedPermissions | undefined
|
|
2715
|
+
try {
|
|
2716
|
+
const proto = originator.startsWith('localhost:') ? 'http' : 'https'
|
|
2717
|
+
const response = await fetch(`${proto}://${originator}/manifest.json`)
|
|
2718
|
+
if (response.ok) {
|
|
2719
|
+
const manifest = await response.json()
|
|
2720
|
+
if (manifest?.babbage?.groupPermissions) {
|
|
2721
|
+
groupPermissions = manifest.babbage.groupPermissions
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
} catch (e) {
|
|
2725
|
+
// Ignore fetch/parse errors, just proceed without group permissions.
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
if (groupPermissions) {
|
|
2729
|
+
// 2. Filter out already-granted permissions
|
|
2730
|
+
const permissionsToRequest: GroupedPermissions = {
|
|
2731
|
+
protocolPermissions: [],
|
|
2732
|
+
basketAccess: [],
|
|
2733
|
+
certificateAccess: []
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
if (groupPermissions.spendingAuthorization) {
|
|
2737
|
+
const hasAuth = await this.hasSpendingAuthorization({
|
|
2738
|
+
originator,
|
|
2739
|
+
satoshis: groupPermissions.spendingAuthorization.amount
|
|
2740
|
+
})
|
|
2741
|
+
if (!hasAuth) {
|
|
2742
|
+
permissionsToRequest.spendingAuthorization = groupPermissions.spendingAuthorization
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
for (const p of groupPermissions.protocolPermissions || []) {
|
|
2747
|
+
const hasPerm = await this.hasProtocolPermission({
|
|
2748
|
+
originator,
|
|
2749
|
+
privileged: false, // Privilege is never allowed here
|
|
2750
|
+
protocolID: p.protocolID,
|
|
2751
|
+
counterparty: p.counterparty || 'self'
|
|
2752
|
+
})
|
|
2753
|
+
if (!hasPerm) {
|
|
2754
|
+
permissionsToRequest.protocolPermissions!.push(p)
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
for (const b of groupPermissions.basketAccess || []) {
|
|
2759
|
+
const hasAccess = await this.hasBasketAccess({
|
|
2760
|
+
originator,
|
|
2761
|
+
basket: b.basket
|
|
2762
|
+
})
|
|
2763
|
+
if (!hasAccess) {
|
|
2764
|
+
permissionsToRequest.basketAccess!.push(b)
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
for (const c of groupPermissions.certificateAccess || []) {
|
|
2769
|
+
const hasAccess = await this.hasCertificateAccess({
|
|
2770
|
+
originator,
|
|
2771
|
+
privileged: false, // Privilege is never allowed here for security
|
|
2772
|
+
verifier: c.verifierPublicKey,
|
|
2773
|
+
certType: c.type,
|
|
2774
|
+
fields: c.fields
|
|
2775
|
+
})
|
|
2776
|
+
if (!hasAccess) {
|
|
2777
|
+
permissionsToRequest.certificateAccess!.push(c)
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
// 3. If any permissions are left to request, start the flow
|
|
2782
|
+
const hasRequests =
|
|
2783
|
+
permissionsToRequest.spendingAuthorization ||
|
|
2784
|
+
(permissionsToRequest.protocolPermissions?.length ?? 0) > 0 ||
|
|
2785
|
+
(permissionsToRequest.basketAccess?.length ?? 0) > 0 ||
|
|
2786
|
+
(permissionsToRequest.certificateAccess?.length ?? 0) > 0
|
|
2787
|
+
|
|
2788
|
+
if (hasRequests) {
|
|
2789
|
+
const key = `group:${originator}`
|
|
2790
|
+
if (this.activeRequests.has(key)) {
|
|
2791
|
+
// Another call is already waiting, piggyback on it
|
|
2792
|
+
await new Promise<boolean>((resolve, reject) => {
|
|
2793
|
+
this.activeRequests.get(key)!.pending.push({ resolve, reject })
|
|
2794
|
+
})
|
|
2795
|
+
} else {
|
|
2796
|
+
// This is the first call, create a new request
|
|
2797
|
+
try {
|
|
2798
|
+
await new Promise<boolean>(async (resolve, reject) => {
|
|
2799
|
+
this.activeRequests.set(key, {
|
|
2800
|
+
request: { originator, permissions: permissionsToRequest },
|
|
2801
|
+
pending: [{ resolve, reject }]
|
|
2802
|
+
})
|
|
2803
|
+
|
|
2804
|
+
await this.callEvent('onGroupedPermissionRequested', {
|
|
2805
|
+
requestID: key,
|
|
2806
|
+
originator,
|
|
2807
|
+
permissions: permissionsToRequest
|
|
2808
|
+
})
|
|
2809
|
+
})
|
|
2810
|
+
} catch (e) {
|
|
2811
|
+
// Permission was denied, re-throw to stop execution
|
|
2812
|
+
throw e
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
// Finally, after handling grouped permissions, call the underlying method.
|
|
2529
2820
|
return this.underlying.waitForAuthentication(...args)
|
|
2530
2821
|
}
|
|
2531
2822
|
|
|
@@ -188,7 +188,7 @@ describe('WalletPermissionsManager - Initialization & Configuration', () => {
|
|
|
188
188
|
'onSpendingAuthorizationRequested',
|
|
189
189
|
jest.fn(x => {
|
|
190
190
|
manager.grantPermission({ requestID: x.requestID, ephemeral: true })
|
|
191
|
-
})
|
|
191
|
+
}) as any
|
|
192
192
|
)
|
|
193
193
|
|
|
194
194
|
// Non-admin origin tries to createAction specifying a basket
|
|
@@ -6,7 +6,7 @@ import { WalletMonitorTask } from './WalletMonitorTask'
|
|
|
6
6
|
* This task polls for new block headers performing two essential functions:
|
|
7
7
|
* 1. The arrival of a new block is the right time to check for proofs for recently broadcast transactions.
|
|
8
8
|
* 2. The height of the block is used to limit which proofs are accepted with the aim of avoiding re-orged proofs.
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* The most common new block orphan is one which is almost immediately orphaned.
|
|
11
11
|
* Waiting a minute before pursuing proof requests avoids almost all the re-org work that could be done.
|
|
12
12
|
* Thus this task queues new headers for one cycle.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"abortAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/abortAction.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/createAction.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createActionToGenerateBeefs.man.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/createActionToGenerateBeefs.man.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internalizeAction.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/internalizeAction.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"relinquishOutput.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/action/relinquishOutput.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Wallet.constructor.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/construct/Wallet.constructor.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listActions.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listActions.test.ts"],"names":[],"mappings":"AAWA,OAAO,qBAAqB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listActions2.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listActions2.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listCertificates.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listCertificates.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"listOutputs.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/list/listOutputs.test.ts"],"names":[],"mappings":"AAUA,OAAO,qBAAqB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Wallet.sync.test.d.ts","sourceRoot":"","sources":["../../../../test/wallet/sync/Wallet.sync.test.ts"],"names":[],"mappings":""}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|