@cofhe/sdk 0.0.0-beta-20251027110729

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 (110) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/adapters/ethers5.test.ts +174 -0
  3. package/adapters/ethers5.ts +36 -0
  4. package/adapters/ethers6.test.ts +169 -0
  5. package/adapters/ethers6.ts +36 -0
  6. package/adapters/hardhat-node.ts +167 -0
  7. package/adapters/hardhat.hh2.test.ts +159 -0
  8. package/adapters/hardhat.ts +37 -0
  9. package/adapters/index.test.ts +25 -0
  10. package/adapters/index.ts +5 -0
  11. package/adapters/smartWallet.ts +91 -0
  12. package/adapters/test-utils.ts +53 -0
  13. package/adapters/types.ts +6 -0
  14. package/adapters/wagmi.test.ts +156 -0
  15. package/adapters/wagmi.ts +17 -0
  16. package/chains/chains/arbSepolia.ts +14 -0
  17. package/chains/chains/baseSepolia.ts +14 -0
  18. package/chains/chains/hardhat.ts +15 -0
  19. package/chains/chains/sepolia.ts +14 -0
  20. package/chains/chains.test.ts +49 -0
  21. package/chains/defineChain.ts +18 -0
  22. package/chains/index.ts +33 -0
  23. package/chains/types.ts +32 -0
  24. package/core/baseBuilder.ts +138 -0
  25. package/core/client.test.ts +298 -0
  26. package/core/client.ts +308 -0
  27. package/core/config.test.ts +224 -0
  28. package/core/config.ts +213 -0
  29. package/core/decrypt/MockQueryDecrypterAbi.ts +129 -0
  30. package/core/decrypt/cofheMocksSealOutput.ts +57 -0
  31. package/core/decrypt/decryptHandleBuilder.ts +281 -0
  32. package/core/decrypt/decryptUtils.ts +28 -0
  33. package/core/decrypt/tnSealOutput.ts +59 -0
  34. package/core/encrypt/MockZkVerifierAbi.ts +106 -0
  35. package/core/encrypt/cofheMocksZkVerifySign.ts +278 -0
  36. package/core/encrypt/encryptInputsBuilder.test.ts +735 -0
  37. package/core/encrypt/encryptInputsBuilder.ts +512 -0
  38. package/core/encrypt/encryptUtils.ts +64 -0
  39. package/core/encrypt/zkPackProveVerify.ts +273 -0
  40. package/core/error.ts +170 -0
  41. package/core/fetchKeys.test.ts +212 -0
  42. package/core/fetchKeys.ts +170 -0
  43. package/core/index.ts +77 -0
  44. package/core/keyStore.test.ts +226 -0
  45. package/core/keyStore.ts +127 -0
  46. package/core/permits.test.ts +242 -0
  47. package/core/permits.ts +136 -0
  48. package/core/result.test.ts +180 -0
  49. package/core/result.ts +67 -0
  50. package/core/test-utils.ts +45 -0
  51. package/core/types.ts +352 -0
  52. package/core/utils.ts +88 -0
  53. package/dist/adapters.cjs +88 -0
  54. package/dist/adapters.d.cts +14558 -0
  55. package/dist/adapters.d.ts +14558 -0
  56. package/dist/adapters.js +83 -0
  57. package/dist/chains.cjs +101 -0
  58. package/dist/chains.d.cts +99 -0
  59. package/dist/chains.d.ts +99 -0
  60. package/dist/chains.js +1 -0
  61. package/dist/chunk-GZCQQYVI.js +93 -0
  62. package/dist/chunk-KFGPTJ6X.js +2295 -0
  63. package/dist/chunk-LU7BMUUT.js +804 -0
  64. package/dist/core.cjs +3174 -0
  65. package/dist/core.d.cts +16 -0
  66. package/dist/core.d.ts +16 -0
  67. package/dist/core.js +3 -0
  68. package/dist/node.cjs +3090 -0
  69. package/dist/node.d.cts +22 -0
  70. package/dist/node.d.ts +22 -0
  71. package/dist/node.js +90 -0
  72. package/dist/permit-S9CnI6MF.d.cts +333 -0
  73. package/dist/permit-S9CnI6MF.d.ts +333 -0
  74. package/dist/permits.cjs +856 -0
  75. package/dist/permits.d.cts +1056 -0
  76. package/dist/permits.d.ts +1056 -0
  77. package/dist/permits.js +1 -0
  78. package/dist/types-KImPrEIe.d.cts +48 -0
  79. package/dist/types-KImPrEIe.d.ts +48 -0
  80. package/dist/types-PhwGgQvs.d.ts +953 -0
  81. package/dist/types-bB7wLj0q.d.cts +953 -0
  82. package/dist/web.cjs +3067 -0
  83. package/dist/web.d.cts +22 -0
  84. package/dist/web.d.ts +22 -0
  85. package/dist/web.js +64 -0
  86. package/node/client.test.ts +152 -0
  87. package/node/config.test.ts +68 -0
  88. package/node/encryptInputs.test.ts +175 -0
  89. package/node/index.ts +96 -0
  90. package/node/storage.ts +51 -0
  91. package/package.json +120 -0
  92. package/permits/index.ts +67 -0
  93. package/permits/localstorage.test.ts +118 -0
  94. package/permits/permit.test.ts +474 -0
  95. package/permits/permit.ts +396 -0
  96. package/permits/sealing.test.ts +84 -0
  97. package/permits/sealing.ts +131 -0
  98. package/permits/signature.ts +79 -0
  99. package/permits/store.test.ts +128 -0
  100. package/permits/store.ts +168 -0
  101. package/permits/test-utils.ts +20 -0
  102. package/permits/types.ts +174 -0
  103. package/permits/utils.ts +63 -0
  104. package/permits/validation.test.ts +288 -0
  105. package/permits/validation.ts +349 -0
  106. package/web/client.web.test.ts +152 -0
  107. package/web/config.web.test.ts +71 -0
  108. package/web/encryptInputs.web.test.ts +195 -0
  109. package/web/index.ts +97 -0
  110. package/web/storage.ts +20 -0
