@docknetwork/wallet-sdk-core 0.4.19 → 1.4.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/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 +20 -0
- package/lib/cloud-wallet.d.ts.map +1 -0
- package/lib/cloud-wallet.js +154 -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.d.ts +8 -6
- package/lib/ecosystem-tools.d.ts.map +1 -1
- package/lib/ecosystem-tools.js +27 -13
- package/lib/ecosystem-tools.js.map +1 -1
- 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 +189 -0
- package/src/credential-provider.test.ts +11 -5
- package/src/credential-provider.ts +78 -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/ecosystem-tools.ts +36 -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
package/src/message-provider.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {logger} from '@docknetwork/wallet-sdk-data-store/src/logger';
|
|
1
2
|
import {IDIDProvider} from './did-provider';
|
|
2
3
|
import {WalletDocumentTypes, captureException} from './helpers';
|
|
3
4
|
import {IWallet} from './types';
|
|
@@ -14,6 +15,7 @@ export interface IMessageProvider {
|
|
|
14
15
|
waitForMessage: () => Promise<any>;
|
|
15
16
|
markMessageAsRead: (messageId: string) => Promise<void>;
|
|
16
17
|
clearCache: () => Promise<void>;
|
|
18
|
+
processMessageRecurrentJob: () => Promise<void>;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
async function getKeyPairDocs(didProvider: IDIDProvider, did?: string) {
|
|
@@ -50,15 +52,30 @@ export function createMessageProvider({
|
|
|
50
52
|
await wallet.removeDocument(messageId);
|
|
51
53
|
} catch (error) {
|
|
52
54
|
captureException(error);
|
|
53
|
-
|
|
55
|
+
console.error(`Failed to mark message as read: ${error.message}`);
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
let processingLock = false;
|
|
57
60
|
async function processDIDCommMessages(limit = 1) {
|
|
61
|
+
if (processingLock) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
processingLock = true;
|
|
58
66
|
try {
|
|
67
|
+
const processMessagesStartTime = Date.now();
|
|
59
68
|
const messages = await wallet.getDocumentsByType(
|
|
60
69
|
WalletDocumentTypes.DIDCommMessage,
|
|
61
70
|
);
|
|
71
|
+
|
|
72
|
+
if (messages.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
logger.debug('Processing DIDComm messages');
|
|
77
|
+
|
|
78
|
+
|
|
62
79
|
const keyPairDocs = await getKeyPairDocs(didProvider);
|
|
63
80
|
let count = 0;
|
|
64
81
|
for (const message of messages) {
|
|
@@ -80,8 +97,8 @@ export function createMessageProvider({
|
|
|
80
97
|
decryptedMessage,
|
|
81
98
|
messageId: message.id,
|
|
82
99
|
});
|
|
100
|
+
await markMessageAsRead(message.id);
|
|
83
101
|
count++;
|
|
84
|
-
// the wallet app will call markMessageAsRead after the message is processed
|
|
85
102
|
} catch (err) {
|
|
86
103
|
if (err.message?.includes('the DID in question does not exist')) {
|
|
87
104
|
// the DID lookup failed (a testnet credential was issued to a mainnet did), so we can't
|
|
@@ -91,43 +108,84 @@ export function createMessageProvider({
|
|
|
91
108
|
captureException(err);
|
|
92
109
|
}
|
|
93
110
|
}
|
|
111
|
+
logger.performance('Processed messages', processMessagesStartTime);
|
|
94
112
|
} catch (error) {
|
|
95
113
|
captureException(error);
|
|
96
114
|
throw new Error(`Failed to process DIDComm messages: ${error.message}`);
|
|
115
|
+
} finally {
|
|
116
|
+
processingLock = false;
|
|
97
117
|
}
|
|
98
118
|
}
|
|
99
119
|
|
|
120
|
+
let recentlyFetchedMessages = [];
|
|
121
|
+
|
|
100
122
|
async function fetchMessages() {
|
|
101
123
|
try {
|
|
124
|
+
logger.debug('Fetching messages');
|
|
125
|
+
const fetchMessagesStartTime = Date.now();
|
|
102
126
|
const keyPairDocs = await getKeyPairDocs(didProvider);
|
|
103
|
-
|
|
127
|
+
let encryptedMessages = await relayService.getMessages({
|
|
104
128
|
keyPairDocs,
|
|
105
129
|
limit: FETCH_MESSAGE_LIMIT,
|
|
106
130
|
skipMessageResolution: true,
|
|
107
131
|
});
|
|
132
|
+
const messageIdsPerDid = {};
|
|
108
133
|
|
|
109
|
-
|
|
110
|
-
|
|
134
|
+
encryptedMessages = encryptedMessages.filter(
|
|
135
|
+
message => !recentlyFetchedMessages.includes(message._id),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (!encryptedMessages.length) {
|
|
139
|
+
return;
|
|
111
140
|
}
|
|
112
141
|
|
|
142
|
+
console.log(`Fetched ${encryptedMessages.length} messages`);
|
|
143
|
+
|
|
113
144
|
for (const message of encryptedMessages) {
|
|
114
145
|
try {
|
|
146
|
+
if (!messageIdsPerDid[message.to]) {
|
|
147
|
+
messageIdsPerDid[message.to] = [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
messageIdsPerDid[message.to].push(message._id);
|
|
151
|
+
|
|
115
152
|
await wallet.addDocument({
|
|
116
153
|
id: message._id,
|
|
117
154
|
type: WalletDocumentTypes.DIDCommMessage,
|
|
118
155
|
encryptedMessage: message,
|
|
119
156
|
});
|
|
157
|
+
|
|
158
|
+
recentlyFetchedMessages.push(message._id);
|
|
120
159
|
} catch (err) {
|
|
121
160
|
// this message will be lost if it fails to be stored in the wallet
|
|
122
161
|
captureException(err);
|
|
123
162
|
}
|
|
124
163
|
}
|
|
125
164
|
|
|
165
|
+
for (const [did, messageIds] of Object.entries(messageIdsPerDid)) {
|
|
166
|
+
logger.debug(`Acknowledging messages for ${did}`);
|
|
167
|
+
let startTime = new Date().getTime();
|
|
168
|
+
relayService
|
|
169
|
+
.ackMessages({
|
|
170
|
+
did,
|
|
171
|
+
messageIds,
|
|
172
|
+
})
|
|
173
|
+
.then(() => {
|
|
174
|
+
logger.performance('Acknowledged messages', startTime);
|
|
175
|
+
})
|
|
176
|
+
.catch(err => {
|
|
177
|
+
console.error('Failed to ack messages', err.message);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
126
181
|
if (encryptedMessages.length > 0) {
|
|
127
182
|
wallet.eventManager.emit(
|
|
128
183
|
'didcomm-messages-received',
|
|
129
184
|
encryptedMessages,
|
|
130
185
|
);
|
|
186
|
+
|
|
187
|
+
logger.debug(`Received ${encryptedMessages.length} messages`);
|
|
188
|
+
logger.performance('Fetched messages', fetchMessagesStartTime);
|
|
131
189
|
}
|
|
132
190
|
|
|
133
191
|
return encryptedMessages;
|
|
@@ -137,22 +195,27 @@ export function createMessageProvider({
|
|
|
137
195
|
}
|
|
138
196
|
}
|
|
139
197
|
|
|
140
|
-
|
|
141
198
|
function addMessageListener(handler) {
|
|
142
199
|
const listener = async message => {
|
|
143
200
|
await Promise.resolve(handler(message.decryptedMessage));
|
|
144
|
-
await markMessageAsRead(message.messageId);
|
|
145
201
|
};
|
|
146
202
|
|
|
147
203
|
wallet.eventManager.addListener('didcomm-message-decrypted', listener);
|
|
148
204
|
return () =>
|
|
149
|
-
wallet.eventManager.removeListener(
|
|
150
|
-
|
|
151
|
-
listener,
|
|
152
|
-
);
|
|
153
|
-
};
|
|
205
|
+
wallet.eventManager.removeListener('didcomm-message-decrypted', listener);
|
|
206
|
+
}
|
|
154
207
|
|
|
155
|
-
let
|
|
208
|
+
let listenerIntervalId = null;
|
|
209
|
+
|
|
210
|
+
const processMessageInterval = 3000;
|
|
211
|
+
|
|
212
|
+
async function processMessageRecurrentJob() {
|
|
213
|
+
try {
|
|
214
|
+
await processDIDCommMessages();
|
|
215
|
+
} finally {
|
|
216
|
+
setTimeout(processMessageRecurrentJob, processMessageInterval);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
156
219
|
|
|
157
220
|
return {
|
|
158
221
|
async sendMessage({
|
|
@@ -165,7 +228,6 @@ export function createMessageProvider({
|
|
|
165
228
|
body,
|
|
166
229
|
type,
|
|
167
230
|
}) {
|
|
168
|
-
|
|
169
231
|
// TODO: rename relay service parameters to make it easier to understand
|
|
170
232
|
if (from) {
|
|
171
233
|
did = from;
|
|
@@ -184,7 +246,12 @@ export function createMessageProvider({
|
|
|
184
246
|
if (!keyPairDoc) {
|
|
185
247
|
throw new Error(`${did} not found in didDocs`);
|
|
186
248
|
}
|
|
187
|
-
await relayService.sendMessage({
|
|
249
|
+
await relayService.sendMessage({
|
|
250
|
+
keyPairDoc,
|
|
251
|
+
message,
|
|
252
|
+
recipientDid,
|
|
253
|
+
type,
|
|
254
|
+
});
|
|
188
255
|
} catch (error) {
|
|
189
256
|
captureException(error);
|
|
190
257
|
throw new Error(`Failed to send message: ${error.message}`);
|
|
@@ -192,30 +259,35 @@ export function createMessageProvider({
|
|
|
192
259
|
},
|
|
193
260
|
waitForMessage() {
|
|
194
261
|
return new Promise((resolve: any) => {
|
|
195
|
-
let removeListener = addMessageListener(async
|
|
262
|
+
let removeListener = addMessageListener(async message => {
|
|
196
263
|
removeListener();
|
|
197
264
|
await resolve(message);
|
|
198
|
-
})
|
|
265
|
+
});
|
|
199
266
|
});
|
|
200
267
|
},
|
|
201
268
|
startAutoFetch(timeout = 2000) {
|
|
202
|
-
clearInterval(
|
|
203
|
-
|
|
269
|
+
clearInterval(listenerIntervalId);
|
|
270
|
+
listenerIntervalId = setInterval(async () => {
|
|
204
271
|
await fetchMessages();
|
|
205
272
|
await processDIDCommMessages();
|
|
206
273
|
}, timeout);
|
|
207
274
|
|
|
208
|
-
return () => clearInterval(
|
|
275
|
+
return () => clearInterval(listenerIntervalId);
|
|
209
276
|
},
|
|
210
277
|
clearCache: async () => {
|
|
211
|
-
return Promise.all(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
278
|
+
return Promise.all(
|
|
279
|
+
(
|
|
280
|
+
await wallet.getDocumentsByType(WalletDocumentTypes.DIDCommMessage)
|
|
281
|
+
).map(document => {
|
|
282
|
+
markMessageAsRead(document.id);
|
|
283
|
+
return wallet.removeDocument(document.id);
|
|
284
|
+
}),
|
|
285
|
+
);
|
|
215
286
|
},
|
|
216
287
|
fetchMessages,
|
|
217
288
|
addMessageListener,
|
|
218
289
|
processDIDCommMessages,
|
|
290
|
+
processMessageRecurrentJob,
|
|
219
291
|
markMessageAsRead,
|
|
220
|
-
};
|
|
292
|
+
} as any;
|
|
221
293
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {buildVerifiablePresentationMessage} from './message-helpers';
|
|
2
|
+
|
|
3
|
+
describe('message-helpers', () => {
|
|
4
|
+
it('should build a verifiable presentation message from the holder to the verifier', () => {
|
|
5
|
+
const message = buildVerifiablePresentationMessage({
|
|
6
|
+
holderDID: 'holderDID',
|
|
7
|
+
verifierDID: 'verifierDID',
|
|
8
|
+
presentation: 'presentation',
|
|
9
|
+
proofRequestId: 'proofRequestId',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
expect(message.from).toBe('holderDID');
|
|
13
|
+
expect(message.to).toBe('verifierDID');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -3,23 +3,27 @@ import {
|
|
|
3
3
|
accountResolver,
|
|
4
4
|
credentialResolver,
|
|
5
5
|
dockDocumentNetworkResolver,
|
|
6
|
+
proofRequestResolver,
|
|
6
7
|
resolveApiNetwork,
|
|
7
8
|
} from './network-resolver';
|
|
9
|
+
import {createDataStore} from '@docknetwork/wallet-sdk-data-store-typeorm/src';
|
|
8
10
|
|
|
9
11
|
describe('Wallet', () => {
|
|
10
12
|
let wallet: IWallet;
|
|
11
13
|
|
|
12
14
|
beforeEach(async () => {
|
|
13
15
|
wallet = await createWallet({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
dataStore: await createDataStore({
|
|
17
|
+
databasePath: ':memory:',
|
|
18
|
+
documentNetworkResolver: dockDocumentNetworkResolver,
|
|
19
|
+
}),
|
|
16
20
|
});
|
|
17
21
|
});
|
|
18
22
|
|
|
19
23
|
it('resolveApiNetwork', () => {
|
|
20
24
|
expect(
|
|
21
25
|
resolveApiNetwork({
|
|
22
|
-
url: 'https://creds-
|
|
26
|
+
url: 'https://creds-example.dock.io/proof/0bb39274-4ef1-4e7f-ab8d-d91d8926d9af',
|
|
23
27
|
dataStore: wallet.dataStore,
|
|
24
28
|
}),
|
|
25
29
|
).toBe('testnet');
|
|
@@ -104,7 +108,7 @@ describe('Wallet', () => {
|
|
|
104
108
|
it('expect to resolve credential to testnet', async () => {
|
|
105
109
|
const result = await credentialResolver({
|
|
106
110
|
document: {
|
|
107
|
-
id: 'https://creds-
|
|
111
|
+
id: 'https://creds-example.dock.io/d39b15fe997004db702c9faaf98f9fd619cdf40088549648fb288ea679b53e23?_ga=2.46968743.1402343540.1684360698-1482908456.1677577177',
|
|
108
112
|
type: ['VerifiableCredential'],
|
|
109
113
|
},
|
|
110
114
|
dataStore: wallet.dataStore,
|
|
@@ -139,4 +143,69 @@ describe('Wallet', () => {
|
|
|
139
143
|
expect(result).toBe('mainnet');
|
|
140
144
|
});
|
|
141
145
|
});
|
|
146
|
+
|
|
147
|
+
describe('proofRequestResolver', () => {
|
|
148
|
+
it('should detect a testnet proof request', async () => {
|
|
149
|
+
let result = await dockDocumentNetworkResolver({
|
|
150
|
+
document: {
|
|
151
|
+
qr: 'https://creds-testnet.dock.io/proof/4970377a-6283-46d8-b95e-db99b011e48c',
|
|
152
|
+
id: '4970377a-6283-46d8-b95e-db99b011e48c',
|
|
153
|
+
response_url:
|
|
154
|
+
'https://api-testnet.dock.io/proof-requests/4970377a-6283-46d8-b95e-db99b011e48c/send-presentation',
|
|
155
|
+
type: 'proof-request',
|
|
156
|
+
},
|
|
157
|
+
dataStore: wallet.dataStore,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
expect(result.networkId).toBe('testnet');
|
|
161
|
+
expect(result.resolver).toBe(proofRequestResolver);
|
|
162
|
+
|
|
163
|
+
result = await dockDocumentNetworkResolver({
|
|
164
|
+
document: {
|
|
165
|
+
qr: 'https://creds-testnet.dock.io/proof/4970377a-6283-46d8-b95e-db99b011e48c',
|
|
166
|
+
id: '4970377a-6283-46d8-b95e-db99b011e48c',
|
|
167
|
+
response_url:
|
|
168
|
+
'https://api-testnet.dock.io/proof-requests/4970377a-6283-46d8-b95e-db99b011e48c/send-presentation',
|
|
169
|
+
type: 'proof-request',
|
|
170
|
+
},
|
|
171
|
+
dataStore: wallet.dataStore,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(result.networkId).toBe('testnet');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should detect a mainnet proof request', async () => {
|
|
178
|
+
const result = await dockDocumentNetworkResolver({
|
|
179
|
+
document: {
|
|
180
|
+
qr: 'https://creds.dock.io/proof/4970377a-6283-46d8-b95e-db99b011e48c',
|
|
181
|
+
id: '4970377a-6283-46d8-b95e-db99b011e48c',
|
|
182
|
+
response_url:
|
|
183
|
+
'https://api-testnet.dock.io/proof-requests/4970377a-6283-46d8-b95e-db99b011e48c/send-presentation',
|
|
184
|
+
type: 'proof-request',
|
|
185
|
+
},
|
|
186
|
+
dataStore: wallet.dataStore,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(result.networkId).toBe('mainnet');
|
|
190
|
+
expect(result.resolver).toBe(proofRequestResolver);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should fallback to current network', async () => {
|
|
194
|
+
await wallet.setNetwork('mainnet');
|
|
195
|
+
|
|
196
|
+
const result = await dockDocumentNetworkResolver({
|
|
197
|
+
document: {
|
|
198
|
+
qr: 'https://something.dock.io/proof/4970377a-6283-46d8-b95e-db99b011e48c',
|
|
199
|
+
id: '4970377a-6283-46d8-b95e-db99b011e48c',
|
|
200
|
+
response_url:
|
|
201
|
+
'https://something.dock.io/proof-requests/4970377a-6283-46d8-b95e-db99b011e48c/send-presentation',
|
|
202
|
+
type: 'proof-request',
|
|
203
|
+
},
|
|
204
|
+
dataStore: wallet.dataStore,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(result.networkId).toBe('mainnet');
|
|
208
|
+
expect(result.isFallback).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
142
211
|
});
|
package/src/network-resolver.ts
CHANGED
|
@@ -15,10 +15,10 @@ export const dockDocumentNetworkResolver: DocumentNetworkResolver = async ({
|
|
|
15
15
|
}: DocumentResolverProps): Promise<DocumentResolverResult> => {
|
|
16
16
|
let networkId;
|
|
17
17
|
let isFallback = false;
|
|
18
|
-
|
|
18
|
+
let currentResolver;
|
|
19
19
|
for (const resolver of resolvers) {
|
|
20
20
|
networkId = await resolver({document, dataStore});
|
|
21
|
-
|
|
21
|
+
currentResolver = resolver;
|
|
22
22
|
if (networkId) {
|
|
23
23
|
break;
|
|
24
24
|
}
|
|
@@ -32,6 +32,7 @@ export const dockDocumentNetworkResolver: DocumentNetworkResolver = async ({
|
|
|
32
32
|
return {
|
|
33
33
|
networkId: networkId,
|
|
34
34
|
isFallback,
|
|
35
|
+
resolver: currentResolver,
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -51,8 +52,14 @@ export function resolveApiNetwork({
|
|
|
51
52
|
}) {
|
|
52
53
|
for (const network of dataStore.networks) {
|
|
53
54
|
for (const hostname of network.credentialHostnames) {
|
|
54
|
-
if (
|
|
55
|
-
|
|
55
|
+
if (hostname instanceof RegExp) {
|
|
56
|
+
if (hostname.test(url)) {
|
|
57
|
+
return network.id;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
if (url.indexOf(hostname) > -1) {
|
|
61
|
+
return network.id;
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
}
|
|
@@ -80,6 +87,27 @@ export async function credentialResolver({
|
|
|
80
87
|
});
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
export async function proofRequestResolver({
|
|
91
|
+
document,
|
|
92
|
+
dataStore,
|
|
93
|
+
}: DocumentResolverProps): Promise<ResolverResult> {
|
|
94
|
+
if (!document) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const isProofRequest =
|
|
99
|
+
document.type === 'proof-request' && document.qr;
|
|
100
|
+
|
|
101
|
+
if (!isProofRequest) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return resolveApiNetwork({
|
|
106
|
+
url: document.qr,
|
|
107
|
+
dataStore,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
83
111
|
export async function didResolver({
|
|
84
112
|
document,
|
|
85
113
|
dataStore,
|
|
@@ -96,7 +124,9 @@ export async function accountResolver({
|
|
|
96
124
|
return null;
|
|
97
125
|
}
|
|
98
126
|
|
|
99
|
-
const isAddress = Array.isArray(document.type)
|
|
127
|
+
const isAddress = Array.isArray(document.type)
|
|
128
|
+
? document.type.includes('Address')
|
|
129
|
+
: document.type === 'Address';
|
|
100
130
|
|
|
101
131
|
if (!isAddress) {
|
|
102
132
|
return null;
|
|
@@ -119,4 +149,9 @@ export async function accountResolver({
|
|
|
119
149
|
return network?.id;
|
|
120
150
|
}
|
|
121
151
|
|
|
122
|
-
const resolvers = [
|
|
152
|
+
const resolvers = [
|
|
153
|
+
credentialResolver,
|
|
154
|
+
accountResolver,
|
|
155
|
+
didResolver,
|
|
156
|
+
proofRequestResolver,
|
|
157
|
+
];
|
package/src/types.ts
CHANGED
|
@@ -37,16 +37,16 @@ export type IWallet = {
|
|
|
37
37
|
getDocumentsById: (idList: string[]) => Promise<WalletDocument[]>;
|
|
38
38
|
getDocumentsByType: (type: string) => Promise<WalletDocument[]>;
|
|
39
39
|
getAllDocuments: () => Promise<WalletDocument[]>;
|
|
40
|
-
addDocument: (json: any) => Promise<WalletDocument>;
|
|
41
|
-
upsertDocument: (json: any) => Promise<WalletDocument>;
|
|
42
|
-
updateDocument: (json: any) => Promise<WalletDocument>;
|
|
40
|
+
addDocument: (json: any, options?: any) => Promise<WalletDocument>;
|
|
41
|
+
upsertDocument: (json: any, options?: any) => Promise<WalletDocument>;
|
|
42
|
+
updateDocument: (json: any, options?: any) => Promise<WalletDocument>;
|
|
43
43
|
getDocumentCorrelations: (documentId: string) => Promise<WalletDocument[]>;
|
|
44
44
|
getAccountKeyPair: (accountId: string) => Promise<any>;
|
|
45
45
|
/**
|
|
46
46
|
* Remove document by id
|
|
47
47
|
* @param id
|
|
48
48
|
*/
|
|
49
|
-
removeDocument: (id: string) => Promise<void>;
|
|
49
|
+
removeDocument: (id: string, options?: any) => Promise<void>;
|
|
50
50
|
/**
|
|
51
51
|
* Import data from a Universal Wallet 2020 JSON
|
|
52
52
|
* https://w3c-ccg.github.io/universal-wallet-interop-spec/
|
|
@@ -72,4 +72,10 @@ export type IWallet = {
|
|
|
72
72
|
dataStore: DataStore;
|
|
73
73
|
} & IV1Wallet;
|
|
74
74
|
|
|
75
|
-
export type
|
|
75
|
+
export type CrateWalletWithDataStore = {
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type CreateWalletProps = {
|
|
80
|
+
dataStore: DataStore;
|
|
81
|
+
}
|
package/src/v1-helpers.ts
CHANGED
|
@@ -41,11 +41,11 @@ export async function toV1Wallet(wallet: IWallet): Promise<IWallet> {
|
|
|
41
41
|
|
|
42
42
|
return wallet.getAllDocuments();
|
|
43
43
|
},
|
|
44
|
-
remove(id: string): Promise<void> {
|
|
44
|
+
remove(id: string, options: any): Promise<void> {
|
|
45
45
|
return wallet.removeDocument(id);
|
|
46
46
|
},
|
|
47
|
-
add(json: any): Promise<WalletDocument> {
|
|
48
|
-
return wallet.addDocument(json);
|
|
47
|
+
add(json: any, options): Promise<WalletDocument> {
|
|
48
|
+
return wallet.addDocument(json, options);
|
|
49
49
|
},
|
|
50
50
|
resolveCorrelations(id: string): Promise<WalletDocument[]> {
|
|
51
51
|
return wallet.getDocumentCorrelations(id);
|
|
@@ -53,8 +53,8 @@ export async function toV1Wallet(wallet: IWallet): Promise<IWallet> {
|
|
|
53
53
|
sync(): Promise<void> {
|
|
54
54
|
return Promise.resolve(undefined);
|
|
55
55
|
},
|
|
56
|
-
update(json: any): Promise<WalletDocument> {
|
|
57
|
-
return wallet.updateDocument(json);
|
|
56
|
+
update(json: any, options): Promise<WalletDocument> {
|
|
57
|
+
return wallet.updateDocument(json, options);
|
|
58
58
|
},
|
|
59
59
|
upsert(json: any): Promise<WalletDocument> {
|
|
60
60
|
return wallet.upsertDocument(json);
|
|
@@ -80,7 +80,7 @@ export type KeypairType = 'sr25519' | 'ed25519' | 'ecdsa';
|
|
|
80
80
|
export function toV1WalletService(wallet: IWallet) {
|
|
81
81
|
return {
|
|
82
82
|
getDocumentById: id => {
|
|
83
|
-
return wallet.getDocumentById(id);
|
|
83
|
+
return wallet.dataStore.documents.getDocumentById(id);
|
|
84
84
|
},
|
|
85
85
|
// accounts are not required in a wallet
|
|
86
86
|
// Ideally should move this code to the accounts provider file
|
|
@@ -12,6 +12,8 @@ import anyCredentialProofRequest from './fixtures/any-credential-proof-request.j
|
|
|
12
12
|
import universityDegreeProofRequest from './fixtures/university-degree-proof-request.json';
|
|
13
13
|
import {createDIDProvider, IDIDProvider} from './did-provider';
|
|
14
14
|
import {WalletEvents} from '@docknetwork/wallet-sdk-wasm/src/modules/wallet';
|
|
15
|
+
import {replaceResponseURL} from './helpers';
|
|
16
|
+
import {createDataStore} from '@docknetwork/wallet-sdk-data-store-typeorm/src';
|
|
15
17
|
|
|
16
18
|
describe('Verification provider', () => {
|
|
17
19
|
let wallet: IWallet;
|
|
@@ -19,8 +21,10 @@ describe('Verification provider', () => {
|
|
|
19
21
|
|
|
20
22
|
beforeAll(async () => {
|
|
21
23
|
wallet = await createWallet({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
dataStore: await createDataStore({
|
|
25
|
+
databasePath: ':memory:',
|
|
26
|
+
defaultNetwork: 'testnet',
|
|
27
|
+
}),
|
|
24
28
|
});
|
|
25
29
|
|
|
26
30
|
await wallet.waitForEvent(WalletEvents.networkConnected);
|
|
@@ -93,8 +97,9 @@ describe('Verification provider', () => {
|
|
|
93
97
|
didProvider,
|
|
94
98
|
});
|
|
95
99
|
|
|
100
|
+
const updatedTemplate = replaceResponseURL(iiwTemplate);
|
|
96
101
|
await controller.start({
|
|
97
|
-
template:
|
|
102
|
+
template: updatedTemplate,
|
|
98
103
|
});
|
|
99
104
|
|
|
100
105
|
const credentials = controller.getFilteredCredentials();
|
|
@@ -10,7 +10,6 @@ import {EventEmitter} from 'events';
|
|
|
10
10
|
import axios from 'axios';
|
|
11
11
|
import assert from 'assert';
|
|
12
12
|
import {createDIDProvider, IDIDProvider} from './did-provider';
|
|
13
|
-
import { getWallet } from '@docknetwork/wallet-sdk-data-store/src/entities/wallet.entity';
|
|
14
13
|
|
|
15
14
|
export enum VerificationStatus {
|
|
16
15
|
Started = 'Started',
|
|
@@ -151,6 +150,10 @@ export function createVerificationController({
|
|
|
151
150
|
return credentialServiceRPC.isBBSPlusCredential({credential});
|
|
152
151
|
}
|
|
153
152
|
|
|
153
|
+
async function isKvacCredential(credential) {
|
|
154
|
+
return credentialServiceRPC.isKvacCredential({credential});
|
|
155
|
+
}
|
|
156
|
+
|
|
154
157
|
async function createPresentation() {
|
|
155
158
|
assert(!!selectedDID, 'No DID selected');
|
|
156
159
|
assert(!!selectedCredentials.size, 'No credentials selected');
|
|
@@ -164,13 +167,12 @@ export function createVerificationController({
|
|
|
164
167
|
|
|
165
168
|
for (const credentialSelection of selectedCredentials.values()) {
|
|
166
169
|
const isBBS = await isBBSPlusCredential(credentialSelection.credential);
|
|
170
|
+
const isKVAC = await isKvacCredential(credentialSelection.credential);
|
|
167
171
|
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
} else {
|
|
171
|
-
// derive BBS credential
|
|
172
|
+
if (isBBS || isKVAC) {
|
|
173
|
+
// derive credential
|
|
172
174
|
const derivedCredentials =
|
|
173
|
-
await credentialServiceRPC.
|
|
175
|
+
await credentialServiceRPC.deriveVCFromPresentation({
|
|
174
176
|
proofRequest: templateJSON,
|
|
175
177
|
|
|
176
178
|
credentials: [
|
|
@@ -188,6 +190,8 @@ export function createVerificationController({
|
|
|
188
190
|
console.log('Credential derived');
|
|
189
191
|
|
|
190
192
|
credentials.push(derivedCredentials[0]);
|
|
193
|
+
} else {
|
|
194
|
+
credentials.push(credentialSelection.credential);
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
197
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import {IWallet} from '../types';
|
|
13
13
|
import {IMessageProvider} from '../message-provider';
|
|
14
14
|
import {logger} from '@docknetwork/wallet-sdk-data-store/src/logger';
|
|
15
|
+
import { EventEmitter } from 'events';
|
|
15
16
|
|
|
16
17
|
const ProofRequestTemplateType = 'ProofRequestTemplate';
|
|
17
18
|
|
|
@@ -29,6 +30,12 @@ export interface IWalletToWalletVerificationProvider {
|
|
|
29
30
|
addProofRequestTemplate: (proofRequestTemplate: any) => Promise<any>;
|
|
30
31
|
getProofRequestTemplates: () => Promise<any[]>;
|
|
31
32
|
handleMessage: (message: any) => Promise<boolean>;
|
|
33
|
+
eventEmitter: EventEmitter;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const Events = {
|
|
37
|
+
VerifierFlowStarted: 'VerifierFlowStarted',
|
|
38
|
+
HolderFlowStarted: 'HolderFlowStarted',
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
export function createWalletToWalletVerificationProvider({
|
|
@@ -47,7 +54,10 @@ export function createWalletToWalletVerificationProvider({
|
|
|
47
54
|
// Can be used by the HOLDER to render the verification results sent by the verifier
|
|
48
55
|
let presentationAckHandler;
|
|
49
56
|
|
|
57
|
+
const eventEmitter = new EventEmitter();
|
|
58
|
+
|
|
50
59
|
return {
|
|
60
|
+
eventEmitter,
|
|
51
61
|
getInvitationOOBMessage: async ({templateId}) => {
|
|
52
62
|
const defaultDID = await didProvider.getDefaultDID();
|
|
53
63
|
const template = await wallet.getDocumentById(templateId);
|
|
@@ -100,6 +110,9 @@ export function createWalletToWalletVerificationProvider({
|
|
|
100
110
|
verifierDID: message.from,
|
|
101
111
|
}),
|
|
102
112
|
);
|
|
113
|
+
|
|
114
|
+
eventEmitter.emit(Events.HolderFlowStarted);
|
|
115
|
+
|
|
103
116
|
return true;
|
|
104
117
|
}
|
|
105
118
|
|
|
@@ -132,6 +145,8 @@ export function createWalletToWalletVerificationProvider({
|
|
|
132
145
|
verifierDID: defaultDID,
|
|
133
146
|
}),
|
|
134
147
|
);
|
|
148
|
+
|
|
149
|
+
eventEmitter.emit(Events.VerifierFlowStarted);
|
|
135
150
|
}
|
|
136
151
|
|
|
137
152
|
process();
|
package/src/wallet-wasm.ts
CHANGED
|
@@ -64,7 +64,7 @@ export async function initWalletWasm(wallet: IWallet) {
|
|
|
64
64
|
await setSubstrateNetwork(wallet);
|
|
65
65
|
|
|
66
66
|
wallet.eventManager.on(WalletEvents.networkUpdated, async () => {
|
|
67
|
-
handleSubstrateNetworkChange(wallet);
|
|
67
|
+
handleSubstrateNetworkChange(wallet).catch(err => console.error(err));
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|