@docknetwork/wallet-sdk-core 1.7.6 → 1.9.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/lib/cloud-wallet.d.ts +79 -3
- package/lib/cloud-wallet.d.ts.map +1 -1
- package/lib/cloud-wallet.js +147 -14
- package/lib/cloud-wallet.js.map +1 -1
- package/lib/credential-provider.d.ts.map +1 -1
- package/lib/credential-provider.js +10 -4
- package/lib/credential-provider.js.map +1 -1
- package/lib/delegation/delegation-chain.d.ts +8 -0
- package/lib/delegation/delegation-chain.d.ts.map +1 -0
- package/lib/delegation/delegation-chain.js +33 -0
- package/lib/delegation/delegation-chain.js.map +1 -0
- package/lib/delegation/delegation-fixtures.d.ts +69 -0
- package/lib/delegation/delegation-fixtures.d.ts.map +1 -0
- package/lib/delegation/delegation-fixtures.js +553 -0
- package/lib/delegation/delegation-fixtures.js.map +1 -0
- package/lib/delegation/delegation-issuance.d.ts +19 -0
- package/lib/delegation/delegation-issuance.d.ts.map +1 -0
- package/lib/delegation/delegation-issuance.js +60 -0
- package/lib/delegation/delegation-issuance.js.map +1 -0
- package/lib/delegation/delegation-offer.d.ts +84 -0
- package/lib/delegation/delegation-offer.d.ts.map +1 -0
- package/lib/delegation/delegation-offer.js +349 -0
- package/lib/delegation/delegation-offer.js.map +1 -0
- package/lib/delegation/delegation-policy-validation.d.ts +28 -0
- package/lib/delegation/delegation-policy-validation.d.ts.map +1 -0
- package/lib/delegation/delegation-policy-validation.js +170 -0
- package/lib/delegation/delegation-policy-validation.js.map +1 -0
- package/lib/delegation/delegation-policy.d.ts +21 -0
- package/lib/delegation/delegation-policy.d.ts.map +1 -0
- package/lib/delegation/delegation-policy.js +73 -0
- package/lib/delegation/delegation-policy.js.map +1 -0
- package/lib/delegation/delegation-tree.d.ts +17 -0
- package/lib/delegation/delegation-tree.d.ts.map +1 -0
- package/lib/delegation/delegation-tree.js +58 -0
- package/lib/delegation/delegation-tree.js.map +1 -0
- package/lib/delegation/delegation-types.d.ts +56 -0
- package/lib/delegation/delegation-types.d.ts.map +1 -0
- package/lib/delegation/delegation-types.js +3 -0
- package/lib/delegation/delegation-types.js.map +1 -0
- package/lib/delegation/delegation-utils.d.ts +3 -0
- package/lib/delegation/delegation-utils.d.ts.map +1 -0
- package/lib/delegation/delegation-utils.js +10 -0
- package/lib/delegation/delegation-utils.js.map +1 -0
- package/lib/did-provider.d.ts +2 -1
- package/lib/did-provider.d.ts.map +1 -1
- package/lib/did-provider.js +11 -7
- package/lib/did-provider.js.map +1 -1
- package/lib/message-provider.js +1 -1
- package/lib/message-provider.js.map +1 -1
- package/lib/verification-controller.d.ts +30 -11
- package/lib/verification-controller.d.ts.map +1 -1
- package/lib/verification-controller.js +372 -68
- package/lib/verification-controller.js.map +1 -1
- package/package.json +3 -3
- package/src/cloud-wallet.test.js +369 -0
- package/src/cloud-wallet.ts +206 -18
- package/src/credential-provider.ts +13 -4
- package/src/delegation/delegation-chain.test.ts +64 -0
- package/src/delegation/delegation-chain.ts +34 -0
- package/src/delegation/delegation-fixtures.ts +552 -0
- package/src/delegation/delegation-issuance.ts +92 -0
- package/src/delegation/delegation-offer.ts +488 -0
- package/src/delegation/delegation-policy-validation.test.ts +237 -0
- package/src/delegation/delegation-policy-validation.ts +281 -0
- package/src/delegation/delegation-policy.ts +100 -0
- package/src/delegation/delegation-tree.test.ts +110 -0
- package/src/delegation/delegation-tree.ts +60 -0
- package/src/delegation/delegation-types.ts +65 -0
- package/src/delegation/delegation-utils.ts +10 -0
- package/src/did-provider.ts +10 -6
- package/src/globals.d.ts +6 -0
- package/src/message-provider.ts +1 -1
- package/src/verification-controller.test.ts +23 -0
- package/src/verification-controller.ts +534 -82
- package/tsconfig.build.json +2 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {delegationPolicyTravelAgent} from './delegation-fixtures';
|
|
2
|
+
import {
|
|
3
|
+
buildDelegationRoleTree,
|
|
4
|
+
getRoleNodeById,
|
|
5
|
+
getRemainingDelegationDepth,
|
|
6
|
+
} from './delegation-tree';
|
|
7
|
+
|
|
8
|
+
describe('Delegation tree', () => {
|
|
9
|
+
it('builds a delegation tree from the delegation policy', () => {
|
|
10
|
+
const delegationTree = buildDelegationRoleTree(delegationPolicyTravelAgent);
|
|
11
|
+
|
|
12
|
+
expect(delegationTree).toMatchObject({
|
|
13
|
+
label: 'Travel Agent 1',
|
|
14
|
+
roleId: 'e79c0d16-8739-4e54-94d7-53d9f1c97c71',
|
|
15
|
+
level: 1,
|
|
16
|
+
children: [
|
|
17
|
+
{
|
|
18
|
+
label: 'Corporate Account Manager',
|
|
19
|
+
roleId: '8e5abc88-7006-42ae-ae48-9e34f8f66124',
|
|
20
|
+
level: 2,
|
|
21
|
+
children: [
|
|
22
|
+
{
|
|
23
|
+
label: 'Booking Specialist',
|
|
24
|
+
roleId: '6375baa1-a52d-4838-9100-3facea02ba49',
|
|
25
|
+
level: 3,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Hotel Sub-agent',
|
|
29
|
+
roleId: '16f68474-bf3b-4494-9fe5-f141a7d74a33',
|
|
30
|
+
level: 3,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
label: 'Flight Sub-agent',
|
|
34
|
+
roleId: 'c1bd8821-c645-4dd6-ab07-9bc087755db9',
|
|
35
|
+
level: 3,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: 'Car Rental Sub-agent',
|
|
41
|
+
roleId: '9726317c-cb60-4ae7-a828-e334b10f6f52',
|
|
42
|
+
level: 2,
|
|
43
|
+
children: [
|
|
44
|
+
{
|
|
45
|
+
label: 'Flight Sub-agent',
|
|
46
|
+
roleId: '888aeee9-c3ed-469b-86bd-910490c9aa20',
|
|
47
|
+
level: 3,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: 'Booking Executor',
|
|
51
|
+
roleId: 'd39f29c4-fc3e-4b5d-9eae-9f576576e4fb',
|
|
52
|
+
level: 3,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('getRoleNodeById', () => {
|
|
61
|
+
it('returns level 1 for the root role', () => {
|
|
62
|
+
const tree = buildDelegationRoleTree(delegationPolicyTravelAgent);
|
|
63
|
+
const node = getRoleNodeById(
|
|
64
|
+
'e79c0d16-8739-4e54-94d7-53d9f1c97c71',
|
|
65
|
+
tree,
|
|
66
|
+
);
|
|
67
|
+
expect(node?.level).toBe(1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('returns the level for nested roles', () => {
|
|
71
|
+
const tree = buildDelegationRoleTree(delegationPolicyTravelAgent);
|
|
72
|
+
expect(
|
|
73
|
+
getRoleNodeById('8e5abc88-7006-42ae-ae48-9e34f8f66124', tree)?.level,
|
|
74
|
+
).toBe(2);
|
|
75
|
+
expect(
|
|
76
|
+
getRoleNodeById('6375baa1-a52d-4838-9100-3facea02ba49', tree)?.level,
|
|
77
|
+
).toBe(3);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('returns null for unknown roleId', () => {
|
|
81
|
+
const tree = buildDelegationRoleTree(delegationPolicyTravelAgent);
|
|
82
|
+
expect(getRoleNodeById('does-not-exist', tree)).toBeNull();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('getRemainingDelegationDepth', () => {
|
|
87
|
+
it('subtracts the role level from maxDelegationDepth', () => {
|
|
88
|
+
const tree = buildDelegationRoleTree(delegationPolicyTravelAgent);
|
|
89
|
+
const max =
|
|
90
|
+
delegationPolicyTravelAgent.ruleset.overallConstraints
|
|
91
|
+
.maxDelegationDepth;
|
|
92
|
+
|
|
93
|
+
const root = getRoleNodeById(
|
|
94
|
+
'e79c0d16-8739-4e54-94d7-53d9f1c97c71',
|
|
95
|
+
tree,
|
|
96
|
+
)!;
|
|
97
|
+
expect(getRemainingDelegationDepth(root, delegationPolicyTravelAgent)).toBe(
|
|
98
|
+
max - 1,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const leaf = getRoleNodeById(
|
|
102
|
+
'6375baa1-a52d-4838-9100-3facea02ba49',
|
|
103
|
+
tree,
|
|
104
|
+
)!;
|
|
105
|
+
expect(getRemainingDelegationDepth(leaf, delegationPolicyTravelAgent)).toBe(
|
|
106
|
+
max - 3,
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import assert from 'assert';
|
|
2
|
+
import {DelegationPolicy, RoleNode, Role} from './delegation-types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Build a tree structure representing the roles in a delegation policy, based on their parent-child relationships
|
|
6
|
+
* @param policy - The delegation policy containing the roles and their relationships
|
|
7
|
+
* @returns A tree structure representing the roles in the delegation policy, where each node contains the role name, roleId, level in the hierarchy, and its children roles (if any)
|
|
8
|
+
*/
|
|
9
|
+
export function buildDelegationRoleTree(policy: DelegationPolicy): RoleNode {
|
|
10
|
+
const root = policy.ruleset.roles.find(r => r.parentRoleId === null);
|
|
11
|
+
assert(root, 'Delegation policy has no root role');
|
|
12
|
+
|
|
13
|
+
const childrenByParent = new Map<string, Role[]>();
|
|
14
|
+
for (const role of policy.ruleset.roles) {
|
|
15
|
+
if (role.parentRoleId === null) continue;
|
|
16
|
+
const siblings = childrenByParent.get(role.parentRoleId) ?? [];
|
|
17
|
+
siblings.push(role);
|
|
18
|
+
childrenByParent.set(role.parentRoleId, siblings);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const toNode = (role: Role, level: number): RoleNode => {
|
|
22
|
+
const children = childrenByParent.get(role.roleId);
|
|
23
|
+
const node: RoleNode = {level, ...role};
|
|
24
|
+
if (children?.length) {
|
|
25
|
+
node.children = children.map(c => toNode(c, level + 1));
|
|
26
|
+
}
|
|
27
|
+
return node;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return toNode(root, 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getRoleNodeById(
|
|
34
|
+
roleId: string,
|
|
35
|
+
node: RoleNode,
|
|
36
|
+
): RoleNode | null {
|
|
37
|
+
if (node.roleId === roleId) return node;
|
|
38
|
+
if (!node.children) return null;
|
|
39
|
+
|
|
40
|
+
for (const child of node.children) {
|
|
41
|
+
const result = getRoleNodeById(roleId, child);
|
|
42
|
+
if (result) return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Compute how many more times the holder of `roleId` may further delegate,
|
|
50
|
+
* based on the policy's maxDelegationDepth and the holder's depth in the tree.
|
|
51
|
+
* @param policy - The delegation policy
|
|
52
|
+
* @param roleId - The roleId of the holder
|
|
53
|
+
* @returns The remaining delegation depth, or null if the role is not in the policy
|
|
54
|
+
*/
|
|
55
|
+
export function getRemainingDelegationDepth(
|
|
56
|
+
roleNode: RoleNode,
|
|
57
|
+
policy: DelegationPolicy,
|
|
58
|
+
): number | null {
|
|
59
|
+
return policy.ruleset.overallConstraints.maxDelegationDepth - roleNode.level;
|
|
60
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {Credential} from '../credential-provider';
|
|
2
|
+
|
|
3
|
+
export type JsonSchema = Record<string, unknown>;
|
|
4
|
+
|
|
5
|
+
export type CapabilityGrant = {
|
|
6
|
+
capability: string;
|
|
7
|
+
schema: JsonSchema;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type Capability = {
|
|
11
|
+
name: string;
|
|
12
|
+
schema: JsonSchema;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type Role = {
|
|
16
|
+
label: string;
|
|
17
|
+
roleId: string;
|
|
18
|
+
attributes: string[];
|
|
19
|
+
parentRoleId: string | null;
|
|
20
|
+
capabilityGrants: CapabilityGrant[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type DelegatedCredentialLifetime = {
|
|
24
|
+
unit: string;
|
|
25
|
+
value: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type OverallConstraints = {
|
|
29
|
+
maxDelegationDepth: number;
|
|
30
|
+
delegatedCredentialLifetime: DelegatedCredentialLifetime;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type Ruleset = {
|
|
34
|
+
roles: Role[];
|
|
35
|
+
capabilities: Capability[];
|
|
36
|
+
delegationTarget: string;
|
|
37
|
+
overallConstraints: OverallConstraints;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type DelegationPolicy = {
|
|
41
|
+
id: string;
|
|
42
|
+
type: 'DelegationPolicy';
|
|
43
|
+
ruleset: Ruleset;
|
|
44
|
+
createdAt: string;
|
|
45
|
+
name?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type RoleNode = Role & {
|
|
49
|
+
level: number;
|
|
50
|
+
children?: RoleNode[];
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type DelegationDetails = {
|
|
54
|
+
delegationPolicy: DelegationPolicy | null;
|
|
55
|
+
delegationChain: Credential[];
|
|
56
|
+
delegatedBy: {
|
|
57
|
+
role: Role | null;
|
|
58
|
+
issuerName: string;
|
|
59
|
+
issuerDid: string;
|
|
60
|
+
};
|
|
61
|
+
role: RoleNode | null;
|
|
62
|
+
roleTree: RoleNode | null;
|
|
63
|
+
remainingDelegationDepth: number | null;
|
|
64
|
+
delegationOptions: RoleNode[];
|
|
65
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {CapabilityGrant} from './delegation-types';
|
|
2
|
+
|
|
3
|
+
export const DELEGATION_CONTEXT = 'https://ld.truvera.io/credentials/delegation';
|
|
4
|
+
|
|
5
|
+
export function isDelegatableCredential(credential): boolean {
|
|
6
|
+
return (
|
|
7
|
+
Array.isArray(credential?.['@context']) &&
|
|
8
|
+
credential['@context'].includes(DELEGATION_CONTEXT)
|
|
9
|
+
);
|
|
10
|
+
}
|
package/src/did-provider.ts
CHANGED
|
@@ -174,7 +174,7 @@ export async function createDIDKey({wallet, name, derivePath=undefined, type=und
|
|
|
174
174
|
* Internal function to retrieve all DIDs stored in the wallet
|
|
175
175
|
* @private
|
|
176
176
|
*/
|
|
177
|
-
export async function
|
|
177
|
+
export async function getAllDIDs({wallet}) {
|
|
178
178
|
assert(!!wallet, 'wallet is required');
|
|
179
179
|
const dids = await wallet.getDocumentsByType('DIDResolutionResponse');
|
|
180
180
|
return dids;
|
|
@@ -186,20 +186,24 @@ export async function getAll({wallet}) {
|
|
|
186
186
|
*/
|
|
187
187
|
export async function getDefaultDID({wallet}) {
|
|
188
188
|
assert(!!wallet, 'wallet is required');
|
|
189
|
-
const allDids = await
|
|
189
|
+
const allDids = await getAllDIDs({ wallet });
|
|
190
190
|
return allDids[0]?.didDocument.id;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
export async function getDIDKeyPair(wallet, didDoc) {
|
|
194
|
+
return wallet.getDocumentById(didDoc.correlation[0])
|
|
195
|
+
}
|
|
196
|
+
|
|
193
197
|
/**
|
|
194
198
|
* Internal function to retrieve all keypairs associated with DIDs
|
|
195
199
|
* @private
|
|
196
200
|
*/
|
|
197
201
|
export async function getDIDKeyPairs({wallet}) {
|
|
198
202
|
assert(!!wallet, 'wallet is required');
|
|
199
|
-
const didDocs = await
|
|
203
|
+
const didDocs = await getAllDIDs({wallet});
|
|
200
204
|
const keyPairs = [];
|
|
201
205
|
for (const didDoc of didDocs) {
|
|
202
|
-
const keyPair = await wallet
|
|
206
|
+
const keyPair = await getDIDKeyPair(wallet, didDoc);
|
|
203
207
|
keyPairs.push(keyPair);
|
|
204
208
|
}
|
|
205
209
|
return keyPairs;
|
|
@@ -208,7 +212,7 @@ export async function getDIDKeyPairs({wallet}) {
|
|
|
208
212
|
|
|
209
213
|
export async function ensureDID({wallet}) {
|
|
210
214
|
assert(!!wallet, 'wallet is required');
|
|
211
|
-
const dids = await
|
|
215
|
+
const dids = await getAllDIDs({wallet});
|
|
212
216
|
if (dids.length === 0) {
|
|
213
217
|
return createDIDKey({wallet, name: 'Default DID'});
|
|
214
218
|
}
|
|
@@ -335,7 +339,7 @@ export function createDIDProvider({wallet}): IDIDProvider {
|
|
|
335
339
|
* console.log(`Found ${allDIDs.length} DIDs in wallet`);
|
|
336
340
|
*/
|
|
337
341
|
async getAll() {
|
|
338
|
-
return
|
|
342
|
+
return getAllDIDs({wallet});
|
|
339
343
|
},
|
|
340
344
|
/**
|
|
341
345
|
* Retrieves all keypairs associated with DIDs in the wallet
|
package/src/globals.d.ts
ADDED
package/src/message-provider.ts
CHANGED
|
@@ -151,7 +151,6 @@ export function createMessageProvider({
|
|
|
151
151
|
|
|
152
152
|
async function fetchMessages() {
|
|
153
153
|
try {
|
|
154
|
-
logger.debug('Fetching messages');
|
|
155
154
|
const fetchMessagesStartTime = Date.now();
|
|
156
155
|
const keyPairDocs = await getKeyPairDocs(didProvider);
|
|
157
156
|
let encryptedMessages = await relayService.getMessages({
|
|
@@ -227,6 +226,7 @@ export function createMessageProvider({
|
|
|
227
226
|
|
|
228
227
|
return encryptedMessages;
|
|
229
228
|
} catch (error) {
|
|
229
|
+
logger.error(`Failed to fetch messages: ${error.message}`);
|
|
230
230
|
captureException(error);
|
|
231
231
|
throw new Error(`Failed to fetch messages: ${error.message}`);
|
|
232
232
|
}
|
|
@@ -90,6 +90,29 @@ describe('Verification provider', () => {
|
|
|
90
90
|
expect(result.isValid).toBe(true);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
+
it('expect to create a default presentation using filtered credentials', async () => {
|
|
94
|
+
const controller = createVerificationController({
|
|
95
|
+
wallet,
|
|
96
|
+
didProvider,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await controller.start({
|
|
100
|
+
template: anyCredentialProofRequest,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const credentials = controller.getFilteredCredentials();
|
|
104
|
+
|
|
105
|
+
const presentation = await controller.createDefaultPresentation();
|
|
106
|
+
|
|
107
|
+
expect(presentation.credentials[0]).toStrictEqual(credentials[0]);
|
|
108
|
+
expect(presentation.type).toEqual(['VerifiablePresentation']);
|
|
109
|
+
|
|
110
|
+
// validate the presentation
|
|
111
|
+
const result = await controller.evaluatePresentation(presentation);
|
|
112
|
+
|
|
113
|
+
expect(result.isValid).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
93
116
|
it('expect to generate presentation iiw credential', async () => {
|
|
94
117
|
const controller = createVerificationController({
|
|
95
118
|
wallet,
|