@docknetwork/wallet-sdk-web 0.0.10 → 1.7.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docknetwork/wallet-sdk-web",
3
- "version": "0.0.10",
3
+ "version": "1.7.6",
4
4
  "license": "https://github.com/docknetwork/wallet-sdk/LICENSE",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,9 +31,9 @@
31
31
  "test:headed": "playwright test --headed"
32
32
  },
33
33
  "devDependencies": {
34
- "@docknetwork/wallet-sdk-core": "^1.7.0",
35
- "@docknetwork/wallet-sdk-data-store": "^1.7.0",
36
- "@docknetwork/wallet-sdk-data-store-web": "^1.7.0",
34
+ "@docknetwork/wallet-sdk-core": "^1.7.6",
35
+ "@docknetwork/wallet-sdk-data-store": "^1.7.6",
36
+ "@docknetwork/wallet-sdk-data-store-web": "^1.7.6",
37
37
  "@playwright/test": "^1.58.0",
38
38
  "@rollup/plugin-babel": "^6.1.0",
39
39
  "@rollup/plugin-commonjs": "^29.0.0",
@@ -58,4 +58,4 @@
58
58
  "webpack": "^5.67.0",
59
59
  "webpack-cli": "^4.10.0"
60
60
  }
61
- }
61
+ }
package/src/index.js CHANGED
@@ -19,6 +19,7 @@ import {createCredentialProvider} from '@docknetwork/wallet-sdk-core/src/credent
19
19
  import {createDIDProvider} from '@docknetwork/wallet-sdk-core/src/did-provider';
20
20
  import {createMessageProvider} from '@docknetwork/wallet-sdk-core/src/message-provider';
21
21
  import {createVerificationController} from '@docknetwork/wallet-sdk-core/src/verification-controller';
22
+ import {blockchainService} from '@docknetwork/wallet-sdk-wasm/src/services/blockchain';
22
23
 
23
24
  /**
24
25
  * Initializes the Dock Wallet SDK with the provided configuration.
@@ -125,24 +126,6 @@ async function initialize({
125
126
  throw new Error(`Failed to create data store: ${error.message}`);
126
127
  }
127
128
 
128
- // Initialize wallet
129
- let wallet;
130
- try {
131
- wallet = await createWallet({dataStore});
132
- } catch (error) {
133
- throw new Error(`Failed to create wallet: ${error.message}`);
134
- }
135
-
136
- // Initialize providers
137
- let didProvider, credentialProvider, messageProvider;
138
- try {
139
- didProvider = createDIDProvider({wallet});
140
- credentialProvider = await createCredentialProvider({wallet});
141
- messageProvider = createMessageProvider({wallet, didProvider});
142
- } catch (error) {
143
- throw new Error(`Failed to initialize wallet providers: ${error.message}`);
144
- }
145
-
146
129
  // Recover or set master key
147
130
  if (mnemonic) {
148
131
  try {
@@ -154,7 +137,9 @@ async function initialize({
154
137
  }
155
138
  }
156
139
 
157
- // Initialize cloud wallet
140
+ // Initialize cloud wallet and pull documents before creating the wallet
141
+ // This ensures existing DIDs are loaded from the cloud before wallet creation,
142
+ // preventing duplicate DID creation
158
143
  let cloudWallet;
159
144
  try {
160
145
  cloudWallet = await initializeCloudWallet({
@@ -177,6 +162,24 @@ async function initialize({
177
162
  );
178
163
  }
179
164
 
165
+ // Initialize wallet after cloud sync so existing DIDs are found in the data store
166
+ let wallet;
167
+ try {
168
+ wallet = await createWallet({dataStore});
169
+ } catch (error) {
170
+ throw new Error(`Failed to create wallet: ${error.message}`);
171
+ }
172
+
173
+ // Initialize providers
174
+ let didProvider, credentialProvider, messageProvider;
175
+ try {
176
+ didProvider = createDIDProvider({wallet});
177
+ credentialProvider = await createCredentialProvider({wallet});
178
+ messageProvider = createMessageProvider({wallet, didProvider});
179
+ } catch (error) {
180
+ throw new Error(`Failed to initialize wallet providers: ${error.message}`);
181
+ }
182
+
180
183
  return {
181
184
  wallet,
182
185
  messageProvider,
@@ -285,6 +288,9 @@ async function initialize({
285
288
  * });
286
289
  */
