@cofhe/sdk 0.1.1 → 0.2.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/adapters/ethers6.ts +28 -28
  3. package/adapters/hardhat.ts +0 -1
  4. package/adapters/index.test.ts +14 -19
  5. package/adapters/smartWallet.ts +81 -73
  6. package/adapters/test-utils.ts +45 -45
  7. package/adapters/types.ts +3 -3
  8. package/chains/chains/localcofhe.ts +14 -0
  9. package/chains/chains.test.ts +2 -1
  10. package/chains/index.ts +3 -1
  11. package/core/baseBuilder.ts +30 -49
  12. package/core/client.test.ts +94 -77
  13. package/core/client.ts +133 -149
  14. package/core/clientTypes.ts +108 -0
  15. package/core/config.test.ts +22 -11
  16. package/core/config.ts +16 -9
  17. package/core/decrypt/decryptHandleBuilder.ts +51 -45
  18. package/core/decrypt/{tnSealOutput.ts → tnSealOutputV1.ts} +1 -1
  19. package/core/decrypt/tnSealOutputV2.ts +298 -0
  20. package/core/encrypt/cofheMocksZkVerifySign.ts +16 -10
  21. package/core/encrypt/encryptInputsBuilder.test.ts +132 -116
  22. package/core/encrypt/encryptInputsBuilder.ts +159 -111
  23. package/core/encrypt/encryptUtils.ts +6 -3
  24. package/core/encrypt/zkPackProveVerify.ts +70 -8
  25. package/core/error.ts +0 -2
  26. package/core/fetchKeys.test.ts +1 -18
  27. package/core/fetchKeys.ts +0 -26
  28. package/core/index.ts +29 -17
  29. package/core/keyStore.ts +65 -38
  30. package/core/permits.test.ts +253 -1
  31. package/core/permits.ts +80 -16
  32. package/core/types.ts +198 -152
  33. package/core/utils.ts +43 -1
  34. package/dist/adapters.d.cts +38 -20
  35. package/dist/adapters.d.ts +38 -20
  36. package/dist/chains.cjs +14 -1
  37. package/dist/chains.d.cts +23 -1
  38. package/dist/chains.d.ts +23 -1
  39. package/dist/chains.js +1 -1
  40. package/dist/{chunk-LU7BMUUT.js → chunk-UGBVZNRT.js} +39 -25
  41. package/dist/{chunk-GZCQQYVI.js → chunk-WEAZ25JO.js} +14 -2
  42. package/dist/{chunk-KFGPTJ6X.js → chunk-WGCRJCBR.js} +1920 -1692
  43. package/dist/{types-bB7wLj0q.d.cts → clientTypes-5_1nwtUe.d.cts} +308 -347
  44. package/dist/{types-PhwGgQvs.d.ts → clientTypes-Es7fyi65.d.ts} +308 -347
  45. package/dist/core.cjs +2872 -2632
  46. package/dist/core.d.cts +101 -6
  47. package/dist/core.d.ts +101 -6
  48. package/dist/core.js +3 -3
  49. package/dist/node.cjs +2716 -2520
  50. package/dist/node.d.cts +3 -3
  51. package/dist/node.d.ts +3 -3
  52. package/dist/node.js +4 -3
  53. package/dist/{permit-S9CnI6MF.d.cts → permit-fUSe6KKq.d.cts} +31 -15
  54. package/dist/{permit-S9CnI6MF.d.ts → permit-fUSe6KKq.d.ts} +31 -15
  55. package/dist/permits.cjs +39 -24
  56. package/dist/permits.d.cts +137 -148
  57. package/dist/permits.d.ts +137 -148
  58. package/dist/permits.js +1 -1
  59. package/dist/web.cjs +2929 -2518
  60. package/dist/web.d.cts +21 -5
  61. package/dist/web.d.ts +21 -5
  62. package/dist/web.js +185 -9
  63. package/dist/zkProve.worker.cjs +93 -0
  64. package/dist/zkProve.worker.d.cts +2 -0
  65. package/dist/zkProve.worker.d.ts +2 -0
  66. package/dist/zkProve.worker.js +91 -0
  67. package/node/client.test.ts +20 -25
  68. package/node/encryptInputs.test.ts +18 -38
  69. package/node/index.ts +1 -0
  70. package/package.json +14 -14
  71. package/permits/index.ts +1 -0
  72. package/permits/localstorage.test.ts +0 -1
  73. package/permits/permit.test.ts +25 -22
  74. package/permits/permit.ts +30 -21
  75. package/permits/sealing.test.ts +3 -3
  76. package/permits/sealing.ts +2 -2
  77. package/permits/store.ts +5 -7
  78. package/permits/test-utils.ts +1 -1
  79. package/permits/types.ts +17 -0
  80. package/permits/utils.ts +0 -1
  81. package/permits/validation.ts +24 -4
  82. package/web/client.web.test.ts +20 -25
  83. package/web/config.web.test.ts +0 -2
  84. package/web/encryptInputs.web.test.ts +31 -54
  85. package/web/index.ts +65 -1
  86. package/web/storage.ts +19 -5
  87. package/web/worker.builder.web.test.ts +148 -0
  88. package/web/worker.config.web.test.ts +329 -0
  89. package/web/worker.output.web.test.ts +84 -0
  90. package/web/workerManager.test.ts +80 -0
  91. package/web/workerManager.ts +214 -0
  92. package/web/workerManager.web.test.ts +114 -0
  93. package/web/zkProve.worker.ts +133 -0
  94. package/core/result.test.ts +0 -180
  95. package/core/result.ts +0 -67
  96. package/core/test-utils.ts +0 -45
