@docknetwork/wallet-sdk-core 0.4.19

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 (97) hide show
  1. package/LICENSE +39 -0
  2. package/babel.config.js +16 -0
  3. package/jest.config.ts +39 -0
  4. package/lib/account-provider.d.ts +8 -0
  5. package/lib/account-provider.d.ts.map +1 -0
  6. package/lib/account-provider.js +15 -0
  7. package/lib/account-provider.js.map +1 -0
  8. package/lib/biometric-provider.d.ts +29 -0
  9. package/lib/biometric-provider.d.ts.map +1 -0
  10. package/lib/biometric-provider.js +54 -0
  11. package/lib/biometric-provider.js.map +1 -0
  12. package/lib/credential-provider.d.ts +58 -0
  13. package/lib/credential-provider.d.ts.map +1 -0
  14. package/lib/credential-provider.js +198 -0
  15. package/lib/credential-provider.js.map +1 -0
  16. package/lib/did-provider.d.ts +79 -0
  17. package/lib/did-provider.d.ts.map +1 -0
  18. package/lib/did-provider.js +215 -0
  19. package/lib/did-provider.js.map +1 -0
  20. package/lib/ecosystem-tools.d.ts +11 -0
  21. package/lib/ecosystem-tools.d.ts.map +1 -0
  22. package/lib/ecosystem-tools.js +33 -0
  23. package/lib/ecosystem-tools.js.map +1 -0
  24. package/lib/helpers.d.ts +8 -0
  25. package/lib/helpers.d.ts.map +1 -0
  26. package/lib/helpers.js +63 -0
  27. package/lib/helpers.js.map +1 -0
  28. package/lib/message-provider.d.ts +36 -0
  29. package/lib/message-provider.d.ts.map +1 -0
  30. package/lib/message-provider.js +172 -0
  31. package/lib/message-provider.js.map +1 -0
  32. package/lib/messages/message-helpers.d.ts +110 -0
  33. package/lib/messages/message-helpers.d.ts.map +1 -0
  34. package/lib/messages/message-helpers.js +106 -0
  35. package/lib/messages/message-helpers.js.map +1 -0
  36. package/lib/network-resolver.d.ts +19 -0
  37. package/lib/network-resolver.d.ts.map +1 -0
  38. package/lib/network-resolver.js +80 -0
  39. package/lib/network-resolver.js.map +1 -0
  40. package/lib/types.d.ts +63 -0
  41. package/lib/types.d.ts.map +1 -0
  42. package/lib/types.js +3 -0
  43. package/lib/types.js.map +1 -0
  44. package/lib/v1-helpers.d.ts +20 -0
  45. package/lib/v1-helpers.d.ts.map +1 -0
  46. package/lib/v1-helpers.js +147 -0
  47. package/lib/v1-helpers.js.map +1 -0
  48. package/lib/verification-controller.d.ts +48 -0
  49. package/lib/verification-controller.d.ts.map +1 -0
  50. package/lib/verification-controller.js +219 -0
  51. package/lib/verification-controller.js.map +1 -0
  52. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts +20 -0
  53. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.d.ts.map +1 -0
  54. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js +140 -0
  55. package/lib/wallet-to-wallet-verification/walletToWalletVerificationProvider.js.map +1 -0
  56. package/lib/wallet-wasm.d.ts +10 -0
  57. package/lib/wallet-wasm.d.ts.map +1 -0
  58. package/lib/wallet-wasm.js +62 -0
  59. package/lib/wallet-wasm.js.map +1 -0
  60. package/lib/wallet.d.ts +11 -0
  61. package/lib/wallet.d.ts.map +1 -0
  62. package/lib/wallet.js +173 -0
  63. package/lib/wallet.js.map +1 -0
  64. package/package.json +34 -0
  65. package/setup-tests.ts +1 -0
  66. package/src/account-provider.ts +18 -0
  67. package/src/biometric-provider.ts +82 -0
  68. package/src/credential-provider.test.ts +164 -0
  69. package/src/credential-provider.ts +272 -0
  70. package/src/did-provider.test.ts +203 -0
  71. package/src/did-provider.ts +263 -0
  72. package/src/ecosystem-tools.ts +37 -0
  73. package/src/fixtures/any-credential-proof-request.json +30 -0
  74. package/src/fixtures/biometrics-credential-bbs-revocation.json +62 -0
  75. package/src/fixtures/customer-credential.json +39 -0
  76. package/src/fixtures/iiw-credential.json +59 -0
  77. package/src/fixtures/iiw-template.json +33 -0
  78. package/src/fixtures/university-degree-bbs.json +57 -0
  79. package/src/fixtures/university-degree-proof-request.json +32 -0
  80. package/src/helpers.ts +61 -0
  81. package/src/message-provider.test.ts +115 -0
  82. package/src/message-provider.ts +221 -0
  83. package/src/messages/message-helpers.ts +125 -0
  84. package/src/messages/relay-service-mocks/demo-app-messages.json +450 -0
  85. package/src/network-resolver.test.ts +142 -0
  86. package/src/network-resolver.ts +122 -0
  87. package/src/types.ts +75 -0
  88. package/src/v1-helpers.ts +160 -0
  89. package/src/verification-controller.test.ts +149 -0
  90. package/src/verification-controller.ts +276 -0
  91. package/src/wallet-to-wallet-verification/walletToWalletVerificationProvider.ts +216 -0
  92. package/src/wallet-wasm.ts +74 -0
  93. package/src/wallet.test.ts +72 -0
  94. package/src/wallet.ts +211 -0
  95. package/tsconfig.build.json +26 -0
  96. package/tsconfig.build.tsbuildinfo +1 -0
  97. package/tsconfig.json +30 -0