@@ -0,0 +1,18 @@
1
+ import { CofheChainSchema, type CofheChain } from './types.js';
2
+
3
+ /**
4
+ * Defines and validates a CofheChain configuration
5
+ * @param chainConfig - The chain configuration object to validate
6
+ * @returns The validated chain configuration unchanged
7
+ * @throws {Error} If the chain configuration is invalid
8
+ */
9
+ export function defineChain(chainConfig: CofheChain): CofheChain {
10
+ const result = CofheChainSchema.safeParse(chainConfig);
11
+
12
+ if (!result.success) {
13
+ const errorMessages = result.error.errors.map((err) => `${err.path.join('.')}: ${err.message}`);
14
+ throw new Error(`Invalid chain configuration: ${errorMessages.join(', ')}`);
15
+ }
16
+
17
+ return result.data;
18
+ }
@@ -0,0 +1,33 @@
1
+ // Export types
2
+ export type { CofheChain, Environment } from './types.js';
3
+
4
+ // Import and export individual chains
5
+ import { sepolia } from './chains/sepolia.js';
6
+ import { arbSepolia } from './chains/arbSepolia.js';
7
+ import { baseSepolia } from './chains/baseSepolia.js';
8
+ import { hardhat } from './chains/hardhat.js';
9
+
10
+ export { sepolia, arbSepolia, baseSepolia, hardhat };
11
+
12
+ // Export all chains as a collection
13
+ export const chains = {
14
+ sepolia,
15
+ arbSepolia,
16
+ baseSepolia,
17
+ hardhat,
18
+ } as const;
19
+
20
+ // Import CofheChain type for helper functions
21
+ import type { CofheChain } from './types.js';
22
+
23
+ // Export chain by ID helper
24
+ export const getChainById = (chainId: number): CofheChain | undefined => {
25
+ return Object.values(chains).find((chain) => chain.id === chainId);
26
+ };
27
+
28
+ // Export chain by name helper
29
+ export const getChainByName = (name: string): CofheChain | undefined => {
30
+ return Object.values(chains).find(
31
+ (chain) => chain.name.toLowerCase() === name.toLowerCase() || chain.network.toLowerCase() === name.toLowerCase()
32
+ );
33
+ };
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Environment schema for @cofhe/sdk chains
5
+ */
6
+ export const EnvironmentSchema = z.enum(['MOCK', 'TESTNET', 'MAINNET']);
7
+
8
+ /**
9
+ * Zod schema for CofheChain validation
10
+ */
11
+ export const CofheChainSchema = z.object({
12
+ /** Chain ID */
13
+ id: z.number().int().positive(),
14
+ /** Human-readable chain name */
15
+ name: z.string().min(1),
16
+ /** Network identifier */
17
+ network: z.string().min(1),
18
+ /** coFhe service URL */
19
+ coFheUrl: z.string().url(),
20
+ /** Verifier service URL */
21
+ verifierUrl: z.string().url(),
22
+ /** Threshold network service URL */
23
+ thresholdNetworkUrl: z.string().url(),
24
+ /** Environment type */
25
+ environment: EnvironmentSchema,
26
+ });
27
+
28
+ /**
29
+ * Type inference from the schema
30
+ */
31
+ export type CofheChain = z.infer<typeof CofheChainSchema>;
32
+ export type Environment = z.infer<typeof EnvironmentSchema>;
@@ -0,0 +1,138 @@
1
+ import { type PublicClient, type WalletClient } from 'viem';
2
+ import { type CofhesdkConfig } from './config.js';
3
+ import { CofhesdkError, CofhesdkErrorCode } from './error.js';
4
+
5
+ /**
6
+ * Base parameters that all builders need
7
+ */
8
+ export type BaseBuilderParams = {
9
+ config: CofhesdkConfig | undefined;
10
+ publicClient: PublicClient | undefined;
11
+ walletClient: WalletClient | undefined;
12
+
13
+ chainId: number | undefined;
14
+ account: string | undefined;
15
+
16
+ requireConnected: (() => void) | undefined;
17
+ };
18
+
19
+ /**
20
+ * Abstract base class for builders that provides common functionality
21
+ * for working with clients, config, and chain IDs
22
+ */
23
+ export abstract class BaseBuilder {
24
+ protected config: CofhesdkConfig | undefined;
25
+ protected publicClient: PublicClient | undefined;
26
+ protected walletClient: WalletClient | undefined;
27
+
28
+ protected chainId: number | undefined;
29
+ protected account: string | undefined;
30
+
31
+ protected requireConnected: (() => void) | undefined;
32
+
33
+ constructor(params: BaseBuilderParams) {
34
+ this.config = params.config;
35
+ this.publicClient = params.publicClient;
36
+ this.walletClient = params.walletClient;
37
+
38
+ this.chainId = params.chainId;
39
+ this.account = params.account;
40
+
41
+ this.requireConnected = params.requireConnected;
42
+ }
43
+
44
+ /**
45
+ * Gets the chain ID from the instance or fetches it from the public client
46
+ * @returns The chain ID
47
+ * @throws {CofhesdkError} If chainId is not set and publicClient is not available
48
+ */
49
+ protected async getChainIdOrThrow(): Promise<number> {
50
+ if (this.chainId) return this.chainId;
51
+
52
+ throw new CofhesdkError({
53
+ code: CofhesdkErrorCode.ChainIdUninitialized,
54
+ message: 'Chain ID is not set',
55
+ hint: 'Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.',
56
+ context: {
57
+ chainId: this.chainId,
58
+ },
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Gets the account address from the instance or fetches it from the wallet client
64
+ * @returns The account address
65
+ * @throws {CofhesdkError} If account is not set and walletClient is not available
66
+ */
67
+ protected async getAccountOrThrow(): Promise<string> {
68
+ if (this.account) return this.account;
69
+
70
+ throw new CofhesdkError({
71
+ code: CofhesdkErrorCode.AccountUninitialized,
72
+ message: 'Account is not set',
73
+ hint: 'Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.',
74
+ context: {
75
+ account: this.account,
76
+ },
77
+ });
78
+ }
79
+
80
+ /**
81
+ * Gets the config or throws an error if not available
82
+ * @returns The config
83
+ * @throws {CofhesdkError} If config is not set
84
+ */
85
+ protected getConfigOrThrow(): CofhesdkConfig {
86
+ if (this.config) return this.config;
87
+ throw new CofhesdkError({
88
+ code: CofhesdkErrorCode.MissingConfig,
89
+ message: 'Builder config is undefined',
90
+ hint: 'Ensure client has been created with a config.',
91
+ context: {
92
+ config: this.config,
93
+ },
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Gets the public client or throws an error if not available
99
+ * @returns The public client
100
+ * @throws {CofhesdkError} If publicClient is not set
101
+ */
102
+ protected getPublicClientOrThrow(): PublicClient {
103
+ if (this.publicClient) return this.publicClient;
104
+ throw new CofhesdkError({
105
+ code: CofhesdkErrorCode.MissingPublicClient,
106
+ message: 'Public client not found',
107
+ hint: 'Ensure client.connect() has been called with a publicClient.',
108
+ context: {
109
+ publicClient: this.publicClient,
110
+ },
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Gets the wallet client or throws an error if not available
116
+ * @returns The wallet client
117
+ * @throws {CofhesdkError} If walletClient is not set
118
+ */
119
+ protected getWalletClientOrThrow(): WalletClient {
120
+ if (this.walletClient) return this.walletClient;
121
+ throw new CofhesdkError({
122
+ code: CofhesdkErrorCode.MissingWalletClient,
123
+ message: 'Wallet client not found',
124
+ hint: 'Ensure client.connect() has been called with a walletClient.',
125
+ context: {
126
+ walletClient: this.walletClient,
127
+ },
128
+ });
129
+ }
130
+
131
+ /**
132
+ * Requires the client to be connected
133
+ * @throws {CofhesdkError} If client is not connected
134
+ */
135
+ protected requireConnectedOrThrow(): void {
136
+ if (this.requireConnected) this.requireConnected();
137
+ }
138
+ }
@@ -0,0 +1,298 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
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';
6
+ import { type PublicClient, type WalletClient } from 'viem';
7
+ import { EncryptInputsBuilder } from './encrypt/encryptInputsBuilder.js';
8
+ import { Encryptable } from './types.js';
9
+
10
+ // Mock dependencies
11
+ vi.mock('./keyStore', () => ({
12
+ createKeysStore: vi.fn(() => ({
13
+ rehydrateKeysStore: vi.fn().mockResolvedValue(undefined),
14
+ getFheKey: vi.fn(),
15
+ getCrs: vi.fn(),
16
+ setFheKey: vi.fn(),
17
+ setCrs: vi.fn(),
18
+ clearKeysStorage: vi.fn(),
19
+ store: {} as any,
20
+ })),
21
+ }));
22
+
23
+ vi.mock('./fetchKeys', () => ({
24
+ fetchMultichainKeys: vi.fn().mockResolvedValue(undefined),
25
+ }));
26
+
27
+ // Test helpers
28
+ const createMockPublicClient = (chainId = 11155111): PublicClient =>
29
+ ({
30
+ getChainId: vi.fn().mockResolvedValue(chainId),
31
+ }) as any;
32
+
33
+ const createMockWalletClient = (addresses = ['0x1234567890123456789012345678901234567890']): WalletClient =>
34
+ ({
35
+ getAddresses: vi.fn().mockResolvedValue(addresses),
36
+ }) as any;
37
+
38
+ const createTestClient = (): CofhesdkClient => {
39
+ const config = createCofhesdkConfigBase({ supportedChains: [] });
40
+ return createCofhesdkClientBase({
41
+ config,
42
+ zkBuilderAndCrsGenerator: {} as any,
43
+ tfhePublicKeyDeserializer: {} as any,
44
+ compactPkeCrsDeserializer: {} as any,
45
+ initTfhe: () => Promise.resolve(false),
46
+ });
47
+ };
48
+
49
+ describe('createCofhesdkClientBase', () => {
50
+ let client: CofhesdkClient;
51
+
52
+ beforeEach(() => {
53
+ client = createTestClient();
54
+ });
55
+
56
+ describe('initial state', () => {
57
+ it('should start disconnected', () => {
58
+ const snapshot = client.getSnapshot();
59
+ expect(snapshot.connected).toBe(false);
60
+ expect(snapshot.connecting).toBe(false);
61
+ expect(snapshot.connectError).toBe(undefined);
62
+ expect(snapshot.chainId).toBe(undefined);
63
+ expect(snapshot.account).toBe(undefined);
64
+ });
65
+
66
+ it('should expose convenience flags', () => {
67
+ expect(client.connected).toBe(false);
68
+ expect(client.connecting).toBe(false);
69
+ });
70
+
71
+ it('should expose config', () => {
72
+ expect(client.config).toBeDefined();
73
+ expect(client.config.supportedChains).toEqual([]);
74
+ });
75
+ });
76
+
77
+ describe('reactive state', () => {
78
+ it('should notify subscribers of state changes', async () => {
79
+ const states: CofhesdkClientConnectionState[] = [];
80
+ client.subscribe((snapshot) => states.push(snapshot));
81
+
82
+ const publicClient = createMockPublicClient();
83
+ const walletClient = createMockWalletClient();
84
+ await client.connect(publicClient, walletClient);
85
+
86
+ // Expect states[0] to be the connecting state
87
+ expect(states[0].connecting).toBe(true);
88
+ expect(states[0].connected).toBe(false);
89
+ expect(states[0].chainId).toBe(undefined);
90
+ expect(states[0].account).toBe(undefined);
91
+
92
+ // Expect states[1] to be the connected state
93
+ expect(states[1].connected).toBe(true);
94
+ expect(states[1].connecting).toBe(false);
95
+ expect(states[1].chainId).toBe(11155111);
96
+ expect(states[1].account).toBe('0x1234567890123456789012345678901234567890');
97
+ });
98
+
99
+ it('should stop notifications after unsubscribe', async () => {
100
+ const states: CofhesdkClientConnectionState[] = [];
101
+ const unsubscribe = client.subscribe((snapshot) => states.push(snapshot));
102
+
103
+ unsubscribe();
104
+
105
+ const publicClient = createMockPublicClient();
106
+ const walletClient = createMockWalletClient();
107
+ await client.connect(publicClient, walletClient);
108
+
109
+ // Should only have the initial notification
110
+ expect(states.length).toBe(0);
111
+ });
112
+ });
113
+
114
+ describe('connect', () => {
115
+ it('should successfully connect with valid clients', async () => {
116
+ const publicClient = createMockPublicClient(11155111);
117
+ const walletClient = createMockWalletClient(['0xabcd']);
118
+
119
+ const result = await client.connect(publicClient, walletClient);
120
+
121
+ expect(result.success).toBe(true);
122
+ expect(result.data).toBe(true);
123
+
124
+ expect(client.connected).toBe(true);
125
+ expect(client.connecting).toBe(false);
126
+
127
+ const snapshot = client.getSnapshot();
128
+ expect(snapshot.chainId).toBe(11155111);
129
+ expect(snapshot.account).toBe('0xabcd');
130
+ });
131
+
132
+ it('should set connecting state during connection', async () => {
133
+ const publicClient = createMockPublicClient();
134
+ const walletClient = createMockWalletClient();
135
+
136
+ const connectPromise = client.connect(publicClient, walletClient);
137
+
138
+ // Check mid-connection state
139
+ expect(client.connecting).toBe(true);
140
+ expect(client.connected).toBe(false);
141
+
142
+ await connectPromise;
143
+
144
+ expect(client.connecting).toBe(false);
145
+ expect(client.connected).toBe(true);
146
+ });
147
+
148
+ it('should return existing promise if already connecting', async () => {
149
+ const publicClient = createMockPublicClient();
150
+ const walletClient = createMockWalletClient();
151
+
152
+ const promise1 = client.connect(publicClient, walletClient);
153
+ const promise2 = client.connect(publicClient, walletClient);
154
+
155
+ expect(promise1).toStrictEqual(promise2);
156
+
157
+ await promise1;
158
+ });
159
+
160
+ it('should return immediately if already connected with same clients', async () => {
161
+ const publicClient = createMockPublicClient();
162
+ const walletClient = createMockWalletClient();
163
+
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);
183
+ });
184
+
185
+ it('should handle getChainId returning null', async () => {
186
+ const publicClient = createMockPublicClient();
187
+ publicClient.getChainId = vi.fn().mockResolvedValue(null);
188
+ const walletClient = createMockWalletClient();
189
+
190
+ const result = await client.connect(publicClient, walletClient);
191
+
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);
197
+ });
198
+
199
+ it('should handle getAddresses throwing an error', async () => {
200
+ const publicClient = createMockPublicClient();
201
+ const error = new Error('Network error');
202
+ const walletClient = createMockWalletClient();
203
+ walletClient.getAddresses = vi.fn().mockRejectedValue(error);
204
+
205
+ const result = await client.connect(publicClient, walletClient);
206
+
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);
212
+ });
213
+
214
+ it('should handle getAddresses returning an empty array', async () => {
215
+ const publicClient = createMockPublicClient();
216
+ const walletClient = createMockWalletClient([]);
217
+
218
+ const result = await client.connect(publicClient, walletClient);
219
+
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);
225
+ });
226
+
227
+ it('should store error in state on failure', async () => {
228
+ const publicClient = createMockPublicClient();
229
+ const error = new Error('Network error');
230
+ publicClient.getChainId = vi.fn().mockRejectedValue(error);
231
+ const walletClient = createMockWalletClient();
232
+
233
+ const result = await client.connect(publicClient, walletClient);
234
+
235
+ expect(result.success).toBe(false);
236
+ const snapshot = client.getSnapshot();
237
+ expect(snapshot.connectError).toBeTruthy();
238
+ expect(snapshot.connected).toBe(false);
239
+ });
240
+ });
241
+
242
+ describe('encryptInputs', () => {
243
+ 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);
249
+ });
250
+
251
+ it('should create EncryptInputsBuilder when connected', async () => {
252
+ const publicClient = createMockPublicClient(123);
253
+ const walletClient = createMockWalletClient(['0xtest']);
254
+
255
+ await client.connect(publicClient, walletClient);
256
+
257
+ const builder = await client.encryptInputs([Encryptable.uint8(1n), Encryptable.uint8(2n), Encryptable.uint8(3n)]);
258
+
259
+ expect(builder).toBeDefined();
260
+ expect(builder).toBeInstanceOf(EncryptInputsBuilder);
261
+ expect(builder).toHaveProperty('encrypt');
262
+ expect(builder.getChainId()).toBe(123);
263
+ expect(builder.getAccount()).toBe('0xtest');
264
+ });
265
+ });
266
+
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
+ describe('permits', () => {
279
+ it('should expose permits', () => {
280
+ expect(client.permits).toBeDefined();
281
+ expect(client.permits).toHaveProperty('getSnapshot');
282
+ expect(client.permits).toHaveProperty('subscribe');
283
+ expect(client.permits).toHaveProperty('createSelf');
284
+ expect(client.permits).toHaveProperty('createSharing');
285
+ expect(client.permits).toHaveProperty('importShared');
286
+ expect(client.permits).toHaveProperty('getHash');
287
+ expect(client.permits).toHaveProperty('serialize');
288
+ expect(client.permits).toHaveProperty('deserialize');
289
+ expect(client.permits).toHaveProperty('getPermit');
290
+ expect(client.permits).toHaveProperty('getPermits');
291
+ expect(client.permits).toHaveProperty('getActivePermit');
292
+ expect(client.permits).toHaveProperty('getActivePermitHash');
293
+ expect(client.permits).toHaveProperty('removePermit');
294
+ expect(client.permits).toHaveProperty('selectActivePermit');
295
+ expect(client.permits).toHaveProperty('removeActivePermit');
296
+ });
297
+ });
298
+ });