287
290
  submitPresentation: async ({credentials, proofRequestUrl}) => {
291
+ // ensure blockchain is connected
292
+ await blockchainService.ensureBlockchainReady();
293
+
288
294
  // Validate inputs
289
295
  if (
290
296
  !credentials ||
@@ -0,0 +1,204 @@
1
+ import WalletSDK from './index';
2
+
3
+ // Track call order
4
+ let mockCallOrder;
5
+
6
+ jest.mock('@docknetwork/wallet-sdk-data-store-web/src/index', () => ({
7
+ createDataStore: jest.fn().mockImplementation(async () => {
8
+ mockCallOrder.push('createDataStore');
9
+ return {mockDataStore: true};
10
+ }),
11
+ }));
12
+
13
+ jest.mock('@docknetwork/wallet-sdk-core/src/cloud-wallet', () => ({
14
+ initializeCloudWallet: jest.fn().mockImplementation(async () => {
15
+ mockCallOrder.push('initializeCloudWallet');
16
+ return {
17
+ pullDocuments: jest.fn().mockImplementation(async () => {
18
+ mockCallOrder.push('pullDocuments');
19
+ }),
20
+ };
21
+ }),
22
+ generateCloudWalletMasterKey: jest.fn(),
23
+ recoverCloudWalletMasterKey: jest.fn().mockImplementation(async () => {
24
+ mockCallOrder.push('recoverCloudWalletMasterKey');
25
+ return 'mock-master-key';
26
+ }),
27
+ }));
28
+
29
+ jest.mock('@docknetwork/wallet-sdk-core/src/wallet', () => ({
30
+ createWallet: jest.fn().mockImplementation(async () => {
31
+ mockCallOrder.push('createWallet');
32
+ return {mockWallet: true};
33
+ }),
34
+ }));
35
+
36
+ jest.mock('@docknetwork/wallet-sdk-core/src/credential-provider', () => ({
37
+ createCredentialProvider: jest.fn().mockImplementation(async () => {
38
+ mockCallOrder.push('createCredentialProvider');
39
+ return {mockCredentialProvider: true};
40
+ }),
41
+ }));
42
+
43
+ jest.mock('@docknetwork/wallet-sdk-core/src/did-provider', () => ({
44
+ createDIDProvider: jest.fn().mockImplementation(() => {
45
+ mockCallOrder.push('createDIDProvider');
46
+ return {mockDIDProvider: true};
47
+ }),
48
+ }));
49
+
50
+ jest.mock('@docknetwork/wallet-sdk-core/src/message-provider', () => ({
51
+ createMessageProvider: jest.fn().mockImplementation(() => {
52
+ mockCallOrder.push('createMessageProvider');
53
+ return {mockMessageProvider: true};
54
+ }),
55
+ }));
56
+
57
+ jest.mock('@docknetwork/wallet-sdk-core/src/verification-controller', () => ({
58
+ createVerificationController: jest.fn(),
59
+ }));
60
+
61
+ jest.mock('@docknetwork/wallet-sdk-wasm/src/services/blockchain', () => ({
62
+ blockchainService: {ensureBlockchainReady: jest.fn()},
63
+ }));
64
+
65
+ const {
66
+ initializeCloudWallet,
67
+ } = require('@docknetwork/wallet-sdk-core/src/cloud-wallet');
68
+ const {createWallet} = require('@docknetwork/wallet-sdk-core/src/wallet');
69
+
70
+ const validConfig = {
71
+ edvUrl: 'https://edv.example.com',
72
+ edvAuthKey: 'test-auth-key',
73
+ mnemonic: 'test mnemonic phrase',
74
+ networkId: 'testnet',
75
+ databasePath: 'test-db',
76
+ };
77
+
78
+ describe('WalletSDK initialize', () => {
79
+ beforeEach(() => {
80
+ mockCallOrder = [];
81
+ jest.clearAllMocks();
82
+ });
83
+
84
+ it('should create data store, pull cloud documents, then create wallet', async () => {
85
+ await WalletSDK.initialize(validConfig);
86
+
87
+ expect(mockCallOrder).toEqual([
88
+ 'createDataStore',
89
+ 'recoverCloudWalletMasterKey',
90
+ 'initializeCloudWallet',
91
+ 'pullDocuments',
92
+ 'createWallet',
93
+ 'createDIDProvider',
94
+ 'createCredentialProvider',
95
+ 'createMessageProvider',
96
+ ]);
97
+ });
98
+
99
+ it('should pull cloud documents before creating wallet to avoid duplicate DIDs', async () => {
100
+ await WalletSDK.initialize(validConfig);
101
+
102
+ const pullIndex = mockCallOrder.indexOf('pullDocuments');
103
+ const walletIndex = mockCallOrder.indexOf('createWallet');
104
+
105
+ expect(pullIndex).toBeLessThan(walletIndex);
106
+ });
107
+
108
+ it('should create data store before initializing cloud wallet', async () => {
109
+ await WalletSDK.initialize(validConfig);
110
+
111
+ const dataStoreIndex = mockCallOrder.indexOf('createDataStore');
112
+ const cloudWalletIndex = mockCallOrder.indexOf('initializeCloudWallet');
113
+
114
+ expect(dataStoreIndex).toBeLessThan(cloudWalletIndex);
115
+ });
116
+
117
+ it('should pass the data store to cloud wallet initialization', async () => {
118
+ await WalletSDK.initialize(validConfig);
119
+
120
+ expect(initializeCloudWallet).toHaveBeenCalledWith({
121
+ dataStore: {mockDataStore: true},
122
+ edvUrl: validConfig.edvUrl,
123
+ masterKey: 'mock-master-key',
124
+ authKey: validConfig.edvAuthKey,
125
+ });
126
+ });
127
+
128
+ it('should pass the data store to wallet creation', async () => {
129
+ await WalletSDK.initialize(validConfig);
130
+
131
+ expect(createWallet).toHaveBeenCalledWith({
132
+ dataStore: {mockDataStore: true},
133
+ });
134
+ });
135
+
136
+ it('should still create wallet if pullDocuments fails', async () => {
137
+ initializeCloudWallet.mockImplementationOnce(async () => {
138
+ mockCallOrder.push('initializeCloudWallet');
139
+ return {
140
+ pullDocuments: jest.fn().mockImplementation(async () => {
141
+ mockCallOrder.push('pullDocuments');
142
+ throw new Error('Network error');
143
+ }),
144
+ };
145
+ });
146
+
147
+ const result = await WalletSDK.initialize(validConfig);
148
+
149
+ expect(result.wallet).toBeDefined();
150
+ expect(mockCallOrder).toContain('createWallet');
151
+ });
152
+
153
+ it('should use masterKey directly when provided instead of mnemonic', async () => {
154
+ await WalletSDK.initialize({
155
+ ...validConfig,
156
+ mnemonic: undefined,
157
+ masterKey: 'direct-master-key',
158
+ });
159
+
160
+ expect(mockCallOrder).not.toContain('recoverCloudWalletMasterKey');
161
+ expect(initializeCloudWallet).toHaveBeenCalledWith(
162
+ expect.objectContaining({masterKey: 'direct-master-key'}),
163
+ );
164
+ });
165
+
166
+ describe('validation', () => {
167
+ it('should throw when neither masterKey nor mnemonic is provided', async () => {
168
+ await expect(
169
+ WalletSDK.initialize({
170
+ ...validConfig,
171
+ mnemonic: undefined,
172
+ masterKey: undefined,
173
+ }),
174
+ ).rejects.toThrow('Either masterKey or mnemonic must be provided');
175
+ });
176
+
177
+ it('should throw when both masterKey and mnemonic are provided', async () => {
178
+ await expect(
179
+ WalletSDK.initialize({
180
+ ...validConfig,
181
+ masterKey: 'some-key',
182
+ }),
183
+ ).rejects.toThrow('Cannot provide both masterKey and mnemonic');
184
+ });
185
+
186
+ it('should throw when edvUrl is not provided', async () => {
187
+ await expect(
188
+ WalletSDK.initialize({...validConfig, edvUrl: undefined}),
189
+ ).rejects.toThrow('edvUrl is required');
190
+ });
191
+
192
+ it('should throw when edvAuthKey is not provided', async () => {
193
+ await expect(
194
+ WalletSDK.initialize({...validConfig, edvAuthKey: undefined}),
195
+ ).rejects.toThrow('edvAuthKey is required');
196
+ });
197
+
198
+ it('should throw when networkId is invalid', async () => {
199
+ await expect(
200
+ WalletSDK.initialize({...validConfig, networkId: 'invalid'}),
201
+ ).rejects.toThrow('networkId is required');
202
+ });
203
+ });
204
+ });