@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.
Files changed (76) hide show
  1. package/lib/cloud-wallet.d.ts +79 -3
  2. package/lib/cloud-wallet.d.ts.map +1 -1
  3. package/lib/cloud-wallet.js +147 -14
  4. package/lib/cloud-wallet.js.map +1 -1
  5. package/lib/credential-provider.d.ts.map +1 -1
  6. package/lib/credential-provider.js +10 -4
  7. package/lib/credential-provider.js.map +1 -1
  8. package/lib/delegation/delegation-chain.d.ts +8 -0
  9. package/lib/delegation/delegation-chain.d.ts.map +1 -0
  10. package/lib/delegation/delegation-chain.js +33 -0
  11. package/lib/delegation/delegation-chain.js.map +1 -0
  12. package/lib/delegation/delegation-fixtures.d.ts +69 -0
  13. package/lib/delegation/delegation-fixtures.d.ts.map +1 -0
  14. package/lib/delegation/delegation-fixtures.js +553 -0
  15. package/lib/delegation/delegation-fixtures.js.map +1 -0
  16. package/lib/delegation/delegation-issuance.d.ts +19 -0
  17. package/lib/delegation/delegation-issuance.d.ts.map +1 -0
  18. package/lib/delegation/delegation-issuance.js +60 -0
  19. package/lib/delegation/delegation-issuance.js.map +1 -0
  20. package/lib/delegation/delegation-offer.d.ts +84 -0
  21. package/lib/delegation/delegation-offer.d.ts.map +1 -0
  22. package/lib/delegation/delegation-offer.js +349 -0
  23. package/lib/delegation/delegation-offer.js.map +1 -0
  24. package/lib/delegation/delegation-policy-validation.d.ts +28 -0
  25. package/lib/delegation/delegation-policy-validation.d.ts.map +1 -0
  26. package/lib/delegation/delegation-policy-validation.js +170 -0
  27. package/lib/delegation/delegation-policy-validation.js.map +1 -0
  28. package/lib/delegation/delegation-policy.d.ts +21 -0
  29. package/lib/delegation/delegation-policy.d.ts.map +1 -0
  30. package/lib/delegation/delegation-policy.js +73 -0
  31. package/lib/delegation/delegation-policy.js.map +1 -0
  32. package/lib/delegation/delegation-tree.d.ts +17 -0
  33. package/lib/delegation/delegation-tree.d.ts.map +1 -0
  34. package/lib/delegation/delegation-tree.js +58 -0
  35. package/lib/delegation/delegation-tree.js.map +1 -0
  36. package/lib/delegation/delegation-types.d.ts +56 -0
  37. package/lib/delegation/delegation-types.d.ts.map +1 -0
  38. package/lib/delegation/delegation-types.js +3 -0
  39. package/lib/delegation/delegation-types.js.map +1 -0
  40. package/lib/delegation/delegation-utils.d.ts +3 -0
  41. package/lib/delegation/delegation-utils.d.ts.map +1 -0
  42. package/lib/delegation/delegation-utils.js +10 -0
  43. package/lib/delegation/delegation-utils.js.map +1 -0
  44. package/lib/did-provider.d.ts +2 -1
  45. package/lib/did-provider.d.ts.map +1 -1
  46. package/lib/did-provider.js +11 -7
  47. package/lib/did-provider.js.map +1 -1
  48. package/lib/message-provider.js +1 -1
  49. package/lib/message-provider.js.map +1 -1
  50. package/lib/verification-controller.d.ts +30 -11
  51. package/lib/verification-controller.d.ts.map +1 -1
  52. package/lib/verification-controller.js +372 -68
  53. package/lib/verification-controller.js.map +1 -1
  54. package/package.json +3 -3
  55. package/src/cloud-wallet.test.js +369 -0
  56. package/src/cloud-wallet.ts +206 -18
  57. package/src/credential-provider.ts +13 -4
  58. package/src/delegation/delegation-chain.test.ts +64 -0
  59. package/src/delegation/delegation-chain.ts +34 -0
  60. package/src/delegation/delegation-fixtures.ts +552 -0
  61. package/src/delegation/delegation-issuance.ts +92 -0
  62. package/src/delegation/delegation-offer.ts +488 -0
  63. package/src/delegation/delegation-policy-validation.test.ts +237 -0
  64. package/src/delegation/delegation-policy-validation.ts +281 -0
  65. package/src/delegation/delegation-policy.ts +100 -0
  66. package/src/delegation/delegation-tree.test.ts +110 -0
  67. package/src/delegation/delegation-tree.ts +60 -0
  68. package/src/delegation/delegation-types.ts +65 -0
  69. package/src/delegation/delegation-utils.ts +10 -0
  70. package/src/did-provider.ts +10 -6
  71. package/src/globals.d.ts +6 -0
  72. package/src/message-provider.ts +1 -1
  73. package/src/verification-controller.test.ts +23 -0
  74. package/src/verification-controller.ts +534 -82
  75. package/tsconfig.build.json +2 -1
  76. 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
+ }
@@ -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 getAll({wallet}) {
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 getAll({ wallet });
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 getAll({wallet});
203
+ const didDocs = await getAllDIDs({wallet});
200
204
  const keyPairs = [];
201
205
  for (const didDoc of didDocs) {
202
- const keyPair = await wallet.getDocumentById(didDoc.correlation[0]);
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 getAll({wallet});
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 getAll({wallet});
342
+ return getAllDIDs({wallet});
339
343
  },
340
344
  /**
341
345
  * Retrieves all keypairs associated with DIDs in the wallet
@@ -0,0 +1,6 @@
1
+ // CryptoKey is available globally in Node.js 15+ but TypeScript needs
2
+ // the DOM lib to recognize it. Declare it here to avoid pulling in all DOM types.
3
+ declare global {
4
+ type CryptoKey = import('crypto').webcrypto.CryptoKey;
5
+ }
6
+ export {};
@@ -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,