@@ -1,8 +1,8 @@
1
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  import { createCofhesdkClientBase } from './client.js';
3
- import { type CofhesdkClient, type CofhesdkClientConnectionState } from './types.js';
4
- import { createCofhesdkConfigBase } from './config.js';
5
- import { CofhesdkErrorCode } from './error.js';
3
+ import { type CofhesdkClient, type CofhesdkClientConnectionState } from './clientTypes.js';
4
+ import { createCofhesdkConfigBase, type CofhesdkEnvironment } from './config.js';
5
+ import { CofhesdkError, CofhesdkErrorCode } from './error.js';
6
6
  import { type PublicClient, type WalletClient } from 'viem';
7
7
  import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js';
8
8
  import { Encryptable } from './types.js';
@@ -20,10 +20,6 @@ vi.mock('./keyStore', () => ({
20
20
  })),
21
21
  }));
22
22
 
23
- vi.mock('./fetchKeys', () => ({
24
- fetchMultichainKeys: vi.fn().mockResolvedValue(undefined),
25
- }));
26
-
27
23
  // Test helpers
28
24
  const createMockPublicClient = (chainId = 11155111): PublicClient =>
29
25
  ({
@@ -61,6 +57,8 @@ describe('createCofhesdkClientBase', () => {
61
57
  expect(snapshot.connectError).toBe(undefined);
62
58
  expect(snapshot.chainId).toBe(undefined);
63
59
  expect(snapshot.account).toBe(undefined);
60
+ expect(snapshot.publicClient).toBe(undefined);
61
+ expect(snapshot.walletClient).toBe(undefined);
64
62
  });
65
63
 
66
64
  it('should expose convenience flags', () => {
@@ -74,6 +72,24 @@ describe('createCofhesdkClientBase', () => {
74
72
  });
75
73
  });
76
74
 
75
+ describe('environment', () => {
76
+ it('should create a client with the correct environment', async () => {
77
+ const environments: CofhesdkEnvironment[] = ['node', 'hardhat', 'web', 'react'];
78
+ for (const environment of environments) {
79
+ const config = createCofhesdkConfigBase({ environment, supportedChains: [] });
80
+ const client = createCofhesdkClientBase({
81
+ config,
82
+ zkBuilderAndCrsGenerator: {} as any,
83
+ tfhePublicKeyDeserializer: {} as any,
84
+ compactPkeCrsDeserializer: {} as any,
85
+ initTfhe: () => Promise.resolve(false),
86
+ });
87
+
88
+ expect(client.config.environment).toBe(environment);
89
+ }
90
+ });
91
+ });
92
+
77
93
  describe('reactive state', () => {
78
94
  it('should notify subscribers of state changes', async () => {
79
95
  const states: CofhesdkClientConnectionState[] = [];
@@ -88,12 +104,16 @@ describe('createCofhesdkClientBase', () => {
88
104
  expect(states[0].connected).toBe(false);
89
105
  expect(states[0].chainId).toBe(undefined);
90
106
  expect(states[0].account).toBe(undefined);
107
+ expect(states[0].publicClient).toBe(undefined);
108
+ expect(states[0].walletClient).toBe(undefined);
91
109
 
92
110
  // Expect states[1] to be the connected state
93
111
  expect(states[1].connected).toBe(true);
94
112
  expect(states[1].connecting).toBe(false);
95
113
  expect(states[1].chainId).toBe(11155111);
96
114
  expect(states[1].account).toBe('0x1234567890123456789012345678901234567890');
115
+ expect(states[1].publicClient).toBe(publicClient);
116
+ expect(states[1].walletClient).toBe(walletClient);
97
117
  });
98
118
 
99
119
  it('should stop notifications after unsubscribe', async () => {
@@ -116,10 +136,7 @@ describe('createCofhesdkClientBase', () => {
116
136
  const publicClient = createMockPublicClient(11155111);
117
137
  const walletClient = createMockWalletClient(['0xabcd']);
118
138
 
119
- const result = await client.connect(publicClient, walletClient);
120
-
121
- expect(result.success).toBe(true);
122
- expect(result.data).toBe(true);
139
+ await client.connect(publicClient, walletClient);
123
140
 
124
141
  expect(client.connected).toBe(true);
125
142
  expect(client.connecting).toBe(false);
@@ -127,6 +144,8 @@ describe('createCofhesdkClientBase', () => {
127
144
  const snapshot = client.getSnapshot();
128
145
  expect(snapshot.chainId).toBe(11155111);
129
146
  expect(snapshot.account).toBe('0xabcd');
147
+ expect(snapshot.publicClient).toBe(publicClient);
148
+ expect(snapshot.walletClient).toBe(walletClient);
130
149
  });
131
150
 
132
151
  it('should set connecting state during connection', async () => {
@@ -157,95 +176,104 @@ describe('createCofhesdkClientBase', () => {
157
176
  await promise1;
158
177
  });
159
178
 
160
- it('should return immediately if already connected with same clients', async () => {
179
+ it('should handle publicClient.getChainId throwing an error', async () => {
161
180
  const publicClient = createMockPublicClient();
181
+ const getChainIdError = new Error('Network error');
182
+ publicClient.getChainId = vi.fn().mockRejectedValue(getChainIdError);
162
183
  const walletClient = createMockWalletClient();
163
184
 
164
- await client.connect(publicClient, walletClient);
165
- const result = await client.connect(publicClient, walletClient);
166
-
167
- expect(result.success).toBe(true);
168
- });
169
-
170
- it('should handle getChainId throwing an error', async () => {
171
- const publicClient = createMockPublicClient();
172
- const error = new Error('Network error');
173
- publicClient.getChainId = vi.fn().mockRejectedValue(error);
174
- const walletClient = createMockWalletClient();
175
-
176
- const result = await client.connect(publicClient, walletClient);
177
-
178
- expect(result.success).toBe(false);
179
- expect(result.error?.code).toBe(CofhesdkErrorCode.PublicWalletGetChainIdFailed);
180
- expect(result.error?.message).toBe('getting chain ID from public client failed | Caused by: Network error');
181
- expect(result.error?.cause).toBe(error);
182
- expect(client.connected).toBe(false);
185
+ try {
186
+ await client.connect(publicClient, walletClient);
187
+ } catch (error) {
188
+ expect(error).toBeInstanceOf(CofhesdkError);
189
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.PublicWalletGetChainIdFailed);
190
+ expect((error as CofhesdkError).message).toBe(
191
+ 'getting chain ID from public client failed | Caused by: Network error'
192
+ );
193
+ expect((error as CofhesdkError).cause).toBe(getChainIdError);
194
+ }
183
195
  });
184
196
 
185
- it('should handle getChainId returning null', async () => {
197
+ it('should handle publicClient.getChainId returning null', async () => {
186
198
  const publicClient = createMockPublicClient();
187
199
  publicClient.getChainId = vi.fn().mockResolvedValue(null);
188
200
  const walletClient = createMockWalletClient();
189
201
 
190
- const result = await client.connect(publicClient, walletClient);
202
+ const connectPromise = client.connect(publicClient, walletClient);
191
203
 
192
- expect(result.success).toBe(false);
193
- expect(result.error?.code).toBe(CofhesdkErrorCode.PublicWalletGetChainIdFailed);
194
- expect(result.error?.message).toBe('chain ID from public client is null');
195
- expect(result.error?.cause).toBe(undefined);
196
- expect(client.connected).toBe(false);
204
+ try {
205
+ await connectPromise;
206
+ } catch (error) {
207
+ expect(error).toBeInstanceOf(CofhesdkError);
208
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.PublicWalletGetChainIdFailed);
209
+ expect((error as CofhesdkError).message).toBe('chain ID from public client is null');
210
+ }
197
211
  });
198
212
 
199
- it('should handle getAddresses throwing an error', async () => {
213
+ it('should handle walletClient.getAddresses throwing an error', async () => {
200
214
  const publicClient = createMockPublicClient();
201
- const error = new Error('Network error');
215
+ const getAddressesError = new Error('Network error');
202
216
  const walletClient = createMockWalletClient();
203
- walletClient.getAddresses = vi.fn().mockRejectedValue(error);
217
+ walletClient.getAddresses = vi.fn().mockRejectedValue(getAddressesError);
204
218
 
205
- const result = await client.connect(publicClient, walletClient);
219
+ const connectPromise = client.connect(publicClient, walletClient);
206
220
 
207
- expect(result.success).toBe(false);
208
- expect(result.error?.code).toBe(CofhesdkErrorCode.PublicWalletGetAddressesFailed);
209
- expect(result.error?.message).toBe('getting address from wallet client failed | Caused by: Network error');
210
- expect(result.error?.cause).toBe(error);
211
- expect(client.connected).toBe(false);
221
+ try {
222
+ await connectPromise;
223
+ } catch (error) {
224
+ expect(error).toBeInstanceOf(CofhesdkError);
225
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.PublicWalletGetAddressesFailed);
226
+ expect((error as CofhesdkError).message).toBe(
227
+ 'getting address from wallet client failed | Caused by: Network error'
228
+ );
229
+ expect((error as CofhesdkError).cause).toBe(getAddressesError);
230
+ }
212
231
  });
213
232
 
214
- it('should handle getAddresses returning an empty array', async () => {
233
+ it('should handle walletClient.getAddresses returning an empty array', async () => {
215
234
  const publicClient = createMockPublicClient();
216
235
  const walletClient = createMockWalletClient([]);
217
236
 
218
- const result = await client.connect(publicClient, walletClient);
237
+ const connectPromise = client.connect(publicClient, walletClient);
219
238
 
220
- expect(result.success).toBe(false);
221
- expect(result.error?.code).toBe(CofhesdkErrorCode.PublicWalletGetAddressesFailed);
222
- expect(result.error?.message).toBe('address from wallet client is null');
223
- expect(result.error?.cause).toBe(undefined);
224
- expect(client.connected).toBe(false);
239
+ try {
240
+ await connectPromise;
241
+ } catch (error) {
242
+ expect(error).toBeInstanceOf(CofhesdkError);
243
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.PublicWalletGetAddressesFailed);
244
+ expect((error as CofhesdkError).message).toBe('address from wallet client is null');
245
+ }
225
246
  });
226
247
 
227
248
  it('should store error in state on failure', async () => {
228
249
  const publicClient = createMockPublicClient();
229
- const error = new Error('Network error');
230
- publicClient.getChainId = vi.fn().mockRejectedValue(error);
250
+ const getChainIdError = new Error('Network error');
251
+ publicClient.getChainId = vi.fn().mockRejectedValue(getChainIdError);
231
252
  const walletClient = createMockWalletClient();
232
253
 
233
- const result = await client.connect(publicClient, walletClient);
254
+ const connectPromise = client.connect(publicClient, walletClient);
234
255
 
235
- expect(result.success).toBe(false);
236
- const snapshot = client.getSnapshot();
237
- expect(snapshot.connectError).toBeTruthy();
238
- expect(snapshot.connected).toBe(false);
256
+ try {
257
+ await connectPromise;
258
+ } catch (error) {
259
+ expect(error).toBeInstanceOf(CofhesdkError);
260
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.PublicWalletGetChainIdFailed);
261
+ expect((error as CofhesdkError).message).toBe(
262
+ 'getting chain ID from public client failed | Caused by: Network error'
263
+ );
264
+ expect((error as CofhesdkError).cause).toBe(getChainIdError);
265
+ }
239
266
  });
240
267
  });
241
268
 
242
269
  describe('encryptInputs', () => {
243
270
  it('should throw if not connected', async () => {
244
- const result = await client
245
- .encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)])
246
- .encrypt();
247
- expect(result.success).toBe(false);
248
- expect(result.error?.code).toBe(CofhesdkErrorCode.NotConnected);
271
+ try {
272
+ await client.encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)]).encrypt();
273
+ } catch (error) {
274
+ expect(error).toBeInstanceOf(CofhesdkError);
275
+ expect((error as CofhesdkError).code).toBe(CofhesdkErrorCode.NotConnected);
276
+ }
249
277
  });
250
278
 
251
279
  it('should create EncryptInputsBuilder when connected', async () => {
@@ -264,17 +292,6 @@ describe('createCofhesdkClientBase', () => {
264
292
  });
265
293
  });
266
294
 
267
- describe('initializationResults', () => {
268
- it('should have keyFetchResult promise', () => {
269
- expect(client.initializationResults.keyFetchResult).toBeInstanceOf(Promise);
270
- });
271
-
272
- it('should resolve keyFetchResult', async () => {
273
- const result = await client.initializationResults.keyFetchResult;
274
- expect(result.success).toBe(true);
275
- });
276
- });
277
-
278
295
  describe('permits', () => {
279
296
  it('should expose permits', () => {
280
297
  expect(client.permits).toBeDefined();
package/core/client.ts CHANGED
@@ -1,59 +1,57 @@
1
- /* eslint-disable no-unused-vars */
2
1
  import type { CreateSelfPermitOptions, CreateSharingPermitOptions, ImportSharedPermitOptions } from '@/permits';
3
2
 
4
3
  import { createStore } from 'zustand/vanilla';
5
4
  import { type PublicClient, type WalletClient } from 'viem';
6
- import { fetchMultichainKeys } from './fetchKeys.js';
7
5
  import { CofhesdkError, CofhesdkErrorCode } from './error.js';
8
6
  import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js';
9
- import { type Result, ResultOk, resultWrapper } from './result.js';
10
7
  import { createKeysStore } from './keyStore.js';
11
8
  import { permits } from './permits.js';
12
9
  import { DecryptHandlesBuilder } from './decrypt/decryptHandleBuilder.js';
13
- import {
14
- type CofhesdkClient,
15
- type CofhesdkClientParams,
16
- type CofhesdkClientConnectionState,
17
- type EncryptableItem,
18
- type FheTypes,
19
- type CofhesdkClientPermits,
20
- } from './types.js';
21
10
  import { getPublicClientChainID, getWalletClientAccount } from './utils.js';
11
+ import type {
12
+ CofhesdkClientConnectionState,
13
+ CofhesdkClientParams,
14
+ CofhesdkClient,
15
+ CofhesdkClientPermits,
16
+ } from './clientTypes.js';
17
+ import type { EncryptableItem, FheTypes } from './types.js';
18
+ import type { CofhesdkConfig } from './config.js';
19
+
20
+ export const InitialConnectStore: CofhesdkClientConnectionState = {
21
+ connected: false,
22
+ connecting: false,
23
+ connectError: undefined,
24
+ chainId: undefined,
25
+ account: undefined,
26
+ publicClient: undefined,
27
+ walletClient: undefined,
28
+ };
22
29
 
23
30
  /**
24
31
  * Creates a CoFHE SDK client instance (base implementation)
25
32
  * @param {CofhesdkClientParams} opts - Initialization options including config and platform-specific serializers
26
33
  * @returns {CofhesdkClient} - The CoFHE SDK client instance
27
34
  */
28
- export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkClient {
35
+ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
36
+ opts: CofhesdkClientParams<TConfig>
37
+ ): CofhesdkClient<TConfig> {
29
38
  // Create keysStorage instance using configured storage
30
39
  const keysStorage = createKeysStore(opts.config.fheKeyStorage);
31
40
 
32
- // refs captured in closure
33
- let _publicClient: PublicClient | undefined = undefined;
34
- let _walletClient: WalletClient | undefined = undefined;
35
-
36
41
  // Zustand store for reactive state management
37
- const connectStore = createStore<CofhesdkClientConnectionState>(() => ({
38
- connected: false,
39
- connecting: false,
40
- connectError: undefined,
41
- chainId: undefined,
42
- account: undefined,
43
- }));
42
+
43
+ const connectStore = createStore<CofhesdkClientConnectionState>(() => InitialConnectStore);
44
44
 
45
45
  // Helper to update state
46
46
  const updateConnectState = (partial: Partial<CofhesdkClientConnectionState>) => {
47
47
  connectStore.setState((state) => ({ ...state, ...partial }));
48
48
  };
49
49
 
50
- // single-flight + abortable warmup
51
- let _connectPromise: Promise<Result<boolean>> | undefined = undefined;
52
-
53
50
  // Called before any operation, throws of connection not yet established
54
51
  const _requireConnected = () => {
55
52
  const state = connectStore.getState();
56
- const notConnected = !state.connected || !_publicClient || !_walletClient || !state.account || !state.chainId;
53
+ const notConnected =
54
+ !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
57
55
  if (notConnected) {
58
56
  throw new CofhesdkError({
59
57
  code: CofhesdkErrorCode.NotConnected,
@@ -63,74 +61,47 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
63
61
  connected: state.connected,
64
62
  account: state.account,
65
63
  chainId: state.chainId,
66
- publicClient: _publicClient,
67
- walletClient: _walletClient,
64
+ publicClient: state.publicClient,
65
+ walletClient: state.walletClient,
68
66
  },
69
67
  });
70
68
  }
71
69
  };
72
70
 
73
- // INITIALIZATION
74
-
75
- const keyFetchResult = resultWrapper(async () => {
76
- // If configured, fetch keys for all supported chains
77
- if (opts.config.fheKeysPrefetching === 'SUPPORTED_CHAINS') {
78
- await fetchMultichainKeys(
79
- opts.config,
80
- 0,
81
- opts.tfhePublicKeyDeserializer,
82
- opts.compactPkeCrsDeserializer,
83
- keysStorage
84
- );
85
- return true;
86
- }
87
-
88
- return false;
89
- });
90
-
91
71
  // LIFECYCLE
92
72
 
93
73
  async function connect(publicClient: PublicClient, walletClient: WalletClient) {
94
74
  const state = connectStore.getState();
95
75
 
96
76
  // Exit if already connected and clients are the same
97
- if (state.connected && _publicClient === publicClient && _walletClient === walletClient) {
98
- return Promise.resolve(ResultOk(true));
99
- }
100
-
101
- // Exit if already connecting
102
- if (_connectPromise && _publicClient === publicClient && _walletClient === walletClient) {
103
- return _connectPromise;
104
- }
77
+ if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient) return;
105
78
 
106
79
  // Set connecting state
107
- updateConnectState({ connecting: true, connectError: null, connected: false });
108
-
109
- _connectPromise = resultWrapper(
110
- // try
111
- async () => {
112
- _publicClient = publicClient;
113
- _walletClient = walletClient;
114
-
115
- const chainId = await getPublicClientChainID(publicClient);
116
- const account = await getWalletClientAccount(walletClient);
117
-
118
- updateConnectState({ connecting: false, connected: true, chainId, account });
119
-
120
- return true;
121
- },
122
- // catch
123
- (e) => {
124
- updateConnectState({ connecting: false, connected: false, connectError: e });
125
- return false;
126
- },
127
- // finally
128
- () => {
129
- _connectPromise = undefined;
130
- }
131
- );
132
-
133
- return _connectPromise;
80
+ updateConnectState({
81
+ ...InitialConnectStore,
82
+ connecting: true,
83
+ });
84
+
85
+ // Fetch chainId and account
86
+ try {
87
+ const chainId = await getPublicClientChainID(publicClient);
88
+ const account = await getWalletClientAccount(walletClient);
89
+ updateConnectState({
90
+ connected: true,
91
+ connecting: false,
92
+ connectError: undefined,
93
+ chainId,
94
+ account,
95
+ publicClient,
96
+ walletClient,
97
+ });
98
+ } catch (e) {
99
+ updateConnectState({
100
+ ...InitialConnectStore,
101
+ connectError: e,
102
+ });
103
+ throw e;
104
+ }
134
105
  }
135
106
 
136
107
  // CLIENT OPERATIONS
@@ -144,14 +115,15 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
144
115
  chainId: state.chainId ?? undefined,
145
116
 
146
117
  config: opts.config,
147
- publicClient: _publicClient ?? undefined,
148
- walletClient: _walletClient ?? undefined,
118
+ publicClient: state.publicClient ?? undefined,
119
+ walletClient: state.walletClient ?? undefined,
149
120
  zkvWalletClient: opts.config._internal?.zkvWalletClient,
150
121
 
151
122
  tfhePublicKeyDeserializer: opts.tfhePublicKeyDeserializer,
152
123
  compactPkeCrsDeserializer: opts.compactPkeCrsDeserializer,
153
124
  zkBuilderAndCrsGenerator: opts.zkBuilderAndCrsGenerator,
154
125
  initTfhe: opts.initTfhe,
126
+ zkProveWorkerFn: opts.zkProveWorkerFn,
155
127
 
156
128
  keysStorage,
157
129
 
@@ -169,8 +141,8 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
169
141
  account: state.account ?? undefined,
170
142
 
171
143
  config: opts.config,
172
- publicClient: _publicClient ?? undefined,
173
- walletClient: _walletClient ?? undefined,
144
+ publicClient: state.publicClient ?? undefined,
145
+ walletClient: state.walletClient ?? undefined,
174
146
 
175
147
  requireConnected: _requireConnected,
176
148
  });
@@ -204,67 +176,84 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
204
176
  subscribe: permits.subscribe,
205
177
 
206
178
  // Creation methods (require connection)
207
- createSelf: async (options: CreateSelfPermitOptions) =>
208
- resultWrapper(async () => {
209
- _requireConnected();
210
- return permits.createSelf(options, _publicClient!, _walletClient!);
211
- }),
212
-
213
- createSharing: async (options: CreateSharingPermitOptions) =>
214
- resultWrapper(async () => {
215
- _requireConnected();
216
- return permits.createSharing(options, _publicClient!, _walletClient!);
217
- }),
218
-
219
- importShared: async (options: ImportSharedPermitOptions | any | string) =>
220
- resultWrapper(async () => {
221
- _requireConnected();
222
- return permits.importShared(options, _publicClient!, _walletClient!);
223
- }),
179
+ createSelf: async (
180
+ options: CreateSelfPermitOptions,
181
+ clients?: { publicClient: PublicClient; walletClient: WalletClient }
182
+ ) => {
183
+ _requireConnected();
184
+ const { publicClient, walletClient } = clients ?? connectStore.getState();
185
+ return permits.createSelf(options, publicClient!, walletClient!);
186
+ },
187
+
188
+ createSharing: async (
189
+ options: CreateSharingPermitOptions,
190
+ clients?: { publicClient: PublicClient; walletClient: WalletClient }
191
+ ) => {
192
+ _requireConnected();
193
+ const { publicClient, walletClient } = clients ?? connectStore.getState();
194
+ return permits.createSharing(options, publicClient!, walletClient!);
195
+ },
196
+
197
+ importShared: async (
198
+ options: ImportSharedPermitOptions | string,
199
+ clients?: { publicClient: PublicClient; walletClient: WalletClient }
200
+ ) => {
201
+ _requireConnected();
202
+ const { publicClient, walletClient } = clients ?? connectStore.getState();
203
+ return permits.importShared(options, publicClient!, walletClient!);
204
+ },
205
+
206
+ // Get or create methods (require connection)
207
+ getOrCreateSelfPermit: async (chainId?: number, account?: string, options?: CreateSelfPermitOptions) => {
208
+ _requireConnected();
209
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
210
+ const { publicClient, walletClient } = connectStore.getState();
211
+ return permits.getOrCreateSelfPermit(publicClient!, walletClient!, _chainId, _account, options);
212
+ },
213
+
214
+ getOrCreateSharingPermit: async (options: CreateSharingPermitOptions, chainId?: number, account?: string) => {
215
+ _requireConnected();
216
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
217
+ const { publicClient, walletClient } = connectStore.getState();
218
+ return permits.getOrCreateSharingPermit(publicClient!, walletClient!, options, _chainId, _account);
219
+ },
224
220
 
225
221
  // Retrieval methods (auto-fill chainId/account)
226
- getPermit: async (hash: string, chainId?: number, account?: string) =>
227
- resultWrapper(async () => {
228
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
229
- return permits.getPermit(_chainId, _account, hash);
230
- }),
231
-
232
- getPermits: async (chainId?: number, account?: string) =>
233
- resultWrapper(async () => {
234
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
235
- return permits.getPermits(_chainId, _account);
236
- }),
237
-
238
- getActivePermit: async (chainId?: number, account?: string) =>
239
- resultWrapper(async () => {
240
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
241
- return permits.getActivePermit(_chainId, _account);
242
- }),
243
-
244
- getActivePermitHash: async (chainId?: number, account?: string) =>
245
- resultWrapper(async () => {
246
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
247
- return permits.getActivePermitHash(_chainId, _account);
248
- }),
222
+ getPermit: async (hash: string, chainId?: number, account?: string) => {
223
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
224
+ return permits.getPermit(_chainId, _account, hash);
225
+ },
226
+
227
+ getPermits: async (chainId?: number, account?: string) => {
228
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
229
+ return permits.getPermits(_chainId, _account);
230
+ },
231
+
232
+ getActivePermit: async (chainId?: number, account?: string) => {
233
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
234
+ return permits.getActivePermit(_chainId, _account);
235
+ },
236
+
237
+ getActivePermitHash: async (chainId?: number, account?: string) => {
238
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
239
+ return permits.getActivePermitHash(_chainId, _account);
240
+ },
249
241
 
250
242
  // Mutation methods (auto-fill chainId/account)
251
- selectActivePermit: async (hash: string, chainId?: number, account?: string) =>
252
- resultWrapper(async () => {
253
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
254
- return permits.selectActivePermit(_chainId, _account, hash);
255
- }),
256
-
257
- removePermit: async (hash: string, chainId?: number, account?: string) =>
258
- resultWrapper(async () => {
259
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
260
- return permits.removePermit(_chainId, _account, hash);
261
- }),
262
-
263
- removeActivePermit: async (chainId?: number, account?: string) =>
264
- resultWrapper(async () => {
265
- const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
266
- return permits.removeActivePermit(_chainId, _account);
267
- }),
243
+ selectActivePermit: (hash: string, chainId?: number, account?: string) => {
244
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
245
+ return permits.selectActivePermit(_chainId, _account, hash);
246
+ },
247
+
248
+ removePermit: async (hash: string, chainId?: number, account?: string, force?: boolean) => {
249
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
250
+ return permits.removePermit(_chainId, _account, hash, force);
251
+ },
252
+
253
+ removeActivePermit: async (chainId?: number, account?: string) => {
254
+ const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
255
+ return permits.removeActivePermit(_chainId, _account);
256
+ },
268
257
 
269
258
  // Utils (no context needed)
270
259
  getHash: permits.getHash,
@@ -277,11 +266,6 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
277
266
  getSnapshot: connectStore.getState,
278
267
  subscribe: connectStore.subscribe,
279
268
 
280
- // initialization results
281
- initializationResults: {
282
- keyFetchResult,
283
- },
284
-
285
269
  // flags (read-only: reflect snapshot)
286
270
  get connected() {
287
271
  return connectStore.getState().connected;
@@ -302,7 +286,7 @@ export function createCofhesdkClientBase(opts: CofhesdkClientParams): CofhesdkCl
302
286
  // Example:
303
287
  // async encryptData(data: unknown) {
304
288
  // requireConnected();
305
- // // Use _publicClient and _walletClient for implementation
289
+ // // Use state.publicClient and state.walletClient for implementation
306
290
  // },
307
291
  };
308
292
  }