@docknetwork/wallet-sdk-core 1.5.9 → 1.5.11

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 (45) hide show
  1. package/jest.config.ts +1 -1
  2. package/lib/credential-provider.d.ts +2 -7
  3. package/lib/credential-provider.d.ts.map +1 -1
  4. package/lib/credential-provider.js +15 -1
  5. package/lib/credential-provider.js.map +1 -1
  6. package/lib/did-provider.js +2 -2
  7. package/lib/did-provider.js.map +1 -1
  8. package/lib/ecosystem-tools.d.ts +2 -0
  9. package/lib/ecosystem-tools.d.ts.map +1 -1
  10. package/lib/ecosystem-tools.js +27 -1
  11. package/lib/ecosystem-tools.js.map +1 -1
  12. package/lib/network-resolver.d.ts +0 -1
  13. package/lib/network-resolver.d.ts.map +1 -1
  14. package/lib/network-resolver.js +1 -23
  15. package/lib/network-resolver.js.map +1 -1
  16. package/lib/types.d.ts +1 -3
  17. package/lib/types.d.ts.map +1 -1
  18. package/lib/wallet-wasm.d.ts.map +1 -1
  19. package/lib/wallet-wasm.js +1 -6
  20. package/lib/wallet-wasm.js.map +1 -1
  21. package/lib/wallet.d.ts +16 -0
  22. package/lib/wallet.d.ts.map +1 -1
  23. package/lib/wallet.js +29 -18
  24. package/lib/wallet.js.map +1 -1
  25. package/package.json +4 -4
  26. package/src/credential-provider.test.ts +105 -13
  27. package/src/credential-provider.ts +18 -1
  28. package/src/did-provider.ts +2 -2
  29. package/src/ecosystem-tools.ts +29 -0
  30. package/src/network-resolver.ts +0 -36
  31. package/src/types.ts +1 -5
  32. package/src/verification-controller.test.ts +1 -1
  33. package/src/wallet-wasm.ts +1 -7
  34. package/src/wallet.ts +24 -8
  35. package/tsconfig.build.tsbuildinfo +1 -1
  36. package/lib/account-provider.d.ts +0 -8
  37. package/lib/account-provider.d.ts.map +0 -1
  38. package/lib/account-provider.js +0 -15
  39. package/lib/account-provider.js.map +0 -1
  40. package/lib/v1-helpers.d.ts +0 -20
  41. package/lib/v1-helpers.d.ts.map +0 -1
  42. package/lib/v1-helpers.js +0 -147
  43. package/lib/v1-helpers.js.map +0 -1
  44. package/src/account-provider.ts +0 -18
  45. package/src/v1-helpers.ts +0 -160
@@ -9,22 +9,56 @@ import {IWallet, createWallet} from './wallet';
9
9
  import biometricsBBSRevocation from './fixtures/biometrics-credential-bbs-revocation.json';
10
10
  import customerCredential from './fixtures/customer-credential.json';
11
11
  import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
12
- import {createDataStore} from '@docknetwork/wallet-sdk-data-store-typeorm/src'
12
+ import {createDataStore} from '@docknetwork/wallet-sdk-data-store-web/src'
13
+ import {blockchainService} from '@docknetwork/wallet-sdk-wasm/src/services/blockchain';
14
+
15
+ jest.mock('@docknetwork/wallet-sdk-wasm/src/services/blockchain', () => ({
16
+ blockchainService: {
17
+ init: jest.fn().mockResolvedValue(true),
18
+ ensureBlockchainReady: jest.fn().mockResolvedValue(true),
19
+ isApiConnected: jest.fn().mockReturnValue(true),
20
+ isBlockchainReady: true,
21
+ },
22
+ }));
13
23
 
