@cofhe/sdk 0.2.1 → 0.3.1
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/CHANGELOG.md +34 -0
- package/core/baseBuilder.ts +18 -18
- package/core/client.test.ts +58 -55
- package/core/client.ts +50 -30
- package/core/clientTypes.ts +21 -17
- package/core/config.test.ts +32 -33
- package/core/config.ts +47 -48
- package/core/consts.ts +6 -2
- package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
- package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
- package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -12
- package/core/decrypt/decryptForTxBuilder.ts +340 -0
- package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
- package/core/decrypt/tnDecrypt.ts +232 -0
- package/core/decrypt/tnSealOutputV1.ts +5 -5
- package/core/decrypt/tnSealOutputV2.ts +27 -27
- package/core/encrypt/cofheMocksZkVerifySign.ts +15 -15
- package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
- package/core/encrypt/encryptInputsBuilder.ts +65 -42
- package/core/encrypt/zkPackProveVerify.ts +11 -11
- package/core/error.ts +18 -18
- package/core/fetchKeys.test.ts +3 -3
- package/core/fetchKeys.ts +3 -3
- package/core/index.ts +14 -11
- package/core/utils.ts +10 -10
- package/dist/{chunk-I5WFEYXX.js → chunk-2TPSCOW3.js} +791 -209
- package/dist/{chunk-R3B5TMVX.js → chunk-NWDKXBIP.js} +3 -2
- package/dist/{clientTypes-RqkgkV2i.d.ts → clientTypes-6aTZPQ_4.d.ts} +204 -85
- package/dist/{clientTypes-e4filDzK.d.cts → clientTypes-Bhq7pCSA.d.cts} +204 -85
- package/dist/core.cjs +799 -214
- package/dist/core.d.cts +25 -23
- package/dist/core.d.ts +25 -23
- package/dist/core.js +2 -2
- package/dist/node.cjs +748 -165
- package/dist/node.d.cts +10 -10
- package/dist/node.d.ts +10 -10
- package/dist/node.js +7 -7
- package/dist/permits.js +1 -1
- package/dist/web.cjs +751 -168
- package/dist/web.d.cts +11 -11
- package/dist/web.d.ts +11 -11
- package/dist/web.js +9 -9
- package/node/client.test.ts +34 -34
- package/node/config.test.ts +11 -11
- package/node/encryptInputs.test.ts +29 -29
- package/node/index.ts +15 -15
- package/package.json +3 -3
- package/web/client.web.test.ts +34 -34
- package/web/config.web.test.ts +11 -11
- package/web/encryptInputs.web.test.ts +29 -29
- package/web/index.ts +19 -19
- package/web/worker.builder.web.test.ts +28 -28
- package/web/worker.config.web.test.ts +47 -47
- package/web/worker.output.web.test.ts +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @cofhe/sdk Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 370f0c7: no-op
|
|
8
|
+
|
|
9
|
+
## 0.3.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 35024b6: Remove `sdk` from function names and exported types. Rename:
|
|
14
|
+
|
|
15
|
+
- `createCofhesdkConfig` -> `createCofheConfig`
|
|
16
|
+
- `createCofhesdkClient` -> `createCofheClient`
|
|
17
|
+
- `hre.cofhesdk.*` -> `hre.cofhe.*`
|
|
18
|
+
- `hre.cofhesdk.createCofheConfig()` → `hre.cofhe.createConfig()`
|
|
19
|
+
- `hre.cofhesdk.createCofheClient()` → `hre.cofhe.createClient()`
|
|
20
|
+
- `hre.cofhesdk.createBatteriesIncludedCofheClient()` → `hre.cofhe.createClientWithBatteries()`
|
|
21
|
+
|
|
22
|
+
- 29c2401: implement decrypt-with-proof flows and related tests:
|
|
23
|
+
|
|
24
|
+
- Implement production `decryptForTx` backed by Threshold Network `POST /decrypt`, with explicit permit vs global-allowance selection.
|
|
25
|
+
- Rename mocks “Query Decrypter” -> “Threshold Network” and update SDK constants/contracts/artifacts accordingly.
|
|
26
|
+
- Extend mock contracts + hardhat plugin to publish & verify decryption results on-chain, and add end-to-end integration tests.
|
|
27
|
+
|
|
28
|
+
- 650ea48: Align builder patterns in cofhe client api (`client.encryptInputs(..).encrypt()` and `client.decryptHandles(..).decrypt()`) to use the same terminator function `.execute()` instead of `.encrypt()`/`.decrypt()`.
|
|
29
|
+
|
|
30
|
+
Rename `setStepCallback` of encryptInputs builder to `onStep` to improve ergonomics.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- 5467d77: Adds `config.mocks.encryptDelay: number | [number, number, number, number, number]` to allow configurable mock encryption delay. Defaults to 0 delay on hardhat to keep tests quick.
|
|
35
|
+
- 73b1502: Add `cofheClient.connection` getter which exposes inner connection state without using `getSnapshot()` reactive utility.
|
|
36
|
+
|
|
3
37
|
## 0.2.1
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
package/core/baseBuilder.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type PublicClient, type WalletClient } from 'viem';
|
|
2
|
-
import { type
|
|
3
|
-
import {
|
|
2
|
+
import { type CofheConfig } from './config.js';
|
|
3
|
+
import { CofheError, CofheErrorCode } from './error.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Base parameters that all builders need
|
|
7
7
|
*/
|
|
8
8
|
export type BaseBuilderParams = {
|
|
9
|
-
config:
|
|
9
|
+
config: CofheConfig | undefined;
|
|
10
10
|
publicClient: PublicClient | undefined;
|
|
11
11
|
walletClient: WalletClient | undefined;
|
|
12
12
|
|
|
@@ -21,7 +21,7 @@ export type BaseBuilderParams = {
|
|
|
21
21
|
* for working with clients, config, and chain IDs
|
|
22
22
|
*/
|
|
23
23
|
export abstract class BaseBuilder {
|
|
24
|
-
protected config:
|
|
24
|
+
protected config: CofheConfig;
|
|
25
25
|
|
|
26
26
|
protected publicClient: PublicClient | undefined;
|
|
27
27
|
protected walletClient: WalletClient | undefined;
|
|
@@ -32,8 +32,8 @@ export abstract class BaseBuilder {
|
|
|
32
32
|
constructor(params: BaseBuilderParams) {
|
|
33
33
|
// Check that config is provided
|
|
34
34
|
if (!params.config) {
|
|
35
|
-
throw new
|
|
36
|
-
code:
|
|
35
|
+
throw new CofheError({
|
|
36
|
+
code: CofheErrorCode.MissingConfig,
|
|
37
37
|
message: 'Builder config is undefined',
|
|
38
38
|
hint: 'Ensure client has been created with a config.',
|
|
39
39
|
context: {
|
|
@@ -55,12 +55,12 @@ export abstract class BaseBuilder {
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Asserts that this.chainId is populated
|
|
58
|
-
* @throws {
|
|
58
|
+
* @throws {CofheError} If chainId is not set
|
|
59
59
|
*/
|
|
60
60
|
protected assertChainId(): asserts this is this & { chainId: number } {
|
|
61
61
|
if (this.chainId) return;
|
|
62
|
-
throw new
|
|
63
|
-
code:
|
|
62
|
+
throw new CofheError({
|
|
63
|
+
code: CofheErrorCode.ChainIdUninitialized,
|
|
64
64
|
message: 'Chain ID is not set',
|
|
65
65
|
hint: 'Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.',
|
|
66
66
|
context: {
|
|
@@ -71,12 +71,12 @@ export abstract class BaseBuilder {
|
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Asserts that this.account is populated
|
|
74
|
-
* @throws {
|
|
74
|
+
* @throws {CofheError} If account is not set
|
|
75
75
|
*/
|
|
76
76
|
protected assertAccount(): asserts this is this & { account: string } {
|
|
77
77
|
if (this.account) return;
|
|
78
|
-
throw new
|
|
79
|
-
code:
|
|
78
|
+
throw new CofheError({
|
|
79
|
+
code: CofheErrorCode.AccountUninitialized,
|
|
80
80
|
message: 'Account is not set',
|
|
81
81
|
hint: 'Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.',
|
|
82
82
|
context: {
|
|
@@ -87,12 +87,12 @@ export abstract class BaseBuilder {
|
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* Asserts that this.publicClient is populated
|
|
90
|
-
* @throws {
|
|
90
|
+
* @throws {CofheError} If publicClient is not set
|
|
91
91
|
*/
|
|
92
92
|
protected assertPublicClient(): asserts this is this & { publicClient: PublicClient } {
|
|
93
93
|
if (this.publicClient) return;
|
|
94
|
-
throw new
|
|
95
|
-
code:
|
|
94
|
+
throw new CofheError({
|
|
95
|
+
code: CofheErrorCode.MissingPublicClient,
|
|
96
96
|
message: 'Public client not found',
|
|
97
97
|
hint: 'Ensure client.connect() has been called with a publicClient.',
|
|
98
98
|
context: {
|
|
@@ -103,12 +103,12 @@ export abstract class BaseBuilder {
|
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* Asserts that this.walletClient is populated
|
|
106
|
-
* @throws {
|
|
106
|
+
* @throws {CofheError} If walletClient is not set
|
|
107
107
|
*/
|
|
108
108
|
protected assertWalletClient(): asserts this is this & { walletClient: WalletClient } {
|
|
109
109
|
if (this.walletClient) return;
|
|
110
|
-
throw new
|
|
111
|
-
code:
|
|
110
|
+
throw new CofheError({
|
|
111
|
+
code: CofheErrorCode.MissingWalletClient,
|
|
112
112
|
message: 'Wallet client not found',
|
|
113
113
|
hint: 'Ensure client.connect() has been called with a walletClient.',
|
|
114
114
|
context: {
|
package/core/client.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
import { type
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { createCofheClientBase } from './client.js';
|
|
3
|
+
import { type CofheClient, type CofheClientConnectionState } from './clientTypes.js';
|
|
4
|
+
import { createCofheConfigBase, type CofheEnvironment } from './config.js';
|
|
5
|
+
import { CofheError, CofheErrorCode } 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';
|
|
@@ -31,9 +31,9 @@ const createMockWalletClient = (addresses = ['0x12345678901234567890123456789012
|
|
|
31
31
|
getAddresses: vi.fn().mockResolvedValue(addresses),
|
|
32
32
|
}) as any;
|
|
33
33
|
|
|
34
|
-
const createTestClient = ():
|
|
35
|
-
const config =
|
|
36
|
-
return
|
|
34
|
+
const createTestClient = (): CofheClient => {
|
|
35
|
+
const config = createCofheConfigBase({ supportedChains: [] });
|
|
36
|
+
return createCofheClientBase({
|
|
37
37
|
config,
|
|
38
38
|
zkBuilderAndCrsGenerator: {} as any,
|
|
39
39
|
tfhePublicKeyDeserializer: {} as any,
|
|
@@ -42,8 +42,8 @@ const createTestClient = (): CofhesdkClient => {
|
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
describe('
|
|
46
|
-
let client:
|
|
45
|
+
describe('createCofheClientBase', () => {
|
|
46
|
+
let client: CofheClient;
|
|
47
47
|
|
|
48
48
|
beforeEach(() => {
|
|
49
49
|
client = createTestClient();
|
|
@@ -59,11 +59,15 @@ describe('createCofhesdkClientBase', () => {
|
|
|
59
59
|
expect(snapshot.account).toBe(undefined);
|
|
60
60
|
expect(snapshot.publicClient).toBe(undefined);
|
|
61
61
|
expect(snapshot.walletClient).toBe(undefined);
|
|
62
|
+
|
|
63
|
+
const connection = client.connection;
|
|
64
|
+
expect(connection).toEqual(snapshot);
|
|
62
65
|
});
|
|
63
66
|
|
|
64
67
|
it('should expose convenience flags', () => {
|
|
65
68
|
expect(client.connected).toBe(false);
|
|
66
69
|
expect(client.connecting).toBe(false);
|
|
70
|
+
expect(client.connection.connected).toBe(false);
|
|
67
71
|
});
|
|
68
72
|
|
|
69
73
|
it('should expose config', () => {
|
|
@@ -74,10 +78,10 @@ describe('createCofhesdkClientBase', () => {
|
|
|
74
78
|
|
|
75
79
|
describe('environment', () => {
|
|
76
80
|
it('should create a client with the correct environment', async () => {
|
|
77
|
-
const environments:
|
|
81
|
+
const environments: CofheEnvironment[] = ['node', 'hardhat', 'web', 'react'];
|
|
78
82
|
for (const environment of environments) {
|
|
79
|
-
const config =
|
|
80
|
-
const client =
|
|
83
|
+
const config = createCofheConfigBase({ environment, supportedChains: [] });
|
|
84
|
+
const client = createCofheClientBase({
|
|
81
85
|
config,
|
|
82
86
|
zkBuilderAndCrsGenerator: {} as any,
|
|
83
87
|
tfhePublicKeyDeserializer: {} as any,
|
|
@@ -92,7 +96,7 @@ describe('createCofhesdkClientBase', () => {
|
|
|
92
96
|
|
|
93
97
|
describe('reactive state', () => {
|
|
94
98
|
it('should notify subscribers of state changes', async () => {
|
|
95
|
-
const states:
|
|
99
|
+
const states: CofheClientConnectionState[] = [];
|
|
96
100
|
client.subscribe((snapshot) => states.push(snapshot));
|
|
97
101
|
|
|
98
102
|
const publicClient = createMockPublicClient();
|
|
@@ -117,7 +121,7 @@ describe('createCofhesdkClientBase', () => {
|
|
|
117
121
|
});
|
|
118
122
|
|
|
119
123
|
it('should stop notifications after unsubscribe', async () => {
|
|
120
|
-
const states:
|
|
124
|
+
const states: CofheClientConnectionState[] = [];
|
|
121
125
|
const unsubscribe = client.subscribe((snapshot) => states.push(snapshot));
|
|
122
126
|
|
|
123
127
|
unsubscribe();
|
|
@@ -141,11 +145,11 @@ describe('createCofhesdkClientBase', () => {
|
|
|
141
145
|
expect(client.connected).toBe(true);
|
|
142
146
|
expect(client.connecting).toBe(false);
|
|
143
147
|
|
|
144
|
-
const
|
|
145
|
-
expect(
|
|
146
|
-
expect(
|
|
147
|
-
expect(
|
|
148
|
-
expect(
|
|
148
|
+
const connection = client.connection;
|
|
149
|
+
expect(connection.chainId).toBe(11155111);
|
|
150
|
+
expect(connection.account).toBe('0xabcd');
|
|
151
|
+
expect(connection.publicClient).toBe(publicClient);
|
|
152
|
+
expect(connection.walletClient).toBe(walletClient);
|
|
149
153
|
});
|
|
150
154
|
|
|
151
155
|
it('should set connecting state during connection', async () => {
|
|
@@ -218,20 +222,20 @@ describe('createCofhesdkClientBase', () => {
|
|
|
218
222
|
|
|
219
223
|
expect(client.connected).toBe(true);
|
|
220
224
|
expect(client.connecting).toBe(false);
|
|
221
|
-
expect(client.
|
|
222
|
-
expect(client.
|
|
223
|
-
expect(client.
|
|
224
|
-
expect(client.
|
|
225
|
+
expect(client.connection.chainId).toBe(222);
|
|
226
|
+
expect(client.connection.account).toBe('0x2222222222222222222222222222222222222222');
|
|
227
|
+
expect(client.connection.publicClient).toBe(publicClient2);
|
|
228
|
+
expect(client.connection.walletClient).toBe(walletClient2);
|
|
225
229
|
|
|
226
230
|
// Now resolve the first connect; it must not overwrite the latest state.
|
|
227
231
|
resolveChainId1!(111);
|
|
228
232
|
resolveAddresses1!(['0x1111111111111111111111111111111111111111']);
|
|
229
233
|
await promise1;
|
|
230
234
|
|
|
231
|
-
expect(client.
|
|
232
|
-
expect(client.
|
|
233
|
-
expect(client.
|
|
234
|
-
expect(client.
|
|
235
|
+
expect(client.connection.chainId).toBe(222);
|
|
236
|
+
expect(client.connection.account).toBe('0x2222222222222222222222222222222222222222');
|
|
237
|
+
expect(client.connection.publicClient).toBe(publicClient2);
|
|
238
|
+
expect(client.connection.walletClient).toBe(walletClient2);
|
|
235
239
|
});
|
|
236
240
|
|
|
237
241
|
it('should allow disconnect while connecting and never end up connected afterwards', async () => {
|
|
@@ -276,12 +280,12 @@ describe('createCofhesdkClientBase', () => {
|
|
|
276
280
|
try {
|
|
277
281
|
await client.connect(publicClient, walletClient);
|
|
278
282
|
} catch (error) {
|
|
279
|
-
expect(error).toBeInstanceOf(
|
|
280
|
-
expect((error as
|
|
281
|
-
expect((error as
|
|
283
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
284
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetChainIdFailed);
|
|
285
|
+
expect((error as CofheError).message).toBe(
|
|
282
286
|
'getting chain ID from public client failed | Caused by: Network error'
|
|
283
287
|
);
|
|
284
|
-
expect((error as
|
|
288
|
+
expect((error as CofheError).cause).toBe(getChainIdError);
|
|
285
289
|
}
|
|
286
290
|
});
|
|
287
291
|
|
|
@@ -295,9 +299,9 @@ describe('createCofhesdkClientBase', () => {
|
|
|
295
299
|
try {
|
|
296
300
|
await connectPromise;
|
|
297
301
|
} catch (error) {
|
|
298
|
-
expect(error).toBeInstanceOf(
|
|
299
|
-
expect((error as
|
|
300
|
-
expect((error as
|
|
302
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
303
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetChainIdFailed);
|
|
304
|
+
expect((error as CofheError).message).toBe('chain ID from public client is null');
|
|
301
305
|
}
|
|
302
306
|
});
|
|
303
307
|
|
|
@@ -312,12 +316,12 @@ describe('createCofhesdkClientBase', () => {
|
|
|
312
316
|
try {
|
|
313
317
|
await connectPromise;
|
|
314
318
|
} catch (error) {
|
|
315
|
-
expect(error).toBeInstanceOf(
|
|
316
|
-
expect((error as
|
|
317
|
-
expect((error as
|
|
319
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
320
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetAddressesFailed);
|
|
321
|
+
expect((error as CofheError).message).toBe(
|
|
318
322
|
'getting address from wallet client failed | Caused by: Network error'
|
|
319
323
|
);
|
|
320
|
-
expect((error as
|
|
324
|
+
expect((error as CofheError).cause).toBe(getAddressesError);
|
|
321
325
|
}
|
|
322
326
|
});
|
|
323
327
|
|
|
@@ -330,9 +334,9 @@ describe('createCofhesdkClientBase', () => {
|
|
|
330
334
|
try {
|
|
331
335
|
await connectPromise;
|
|
332
336
|
} catch (error) {
|
|
333
|
-
expect(error).toBeInstanceOf(
|
|
334
|
-
expect((error as
|
|
335
|
-
expect((error as
|
|
337
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
338
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetAddressesFailed);
|
|
339
|
+
expect((error as CofheError).message).toBe('address from wallet client is null');
|
|
336
340
|
}
|
|
337
341
|
});
|
|
338
342
|
|
|
@@ -347,12 +351,12 @@ describe('createCofhesdkClientBase', () => {
|
|
|
347
351
|
try {
|
|
348
352
|
await connectPromise;
|
|
349
353
|
} catch (error) {
|
|
350
|
-
expect(error).toBeInstanceOf(
|
|
351
|
-
expect((error as
|
|
352
|
-
expect((error as
|
|
354
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
355
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.PublicWalletGetChainIdFailed);
|
|
356
|
+
expect((error as CofheError).message).toBe(
|
|
353
357
|
'getting chain ID from public client failed | Caused by: Network error'
|
|
354
358
|
);
|
|
355
|
-
expect((error as
|
|
359
|
+
expect((error as CofheError).cause).toBe(getChainIdError);
|
|
356
360
|
}
|
|
357
361
|
});
|
|
358
362
|
|
|
@@ -368,22 +372,21 @@ describe('createCofhesdkClientBase', () => {
|
|
|
368
372
|
expect(client.connected).toBe(false);
|
|
369
373
|
expect(client.connecting).toBe(false);
|
|
370
374
|
|
|
371
|
-
|
|
372
|
-
expect(
|
|
373
|
-
expect(
|
|
374
|
-
expect(
|
|
375
|
-
expect(
|
|
376
|
-
expect(snapshot.connectError).toBe(undefined);
|
|
375
|
+
expect(client.connection.chainId).toBe(undefined);
|
|
376
|
+
expect(client.connection.account).toBe(undefined);
|
|
377
|
+
expect(client.connection.publicClient).toBe(undefined);
|
|
378
|
+
expect(client.connection.walletClient).toBe(undefined);
|
|
379
|
+
expect(client.connection.connectError).toBe(undefined);
|
|
377
380
|
});
|
|
378
381
|
});
|
|
379
382
|
|
|
380
383
|
describe('encryptInputs', () => {
|
|
381
384
|
it('should throw if not connected', async () => {
|
|
382
385
|
try {
|
|
383
|
-
await client.encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)]).
|
|
386
|
+
await client.encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)]).execute();
|
|
384
387
|
} catch (error) {
|
|
385
|
-
expect(error).toBeInstanceOf(
|
|
386
|
-
expect((error as
|
|
388
|
+
expect(error).toBeInstanceOf(CofheError);
|
|
389
|
+
expect((error as CofheError).code).toBe(CofheErrorCode.NotConnected);
|
|
387
390
|
}
|
|
388
391
|
});
|
|
389
392
|
|
|
@@ -397,7 +400,7 @@ describe('createCofhesdkClientBase', () => {
|
|
|
397
400
|
|
|
398
401
|
expect(builder).toBeDefined();
|
|
399
402
|
expect(builder).toBeInstanceOf(EncryptInputsBuilder);
|
|
400
|
-
expect(builder).toHaveProperty('
|
|
403
|
+
expect(builder).toHaveProperty('execute');
|
|
401
404
|
expect(builder.getChainId()).toBe(123);
|
|
402
405
|
expect(builder.getAccount()).toBe('0xtest');
|
|
403
406
|
});
|
package/core/client.ts
CHANGED
|
@@ -2,22 +2,18 @@ import type { CreateSelfPermitOptions, CreateSharingPermitOptions, ImportSharedP
|
|
|
2
2
|
|
|
3
3
|
import { createStore } from 'zustand/vanilla';
|
|
4
4
|
import { type PublicClient, type WalletClient } from 'viem';
|
|
5
|
-
import {
|
|
5
|
+
import { CofheError, CofheErrorCode } from './error.js';
|
|
6
6
|
import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js';
|
|
7
7
|
import { createKeysStore } from './keyStore.js';
|
|
8
8
|
import { permits } from './permits.js';
|
|
9
|
-
import {
|
|
9
|
+
import { DecryptForViewBuilder } from './decrypt/decryptForViewBuilder.js';
|
|
10
|
+
import { DecryptForTxBuilder, type DecryptForTxBuilderUnset } from './decrypt/decryptForTxBuilder.js';
|
|
10
11
|
import { getPublicClientChainID, getWalletClientAccount } from './utils.js';
|
|
11
|
-
import type {
|
|
12
|
-
CofhesdkClientConnectionState,
|
|
13
|
-
CofhesdkClientParams,
|
|
14
|
-
CofhesdkClient,
|
|
15
|
-
CofhesdkClientPermits,
|
|
16
|
-
} from './clientTypes.js';
|
|
12
|
+
import type { CofheClientConnectionState, CofheClientParams, CofheClient, CofheClientPermits } from './clientTypes.js';
|
|
17
13
|
import type { EncryptableItem, FheTypes } from './types.js';
|
|
18
|
-
import type {
|
|
14
|
+
import type { CofheConfig } from './config.js';
|
|
19
15
|
|
|
20
|
-
export const InitialConnectStore:
|
|
16
|
+
export const InitialConnectStore: CofheClientConnectionState = {
|
|
21
17
|
connected: false,
|
|
22
18
|
connecting: false,
|
|
23
19
|
connectError: undefined,
|
|
@@ -28,26 +24,26 @@ export const InitialConnectStore: CofhesdkClientConnectionState = {
|
|
|
28
24
|
};
|
|
29
25
|
|
|
30
26
|
/**
|
|
31
|
-
* Creates a CoFHE
|
|
32
|
-
* @param {
|
|
33
|
-
* @returns {
|
|
27
|
+
* Creates a CoFHE client instance (base implementation)
|
|
28
|
+
* @param {CofheClientParams} opts - Initialization options including config and platform-specific serializers
|
|
29
|
+
* @returns {CofheClient} - The CoFHE client instance
|
|
34
30
|
*/
|
|
35
|
-
export function
|
|
36
|
-
opts:
|
|
37
|
-
):
|
|
31
|
+
export function createCofheClientBase<TConfig extends CofheConfig>(
|
|
32
|
+
opts: CofheClientParams<TConfig>
|
|
33
|
+
): CofheClient<TConfig> {
|
|
38
34
|
// Create keysStorage instance using configured storage
|
|
39
35
|
const keysStorage = createKeysStore(opts.config.fheKeyStorage);
|
|
40
36
|
|
|
41
37
|
// Zustand store for reactive state management
|
|
42
38
|
|
|
43
|
-
const connectStore = createStore<
|
|
39
|
+
const connectStore = createStore<CofheClientConnectionState>(() => InitialConnectStore);
|
|
44
40
|
|
|
45
41
|
// Minimal cancellation mechanism: incremented on each connect/disconnect.
|
|
46
42
|
// If a connect finishes after a disconnect, it must not overwrite the disconnected state.
|
|
47
43
|
let connectAttemptId = 0;
|
|
48
44
|
|
|
49
45
|
// Helper to update state
|
|
50
|
-
const updateConnectState = (partial: Partial<
|
|
46
|
+
const updateConnectState = (partial: Partial<CofheClientConnectionState>) => {
|
|
51
47
|
connectStore.setState((state) => ({ ...state, ...partial }));
|
|
52
48
|
};
|
|
53
49
|
|
|
@@ -57,8 +53,8 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
57
53
|
const notConnected =
|
|
58
54
|
!state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
|
|
59
55
|
if (notConnected) {
|
|
60
|
-
throw new
|
|
61
|
-
code:
|
|
56
|
+
throw new CofheError({
|
|
57
|
+
code: CofheErrorCode.NotConnected,
|
|
62
58
|
message: 'Client must be connected, account and chainId must be initialized',
|
|
63
59
|
hint: 'Ensure client.connect() has been called and awaited.',
|
|
64
60
|
context: {
|
|
@@ -150,18 +146,34 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
150
146
|
});
|
|
151
147
|
}
|
|
152
148
|
|
|
153
|
-
function
|
|
149
|
+
function decryptForView<U extends FheTypes>(ctHash: bigint, utype: U): DecryptForViewBuilder<U> {
|
|
154
150
|
const state = connectStore.getState();
|
|
155
151
|
|
|
156
|
-
return new
|
|
152
|
+
return new DecryptForViewBuilder({
|
|
157
153
|
ctHash,
|
|
158
154
|
utype,
|
|
159
|
-
chainId: state.chainId
|
|
160
|
-
account: state.account
|
|
155
|
+
chainId: state.chainId,
|
|
156
|
+
account: state.account,
|
|
161
157
|
|
|
162
158
|
config: opts.config,
|
|
163
|
-
publicClient: state.publicClient
|
|
164
|
-
walletClient: state.walletClient
|
|
159
|
+
publicClient: state.publicClient,
|
|
160
|
+
walletClient: state.walletClient,
|
|
161
|
+
|
|
162
|
+
requireConnected: _requireConnected,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function decryptForTx(ctHash: bigint): DecryptForTxBuilderUnset {
|
|
167
|
+
const state = connectStore.getState();
|
|
168
|
+
|
|
169
|
+
return new DecryptForTxBuilder({
|
|
170
|
+
ctHash,
|
|
171
|
+
chainId: state.chainId,
|
|
172
|
+
account: state.account,
|
|
173
|
+
|
|
174
|
+
config: opts.config,
|
|
175
|
+
publicClient: state.publicClient,
|
|
176
|
+
walletClient: state.walletClient,
|
|
165
177
|
|
|
166
178
|
requireConnected: _requireConnected,
|
|
167
179
|
});
|
|
@@ -175,8 +187,8 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
175
187
|
const _account = account ?? state.account;
|
|
176
188
|
|
|
177
189
|
if (_chainId == null || _account == null) {
|
|
178
|
-
throw new
|
|
179
|
-
code:
|
|
190
|
+
throw new CofheError({
|
|
191
|
+
code: CofheErrorCode.NotConnected,
|
|
180
192
|
message: 'ChainId or account not available.',
|
|
181
193
|
hint: 'Ensure client.connect() has been called, or provide chainId and account explicitly.',
|
|
182
194
|
context: {
|
|
@@ -189,7 +201,7 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
189
201
|
return { chainId: _chainId, account: _account };
|
|
190
202
|
};
|
|
191
203
|
|
|
192
|
-
const clientPermits:
|
|
204
|
+
const clientPermits: CofheClientPermits = {
|
|
193
205
|
// Pass through store access
|
|
194
206
|
getSnapshot: permits.getSnapshot,
|
|
195
207
|
subscribe: permits.subscribe,
|
|
@@ -286,6 +298,9 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
286
298
|
subscribe: connectStore.subscribe,
|
|
287
299
|
|
|
288
300
|
// flags (read-only: reflect snapshot)
|
|
301
|
+
get connection() {
|
|
302
|
+
return connectStore.getState();
|
|
303
|
+
},
|
|
289
304
|
get connected() {
|
|
290
305
|
return connectStore.getState().connected;
|
|
291
306
|
},
|
|
@@ -299,7 +314,12 @@ export function createCofhesdkClientBase<TConfig extends CofhesdkConfig>(
|
|
|
299
314
|
connect,
|
|
300
315
|
disconnect,
|
|
301
316
|
encryptInputs,
|
|
302
|
-
|
|
317
|
+
decryptForView,
|
|
318
|
+
/**
|
|
319
|
+
* @deprecated Use `decryptForView` instead. Kept for backward compatibility.
|
|
320
|
+
*/
|
|
321
|
+
decryptHandle: decryptForView,
|
|
322
|
+
decryptForTx,
|
|
303
323
|
permits: clientPermits,
|
|
304
324
|
|
|
305
325
|
// Add SDK-specific methods below that require connection
|
package/core/clientTypes.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// TODO: Extract client types to its own file, keep this one as primitives
|
|
2
2
|
import { type PublicClient, type WalletClient } from 'viem';
|
|
3
|
-
import { type
|
|
4
|
-
import { type
|
|
3
|
+
import { type CofheConfig } from './config.js';
|
|
4
|
+
import { type DecryptForViewBuilder } from './decrypt/decryptForViewBuilder.js';
|
|
5
|
+
import { type DecryptForTxBuilderUnset } from './decrypt/decryptForTxBuilder.js';
|
|
5
6
|
import { type EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js';
|
|
6
7
|
import { type ZkBuilderAndCrsGenerator, type ZkProveWorkerFunction } from './encrypt/zkPackProveVerify.js';
|
|
7
8
|
import { type FheKeyDeserializer } from './fetchKeys.js';
|
|
@@ -20,12 +21,13 @@ import type {
|
|
|
20
21
|
|
|
21
22
|
// CLIENT
|
|
22
23
|
|
|
23
|
-
export type
|
|
24
|
+
export type CofheClient<TConfig extends CofheConfig = CofheConfig> = {
|
|
24
25
|
// --- state access ---
|
|
25
|
-
getSnapshot():
|
|
26
|
+
getSnapshot(): CofheClientConnectionState;
|
|
26
27
|
subscribe(listener: Listener): () => void;
|
|
27
28
|
|
|
28
29
|
// --- convenience flags (read-only) ---
|
|
30
|
+
readonly connection: CofheClientConnectionState;
|
|
29
31
|
readonly connected: boolean;
|
|
30
32
|
readonly connecting: boolean;
|
|
31
33
|
|
|
@@ -43,11 +45,16 @@ export type CofhesdkClient<TConfig extends CofhesdkConfig = CofhesdkConfig> = {
|
|
|
43
45
|
* Types docstring
|
|
44
46
|
*/
|
|
45
47
|
encryptInputs<T extends EncryptableItem[]>(inputs: [...T]): EncryptInputsBuilder<[...T]>;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Use `decryptForView` instead. Kept for backward compatibility.
|
|
50
|
+
*/
|
|
51
|
+
decryptHandle<U extends FheTypes>(ctHash: bigint, utype: U): DecryptForViewBuilder<U>;
|
|
52
|
+
decryptForView<U extends FheTypes>(ctHash: bigint, utype: U): DecryptForViewBuilder<U>;
|
|
53
|
+
decryptForTx(ctHash: bigint): DecryptForTxBuilderUnset;
|
|
54
|
+
permits: CofheClientPermits;
|
|
48
55
|
};
|
|
49
56
|
|
|
50
|
-
export type
|
|
57
|
+
export type CofheClientConnectionState = {
|
|
51
58
|
connected: boolean;
|
|
52
59
|
connecting: boolean;
|
|
53
60
|
connectError: unknown | undefined;
|
|
@@ -57,26 +64,23 @@ export type CofhesdkClientConnectionState = {
|
|
|
57
64
|
walletClient: WalletClient | undefined;
|
|
58
65
|
};
|
|
59
66
|
|
|
60
|
-
type Listener = (snapshot:
|
|
67
|
+
type Listener = (snapshot: CofheClientConnectionState) => void;
|
|
61
68
|
|
|
62
|
-
export type
|
|
69
|
+
export type CofheClientPermitsClients = {
|
|
63
70
|
publicClient: PublicClient;
|
|
64
71
|
walletClient: WalletClient;
|
|
65
72
|
};
|
|
66
73
|
|
|
67
|
-
export type
|
|
74
|
+
export type CofheClientPermits = {
|
|
68
75
|
getSnapshot: typeof permits.getSnapshot;
|
|
69
76
|
subscribe: typeof permits.subscribe;
|
|
70
77
|
|
|
71
78
|
// Creation methods (require connection, no params)
|
|
72
|
-
createSelf: (options: CreateSelfPermitOptions, clients?:
|
|
73
|
-
createSharing: (
|
|
74
|
-
options: CreateSharingPermitOptions,
|
|
75
|
-
clients?: CofhesdkClientPermitsClients
|
|
76
|
-
) => Promise<SharingPermit>;
|
|
79
|
+
createSelf: (options: CreateSelfPermitOptions, clients?: CofheClientPermitsClients) => Promise<SelfPermit>;
|
|
80
|
+
createSharing: (options: CreateSharingPermitOptions, clients?: CofheClientPermitsClients) => Promise<SharingPermit>;
|
|
77
81
|
importShared: (
|
|
78
82
|
options: ImportSharedPermitOptions | string,
|
|
79
|
-
clients?:
|
|
83
|
+
clients?: CofheClientPermitsClients
|
|
80
84
|
) => Promise<RecipientPermit>;
|
|
81
85
|
|
|
82
86
|
// Retrieval methods (chainId/account optional)
|
|
@@ -104,7 +108,7 @@ export type CofhesdkClientPermits = {
|
|
|
104
108
|
deserialize: typeof PermitUtils.deserialize;
|
|
105
109
|
};
|
|
106
110
|
|
|
107
|
-
export type
|
|
111
|
+
export type CofheClientParams<TConfig extends CofheConfig> = {
|
|
108
112
|
config: TConfig;
|
|
109
113
|
zkBuilderAndCrsGenerator: ZkBuilderAndCrsGenerator;
|
|
110
114
|
tfhePublicKeyDeserializer: FheKeyDeserializer;
|