@@ -0,0 +1,276 @@
1
+ import {getJSON} from './helpers';
2
+ import {pexService} from '@docknetwork/wallet-sdk-wasm/src/services/pex';
3
+ import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
4
+ import {
5
+ createCredentialProvider,
6
+ ICredentialProvider,
7
+ } from './credential-provider';
8
+ import {IWallet} from './types';
9
+ import {EventEmitter} from 'events';
10
+ import axios from 'axios';
11
+ import assert from 'assert';
12
+ import {createDIDProvider, IDIDProvider} from './did-provider';
13
+ import { getWallet } from '@docknetwork/wallet-sdk-data-store/src/entities/wallet.entity';
14
+
15
+ export enum VerificationStatus {
16
+ Started = 'Started',
17
+ LoadingTemplate = 'LoadingTemplate',
18
+ Filtering = 'Filtering',
19
+ FetchingProvingKey = 'FetchingProvingKey',
20
+ Error = 'Error',
21
+ NoCredentialsInTheWallet = 'NoCredentialsInTheWallet',
22
+ SelectingCredentials = 'SelectingCredentials',
23
+ }
24
+
25
+ function isRangeProofTemplate(templateJSON) {
26
+ return templateJSON.proving_key;
27
+ }
28
+
29
+ type CredentialId = string;
30
+ type CredentialSelection = {
31
+ credential: any;
32
+ attributesToReveal?: string[];
33
+ };
34
+ type CredentialSelectionMap = Map<CredentialId, CredentialSelection>;
35
+
36
+ export function createVerificationController({
37
+ wallet,
38
+ credentialProvider,
39
+ didProvider,
40
+ }: {
41
+ wallet: IWallet;
42
+ credentialProvider?: ICredentialProvider;
43
+ didProvider?: IDIDProvider;
44
+ }) {
45
+ const emitter = new EventEmitter();
46
+ let templateJSON = null;
47
+ let status = VerificationStatus.Started;
48
+ /**
49
+ * Extra data to give better context to the current state
50
+ * Can be used to show error messages, or more specific information about the state
51
+ */
52
+ let statusData = null;
53
+ let filteredCredentials = [];
54
+ let selectedCredentials: CredentialSelectionMap = new Map();
55
+ let selectedDID = null;
56
+ let provingKey = null;
57
+
58
+ if (!credentialProvider) {
59
+ credentialProvider = createCredentialProvider({wallet});
60
+ }
61
+
62
+ if (!didProvider) {
63
+ didProvider = createDIDProvider({wallet});
64
+ }
65
+
66
+ async function fetchProvingKey(templateJSON: any) {
67
+ if (templateJSON.proving_key) {
68
+ setState(VerificationStatus.FetchingProvingKey);
69
+ try {
70
+ provingKey = await axios
71
+ .get(templateJSON.proving_key)
72
+ .then(res => res.data);
73
+ } catch (err) {
74
+ setState(VerificationStatus.Error, {
75
+ message: 'failed_to_fetch_proving_key',
76
+ });
77
+
78
+ throw err;
79
+ }
80
+ }
81
+ }
82
+
83
+ async function start({template}: {template: string | any}) {
84
+ setState(VerificationStatus.LoadingTemplate);
85
+
86
+ // check for dids
87
+ const dids = await didProvider.getAll();
88
+
89
+ if (!dids.length) {
90
+ setState(VerificationStatus.Error, {
91
+ message: 'no_dids_in_the_wallet',
92
+ });
93
+ throw new Error('No DIDs in the wallet');
94
+ }
95
+
96
+ // the application needs to verify if there are more DIDs available, and allow the user to change this selection before creating a presentation
97
+ selectedDID = dids[0].didDocument.id;
98
+ templateJSON = await getJSON(template);
99
+
100
+ await fetchProvingKey(templateJSON);
101
+ await loadCredentials();
102
+
103
+ setState(VerificationStatus.SelectingCredentials);
104
+ }
105
+
106
+ function setState(_status: VerificationStatus, data?: any) {
107
+ status = _status;
108
+ statusData = data;
109
+ emitter.emit(_status, data);
110
+ }
111
+
112
+ async function loadCredentials() {
113
+ setState(VerificationStatus.Filtering);
114
+
115
+ // get wallet credentials and apply pex filter
116
+ const allCredentials = await credentialProvider.getCredentials();
117
+
118
+ if (!allCredentials.length) {
119
+ setState(VerificationStatus.NoCredentialsInTheWallet);
120
+ return;
121
+ }
122
+
123
+ try {
124
+ const result = await pexService.filterCredentials({
125
+ credentials: allCredentials,
126
+ presentationDefinition: getPresentationDefinition(),
127
+ holderDIDs: [],
128
+ });
129
+
130
+ filteredCredentials = result.verifiableCredential;
131
+ } catch (err) {
132
+ console.error(
133
+ `Unable to filter credentials using the template: \n ${JSON.stringify(
134
+ templateJSON,
135
+ null,
136
+ 2,
137
+ )}`,
138
+ );
139
+ console.error(err);
140
+
141
+ setState(VerificationStatus.Error);
142
+ throw err;
143
+ }
144
+ }
145
+
146
+ function getPresentationDefinition() {
147
+ return templateJSON.request;
148
+ }
149
+
150
+ async function isBBSPlusCredential(credential) {
151
+ return credentialServiceRPC.isBBSPlusCredential({credential});
152
+ }
153
+
154
+ async function createPresentation() {
155
+ assert(!!selectedDID, 'No DID selected');
156
+ assert(!!selectedCredentials.size, 'No credentials selected');
157
+
158
+ if (isRangeProofTemplate(templateJSON)) {
159
+ // TODO: Implement proving key usage for range-proofs
160
+ assert(!!provingKey, 'No proving key found');
161
+ }
162
+
163
+ const credentials = [];
164
+
165
+ for (const credentialSelection of selectedCredentials.values()) {
166
+ const isBBS = await isBBSPlusCredential(credentialSelection.credential);
167
+
168
+ if (!isBBS) {
169
+ credentials.push(credentialSelection.credential);
170
+ } else {
171
+ // derive BBS credential
172
+ const derivedCredentials =
173
+ await credentialServiceRPC.deriveVCFromBBSPresentation({
174
+ proofRequest: templateJSON,
175
+
176
+ credentials: [
177
+ {
178
+ credential: credentialSelection.credential,
179
+ witness: await credentialProvider.getMembershipWitness(credentialSelection.credential.id),
180
+ attributesToReveal: [
181
+ ...(credentialSelection.attributesToReveal || []),
182
+ 'id',
183
+ ],
184
+ },
185
+ ],
186
+ });
187
+
188
+ console.log('Credential derived');
189
+
190
+ credentials.push(derivedCredentials[0]);
191
+ }
192
+ }
193
+
194
+ const didKeyPairList = await didProvider.getDIDKeyPairs();
195
+ const keyDoc = didKeyPairList.find(doc => doc.controller === selectedDID);
196
+
197
+ assert(keyDoc, `No key pair found for the selected DID ${selectedDID}`);
198
+
199
+ const presentation = await credentialServiceRPC.createPresentation({
200
+ credentials,
201
+ challenge: templateJSON.nonce,
202
+ keyDoc,
203
+ id: keyDoc.controller.startsWith('did:key:')
204
+ ? keyDoc.id
205
+ : `${keyDoc.controller}#keys-1`,
206
+ domain: 'dock.io',
207
+ });
208
+
209
+ return presentation;
210
+ }
211
+
212
+ /**
213
+ * Filtered credentials
214
+ */
215
+ function getFilteredCredentials() {
216
+ return filteredCredentials;
217
+ }
218
+
219
+ function getStatus() {
220
+ return status;
221
+ }
222
+
223
+ function getStatusData() {
224
+ return statusData;
225
+ }
226
+
227
+ function setSelectedDID(did: string) {
228
+ selectedDID = did;
229
+ }
230
+
231
+ /**
232
+ * Use pex to evaluate presentation
233
+ *
234
+ * @param presentation
235
+ */
236
+ function evaluatePresentation(presentation) {
237
+ const definition = getPresentationDefinition();
238
+ const result = credentialServiceRPC.evaluatePresentation({
239
+ presentation,
240
+ presentationDefinition: definition,
241
+ });
242
+
243
+ return {
244
+ isValid: result.errors.length === 0,
245
+ errors: result.errors,
246
+ warnings: result.warnings,
247
+ };
248
+ }
249
+
250
+ function submitPresentation(presentation) {
251
+ return axios
252
+ .post(templateJSON.response_url, presentation)
253
+ .then(res => res.data);
254
+ }
255
+
256
+ return {
257
+ emitter,
258
+ selectedCredentials,
259
+ getStatus,
260
+ getStatusData,
261
+ submitPresentation,
262
+ getSelectedDID() {
263
+ return selectedDID;
264
+ },
265
+ setSelectedDID,
266
+ start,
267
+ isBBSPlusCredential,
268
+ loadCredentials,
269
+ getFilteredCredentials,
270
+ createPresentation,
271
+ evaluatePresentation,
272
+ getTemplateJSON() {
273
+ return templateJSON;
274
+ },
275
+ };
276
+ }
@@ -0,0 +1,216 @@
1
+ import assert from 'assert';
2
+ import {IDIDProvider} from '../did-provider';
3
+ import {
4
+ Goals,
5
+ MessageTypes,
6
+ buildAckWalletToWalletVerificationMessage,
7
+ buildVerificationFlowInviteMessage,
8
+ buildRequestVerifiablePresentationMessage,
9
+ buildVerifiablePresentationAckMessage,
10
+ buildVerifiablePresentationMessage,
11
+ } from '../messages/message-helpers';
12
+ import {IWallet} from '../types';
13
+ import {IMessageProvider} from '../message-provider';
14
+ import {logger} from '@docknetwork/wallet-sdk-data-store/src/logger';
15
+
16
+ const ProofRequestTemplateType = 'ProofRequestTemplate';
17
+
18
+ export interface IWalletToWalletVerificationProvider {
19
+ getInvitationOOBMessage: ({templateId}: {templateId: string}) => Promise<any>;
20
+ setProofRequestHandler: (
21
+ handler: (proofRequest: any) => any,
22
+ ) => Promise<void>;
23
+ setPresentationHandler: (
24
+ handler: (presentation: any, proofRequest: any) => any,
25
+ ) => Promise<void>;
26
+ setPresentationAckHandler: (
27
+ handler: (proofRequest: any) => any,
28
+ ) => Promise<void>;
29
+ addProofRequestTemplate: (proofRequestTemplate: any) => Promise<any>;
30
+ getProofRequestTemplates: () => Promise<any[]>;
31
+ handleMessage: (message: any) => Promise<boolean>;
32
+ }
33
+
34
+ export function createWalletToWalletVerificationProvider({
35
+ wallet,
36
+ didProvider,
37
+ messageProvider,
38
+ }: {
39
+ wallet: IWallet;
40
+ didProvider: IDIDProvider;
41
+ messageProvider: IMessageProvider;
42
+ }): IWalletToWalletVerificationProvider {
43
+ // Should be used by the HOLDER to create a presentation for the verifier
44
+ let proofRequestHandler;
45
+ // Should be used by the VERIFIER verify a presentation received by the holder
46
+ let presentationHandler;
47
+ // Can be used by the HOLDER to render the verification results sent by the verifier
48
+ let presentationAckHandler;
49
+
50
+ return {
51
+ getInvitationOOBMessage: async ({templateId}) => {
52
+ const defaultDID = await didProvider.getDefaultDID();
53
+ const template = await wallet.getDocumentById(templateId);
54
+
55
+ assert(!!template, `Template with id ${templateId} not found`);
56
+
57
+ return buildVerificationFlowInviteMessage({
58
+ proofRequestId: templateId,
59
+ verifierDID: defaultDID,
60
+ });
61
+ },
62
+ setProofRequestHandler: async (handler: (proofRequest: any) => any) => {
63
+ proofRequestHandler = handler;
64
+ },
65
+ setPresentationHandler: async (handler: (presentation: any, proofRequest: any) => any) => {
66
+ presentationHandler = handler;
67
+ },
68
+ setPresentationAckHandler: async (handler: (proofRequest: any) => any) => {
69
+ presentationAckHandler = handler;
70
+ },
71
+ addProofRequestTemplate: async (proofRequestTemplate: any) => {
72
+ assert(
73
+ !!proofRequestTemplate.input_descriptors,
74
+ 'Input descriptions are required',
75
+ );
76
+ return wallet.addDocument({
77
+ type: ProofRequestTemplateType,
78
+ template: proofRequestTemplate,
79
+ });
80
+ },
81
+ getProofRequestTemplates: async () => {
82
+ return wallet.getDocumentsByType(ProofRequestTemplateType);
83
+ },
84
+ handleMessage: async (message: any) => {
85
+ logger.debug('Received message');
86
+ logger.debug(message);
87
+ if (
88
+ message.type === MessageTypes.Invitation &&
89
+ message?.body?.goal_code === Goals.WalletToWalletVerification
90
+ ) {
91
+ // Received a verification invitation from the verifier
92
+ // Sends back an ack message to the verifier
93
+ const defaultDID = await didProvider.getDefaultDID();
94
+ logger.debug('Received invitation');
95
+ logger.debug('Sending ack message to the verifier');
96
+ messageProvider.sendMessage(
97
+ buildAckWalletToWalletVerificationMessage({
98
+ holderDID: defaultDID,
99
+ proofRequestId: message.body.proofRequestId,
100
+ verifierDID: message.from,
101
+ }),
102
+ );
103
+ return true;
104
+ }
105
+
106
+ // The holder sent an ack message to the verifier invite
107
+ // Now the verifier knows the holder did and can offer a proof request
108
+ if (
109
+ message.type === MessageTypes.Ack &&
110
+ message?.body?.goal_code === Goals.WalletToWalletVerification
111
+ ) {
112
+ async function process() {
113
+ logger.debug(message);
114
+ const templateId = message.body.proofRequestId;
115
+ assert(!!templateId, 'Template ID not found in ack message');
116
+ const defaultDID = await didProvider.getDefaultDID();
117
+ const proofRequestTemplate = await wallet.getDocumentById(templateId);
118
+
119
+ assert(!!proofRequestTemplate, 'Proof request template not found');
120
+
121
+ logger.debug('Sending proof request to the holder');
122
+
123
+ const proofRequest = proofRequestTemplate.template;
124
+
125
+ assert(!!proofRequest, 'Proof request not found');
126
+
127
+ messageProvider.sendMessage(
128
+ buildRequestVerifiablePresentationMessage({
129
+ proofRequestId: templateId,
130
+ proofRequest: proofRequestTemplate.template,
131
+ holderDID: message.from,
132
+ verifierDID: defaultDID,
133
+ }),
134
+ );
135
+ }
136
+
137
+ process();
138
+
139
+ return true;
140
+ }
141
+
142
+ // The holder received a proof request from the verifier
143
+ if (message.type === MessageTypes.RequestPresentation) {
144
+ logger.debug('Received proof request from the verifier');
145
+
146
+ assert(!!proofRequestHandler, 'No proof request handler set');
147
+
148
+ logger.debug(
149
+ 'Waiting for proofRequest handler to return a presentation',
150
+ );
151
+ Promise.resolve(proofRequestHandler(message.body.proofRequest)).then(
152
+ async presentation => {
153
+ logger.debug('Presentation received from handler');
154
+ const defaultDID = await didProvider.getDefaultDID();
155
+ logger.debug('Sending presentation to the verifier');
156
+ messageProvider.sendMessage(
157
+ buildVerifiablePresentationMessage({
158
+ holderDID: defaultDID,
159
+ presentation,
160
+ proofRequestId: message.body.proofRequestId,
161
+ verifierDID: message.from,
162
+ }),
163
+ );
164
+ },
165
+ );
166
+
167
+ return true;
168
+ }
169
+
170
+ // The verifier received a presentation from the holder
171
+ if (message.type === MessageTypes.Presentation) {
172
+ logger.debug('Received presentation from the holder');
173
+
174
+ const proofRequestTemplate = await wallet.getDocumentById(message.body.proofRequestId);
175
+ const proofRequest = proofRequestTemplate?.template;
176
+
177
+ assert(!!proofRequest, 'Proof request template not found');
178
+
179
+ logger.debug(
180
+ 'Waiting for presentation handler to return a presentation',
181
+ );
182
+ assert(!!presentationHandler, 'No presentation handler set');
183
+
184
+ Promise.resolve(presentationHandler(message.body.presentation, proofRequest)).then(
185
+ async presentationResult => {
186
+ const defaultDID = await didProvider.getDefaultDID();
187
+ logger.debug('Sending presentation ack to the holder');
188
+ messageProvider.sendMessage(
189
+ buildVerifiablePresentationAckMessage({
190
+ holderDID: message.from,
191
+ presentationResult,
192
+ proofRequestId: message.body.proofRequestId,
193
+ verifierDID: defaultDID,
194
+ }),
195
+ );
196
+ },
197
+ );
198
+
199
+ return true;
200
+ }
201
+
202
+ // The holder received a presentation ack from the verifier
203
+ if (
204
+ message.type === MessageTypes.Ack &&
205
+ message.body.goal_code === Goals.PresentationAckFromVerifier
206
+ ) {
207
+ logger.debug('Received presentation ack from the verifier');
208
+ logger.debug('Presentation ack received');
209
+ if (presentationAckHandler) {
210
+ presentationAckHandler(message.body.presentationResult);
211
+ }
212
+ return true;
213
+ }
214
+ },
215
+ };
216
+ }
@@ -0,0 +1,74 @@
1
+ import {keyringService} from '@docknetwork/wallet-sdk-wasm/src/services/keyring';
2
+ import {utilCryptoService} from '@docknetwork/wallet-sdk-wasm/src/services/util-crypto';
3
+ import {dockService} from '@docknetwork/wallet-sdk-wasm/src/services/dock';
4
+
5
+ import {IWallet} from './types';
6
+ import {Network} from '@docknetwork/wallet-sdk-data-store/src/types';
7
+ import {WalletEvents} from '@docknetwork/wallet-sdk-wasm/src/modules/wallet';
8
+ import { captureException } from './helpers';
9
+
10
+ function isSubstrateNetwork(network: Network) {
11
+ return !!network.configs.substrateUrl;
12
+ }
13
+
14
+ /**
15
+ * Update existing substrate network connection
16
+ * Compare connected substrate connection with the current walle network
17
+ * Disconnect and Establish a new connection if the network is different
18
+ */
19
+ export async function handleSubstrateNetworkChange(
20
+ wallet: IWallet,
21
+ ): Promise<void> {
22
+ const currentSubstrateAddress = await dockService.getAddress();
23
+ const substrateNetworkId = wallet.dataStore.networks.find(
24
+ network => network.configs.substrateUrl === currentSubstrateAddress,
25
+ )?.id;
26
+ const currentNetworkId = wallet.dataStore.network?.id;
27
+
28
+ if (substrateNetworkId === currentNetworkId) {
29
+ return;
30
+ }
31
+
32
+ await dockService.disconnect();
33
+ await setSubstrateNetwork(wallet);
34
+ }
35
+
36
+ export async function setSubstrateNetwork(wallet: IWallet) {
37
+ const network = wallet.dataStore.network;
38
+ const networkConfigs = network.configs;
39
+
40
+ await keyringService.initialize({
41
+ ss58Format: networkConfigs.addressPrefix,
42
+ });
43
+
44
+ dockService
45
+ .init({
46
+ address: networkConfigs.substrateUrl,
47
+ })
48
+ .then(() => {
49
+ wallet.eventManager.emit(WalletEvents.networkConnected);
50
+ })
51
+ .catch(err => {
52
+ captureException(new Error('Unable to connect to substrate node'));
53
+ captureException(err);
54
+ console.error(err);
55
+ wallet.eventManager.emit(WalletEvents.networkError, err);
56
+ });
57
+ }
58
+
59
+ export async function initWalletWasm(wallet: IWallet) {
60
+ await utilCryptoService.cryptoWaitReady();
61
+ const network = wallet.dataStore.network;
62
+
63
+ if (isSubstrateNetwork(network)) {
64
+ await setSubstrateNetwork(wallet);
65
+
66
+ wallet.eventManager.on(WalletEvents.networkUpdated, async () => {
67
+ handleSubstrateNetworkChange(wallet);
68
+ });
69
+ }
70
+
71
+ wallet.setStatus('ready');
72
+
73
+ wallet.eventManager.emit(WalletEvents.ready);
74
+ }
@@ -0,0 +1,72 @@
1
+ import {createDIDProvider} from './did-provider';
2
+ import {createWallet, ensureDocumentContext, IWallet} from './wallet';
3
+
4
+ describe('Wallet', () => {
5
+ let wallet: IWallet;
6
+
7
+ beforeEach(async () => {
8
+ wallet = await createWallet({
9
+ databasePath: ':memory:',
10
+ });
11
+ });
12
+
13
+ it('expect to create a wallet', async () => {
14
+ expect(wallet).toBeDefined();
15
+ expect(wallet.dataStore).toBeDefined();
16
+ });
17
+
18
+ it('expect to add missing @context on documents', () => {
19
+ const documents = [
20
+ {
21
+ id: 1,
22
+ },
23
+ {
24
+ id: 2,
25
+ '@context': 'test',
26
+ },
27
+ ];
28
+
29
+ const result = documents.map(ensureDocumentContext);
30
+
31
+ expect(result[0]['@context']).toStrictEqual(['https://w3id.org/wallet/v1']);
32
+ expect(result[1]['@context']).toEqual('test');
33
+ });
34
+
35
+ it('expect to create default dids', async () => {
36
+ const mainnetDIDs = await createDIDProvider({wallet}).getAll();
37
+ expect(mainnetDIDs.length).toBe(1);
38
+ await wallet.setNetwork('testnet');
39
+ await new Promise(resolve => setTimeout(resolve, 1000));
40
+ const testnetDIDs = await createDIDProvider({wallet}).getAll();
41
+ expect(testnetDIDs.length).toBe(1);
42
+ expect(mainnetDIDs[0]).not.toEqual(testnetDIDs[0]);
43
+ });
44
+
45
+ describe('document CRUD', () => {
46
+ const mockDocument = {
47
+ id: 'test',
48
+ type: 'VerifiableCredential',
49
+ };
50
+
51
+ beforeEach(async () => {
52
+ await wallet.addDocument(mockDocument);
53
+ });
54
+
55
+ it('expect to get a document by id', async () => {
56
+ const result = await wallet.getDocumentById(mockDocument.id);
57
+ expect(result.id).toEqual(mockDocument.id);
58
+ expect(result).toStrictEqual(mockDocument);
59
+ });
60
+
61
+ it('expect to get document by type', async () => {
62
+ const result = await wallet.getDocumentsByType(mockDocument.type);
63
+ expect(result[0]).toStrictEqual(mockDocument);
64
+ });
65
+
66
+ it('expect to remove a document', async () => {
67
+ await wallet.removeDocument(mockDocument.id);
68
+ const result = await wallet.getDocumentById(mockDocument.id);
69
+ expect(result).toBeNull();
70
+ });
71
+ });
72
+ });