14
24
  describe('CredentialProvider', () => {
15
25
  let wallet: IWallet;
16
26
  let provider: ICredentialProvider;
27
+ let testId = 0;
17
28
 
18
29
  beforeEach(async () => {
30
+ jest.clearAllMocks();
31
+ jest.spyOn(credentialServiceRPC, 'verifyCredential').mockImplementation(async () => {
32
+ return {
33
+ verified: true,
34
+ };
35
+ });
36
+
19
37
  wallet = await createWallet({
20
38
  dataStore: await createDataStore({
21
- databasePath: ':memory:',
39
+ databasePath: `:memory:${testId++}`,
22
40
  }),
23
41
  });
24
42
 
25
43
  provider = createCredentialProvider({wallet});
26
44
  });
27
45
 
46
+ afterEach(async () => {
47
+ if (wallet) {
48
+ if (wallet.networkCheckInterval) {
49
+ clearInterval(wallet.networkCheckInterval);
50
+ }
51
+
52
+ if (wallet.dataStore && wallet.dataStore.documents) {
53
+ await wallet.dataStore.documents.removeAllDocuments();
54
+ }
55
+ }
56
+
57
+ await new Promise(resolve => setTimeout(resolve, 100));
58
+
59
+ jest.restoreAllMocks();
60
+ });
61
+
28
62
  describe('addCredential', () => {
29
63
  it('should add a credential to the wallet', async () => {
30
64
  await provider.addCredential({
@@ -49,6 +83,9 @@ describe('CredentialProvider', () => {
49
83
  await provider.addCredential({
50
84
  ...biometricsBBSRevocation,
51
85
  });
86
+
87
+ await new Promise(resolve => setTimeout(resolve, 500));
88
+ jest.clearAllMocks();
52
89
  });
53
90
 
54
91
  it('should create credential status doc with verified status', async () => {
@@ -79,7 +116,8 @@ describe('CredentialProvider', () => {
79
116
  };
80
117
  });
81
118
 
82
- const statusDocs = await provider.syncCredentialStatus({});
119
+ // Force re-fetch by passing forceFetch option
120
+ const statusDocs = await provider.syncCredentialStatus({forceFetch: true});
83
121
 
84
122
  expect(statusDocs.length).toBe(2);
85
123
 
@@ -88,7 +126,7 @@ describe('CredentialProvider', () => {
88
126
  }
89
127
  });
90
128
 
91
- it('should not call verifyCredential twice', async () => {
129
+ it('should not call verifyCredential twice for same credential', async () => {
92
130
  jest
93
131
  .spyOn(credentialServiceRPC, 'verifyCredential')
94
132
  .mockImplementation(async () => {
@@ -97,13 +135,21 @@ describe('CredentialProvider', () => {
97
135
  };
98
136
  });
99
137
 
100
- // first call will do actual fetch
101
- await provider.syncCredentialStatus({});
102
- // additional calls will use cached data
138
+ // Force initial fetch to ensure clean state
139
+ await provider.syncCredentialStatus({forceFetch: true});
140
+
141
+ // Verify initial calls
142
+ expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(2);
143
+
144
+ // Clear mock to track only subsequent calls
145
+ jest.clearAllMocks();
146
+
147
+ // Second call should use cached data
103
148
  const statusDocs = await provider.syncCredentialStatus({});
104
-
149
+
105
150
  expect(statusDocs.length).toBe(2);
106
- expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(2);
151
+ // Should not call verifyCredential at all since data is already cached
152
+ expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(0);
107
153
 
108
154
  for (const statusDoc of statusDocs) {
109
155
  expect(statusDoc.status).toBe(CredentialStatus.Verified);
@@ -119,8 +165,11 @@ describe('CredentialProvider', () => {
119
165
  };
120
166
  });
121
167
 
122
- // load data into cache
123
- await provider.syncCredentialStatus({});
168
+ // Force initial fetch to ensure clean state
169
+ await provider.syncCredentialStatus({forceFetch: true});
170
+
171
+ // Verify initial calls
172
+ expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(2);
124
173
 
125
174
  // update statusDoc updateAt to 25 hours ago
126
175
  const statusDoc = await wallet.getDocumentById(
@@ -131,12 +180,16 @@ describe('CredentialProvider', () => {
131
180
  ).toISOString();
132
181
  await wallet.updateDocument(statusDoc);
133
182
 
183
+ // Clear mock to count only the next calls
184
+ jest.clearAllMocks();
185
+
134
186
  const statusDocs = await provider.syncCredentialStatus({});
135
187
 
136
188
  expect(statusDocs.length).toBe(2);
137
189
 
138
- // Expect to have a second status fetch for the customerCredential
139
- expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(3);
190
+ // Expect only one call for the expired customerCredential
191
+ // The biometricsBBSRevocation should use cached data
192
+ expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(1);
140
193
 
141
194
  for (const statusDoc of statusDocs) {
142
195
  expect(statusDoc.status).toBe(CredentialStatus.Verified);
@@ -163,6 +216,45 @@ describe('CredentialProvider', () => {
163
216
  }
164
217
  });
165
218
 
219
+ it('should return cached status with unable_to_refresh_status warning when verification fails', async () => {
220
+ // First, sync to create initial status documents
221
+ jest
222
+ .spyOn(credentialServiceRPC, 'verifyCredential')
223
+ .mockImplementation(async () => {
224
+ return {
225
+ verified: true,
226
+ };
227
+ });
228
+
229
+ await provider.syncCredentialStatus({forceFetch: true});
230
+
231
+ // Clear mocks
232
+ jest.clearAllMocks();
233
+
234
+ // Now simulate a network error during verification
235
+ jest
236
+ .spyOn(credentialServiceRPC, 'verifyCredential')
237
+ .mockImplementation(async () => {
238
+ throw new Error('Network error: Unable to connect to blockchain');
239
+ });
240
+
241
+ // Force fetch to trigger the error scenario
242
+ const statusDocs = await provider.syncCredentialStatus({forceFetch: true});
243
+
244
+ expect(statusDocs.length).toBe(2);
245
+
246
+ // Check that status documents retain their previous status with warning
247
+ for (const statusDoc of statusDocs) {
248
+ // The status should remain as 'verified' from the cached value
249
+ expect(statusDoc.status).toBe(CredentialStatus.Verified);
250
+ // The warning field should be added
251
+ expect(statusDoc.warning).toBe('unable_to_refresh_status');
252
+ }
253
+
254
+ // Verify that verifyCredential was called despite the error
255
+ expect(credentialServiceRPC.verifyCredential).toHaveBeenCalledTimes(2);
256
+ });
257
+
166
258
  afterEach(() => {
167
259
  (credentialServiceRPC.verifyCredential as any).mockReset();
168
260
  });
@@ -130,10 +130,25 @@ export async function isValid({
130
130
  status: CredentialStatus.Verified,
131
131
  };
132
132
  } catch (err) {
133
+ // Handle unknown error, when we can't determine the status
134
+ // Potential reasons can be network error, blockchain offline, internal SDK error
133
135
  console.error(err);
134
136
 
137
+ // in this case we return the cached status if possible
138
+ // It will avoid showing unknown status in case of a network error
139
+ const statusDoc = await wallet.getDocumentById(`${credential.id}#status`);
140
+
141
+ if (statusDoc) {
142
+ return {
143
+ ...statusDoc,
144
+ warning: 'unable_to_refresh_status',
145
+ };
146
+ }
147
+
148
+ // Return pending status
149
+ // As we can't determine the status, and there is no cached status
135
150
  return {
136
- status: CredentialStatus.Invalid,
151
+ status: CredentialStatus.Pending,
137
152
  error: err.toString(),
138
153
  };
139
154
  }
@@ -188,6 +203,7 @@ type CredentialStatusDocument = {
188
203
  id: string;
189
204
  status: string;
190
205
  error: string;
206
+ warning?: string;
191
207
  };
192
208
 
193
209
  /**
@@ -268,6 +284,7 @@ async function syncCredentialStatus({
268
284
  const result = await isValid({credential, wallet});
269
285
  statusDoc.status = result?.status;
270
286
  statusDoc.error = result?.error;
287
+ statusDoc.warning = result?.warning;
271
288
  statusDoc.updatedAt = new Date().toISOString();
272
289
 
273
290
  await wallet.updateDocument(statusDoc);
@@ -136,8 +136,8 @@ export async function createDIDKey({wallet, name, derivePath=undefined, type=und
136
136
  name,
137
137
  });
138
138
 
139
- await wallet.add(keyDoc);
140
- await wallet.add(didDocumentResolution);
139
+ await wallet.addDocument(keyDoc);
140
+ await wallet.addDocument(didDocumentResolution);
141
141
 
142
142
  return {
143
143
  keyDoc,
@@ -1,5 +1,6 @@
1
1
  import assert from 'assert';
2
2
  import axios from 'axios';
3
+ import {utilCryptoService} from '@docknetwork/wallet-sdk-wasm/src/services/util-crypto';
3
4
 
4
5
  // TODO: FIXME: this wont work for other staging envs
5
6
  function getApiURL(networkId) {
@@ -58,3 +59,31 @@ export async function getVerifiers({trustRegistryId, issuerDID, schemaId, networ
58
59
  return [];
59
60
  }
60
61
  }
62
+
63
+ export async function getMetadata(govFramework: string): Promise<any> {
64
+ try {
65
+ const metadataURL = await utilCryptoService.hexToString(govFramework);
66
+ const response = await axios.get(metadataURL);
67
+ return response.data;
68
+ } catch (e) {
69
+ console.log('error: ', e);
70
+ }
71
+
72
+ return {};
73
+ }
74
+
75
+ export async function formatEcosystemData(ecosystems: any): Promise<any[]> {
76
+ const formattedEcosystems = [];
77
+ const ecosystemsList: any = Object.entries(ecosystems);
78
+
79
+ for (let i = 0; i < ecosystemsList.length; i++) {
80
+ let ecosystemData: any = {};
81
+ ecosystemData.trustRegistryId = ecosystemsList[i][0];
82
+ ecosystemData = {...ecosystemData, ...ecosystemsList[i][1]};
83
+
84
+ const metadata = await getMetadata(ecosystemsList[i][1]?.govFramework);
85
+ formattedEcosystems.push({...ecosystemData, ...metadata});
86
+ }
87
+
88
+ return formattedEcosystems;
89
+ }
@@ -3,9 +3,7 @@ import {
3
3
  DocumentNetworkResolver,
4
4
  DocumentResolverProps,
5
5
  DocumentResolverResult,
6
- WalletDocument,
7
6
  } from '@docknetwork/wallet-sdk-data-store/src/types';
8
- import {utilCryptoService} from '@docknetwork/wallet-sdk-wasm/src/services/util-crypto';
9
7
 
10
8
  type ResolverResult = string | null;
11
9
 
@@ -116,42 +114,8 @@ export async function didResolver({
116
114
  return null;
117
115
  }
118
116
 
119
- export async function accountResolver({
120
- document,
121
- dataStore,
122
- }: DocumentResolverProps): Promise<ResolverResult> {
123
- if (!document) {
124
- return null;
125
- }
126
-
127
- const isAddress = Array.isArray(document.type)
128
- ? document.type.includes('Address')
129
- : document.type === 'Address';
130
-
131
- if (!isAddress) {
132
- return null;
133
- }
134
-
135
- const addressPrefixList = dataStore.networks.map(
136
- network => network?.configs?.addressPrefix,
137
- );
138
-
139
- const addressPrefix = await utilCryptoService.getAddressPrefix({
140
- address: document.id,
141
- startPrefix: Math.min(...addressPrefixList),
142
- endPrefix: Math.max(...addressPrefixList),
143
- });
144
-
145
- const network = dataStore.networks.find(
146
- item => item.configs?.addressPrefix === addressPrefix,
147
- );
148
-
149
- return network?.id;
150
- }
151
-
152
117
  const resolvers = [
153
118
  credentialResolver,
154
- accountResolver,
155
119
  didResolver,
156
120
  proofRequestResolver,
157
121
  ];
package/src/types.ts CHANGED
@@ -1,15 +1,11 @@
1
1
  import {
2
2
  DataStore,
3
- DataStoreConfigs,
4
3
  DocumentResolverResult,
5
4
  WalletDocument,
6
5
  } from '@docknetwork/wallet-sdk-data-store/src/types';
7
- import {Accounts} from '@docknetwork/wallet-sdk-wasm/src/modules/accounts';
8
6
  import {EventEmitter} from 'events';
9
7
 
10
8
  export interface IV1Wallet {
11
- accounts: Accounts;
12
-
13
9
  getStatus: () => string;
14
10
  setStatus: (status: string) => void;
15
11
  eventManager: EventEmitter;
@@ -70,7 +66,7 @@ export type IWallet = {
70
66
  getNetworkId: () => string;
71
67
  resolveDocumentNetwork: (document: any) => Promise<DocumentResolverResult>;
72
68
  dataStore: DataStore;
73
- networkCheckInterval?: NodeJS.Timeout;
69
+ networkCheckInterval?: NodeJS.Timeout | number;
74
70
  } & IV1Wallet;
75
71
 
76
72
  export type CrateWalletWithDataStore = {
@@ -11,7 +11,7 @@ import iiwTemplate from './fixtures/iiw-template.json';
11
11
  import anyCredentialProofRequest from './fixtures/any-credential-proof-request.json';
12
12
  import universityDegreeProofRequest from './fixtures/university-degree-proof-request.json';
13
13
  import {createDIDProvider, IDIDProvider} from './did-provider';
14
- import {WalletEvents} from '@docknetwork/wallet-sdk-wasm/src/modules/wallet';
14
+ import {WalletEvents} from '@docknetwork/wallet-sdk-core/src/wallet';
15
15
  import {replaceResponseURL} from './helpers';
16
16
  import {createDataStore} from '@docknetwork/wallet-sdk-data-store-typeorm/src';
17
17
 
@@ -1,9 +1,8 @@
1
1
  import { blockchainService } from '@docknetwork/wallet-sdk-wasm/src/services/blockchain';
2
- import { keyringService } from '@docknetwork/wallet-sdk-wasm/src/services/keyring';
3
2
  import { utilCryptoService } from '@docknetwork/wallet-sdk-wasm/src/services/util-crypto';
4
3
 
5
4
  import { Network } from '@docknetwork/wallet-sdk-data-store/src/types';
6
- import { WalletEvents } from '@docknetwork/wallet-sdk-wasm/src/modules/wallet';
5
+ import { WalletEvents } from '@docknetwork/wallet-sdk-core/src/wallet';
7
6
  import { captureException } from './helpers';
8
7
  import { IWallet } from './types';
9
8
 
@@ -50,10 +49,6 @@ export async function setBlockchainNetwork(wallet: IWallet) {
50
49
  await wallet.addDocument(cheqdMnemonicDoc);
51
50
  }
52
51
 
53
- await keyringService.initialize({
54
- ss58Format: networkConfigs.addressPrefix,
55
- });
56
-
57
52
  let connectionInProgress = false;
58
53
 
59
54
  const initializeBlockchain = () => {
@@ -102,7 +97,6 @@ export async function setBlockchainNetwork(wallet: IWallet) {
102
97
  }
103
98
 
104
99
  export async function initWalletWasm(wallet: IWallet) {
105
- await utilCryptoService.cryptoWaitReady();
106
100
  const network = wallet.dataStore.network;
107
101
 
108
102
  if (isBlockchainNetwork(network)) {
package/src/wallet.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import {CreateWalletProps, IWallet} from './types';
2
- import {toV1Wallet} from './v1-helpers';
3
2
  import {initWalletWasm} from './wallet-wasm';
4
3
  import {EventEmitter} from 'events';
5
- import {WalletEvents} from '@docknetwork/wallet-sdk-wasm/src/modules/wallet';
6
4
  import {walletService} from '@docknetwork/wallet-sdk-wasm/src/services/wallet';
7
5
  import {importUniversalWalletDocuments} from '@docknetwork/wallet-sdk-data-store/src/helpers';
8
6
  import {ensureDID} from './did-provider';
@@ -23,6 +21,26 @@ export function ensureDocumentContext(document) {
23
21
  };
24
22
  }
25
23
 
24
+
25
+ export type WalletStatus = 'closed' | 'loading' | 'ready' | 'error';
26
+
27
+ export type KeypairType = 'sr25519' | 'ed25519' | 'ecdsa';
28
+
29
+ export const WalletEvents = {
30
+ ready: 'ready',
31
+ error: 'error',
32
+ migrated: 'migrated',
33
+ statusUpdated: 'status-updated',
34
+ documentAdded: 'document-added',
35
+ documentUpdated: 'document-updated',
36
+ documentRemoved: 'document-removed',
37
+ walletDeleted: 'wallet-deleted',
38
+ walletImported: 'wallet-imported',
39
+ networkUpdated: 'network-updated',
40
+ networkConnected: 'network-connected',
41
+ networkError: 'network-error',
42
+ };
43
+
26
44
  /**
27
45
  * Create wallet
28
46
  *
@@ -138,21 +156,19 @@ export async function createWallet({
138
156
  },
139
157
  } as IWallet;
140
158
 
141
- const v1Wallet = await toV1Wallet(wallet);
142
-
143
- await initWalletWasm(v1Wallet);
159
+ await initWalletWasm(wallet);
144
160
 
145
161
  await ensureDID({
146
- wallet: v1Wallet,
162
+ wallet,
147
163
  });
148
164
 
149
165
  [WalletEvents.networkUpdated, WalletEvents.walletDeleted].forEach(event =>
150
166
  eventEmitter.on(event, () => {
151
167
  ensureDID({
152
- wallet: v1Wallet,
168
+ wallet,
153
169
  });
154
170
  }),
155
171
  );
156
172
 
157
- return v1Wallet;
173
+ return wallet;
158
174
  }