@docknetwork/wallet-sdk-core 0.4.19 → 0.4.22
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/account-provider.d.ts +1 -1
- package/lib/account-provider.js +1 -1
- package/lib/biometric-provider.d.ts +1 -1
- package/lib/biometric-provider.d.ts.map +1 -1
- package/lib/biometric-provider.js +1 -0
- package/lib/biometric-provider.js.map +1 -1
- package/lib/cloud-wallet.d.ts +19 -0
- package/lib/cloud-wallet.d.ts.map +1 -0
- package/lib/cloud-wallet.js +150 -0
- package/lib/cloud-wallet.js.map +1 -0
- package/lib/credential-provider.d.ts +10 -0
- package/lib/credential-provider.d.ts.map +1 -1
- package/lib/credential-provider.js +31 -10
- package/lib/credential-provider.js.map +1 -1
- package/lib/credentials/oidvc.d.ts +14 -0
- package/lib/credentials/oidvc.d.ts.map +1 -0
- package/lib/credentials/oidvc.js +84 -0
- package/lib/credentials/oidvc.js.map +1 -0
- package/lib/did-provider.js +1 -1
- package/lib/ecosystem-tools.js +2 -2
- package/lib/helpers.d.ts +1 -0
- package/lib/helpers.d.ts.map +1 -1
- package/lib/helpers.js +9 -1
- package/lib/helpers.js.map +1 -1
- package/lib/message-provider.d.ts +2 -19
- package/lib/message-provider.d.ts.map +1 -1
- package/lib/message-provider.js +69 -13
- package/lib/message-provider.js.map +1 -1
- package/lib/messages/message-helpers.js +2 -2
- package/lib/messages/message-helpers.js.map +1 -1
- package/lib/network-resolver.d.ts +2 -1
- package/lib/network-resolver.d.ts.map +1 -1
- package/lib/network-resolver.js +37 -6
- package/lib/network-resolver.js.map +1 -1
- package/lib/types.d.ts +10 -7
- package/lib/types.d.ts.map +1 -1
- package/lib/v1-helpers.js +9 -9
- package/lib/v1-helpers.js.map +1 -1
- package/lib/verification-controller.d.ts.map +1 -1
- package/lib/verification-controller.js +12 -8
- package/lib/verification-controller.js.map +1 -1
- package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts +7 -0
- package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts.map +1 -1
- package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js +11 -2
- package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js.map +1 -1
- package/lib/wallet-wasm.js +5 -5
- package/lib/wallet-wasm.js.map +1 -1
- package/lib/wallet.d.ts +1 -1
- package/lib/wallet.d.ts.map +1 -1
- package/lib/wallet.js +17 -53
- package/lib/wallet.js.map +1 -1
- package/package.json +6 -6
- package/src/biometric-provider.ts +1 -0
- package/src/cloud-wallet.ts +185 -0
- package/src/credential-provider.test.ts +11 -5
- package/src/credential-provider.ts +77 -25
- package/src/credentials/oidvc.test.ts +124 -0
- package/src/credentials/oidvc.ts +115 -0
- package/src/did-provider.test.ts +19 -11
- package/src/fixtures/biometrics-credential-bbs-revocation.json +2 -2
- package/src/fixtures/iiw-credential.json +1 -1
- package/src/fixtures/iiw-template.json +2 -2
- package/src/helpers.ts +10 -0
- package/src/message-provider.test.ts +9 -3
- package/src/message-provider.ts +97 -25
- package/src/messages/message-helpers.test.ts +15 -0
- package/src/messages/message-helpers.ts +2 -2
- package/src/network-resolver.test.ts +73 -4
- package/src/network-resolver.ts +41 -6
- package/src/types.ts +11 -5
- package/src/v1-helpers.ts +6 -6
- package/src/verification-controller.test.ts +8 -3
- package/src/verification-controller.ts +10 -6
- package/src/wallet-to-wallet-verification/walletToWalletVerificationProvider.ts +15 -0
- package/src/wallet-wasm.ts +1 -1
- package/src/wallet.test.ts +4 -1
- package/src/wallet.ts +22 -75
- package/tsconfig.build.tsbuildinfo +1 -1
- package/LICENSE +0 -39
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
|
|
2
2
|
import {IWallet} from './types';
|
|
3
3
|
import assert from 'assert';
|
|
4
|
-
import {
|
|
4
|
+
import {dockService} from '@docknetwork/wallet-sdk-wasm/src/services/dock';
|
|
5
|
+
import {acquireOpenIDCredentialFromURI} from './credentials/oidvc';
|
|
6
|
+
import {IDIDProvider} from './did-provider';
|
|
5
7
|
|
|
6
8
|
export type Credential = any;
|
|
7
9
|
|
|
@@ -12,8 +14,15 @@ export interface ICredentialProvider {
|
|
|
12
14
|
isBBSPlusCredential(credential: any): boolean;
|
|
13
15
|
isValid(credential: any, forceFetch?: boolean): Promise<boolean>;
|
|
14
16
|
addCredential(credential: any): Promise<Credential>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
importCredentialFromURI(
|
|
18
|
+
params: importCredentialFromUriParams,
|
|
19
|
+
): Promise<Credential>;
|
|
20
|
+
syncCredentialStatus(
|
|
21
|
+
params: SyncCredentialStatusParams,
|
|
22
|
+
): Promise<CredentialStatusDocument[]>;
|
|
23
|
+
getCredentialStatus(
|
|
24
|
+
credential: Credential,
|
|
25
|
+
): Promise<{status: string; error?: string}>;
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
export function isBBSPlusCredential(credential) {
|
|
@@ -27,8 +36,38 @@ export function isBBSPlusCredential(credential) {
|
|
|
27
36
|
);
|
|
28
37
|
}
|
|
29
38
|
|
|
39
|
+
type importCredentialFromUriParams = {
|
|
40
|
+
uri: string;
|
|
41
|
+
didProvider: IDIDProvider;
|
|
42
|
+
getAuthCode?: (authorizationURL: string) => Promise<string>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export async function importCredentialFromURI({
|
|
46
|
+
uri,
|
|
47
|
+
wallet,
|
|
48
|
+
didProvider,
|
|
49
|
+
getAuthCode,
|
|
50
|
+
}: importCredentialFromUriParams & {
|
|
51
|
+
wallet: IWallet;
|
|
52
|
+
}) {
|
|
53
|
+
// TODO: unify the impl with the existing import credential flow
|
|
54
|
+
// if the URI is an OpenID credential offer, use the OpenID flow
|
|
55
|
+
// if the URI is a dock credential, then get user password and import that
|
|
56
|
+
// we can add support for other types of credentials later
|
|
57
|
+
const credential = await acquireOpenIDCredentialFromURI({
|
|
58
|
+
didProvider,
|
|
59
|
+
uri,
|
|
60
|
+
getAuthCode,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await addCredential({wallet, credential});
|
|
64
|
+
}
|
|
65
|
+
|
|
30
66
|
export function isCredentialExpired(credential) {
|
|
31
|
-
return
|
|
67
|
+
return (
|
|
68
|
+
!!credential.expirationDate &&
|
|
69
|
+
new Date(credential.expirationDate) < new Date()
|
|
70
|
+
);
|
|
32
71
|
}
|
|
33
72
|
|
|
34
73
|
/**
|
|
@@ -52,10 +91,12 @@ export async function isValid({
|
|
|
52
91
|
};
|
|
53
92
|
}
|
|
54
93
|
|
|
55
|
-
const membershipWitness =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
94
|
+
const membershipWitness =
|
|
95
|
+
credential[ACUMM_WITNESS_PROP_KEY] ||
|
|
96
|
+
(await getMembershipWitness({
|
|
97
|
+
credentialId: credential.id,
|
|
98
|
+
wallet,
|
|
99
|
+
}));
|
|
59
100
|
|
|
60
101
|
delete credential[ACUMM_WITNESS_PROP_KEY];
|
|
61
102
|
|
|
@@ -64,10 +105,13 @@ export async function isValid({
|
|
|
64
105
|
membershipWitness,
|
|
65
106
|
});
|
|
66
107
|
|
|
67
|
-
const {
|
|
68
|
-
|
|
108
|
+
const {verified, error} = verificationResult;
|
|
109
|
+
|
|
69
110
|
if (!verified) {
|
|
70
|
-
if (
|
|
111
|
+
if (
|
|
112
|
+
typeof error === 'string' &&
|
|
113
|
+
error.toLowerCase().includes('revocation')
|
|
114
|
+
) {
|
|
71
115
|
return {
|
|
72
116
|
status: CredentialStatus.Revoked,
|
|
73
117
|
error,
|
|
@@ -113,7 +157,7 @@ export async function addCredential({wallet, credential}) {
|
|
|
113
157
|
});
|
|
114
158
|
}
|
|
115
159
|
|
|
116
|
-
syncCredentialStatus({
|
|
160
|
+
syncCredentialStatus({wallet, credentialIds: [credential.id]});
|
|
117
161
|
|
|
118
162
|
return response;
|
|
119
163
|
}
|
|
@@ -123,7 +167,6 @@ async function getMembershipWitness({credentialId, wallet}) {
|
|
|
123
167
|
return document?.value;
|
|
124
168
|
}
|
|
125
169
|
|
|
126
|
-
|
|
127
170
|
export const CredentialStatus = {
|
|
128
171
|
Invalid: 'invalid',
|
|
129
172
|
Expired: 'expired',
|
|
@@ -134,28 +177,32 @@ export const CredentialStatus = {
|
|
|
134
177
|
|
|
135
178
|
type SyncCredentialStatusParams = {
|
|
136
179
|
// Optional credential IDs to sync
|
|
137
|
-
credentialIds?: string[]
|
|
180
|
+
credentialIds?: string[];
|
|
138
181
|
// Skip the cache and re-fetch from the chain
|
|
139
|
-
forceFetch?: boolean
|
|
182
|
+
forceFetch?: boolean;
|
|
140
183
|
};
|
|
141
184
|
|
|
142
185
|
type CredentialStatusDocument = {
|
|
143
186
|
id: string;
|
|
144
187
|
status: string;
|
|
145
188
|
error: string;
|
|
146
|
-
}
|
|
189
|
+
};
|
|
147
190
|
|
|
148
191
|
/**
|
|
149
192
|
* Fetch credential status from the chain and update the wallet
|
|
150
193
|
* Store a new document <credentialId>#status in the wallet
|
|
151
194
|
* Returns a list of CredentialStatusDocument
|
|
152
|
-
*
|
|
195
|
+
*
|
|
153
196
|
* @param param0
|
|
154
197
|
* @returns CredentialStatusDocument[]
|
|
155
198
|
*/
|
|
156
|
-
async function syncCredentialStatus({
|
|
199
|
+
async function syncCredentialStatus({
|
|
200
|
+
wallet,
|
|
201
|
+
credentialIds,
|
|
202
|
+
forceFetch,
|
|
203
|
+
}: SyncCredentialStatusParams & {
|
|
157
204
|
wallet: IWallet;
|
|
158
|
-
}
|
|
205
|
+
}): Promise<CredentialStatusDocument[]> {
|
|
159
206
|
let credentials;
|
|
160
207
|
|
|
161
208
|
if (credentialIds && credentialIds.length) {
|
|
@@ -167,7 +214,7 @@ async function syncCredentialStatus({ wallet, credentialIds, forceFetch }: SyncC
|
|
|
167
214
|
let statusDocs = [];
|
|
168
215
|
|
|
169
216
|
let isApiConnected;
|
|
170
|
-
|
|
217
|
+
|
|
171
218
|
for (const credential of credentials) {
|
|
172
219
|
let shouldFetch = !!forceFetch;
|
|
173
220
|
let statusDoc = await wallet.getDocumentById(`${credential.id}#status`);
|
|
@@ -214,10 +261,10 @@ async function syncCredentialStatus({ wallet, credentialIds, forceFetch }: SyncC
|
|
|
214
261
|
if (!isApiConnected) {
|
|
215
262
|
await dockService.ensureDockReady();
|
|
216
263
|
isApiConnected = true;
|
|
217
|
-
}
|
|
264
|
+
}
|
|
218
265
|
|
|
219
|
-
const result = await isValid({
|
|
220
|
-
statusDoc.status = result?.status
|
|
266
|
+
const result = await isValid({credential, wallet});
|
|
267
|
+
statusDoc.status = result?.status;
|
|
221
268
|
statusDoc.error = result?.error;
|
|
222
269
|
statusDoc.updatedAt = new Date().toISOString();
|
|
223
270
|
|
|
@@ -237,6 +284,11 @@ export function createCredentialProvider({
|
|
|
237
284
|
}
|
|
238
285
|
|
|
239
286
|
return {
|
|
287
|
+
importCredentialFromURI: async (params: importCredentialFromUriParams) =>
|
|
288
|
+
importCredentialFromURI({
|
|
289
|
+
...params,
|
|
290
|
+
wallet,
|
|
291
|
+
}),
|
|
240
292
|
getCredentials,
|
|
241
293
|
getMembershipWitness: async (credentialId: string) =>
|
|
242
294
|
getMembershipWitness({credentialId, wallet}),
|
|
@@ -261,10 +313,10 @@ export function createCredentialProvider({
|
|
|
261
313
|
return {
|
|
262
314
|
status: statusDoc?.status || CredentialStatus.Pending,
|
|
263
315
|
error: statusDoc?.error,
|
|
264
|
-
}
|
|
316
|
+
};
|
|
265
317
|
},
|
|
266
318
|
syncCredentialStatus: async (props: SyncCredentialStatusParams) => {
|
|
267
|
-
return syncCredentialStatus({
|
|
319
|
+
return syncCredentialStatus({wallet, ...props});
|
|
268
320
|
},
|
|
269
321
|
addCredential: credential => addCredential({wallet, credential}),
|
|
270
322
|
// TODO: move import credential from json or URL to this provider
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
acquireOpenIDCredentialFromURI,
|
|
3
|
+
getAuthURL,
|
|
4
|
+
decodeRequestJWT,
|
|
5
|
+
getPresentationSubmision,
|
|
6
|
+
} from './oidvc'; // replace with your actual file path
|
|
7
|
+
import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
|
|
8
|
+
import {MetadataClient} from '@sphereon/oid4vci-client';
|
|
9
|
+
import jwtDecode from 'jwt-decode';
|
|
10
|
+
import axios from 'axios';
|
|
11
|
+
import {pexService} from '@docknetwork/wallet-sdk-wasm/src/services/pex';
|
|
12
|
+
|
|
13
|
+
jest.mock('@docknetwork/wallet-sdk-wasm/src/services/credential');
|
|
14
|
+
jest.mock('@sphereon/oid4vci-client');
|
|
15
|
+
jest.mock('jwt-decode');
|
|
16
|
+
jest.mock('axios');
|
|
17
|
+
jest.mock('@docknetwork/wallet-sdk-wasm/src/services/pex');
|
|
18
|
+
|
|
19
|
+
describe('acquireOpenIDCredentialFromURI', () => {
|
|
20
|
+
const didProvider: any = {
|
|
21
|
+
getDIDKeyPairs: jest.fn(),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const uri = 'https://example.com/credential';
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
didProvider.getDIDKeyPairs.mockResolvedValue([{id: 'did:example:123'}]);
|
|
28
|
+
(credentialServiceRPC.acquireOIDCredential as jest.Mock).mockResolvedValue({
|
|
29
|
+
credential: 'fake-credential',
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should acquire OID credential without authorization URL', async () => {
|
|
34
|
+
const response = await acquireOpenIDCredentialFromURI({didProvider, uri});
|
|
35
|
+
expect(didProvider.getDIDKeyPairs).toHaveBeenCalled();
|
|
36
|
+
expect(credentialServiceRPC.acquireOIDCredential).toHaveBeenCalledWith({
|
|
37
|
+
uri,
|
|
38
|
+
holderKeyDocument: {id: 'did:example:123'},
|
|
39
|
+
});
|
|
40
|
+
expect(response).toBe('credential');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should acquire OID credential with authorization URL', async () => {
|
|
44
|
+
const getAuthCode = jest.fn().mockResolvedValue('auth-code');
|
|
45
|
+
(credentialServiceRPC.acquireOIDCredential as jest.Mock).mockResolvedValueOnce({
|
|
46
|
+
authorizationURL: 'https://example.com/auth',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const response = await acquireOpenIDCredentialFromURI({
|
|
50
|
+
didProvider,
|
|
51
|
+
uri,
|
|
52
|
+
getAuthCode,
|
|
53
|
+
});
|
|
54
|
+
expect(getAuthCode).toHaveBeenCalledWith('https://example.com/auth');
|
|
55
|
+
expect(credentialServiceRPC.acquireOIDCredential).toHaveBeenCalledWith({
|
|
56
|
+
uri,
|
|
57
|
+
holderKeyDocument: {id: 'did:example:123'},
|
|
58
|
+
authorizationCode: 'auth-code',
|
|
59
|
+
});
|
|
60
|
+
expect(response).toBe('credential');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('getAuthURL', () => {
|
|
65
|
+
it('should generate an auth URL', async () => {
|
|
66
|
+
const uri = 'https://example.com?client_id=fake-client';
|
|
67
|
+
const metadata = {
|
|
68
|
+
authorizationServerMetadata: {
|
|
69
|
+
request_object_signing_alg_values_supported: ['RS256'],
|
|
70
|
+
},
|
|
71
|
+
authorization_endpoint: 'https://auth.example.com/authorize',
|
|
72
|
+
};
|
|
73
|
+
(MetadataClient.retrieveAllMetadata as jest.Mock).mockResolvedValue(metadata);
|
|
74
|
+
|
|
75
|
+
const result = await getAuthURL(uri);
|
|
76
|
+
expect(MetadataClient.retrieveAllMetadata).toHaveBeenCalledWith(
|
|
77
|
+
'fake-client',
|
|
78
|
+
);
|
|
79
|
+
expect(result).toContain('https://auth.example.com/authorize?');
|
|
80
|
+
expect(result).toContain('client_id=dock-wallet');
|
|
81
|
+
expect(result).toContain('redirect_uri=dockwallet://vp');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('decodeRequestJWT', () => {
|
|
86
|
+
it('should decode JWT from the request URI', async () => {
|
|
87
|
+
const uri = 'https://example.com?request_uri=https://example.com/jwt';
|
|
88
|
+
const jwt = 'some-jwt';
|
|
89
|
+
const decodedJWT = {sub: '1234567890', name: 'Testing', admin: true};
|
|
90
|
+
(axios.get as jest.Mock).mockResolvedValue({data: jwt});
|
|
91
|
+
(jwtDecode as jest.Mock).mockReturnValue(decodedJWT);
|
|
92
|
+
|
|
93
|
+
const result = await decodeRequestJWT(uri);
|
|
94
|
+
expect(axios.get).toHaveBeenCalledWith('https://example.com/jwt');
|
|
95
|
+
expect(jwtDecode).toHaveBeenCalledWith(jwt);
|
|
96
|
+
expect(result).toEqual(decodedJWT);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('getPresentationSubmision', () => {
|
|
101
|
+
it('should get presentation submission', async () => {
|
|
102
|
+
const credentials = [{id: 'credential-1'}];
|
|
103
|
+
const presentationDefinition = {id: 'presentation-definition-1'};
|
|
104
|
+
const holderDID = 'did:example:123';
|
|
105
|
+
const presentationSubmission = {definition_id: 'presentation-submission-1'};
|
|
106
|
+
|
|
107
|
+
(pexService.presentationFrom as jest.Mock).mockResolvedValue({
|
|
108
|
+
presentation_submission: presentationSubmission,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const result = await getPresentationSubmision({
|
|
112
|
+
credentials,
|
|
113
|
+
presentationDefinition,
|
|
114
|
+
holderDID,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(pexService.presentationFrom).toHaveBeenCalledWith({
|
|
118
|
+
presentationDefinition,
|
|
119
|
+
credentials,
|
|
120
|
+
holderDID,
|
|
121
|
+
});
|
|
122
|
+
expect(result).toEqual(presentationSubmission);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {IWallet} from '../types';
|
|
2
|
+
import {IDIDProvider} from '../did-provider';
|
|
3
|
+
import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
|
|
4
|
+
import {MetadataClient} from '@sphereon/oid4vci-client';
|
|
5
|
+
import jwtDecode from 'jwt-decode';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import {pexService} from '@docknetwork/wallet-sdk-wasm/src/services/pex';
|
|
8
|
+
import {WellKnownEndpoints} from '@sphereon/oid4vci-common';
|
|
9
|
+
|
|
10
|
+
export async function acquireOpenIDCredentialFromURI({
|
|
11
|
+
didProvider,
|
|
12
|
+
uri,
|
|
13
|
+
getAuthCode,
|
|
14
|
+
}: {
|
|
15
|
+
didProvider: IDIDProvider;
|
|
16
|
+
uri: string;
|
|
17
|
+
getAuthCode?: (authorizationURL: string) => Promise<string>;
|
|
18
|
+
}) {
|
|
19
|
+
const [holderKeyDocument] = await didProvider.getDIDKeyPairs();
|
|
20
|
+
|
|
21
|
+
let response = await credentialServiceRPC.acquireOIDCredential({
|
|
22
|
+
uri,
|
|
23
|
+
holderKeyDocument,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (response.authorizationURL) {
|
|
27
|
+
const authorizationCode = await getAuthCode(response.authorizationURL);
|
|
28
|
+
response = await credentialServiceRPC.acquireOIDCredential({
|
|
29
|
+
uri,
|
|
30
|
+
holderKeyDocument,
|
|
31
|
+
authorizationCode,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return response.credential;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function getAuthURL(
|
|
39
|
+
uri: string,
|
|
40
|
+
walletClientId: string = 'dock-wallet',
|
|
41
|
+
requestedRedirectURI: string = 'dockwallet://vp',
|
|
42
|
+
) {
|
|
43
|
+
function buildOID4VPRequestURL(params, prefix = 'dockwallet://') {
|
|
44
|
+
return `${prefix}?${Object.keys(params)
|
|
45
|
+
.map(
|
|
46
|
+
key =>
|
|
47
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(
|
|
48
|
+
typeof params[key] === 'object'
|
|
49
|
+
? JSON.stringify(params[key])
|
|
50
|
+
: params[key],
|
|
51
|
+
)}`,
|
|
52
|
+
)
|
|
53
|
+
.join('&')}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const searchParams = new URL(uri).searchParams;
|
|
57
|
+
const params = new URLSearchParams(searchParams);
|
|
58
|
+
const clientId = params.get('client_id');
|
|
59
|
+
// We need to investigate why MetadataClient.retrieveAllMetadata(clientId); is not working on android
|
|
60
|
+
// Follow up bug ticket: https://dock-team.atlassian.net/browse/DCKM-600
|
|
61
|
+
const metadataURI = `${clientId}${WellKnownEndpoints.OPENID_CONFIGURATION}`;
|
|
62
|
+
const {data: metadata} = await axios.get(metadataURI);
|
|
63
|
+
|
|
64
|
+
const requestedAlg =
|
|
65
|
+
metadata?.authorizationServerMetadata
|
|
66
|
+
?.request_object_signing_alg_values_supported[0];
|
|
67
|
+
const requestParams = {
|
|
68
|
+
scope: 'openid vp_token',
|
|
69
|
+
redirect_uri: requestedRedirectURI,
|
|
70
|
+
client_metadata:
|
|
71
|
+
requestedAlg && requestedAlg !== 'EdDSA'
|
|
72
|
+
? JSON.stringify({
|
|
73
|
+
vp_formats_supported: {
|
|
74
|
+
vc_json: {
|
|
75
|
+
alg_values_supported: [requestedAlg],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
: ['EdDSA'],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return buildOID4VPRequestURL(
|
|
83
|
+
{
|
|
84
|
+
...requestParams,
|
|
85
|
+
client_id: walletClientId,
|
|
86
|
+
},
|
|
87
|
+
metadata.authorization_endpoint,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function decodeRequestJWT(uri: string) {
|
|
92
|
+
const searchParams = new URL(uri).searchParams;
|
|
93
|
+
const params = new URLSearchParams(searchParams);
|
|
94
|
+
const requestUri = params.get('request_uri');
|
|
95
|
+
const jwt = await axios.get(requestUri).then(res => res.data);
|
|
96
|
+
const decoded = jwtDecode(jwt);
|
|
97
|
+
|
|
98
|
+
return decoded;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function getPresentationSubmision({
|
|
102
|
+
credentials,
|
|
103
|
+
presentationDefinition,
|
|
104
|
+
holderDID,
|
|
105
|
+
}) {
|
|
106
|
+
const presentation = await pexService.presentationFrom({
|
|
107
|
+
presentationDefinition,
|
|
108
|
+
credentials,
|
|
109
|
+
holderDID,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return presentation.presentation_submission;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
pexService.evaluatePresentation;
|
package/src/did-provider.test.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import {IWallet} from './types';
|
|
2
2
|
import {createWallet} from './wallet';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
createDIDock,
|
|
5
|
+
createDIDKey,
|
|
6
|
+
createDIDProvider,
|
|
7
|
+
IDIDProvider,
|
|
8
|
+
} from './did-provider';
|
|
4
9
|
import {createAccountProvider} from './account-provider';
|
|
5
10
|
import {didServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/dids';
|
|
11
|
+
import {createDataStore} from '@docknetwork/wallet-sdk-data-store-typeorm/src';
|
|
6
12
|
|
|
7
13
|
describe('DID Provider', () => {
|
|
8
14
|
let wallet: IWallet;
|
|
@@ -49,7 +55,9 @@ describe('DID Provider', () => {
|
|
|
49
55
|
|
|
50
56
|
beforeEach(async () => {
|
|
51
57
|
wallet = await createWallet({
|
|
52
|
-
|
|
58
|
+
dataStore: await createDataStore({
|
|
59
|
+
databasePath: ':memory:',
|
|
60
|
+
}),
|
|
53
61
|
});
|
|
54
62
|
accountProvider = createAccountProvider({wallet});
|
|
55
63
|
didProvider = createDIDProvider({wallet});
|
|
@@ -149,18 +157,19 @@ describe('DID Provider', () => {
|
|
|
149
157
|
|
|
150
158
|
describe('create DID Key', () => {
|
|
151
159
|
it('expect to create a DID Key', async () => {
|
|
152
|
-
|
|
153
160
|
jest.spyOn(didServiceRPC, 'generateKeyDoc').mockResolvedValueOnce({
|
|
154
161
|
id: 'did:key:abcde#key-1',
|
|
155
162
|
type: 'KeyDocument',
|
|
156
163
|
});
|
|
157
164
|
|
|
158
|
-
jest
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
jest
|
|
166
|
+
.spyOn(didServiceRPC, 'keypairToDIDKeyDocument')
|
|
167
|
+
.mockResolvedValueOnce({
|
|
168
|
+
didDocument: {
|
|
169
|
+
id: 'did:key:abcde#key-2',
|
|
170
|
+
type: 'DidDocument',
|
|
171
|
+
},
|
|
172
|
+
});
|
|
164
173
|
|
|
165
174
|
jest.spyOn(didServiceRPC, 'getDIDResolution').mockResolvedValueOnce({
|
|
166
175
|
id: new Date().getTime().toString(),
|
|
@@ -185,10 +194,9 @@ describe('DID Provider', () => {
|
|
|
185
194
|
expect(didDocument.length).toBe(2);
|
|
186
195
|
});
|
|
187
196
|
it('expect to assert parameters', async () => {
|
|
188
|
-
|
|
189
197
|
await expect(
|
|
190
198
|
didProvider.createDIDKey({
|
|
191
|
-
name: ''
|
|
199
|
+
name: '',
|
|
192
200
|
}),
|
|
193
201
|
).rejects.toThrowError('name is required');
|
|
194
202
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"revocationCheck": "membership",
|
|
14
14
|
"revocationId": "9"
|
|
15
15
|
},
|
|
16
|
-
"id": "https://creds-
|
|
16
|
+
"id": "https://creds-example.dock.io/83e0641f88e7ae5b18e8ae4a9ca616d23df8370501375269db9e21d857d6ce55",
|
|
17
17
|
"type": [
|
|
18
18
|
"VerifiableCredential",
|
|
19
19
|
"BiometricsCredential"
|
|
@@ -59,4 +59,4 @@
|
|
|
59
59
|
"proofValue": "zY4LVnbLxwjnk2En988EVHvqsysjELpAcD3A72832JUHS3DreVjv2P9fN6J4CyWo9qC1qiiqBWkNzKP73ZF6tdSzTLzYgByqsXKDxLoyW7LqU2byPjAhHx2GKXTkKVqB3P3WtwxMGCcXR1tQqNhz91do5h"
|
|
60
60
|
},
|
|
61
61
|
"$$accum__witness$$": "0xb2249e8faadb33015bfc2dbe74bbd916f5efacff92d0e1235827e4e1b23438d9c45e427376cbcc164ab41c3bd0ace3c8"
|
|
62
|
-
}
|
|
62
|
+
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"https://ld.dock.io/credentials/prettyvc"
|
|
14
14
|
],
|
|
15
|
-
"id": "https://creds-
|
|
15
|
+
"id": "https://creds-example.dock.io/d02cc3892ae688dae923dd470443b1ee41a046206a6ae1775e4dbff25abccc6f",
|
|
16
16
|
"type": [
|
|
17
17
|
"VerifiableCredential",
|
|
18
18
|
"IIW",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"qr": "https://creds-
|
|
2
|
+
"qr": "https://creds-example.dock.io/proof/f6b0c6a7-ae27-4044-80a3-07f5af6e61c8",
|
|
3
3
|
"id": "f6b0c6a7-ae27-4044-80a3-07f5af6e61c8",
|
|
4
4
|
"name": "boolean",
|
|
5
5
|
"nonce": "e2cb13292035d73e97543c8f463c3f06",
|
|
6
6
|
"created": "2023-08-17T17:38:38.276Z",
|
|
7
7
|
"updated": "2023-08-17T17:38:38.276Z",
|
|
8
8
|
"verified": false,
|
|
9
|
-
"response_url": "
|
|
9
|
+
"response_url": "${TESTING_API_URL}/proof-requests/f6b0c6a7-ae27-4044-80a3-07f5af6e61c8/send-presentation",
|
|
10
10
|
"request": {
|
|
11
11
|
"id": "f6b0c6a7-ae27-4044-80a3-07f5af6e61c8",
|
|
12
12
|
"input_descriptors": [
|
package/src/helpers.ts
CHANGED
|
@@ -59,3 +59,13 @@ export function getJSON(jsonOrURL: string | any) {
|
|
|
59
59
|
|
|
60
60
|
throw new Error(`Invalid data ${jsonOrURL}`);
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
export function replaceResponseURL(templateRequest){
|
|
64
|
+
assert(process.env.TESTING_API_URL, "Please configure the TESTING_API_URL env var.");
|
|
65
|
+
|
|
66
|
+
if (templateRequest?.response_url){
|
|
67
|
+
templateRequest.response_url = templateRequest.response_url.replace("${TESTING_API_URL}", process.env.TESTING_API_URL);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return templateRequest;
|
|
71
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createDataStore } from '@docknetwork/wallet-sdk-data-store-typeorm/src';
|
|
1
2
|
import {IDIDProvider, createDIDProvider} from './did-provider';
|
|
2
3
|
import {IMessageProvider, createMessageProvider} from './message-provider';
|
|
3
4
|
import {IWallet, createWallet} from './wallet';
|
|
@@ -25,17 +26,20 @@ describe('MessageProvider', () => {
|
|
|
25
26
|
beforeEach(async () => {
|
|
26
27
|
relayService = {
|
|
27
28
|
sendMessage: jest.fn(),
|
|
29
|
+
ackMessages: jest.fn(),
|
|
28
30
|
getMessages: jest.fn().mockResolvedValue(didCommMessages),
|
|
29
31
|
resolveDidcommMessage: jest.fn().mockImplementation(({ message }) => message),
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
wallet = await createWallet({
|
|
33
|
-
|
|
35
|
+
dataStore: await createDataStore({
|
|
36
|
+
databasePath: ':memory:',
|
|
37
|
+
})
|
|
34
38
|
});
|
|
35
39
|
didProvider = createDIDProvider({
|
|
36
40
|
wallet,
|
|
37
41
|
});
|
|
38
|
-
didProvider.getDIDKeyPairs = jest.fn().mockResolvedValue([{controller: "
|
|
42
|
+
didProvider.getDIDKeyPairs = jest.fn().mockResolvedValue([{controller: "did:key:z6MkoQzWru66w91EH7U9Xsv5eYXQabw9U3ZJd5GkatMWkmZT"}])
|
|
39
43
|
messageProvider = createMessageProvider({
|
|
40
44
|
wallet,
|
|
41
45
|
didProvider,
|
|
@@ -51,6 +55,8 @@ describe('MessageProvider', () => {
|
|
|
51
55
|
const walletMessage = await wallet.getDocumentById(message._id);
|
|
52
56
|
expect(walletMessage.encryptedMessage).toEqual(message);
|
|
53
57
|
}
|
|
58
|
+
|
|
59
|
+
expect(relayService.ackMessages).toBeCalledWith({did: 'did:key:z6MkoQzWru66w91EH7U9Xsv5eYXQabw9U3ZJd5GkatMWkmZT', messageIds: didCommMessages.map(m => m._id)});
|
|
54
60
|
});
|
|
55
61
|
|
|
56
62
|
it('should decrypt encrypted messages in the wallet', async () => {
|
|
@@ -75,7 +81,7 @@ describe('MessageProvider', () => {
|
|
|
75
81
|
|
|
76
82
|
await expect(
|
|
77
83
|
messageProvider.sendMessage({
|
|
78
|
-
did: '
|
|
84
|
+
did: 'did:key:z6MkoQzWru66w91EH7U9Xsv5eYXQabw9U3ZJd5GkatMWkmZT',
|
|
79
85
|
message: 'someMessage',
|
|
80
86
|
recipientDid: 'recipientDid',
|
|
81
87
|
})
|