@cofhe/sdk 0.1.1 → 0.2.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 +22 -0
- package/adapters/ethers6.ts +28 -28
- package/adapters/hardhat.ts +0 -1
- package/adapters/index.test.ts +14 -19
- package/adapters/smartWallet.ts +81 -73
- package/adapters/test-utils.ts +45 -45
- package/adapters/types.ts +3 -3
- package/chains/chains/localcofhe.ts +14 -0
- package/chains/chains.test.ts +2 -1
- package/chains/defineChain.ts +2 -2
- package/chains/index.ts +3 -1
- package/chains/types.ts +3 -3
- package/core/baseBuilder.ts +30 -49
- package/core/client.test.ts +200 -72
- package/core/client.ts +152 -148
- package/core/clientTypes.ts +114 -0
- package/core/config.test.ts +30 -11
- package/core/config.ts +26 -13
- package/core/consts.ts +18 -0
- package/core/decrypt/cofheMocksSealOutput.ts +2 -4
- package/core/decrypt/decryptHandleBuilder.ts +51 -45
- package/core/decrypt/{tnSealOutput.ts → tnSealOutputV1.ts} +1 -1
- package/core/decrypt/tnSealOutputV2.ts +298 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +15 -16
- package/core/encrypt/encryptInputsBuilder.test.ts +132 -116
- package/core/encrypt/encryptInputsBuilder.ts +159 -111
- package/core/encrypt/encryptUtils.ts +6 -3
- package/core/encrypt/zkPackProveVerify.ts +70 -8
- package/core/error.ts +0 -2
- package/core/fetchKeys.test.ts +1 -18
- package/core/fetchKeys.ts +0 -26
- package/core/index.ts +37 -17
- package/core/keyStore.ts +65 -38
- package/core/permits.test.ts +255 -4
- package/core/permits.ts +83 -18
- package/core/types.ts +198 -152
- package/core/utils.ts +43 -1
- package/dist/adapters.d.cts +38 -20
- package/dist/adapters.d.ts +38 -20
- package/dist/chains.cjs +18 -8
- package/dist/chains.d.cts +31 -9
- package/dist/chains.d.ts +31 -9
- package/dist/chains.js +1 -1
- package/dist/{chunk-KFGPTJ6X.js → chunk-I5WFEYXX.js} +1768 -1526
- package/dist/{chunk-LU7BMUUT.js → chunk-R3B5TMVX.js} +330 -197
- package/dist/{chunk-GZCQQYVI.js → chunk-TBLR7NNE.js} +18 -9
- package/dist/{types-PhwGgQvs.d.ts → clientTypes-RqkgkV2i.d.ts} +331 -429
- package/dist/{types-bB7wLj0q.d.cts → clientTypes-e4filDzK.d.cts} +331 -429
- package/dist/core.cjs +3000 -2625
- package/dist/core.d.cts +113 -7
- package/dist/core.d.ts +113 -7
- package/dist/core.js +3 -3
- package/dist/node.cjs +2851 -2526
- package/dist/node.d.cts +4 -4
- package/dist/node.d.ts +4 -4
- package/dist/node.js +4 -3
- package/dist/{permit-S9CnI6MF.d.cts → permit-MZ502UBl.d.cts} +54 -41
- package/dist/{permit-S9CnI6MF.d.ts → permit-MZ502UBl.d.ts} +54 -41
- package/dist/permits.cjs +328 -195
- package/dist/permits.d.cts +113 -825
- package/dist/permits.d.ts +113 -825
- package/dist/permits.js +1 -1
- package/dist/types-YiAC4gig.d.cts +33 -0
- package/dist/types-YiAC4gig.d.ts +33 -0
- package/dist/web.cjs +3067 -2527
- package/dist/web.d.cts +22 -6
- package/dist/web.d.ts +22 -6
- package/dist/web.js +185 -9
- package/dist/zkProve.worker.cjs +93 -0
- package/dist/zkProve.worker.d.cts +2 -0
- package/dist/zkProve.worker.d.ts +2 -0
- package/dist/zkProve.worker.js +91 -0
- package/node/client.test.ts +20 -25
- package/node/encryptInputs.test.ts +18 -38
- package/node/index.ts +1 -0
- package/package.json +15 -15
- package/permits/index.ts +1 -0
- package/permits/localstorage.test.ts +9 -14
- package/permits/onchain-utils.ts +221 -0
- package/permits/permit.test.ts +76 -27
- package/permits/permit.ts +58 -95
- package/permits/sealing.test.ts +3 -3
- package/permits/sealing.ts +2 -2
- package/permits/store.test.ts +10 -50
- package/permits/store.ts +9 -21
- package/permits/test-utils.ts +11 -3
- package/permits/types.ts +39 -9
- package/permits/utils.ts +0 -5
- package/permits/validation.test.ts +29 -32
- package/permits/validation.ts +114 -176
- package/web/client.web.test.ts +20 -25
- package/web/config.web.test.ts +0 -2
- package/web/encryptInputs.web.test.ts +31 -54
- package/web/index.ts +65 -1
- package/web/storage.ts +19 -5
- package/web/worker.builder.web.test.ts +148 -0
- package/web/worker.config.web.test.ts +329 -0
- package/web/worker.output.web.test.ts +84 -0
- package/web/workerManager.test.ts +80 -0
- package/web/workerManager.ts +214 -0
- package/web/workerManager.web.test.ts +114 -0
- package/web/zkProve.worker.ts +133 -0
- package/core/result.test.ts +0 -180
- package/core/result.ts +0 -67
- package/core/test-utils.ts +0 -45
- package/dist/types-KImPrEIe.d.cts +0 -48
- package/dist/types-KImPrEIe.d.ts +0 -48
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { hardhat } from './chunk-
|
|
2
|
-
import { permitStore, PermitUtils } from './chunk-
|
|
1
|
+
import { hardhat as hardhat$1 } from './chunk-TBLR7NNE.js';
|
|
2
|
+
import { permitStore, PermitUtils, MOCKS_QUERY_DECRYPTER_ADDRESS, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from './chunk-R3B5TMVX.js';
|
|
3
3
|
import { createStore } from 'zustand/vanilla';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { hardhat as hardhat$1 } from 'viem/chains';
|
|
4
|
+
import { createWalletClient, http, encodePacked, keccak256, toBytes, hashMessage, getAddress } from 'viem';
|
|
5
|
+
import { hardhat } from 'viem/chains';
|
|
7
6
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
7
|
+
import { z } from 'zod';
|
|
8
8
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
9
9
|
import { produce } from 'immer';
|
|
10
10
|
|
|
@@ -143,250 +143,123 @@ var bigintSafeJsonStringify = (value) => {
|
|
|
143
143
|
};
|
|
144
144
|
var isCofhesdkError = (error) => error instanceof CofhesdkError;
|
|
145
145
|
|
|
146
|
-
// core/
|
|
147
|
-
var
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const permit = await permitMethod(options, publicClient, walletClient);
|
|
204
|
-
await storeActivePermit(permit, publicClient, walletClient);
|
|
205
|
-
return permit;
|
|
206
|
-
};
|
|
207
|
-
var createSelf = async (options, publicClient, walletClient) => {
|
|
208
|
-
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSelfAndSign);
|
|
209
|
-
};
|
|
210
|
-
var createSharing = async (options, publicClient, walletClient) => {
|
|
211
|
-
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSharingAndSign);
|
|
212
|
-
};
|
|
213
|
-
var importShared = async (options, publicClient, walletClient) => {
|
|
214
|
-
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.importSharedAndSign);
|
|
215
|
-
};
|
|
216
|
-
var getHash = (permit) => {
|
|
217
|
-
return PermitUtils.getHash(permit);
|
|
218
|
-
};
|
|
219
|
-
var serialize = (permit) => {
|
|
220
|
-
return PermitUtils.serialize(permit);
|
|
221
|
-
};
|
|
222
|
-
var deserialize = (serialized) => {
|
|
223
|
-
return PermitUtils.deserialize(serialized);
|
|
224
|
-
};
|
|
225
|
-
var getPermit = async (chainId, account, hash) => {
|
|
226
|
-
return permitStore.getPermit(chainId, account, hash);
|
|
227
|
-
};
|
|
228
|
-
var getPermits = async (chainId, account) => {
|
|
229
|
-
return permitStore.getPermits(chainId, account);
|
|
230
|
-
};
|
|
231
|
-
var getActivePermit = async (chainId, account) => {
|
|
232
|
-
return permitStore.getActivePermit(chainId, account);
|
|
233
|
-
};
|
|
234
|
-
var getActivePermitHash = async (chainId, account) => {
|
|
235
|
-
return permitStore.getActivePermitHash(chainId, account);
|
|
236
|
-
};
|
|
237
|
-
var selectActivePermit = async (chainId, account, hash) => {
|
|
238
|
-
await permitStore.setActivePermitHash(chainId, account, hash);
|
|
239
|
-
};
|
|
240
|
-
var removePermit = async (chainId, account, hash) => {
|
|
241
|
-
await permitStore.removePermit(chainId, account, hash);
|
|
242
|
-
};
|
|
243
|
-
var removeActivePermit = async (chainId, account) => {
|
|
244
|
-
await permitStore.removeActivePermitHash(chainId, account);
|
|
245
|
-
};
|
|
246
|
-
var permits = {
|
|
247
|
-
getSnapshot: permitStore.store.getState,
|
|
248
|
-
subscribe: permitStore.store.subscribe,
|
|
249
|
-
createSelf,
|
|
250
|
-
createSharing,
|
|
251
|
-
importShared,
|
|
252
|
-
getHash,
|
|
253
|
-
serialize,
|
|
254
|
-
deserialize,
|
|
255
|
-
getPermit,
|
|
256
|
-
getPermits,
|
|
257
|
-
getActivePermit,
|
|
258
|
-
getActivePermitHash,
|
|
259
|
-
removePermit,
|
|
260
|
-
selectActivePermit,
|
|
261
|
-
removeActivePermit
|
|
262
|
-
};
|
|
263
|
-
function uint160ToAddress(uint160) {
|
|
264
|
-
const hexStr = uint160.toString(16).padStart(40, "0");
|
|
265
|
-
return getAddress("0x" + hexStr);
|
|
146
|
+
// core/types.ts
|
|
147
|
+
var FheTypes = /* @__PURE__ */ ((FheTypes2) => {
|
|
148
|
+
FheTypes2[FheTypes2["Bool"] = 0] = "Bool";
|
|
149
|
+
FheTypes2[FheTypes2["Uint4"] = 1] = "Uint4";
|
|
150
|
+
FheTypes2[FheTypes2["Uint8"] = 2] = "Uint8";
|
|
151
|
+
FheTypes2[FheTypes2["Uint16"] = 3] = "Uint16";
|
|
152
|
+
FheTypes2[FheTypes2["Uint32"] = 4] = "Uint32";
|
|
153
|
+
FheTypes2[FheTypes2["Uint64"] = 5] = "Uint64";
|
|
154
|
+
FheTypes2[FheTypes2["Uint128"] = 6] = "Uint128";
|
|
155
|
+
FheTypes2[FheTypes2["Uint160"] = 7] = "Uint160";
|
|
156
|
+
FheTypes2[FheTypes2["Uint256"] = 8] = "Uint256";
|
|
157
|
+
FheTypes2[FheTypes2["Uint512"] = 9] = "Uint512";
|
|
158
|
+
FheTypes2[FheTypes2["Uint1024"] = 10] = "Uint1024";
|
|
159
|
+
FheTypes2[FheTypes2["Uint2048"] = 11] = "Uint2048";
|
|
160
|
+
FheTypes2[FheTypes2["Uint2"] = 12] = "Uint2";
|
|
161
|
+
FheTypes2[FheTypes2["Uint6"] = 13] = "Uint6";
|
|
162
|
+
FheTypes2[FheTypes2["Uint10"] = 14] = "Uint10";
|
|
163
|
+
FheTypes2[FheTypes2["Uint12"] = 15] = "Uint12";
|
|
164
|
+
FheTypes2[FheTypes2["Uint14"] = 16] = "Uint14";
|
|
165
|
+
FheTypes2[FheTypes2["Int2"] = 17] = "Int2";
|
|
166
|
+
FheTypes2[FheTypes2["Int4"] = 18] = "Int4";
|
|
167
|
+
FheTypes2[FheTypes2["Int6"] = 19] = "Int6";
|
|
168
|
+
FheTypes2[FheTypes2["Int8"] = 20] = "Int8";
|
|
169
|
+
FheTypes2[FheTypes2["Int10"] = 21] = "Int10";
|
|
170
|
+
FheTypes2[FheTypes2["Int12"] = 22] = "Int12";
|
|
171
|
+
FheTypes2[FheTypes2["Int14"] = 23] = "Int14";
|
|
172
|
+
FheTypes2[FheTypes2["Int16"] = 24] = "Int16";
|
|
173
|
+
FheTypes2[FheTypes2["Int32"] = 25] = "Int32";
|
|
174
|
+
FheTypes2[FheTypes2["Int64"] = 26] = "Int64";
|
|
175
|
+
FheTypes2[FheTypes2["Int128"] = 27] = "Int128";
|
|
176
|
+
FheTypes2[FheTypes2["Int160"] = 28] = "Int160";
|
|
177
|
+
FheTypes2[FheTypes2["Int256"] = 29] = "Int256";
|
|
178
|
+
return FheTypes2;
|
|
179
|
+
})(FheTypes || {});
|
|
180
|
+
var FheUintUTypes = [
|
|
181
|
+
2 /* Uint8 */,
|
|
182
|
+
3 /* Uint16 */,
|
|
183
|
+
4 /* Uint32 */,
|
|
184
|
+
5 /* Uint64 */,
|
|
185
|
+
6 /* Uint128 */
|
|
186
|
+
// [U256-DISABLED]
|
|
187
|
+
// FheTypes.Uint256,
|
|
188
|
+
];
|
|
189
|
+
var FheAllUTypes = [
|
|
190
|
+
0 /* Bool */,
|
|
191
|
+
2 /* Uint8 */,
|
|
192
|
+
3 /* Uint16 */,
|
|
193
|
+
4 /* Uint32 */,
|
|
194
|
+
5 /* Uint64 */,
|
|
195
|
+
6 /* Uint128 */,
|
|
196
|
+
// [U256-DISABLED]
|
|
197
|
+
// FheTypes.Uint256,
|
|
198
|
+
7 /* Uint160 */
|
|
199
|
+
];
|
|
200
|
+
function assertCorrectEncryptedItemInput(input) {
|
|
201
|
+
if (!input.signature.startsWith("0x"))
|
|
202
|
+
throw new Error("Signature must be a hex string starting with 0x");
|
|
266
203
|
}
|
|
267
|
-
var
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
throw new Error(`convertViaUtype :: invalid utype :: ${utype}`);
|
|
279
|
-
}
|
|
204
|
+
var EncryptableFactoriesImpl = {
|
|
205
|
+
bool: (data, securityZone = 0) => ({ data, securityZone, utype: 0 /* Bool */ }),
|
|
206
|
+
address: (data, securityZone = 0) => ({ data, securityZone, utype: 7 /* Uint160 */ }),
|
|
207
|
+
uint8: (data, securityZone = 0) => ({ data, securityZone, utype: 2 /* Uint8 */ }),
|
|
208
|
+
uint16: (data, securityZone = 0) => ({ data, securityZone, utype: 3 /* Uint16 */ }),
|
|
209
|
+
uint32: (data, securityZone = 0) => ({ data, securityZone, utype: 4 /* Uint32 */ }),
|
|
210
|
+
uint64: (data, securityZone = 0) => ({ data, securityZone, utype: 5 /* Uint64 */ }),
|
|
211
|
+
uint128: (data, securityZone = 0) => ({ data, securityZone, utype: 6 /* Uint128 */ })
|
|
212
|
+
// [U256-DISABLED]
|
|
213
|
+
// uint256: (data: EncryptableUint256['data'], securityZone = 0) =>
|
|
214
|
+
// ({ data, securityZone, utype: FheTypes.Uint256 }) as EncryptableUint256,
|
|
280
215
|
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (this.chainId)
|
|
303
|
-
return this.chainId;
|
|
304
|
-
throw new CofhesdkError({
|
|
305
|
-
code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
|
|
306
|
-
message: "Chain ID is not set",
|
|
307
|
-
hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
|
|
308
|
-
context: {
|
|
309
|
-
chainId: this.chainId
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Gets the account address from the instance or fetches it from the wallet client
|
|
315
|
-
* @returns The account address
|
|
316
|
-
* @throws {CofhesdkError} If account is not set and walletClient is not available
|
|
317
|
-
*/
|
|
318
|
-
async getAccountOrThrow() {
|
|
319
|
-
if (this.account)
|
|
320
|
-
return this.account;
|
|
321
|
-
throw new CofhesdkError({
|
|
322
|
-
code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
|
|
323
|
-
message: "Account is not set",
|
|
324
|
-
hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
|
|
325
|
-
context: {
|
|
326
|
-
account: this.account
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Gets the config or throws an error if not available
|
|
332
|
-
* @returns The config
|
|
333
|
-
* @throws {CofhesdkError} If config is not set
|
|
334
|
-
*/
|
|
335
|
-
getConfigOrThrow() {
|
|
336
|
-
if (this.config)
|
|
337
|
-
return this.config;
|
|
338
|
-
throw new CofhesdkError({
|
|
339
|
-
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
340
|
-
message: "Builder config is undefined",
|
|
341
|
-
hint: "Ensure client has been created with a config.",
|
|
342
|
-
context: {
|
|
343
|
-
config: this.config
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Gets the public client or throws an error if not available
|
|
349
|
-
* @returns The public client
|
|
350
|
-
* @throws {CofhesdkError} If publicClient is not set
|
|
351
|
-
*/
|
|
352
|
-
getPublicClientOrThrow() {
|
|
353
|
-
if (this.publicClient)
|
|
354
|
-
return this.publicClient;
|
|
355
|
-
throw new CofhesdkError({
|
|
356
|
-
code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
|
|
357
|
-
message: "Public client not found",
|
|
358
|
-
hint: "Ensure client.connect() has been called with a publicClient.",
|
|
359
|
-
context: {
|
|
360
|
-
publicClient: this.publicClient
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Gets the wallet client or throws an error if not available
|
|
366
|
-
* @returns The wallet client
|
|
367
|
-
* @throws {CofhesdkError} If walletClient is not set
|
|
368
|
-
*/
|
|
369
|
-
getWalletClientOrThrow() {
|
|
370
|
-
if (this.walletClient)
|
|
371
|
-
return this.walletClient;
|
|
372
|
-
throw new CofhesdkError({
|
|
373
|
-
code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
|
|
374
|
-
message: "Wallet client not found",
|
|
375
|
-
hint: "Ensure client.connect() has been called with a walletClient.",
|
|
376
|
-
context: {
|
|
377
|
-
walletClient: this.walletClient
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Requires the client to be connected
|
|
383
|
-
* @throws {CofhesdkError} If client is not connected
|
|
384
|
-
*/
|
|
385
|
-
requireConnectedOrThrow() {
|
|
386
|
-
if (this.requireConnected)
|
|
387
|
-
this.requireConnected();
|
|
216
|
+
function createEncryptableByLiteral(type, data, securityZone = 0) {
|
|
217
|
+
switch (type) {
|
|
218
|
+
case "bool": {
|
|
219
|
+
if (typeof data !== "boolean")
|
|
220
|
+
throw new Error("Bool encryptable data must be boolean");
|
|
221
|
+
return EncryptableFactoriesImpl.bool(data, securityZone);
|
|
222
|
+
}
|
|
223
|
+
case "address":
|
|
224
|
+
case "uint8":
|
|
225
|
+
case "uint16":
|
|
226
|
+
case "uint32":
|
|
227
|
+
case "uint64":
|
|
228
|
+
case "uint128": {
|
|
229
|
+
if (typeof data === "boolean")
|
|
230
|
+
throw new Error("Uint encryptable data must be string or bigint");
|
|
231
|
+
return EncryptableFactoriesImpl[type](data, securityZone);
|
|
232
|
+
}
|
|
233
|
+
default: {
|
|
234
|
+
const _exhaustive = type;
|
|
235
|
+
throw new Error(`Unsupported encryptable type: ${_exhaustive}`);
|
|
236
|
+
}
|
|
388
237
|
}
|
|
238
|
+
}
|
|
239
|
+
var Encryptable = {
|
|
240
|
+
...EncryptableFactoriesImpl,
|
|
241
|
+
create: createEncryptableByLiteral
|
|
389
242
|
};
|
|
243
|
+
function isEncryptableItem(value) {
|
|
244
|
+
return (
|
|
245
|
+
// Is object and exists
|
|
246
|
+
typeof value === "object" && value !== null && // Has securityZone
|
|
247
|
+
"securityZone" in value && typeof value.securityZone === "number" && // Has utype
|
|
248
|
+
"utype" in value && FheAllUTypes.includes(value.utype) && // Has data
|
|
249
|
+
"data" in value && ["string", "number", "bigint", "boolean"].includes(typeof value.data)
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
var EncryptStep = /* @__PURE__ */ ((EncryptStep2) => {
|
|
253
|
+
EncryptStep2["InitTfhe"] = "initTfhe";
|
|
254
|
+
EncryptStep2["FetchKeys"] = "fetchKeys";
|
|
255
|
+
EncryptStep2["Pack"] = "pack";
|
|
256
|
+
EncryptStep2["Prove"] = "prove";
|
|
257
|
+
EncryptStep2["Verify"] = "verify";
|
|
258
|
+
return EncryptStep2;
|
|
259
|
+
})(EncryptStep || {});
|
|
260
|
+
function isLastEncryptionStep(step) {
|
|
261
|
+
return step === "verify" /* Verify */;
|
|
262
|
+
}
|
|
390
263
|
var toHexString = (bytes) => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
|
|
391
264
|
var toBigIntOrThrow = (value) => {
|
|
392
265
|
if (typeof value === "bigint") {
|
|
@@ -455,23 +328,211 @@ async function getWalletClientAccount(walletClient) {
|
|
|
455
328
|
}
|
|
456
329
|
return address;
|
|
457
330
|
}
|
|
331
|
+
function fheTypeToString(utype) {
|
|
332
|
+
switch (utype) {
|
|
333
|
+
case 0 /* Bool */:
|
|
334
|
+
return "bool";
|
|
335
|
+
case 1 /* Uint4 */:
|
|
336
|
+
return "uint4";
|
|
337
|
+
case 2 /* Uint8 */:
|
|
338
|
+
return "uint8";
|
|
339
|
+
case 3 /* Uint16 */:
|
|
340
|
+
return "uint16";
|
|
341
|
+
case 4 /* Uint32 */:
|
|
342
|
+
return "uint32";
|
|
343
|
+
case 5 /* Uint64 */:
|
|
344
|
+
return "uint64";
|
|
345
|
+
case 6 /* Uint128 */:
|
|
346
|
+
return "uint128";
|
|
347
|
+
case 7 /* Uint160 */:
|
|
348
|
+
return "uint160";
|
|
349
|
+
case 8 /* Uint256 */:
|
|
350
|
+
return "uint256";
|
|
351
|
+
case 9 /* Uint512 */:
|
|
352
|
+
return "uint512";
|
|
353
|
+
case 10 /* Uint1024 */:
|
|
354
|
+
return "uint1024";
|
|
355
|
+
case 11 /* Uint2048 */:
|
|
356
|
+
return "uint2048";
|
|
357
|
+
case 12 /* Uint2 */:
|
|
358
|
+
return "uint2";
|
|
359
|
+
case 13 /* Uint6 */:
|
|
360
|
+
return "uint6";
|
|
361
|
+
case 14 /* Uint10 */:
|
|
362
|
+
return "uint10";
|
|
363
|
+
default:
|
|
364
|
+
throw new Error(`Unknown FheType: ${utype}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
458
367
|
|
|
459
|
-
// core/
|
|
460
|
-
var
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
368
|
+
// core/encrypt/zkPackProveVerify.ts
|
|
369
|
+
var MAX_UINT8 = 255n;
|
|
370
|
+
var MAX_UINT16 = 65535n;
|
|
371
|
+
var MAX_UINT32 = 4294967295n;
|
|
372
|
+
var MAX_UINT64 = 18446744073709551615n;
|
|
373
|
+
var MAX_UINT128 = 340282366920938463463374607431768211455n;
|
|
374
|
+
var MAX_UINT160 = 1461501637330902918203684832716283019655932542975n;
|
|
375
|
+
var MAX_ENCRYPTABLE_BITS = 2048;
|
|
376
|
+
var zkPack = (items, builder) => {
|
|
377
|
+
let totalBits = 0;
|
|
378
|
+
for (const item of items) {
|
|
379
|
+
switch (item.utype) {
|
|
380
|
+
case 0 /* Bool */: {
|
|
381
|
+
builder.push_boolean(item.data);
|
|
382
|
+
totalBits += 1;
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
case 2 /* Uint8 */: {
|
|
386
|
+
const bint = toBigIntOrThrow(item.data);
|
|
387
|
+
validateBigIntInRange(bint, MAX_UINT8);
|
|
388
|
+
builder.push_u8(parseInt(bint.toString()));
|
|
389
|
+
totalBits += 8;
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case 3 /* Uint16 */: {
|
|
393
|
+
const bint = toBigIntOrThrow(item.data);
|
|
394
|
+
validateBigIntInRange(bint, MAX_UINT16);
|
|
395
|
+
builder.push_u16(parseInt(bint.toString()));
|
|
396
|
+
totalBits += 16;
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
case 4 /* Uint32 */: {
|
|
400
|
+
const bint = toBigIntOrThrow(item.data);
|
|
401
|
+
validateBigIntInRange(bint, MAX_UINT32);
|
|
402
|
+
builder.push_u32(parseInt(bint.toString()));
|
|
403
|
+
totalBits += 32;
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
case 5 /* Uint64 */: {
|
|
407
|
+
const bint = toBigIntOrThrow(item.data);
|
|
408
|
+
validateBigIntInRange(bint, MAX_UINT64);
|
|
409
|
+
builder.push_u64(bint);
|
|
410
|
+
totalBits += 64;
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case 6 /* Uint128 */: {
|
|
414
|
+
const bint = toBigIntOrThrow(item.data);
|
|
415
|
+
validateBigIntInRange(bint, MAX_UINT128);
|
|
416
|
+
builder.push_u128(bint);
|
|
417
|
+
totalBits += 128;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
case 7 /* Uint160 */: {
|
|
421
|
+
const bint = toBigIntOrThrow(item.data);
|
|
422
|
+
validateBigIntInRange(bint, MAX_UINT160);
|
|
423
|
+
builder.push_u160(bint);
|
|
424
|
+
totalBits += 160;
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
default: {
|
|
428
|
+
throw new CofhesdkError({
|
|
429
|
+
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
430
|
+
message: `Invalid utype: ${item.utype}`,
|
|
431
|
+
hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
|
|
432
|
+
context: {
|
|
433
|
+
item
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
440
|
+
throw new CofhesdkError({
|
|
441
|
+
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
442
|
+
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
443
|
+
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
444
|
+
context: {
|
|
445
|
+
totalBits,
|
|
446
|
+
maxBits: MAX_ENCRYPTABLE_BITS,
|
|
447
|
+
items
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
return builder;
|
|
452
|
+
};
|
|
453
|
+
var zkProveWithWorker = async (workerFn, fheKeyHex, crsHex, items, metadata) => {
|
|
454
|
+
return await workerFn(fheKeyHex, crsHex, items, metadata);
|
|
455
|
+
};
|
|
456
|
+
var zkProve = async (builder, crs, metadata) => {
|
|
457
|
+
return new Promise((resolve) => {
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
const compactList = builder.build_with_proof_packed(
|
|
460
|
+
crs,
|
|
461
|
+
metadata,
|
|
462
|
+
1
|
|
463
|
+
// ZkComputeLoad.Verify
|
|
464
|
+
);
|
|
465
|
+
resolve(compactList.serialize());
|
|
466
|
+
}, 0);
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
var constructZkPoKMetadata = (accountAddr, securityZone, chainId) => {
|
|
470
|
+
const accountAddrNoPrefix = accountAddr.startsWith("0x") ? accountAddr.slice(2) : accountAddr;
|
|
471
|
+
const accountBytes = hexToBytes(accountAddrNoPrefix);
|
|
472
|
+
const chainIdBytes = new Uint8Array(32);
|
|
473
|
+
let value = chainId;
|
|
474
|
+
for (let i = 31; i >= 0 && value > 0; i--) {
|
|
475
|
+
chainIdBytes[i] = value & 255;
|
|
476
|
+
value = value >>> 8;
|
|
477
|
+
}
|
|
478
|
+
const metadata = new Uint8Array(1 + accountBytes.length + 32);
|
|
479
|
+
metadata[0] = securityZone;
|
|
480
|
+
metadata.set(accountBytes, 1);
|
|
481
|
+
metadata.set(chainIdBytes, 1 + accountBytes.length);
|
|
482
|
+
return metadata;
|
|
483
|
+
};
|
|
484
|
+
var zkVerify = async (verifierUrl, serializedBytes, address, securityZone, chainId) => {
|
|
485
|
+
const packed_list = toHexString(serializedBytes);
|
|
486
|
+
const sz_byte = new Uint8Array([securityZone]);
|
|
487
|
+
const payload = {
|
|
488
|
+
packed_list,
|
|
489
|
+
account_addr: address,
|
|
490
|
+
security_zone: sz_byte[0],
|
|
491
|
+
chain_id: chainId
|
|
492
|
+
};
|
|
493
|
+
const body = JSON.stringify(payload);
|
|
494
|
+
try {
|
|
495
|
+
const response = await fetch(`${verifierUrl}/verify`, {
|
|
496
|
+
method: "POST",
|
|
497
|
+
headers: {
|
|
498
|
+
"Content-Type": "application/json"
|
|
499
|
+
},
|
|
500
|
+
body
|
|
501
|
+
});
|
|
502
|
+
if (!response.ok) {
|
|
503
|
+
const errorBody = await response.text();
|
|
504
|
+
throw new CofhesdkError({
|
|
505
|
+
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
506
|
+
message: `HTTP error! ZK proof verification failed - ${errorBody}`
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
const json = await response.json();
|
|
510
|
+
if (json.status !== "success") {
|
|
511
|
+
throw new CofhesdkError({
|
|
512
|
+
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
513
|
+
message: `ZK proof verification response malformed - ${json.error}`
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
return json.data.map(({ ct_hash, signature, recid }) => {
|
|
517
|
+
return {
|
|
518
|
+
ct_hash,
|
|
519
|
+
signature: concatSigRecid(signature, recid)
|
|
520
|
+
};
|
|
521
|
+
});
|
|
522
|
+
} catch (e) {
|
|
523
|
+
throw new CofhesdkError({
|
|
524
|
+
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
525
|
+
message: `ZK proof verification failed`,
|
|
526
|
+
cause: e instanceof Error ? e : void 0
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
var concatSigRecid = (signature, recid) => {
|
|
531
|
+
return signature + (recid + 27).toString(16).padStart(2, "0");
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// core/encrypt/MockZkVerifierAbi.ts
|
|
535
|
+
var MockZkVerifierAbi = [
|
|
475
536
|
{
|
|
476
537
|
type: "function",
|
|
477
538
|
name: "exists",
|
|
@@ -481,943 +542,670 @@ var MockQueryDecrypterAbi = [
|
|
|
481
542
|
},
|
|
482
543
|
{
|
|
483
544
|
type: "function",
|
|
484
|
-
name: "
|
|
545
|
+
name: "insertCtHash",
|
|
485
546
|
inputs: [
|
|
486
|
-
{ name: "
|
|
487
|
-
{ name: "
|
|
547
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
548
|
+
{ name: "value", type: "uint256", internalType: "uint256" }
|
|
488
549
|
],
|
|
489
550
|
outputs: [],
|
|
490
551
|
stateMutability: "nonpayable"
|
|
491
552
|
},
|
|
492
553
|
{
|
|
493
554
|
type: "function",
|
|
494
|
-
name: "
|
|
555
|
+
name: "insertPackedCtHashes",
|
|
495
556
|
inputs: [
|
|
496
|
-
{ name: "
|
|
497
|
-
{ name: "", type: "uint256", internalType: "uint256" }
|
|
498
|
-
{
|
|
499
|
-
name: "permission",
|
|
500
|
-
type: "tuple",
|
|
501
|
-
internalType: "struct Permission",
|
|
502
|
-
components: [
|
|
503
|
-
{ name: "issuer", type: "address", internalType: "address" },
|
|
504
|
-
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
505
|
-
{ name: "recipient", type: "address", internalType: "address" },
|
|
506
|
-
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
507
|
-
{
|
|
508
|
-
name: "validatorContract",
|
|
509
|
-
type: "address",
|
|
510
|
-
internalType: "address"
|
|
511
|
-
},
|
|
512
|
-
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
513
|
-
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
514
|
-
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
515
|
-
]
|
|
516
|
-
}
|
|
517
|
-
],
|
|
518
|
-
outputs: [
|
|
519
|
-
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
520
|
-
{ name: "error", type: "string", internalType: "string" },
|
|
521
|
-
{ name: "", type: "uint256", internalType: "uint256" }
|
|
557
|
+
{ name: "ctHashes", type: "uint256[]", internalType: "uint256[]" },
|
|
558
|
+
{ name: "values", type: "uint256[]", internalType: "uint256[]" }
|
|
522
559
|
],
|
|
523
|
-
|
|
560
|
+
outputs: [],
|
|
561
|
+
stateMutability: "nonpayable"
|
|
524
562
|
},
|
|
525
563
|
{
|
|
526
564
|
type: "function",
|
|
527
|
-
name: "
|
|
565
|
+
name: "zkVerify",
|
|
528
566
|
inputs: [
|
|
529
|
-
{ name: "
|
|
530
|
-
{ name: "", type: "
|
|
567
|
+
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
568
|
+
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
569
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
570
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
571
|
+
{ name: "", type: "uint256", internalType: "uint256" }
|
|
572
|
+
],
|
|
573
|
+
outputs: [
|
|
531
574
|
{
|
|
532
|
-
name: "
|
|
575
|
+
name: "",
|
|
533
576
|
type: "tuple",
|
|
534
|
-
internalType: "struct
|
|
577
|
+
internalType: "struct EncryptedInput",
|
|
535
578
|
components: [
|
|
536
|
-
{ name: "
|
|
537
|
-
{ name: "
|
|
538
|
-
{ name: "
|
|
539
|
-
{ name: "
|
|
540
|
-
{
|
|
541
|
-
name: "validatorContract",
|
|
542
|
-
type: "address",
|
|
543
|
-
internalType: "address"
|
|
544
|
-
},
|
|
545
|
-
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
546
|
-
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
547
|
-
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
579
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
580
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
581
|
+
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
582
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
548
583
|
]
|
|
549
584
|
}
|
|
550
585
|
],
|
|
551
|
-
|
|
552
|
-
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
553
|
-
{ name: "error", type: "string", internalType: "string" },
|
|
554
|
-
{ name: "", type: "bytes32", internalType: "bytes32" }
|
|
555
|
-
],
|
|
556
|
-
stateMutability: "view"
|
|
586
|
+
stateMutability: "nonpayable"
|
|
557
587
|
},
|
|
558
588
|
{
|
|
559
589
|
type: "function",
|
|
560
|
-
name: "
|
|
590
|
+
name: "zkVerifyCalcCtHash",
|
|
561
591
|
inputs: [
|
|
562
|
-
{ name: "
|
|
563
|
-
{ name: "
|
|
592
|
+
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
593
|
+
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
594
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
595
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
596
|
+
{ name: "", type: "uint256", internalType: "uint256" }
|
|
564
597
|
],
|
|
565
|
-
outputs: [{ name: "", type: "
|
|
566
|
-
stateMutability: "
|
|
598
|
+
outputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
|
|
599
|
+
stateMutability: "view"
|
|
567
600
|
},
|
|
568
601
|
{
|
|
569
602
|
type: "function",
|
|
570
|
-
name: "
|
|
571
|
-
inputs: [
|
|
572
|
-
|
|
603
|
+
name: "zkVerifyCalcCtHashesPacked",
|
|
604
|
+
inputs: [
|
|
605
|
+
{ name: "values", type: "uint256[]", internalType: "uint256[]" },
|
|
606
|
+
{ name: "utypes", type: "uint8[]", internalType: "uint8[]" },
|
|
607
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
608
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
609
|
+
{ name: "chainId", type: "uint256", internalType: "uint256" }
|
|
610
|
+
],
|
|
611
|
+
outputs: [{ name: "ctHashes", type: "uint256[]", internalType: "uint256[]" }],
|
|
573
612
|
stateMutability: "view"
|
|
574
613
|
},
|
|
575
614
|
{
|
|
576
615
|
type: "function",
|
|
577
|
-
name: "
|
|
616
|
+
name: "zkVerifyPacked",
|
|
578
617
|
inputs: [
|
|
579
|
-
{ name: "
|
|
580
|
-
{ name: "
|
|
618
|
+
{ name: "values", type: "uint256[]", internalType: "uint256[]" },
|
|
619
|
+
{ name: "utypes", type: "uint8[]", internalType: "uint8[]" },
|
|
620
|
+
{ name: "user", type: "address", internalType: "address" },
|
|
621
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
622
|
+
{ name: "chainId", type: "uint256", internalType: "uint256" }
|
|
581
623
|
],
|
|
582
|
-
outputs: [
|
|
583
|
-
|
|
624
|
+
outputs: [
|
|
625
|
+
{
|
|
626
|
+
name: "inputs",
|
|
627
|
+
type: "tuple[]",
|
|
628
|
+
internalType: "struct EncryptedInput[]",
|
|
629
|
+
components: [
|
|
630
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
631
|
+
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
632
|
+
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
633
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
634
|
+
]
|
|
635
|
+
}
|
|
636
|
+
],
|
|
637
|
+
stateMutability: "nonpayable"
|
|
584
638
|
},
|
|
585
|
-
{ type: "error", name: "
|
|
586
|
-
{ type: "error", name: "SealingKeyInvalid", inputs: [] },
|
|
587
|
-
{ type: "error", name: "SealingKeyMissing", inputs: [] }
|
|
639
|
+
{ type: "error", name: "InvalidInputs", inputs: [] }
|
|
588
640
|
];
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
await sleep(mocksSealOutputDelay);
|
|
595
|
-
const permission = PermitUtils.getPermission(permit, true);
|
|
596
|
-
const permissionWithBigInts = {
|
|
597
|
-
...permission,
|
|
598
|
-
expiration: BigInt(permission.expiration),
|
|
599
|
-
validatorId: BigInt(permission.validatorId)
|
|
600
|
-
};
|
|
601
|
-
const [allowed, error, result] = await publicClient.readContract({
|
|
602
|
-
address: MockQueryDecrypterAddress,
|
|
603
|
-
abi: MockQueryDecrypterAbi,
|
|
604
|
-
functionName: "querySealOutput",
|
|
605
|
-
args: [ctHash, BigInt(utype), permissionWithBigInts]
|
|
641
|
+
function createMockZkVerifierSigner() {
|
|
642
|
+
return createWalletClient({
|
|
643
|
+
chain: hardhat,
|
|
644
|
+
transport: http(),
|
|
645
|
+
account: privateKeyToAccount(MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY)
|
|
606
646
|
});
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
647
|
+
}
|
|
648
|
+
async function cofheMocksCheckEncryptableBits(items) {
|
|
649
|
+
let totalBits = 0;
|
|
650
|
+
for (const item of items) {
|
|
651
|
+
switch (item.utype) {
|
|
652
|
+
case 0 /* Bool */: {
|
|
653
|
+
totalBits += 1;
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
case 2 /* Uint8 */: {
|
|
657
|
+
totalBits += 8;
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
case 3 /* Uint16 */: {
|
|
661
|
+
totalBits += 16;
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
case 4 /* Uint32 */: {
|
|
665
|
+
totalBits += 32;
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
case 5 /* Uint64 */: {
|
|
669
|
+
totalBits += 64;
|
|
670
|
+
break;
|
|
671
|
+
}
|
|
672
|
+
case 6 /* Uint128 */: {
|
|
673
|
+
totalBits += 128;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
case 7 /* Uint160 */: {
|
|
677
|
+
totalBits += 160;
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
612
681
|
}
|
|
613
|
-
if (
|
|
682
|
+
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
614
683
|
throw new CofhesdkError({
|
|
615
|
-
code: "
|
|
616
|
-
message: `
|
|
684
|
+
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
685
|
+
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
686
|
+
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
687
|
+
context: {
|
|
688
|
+
totalBits,
|
|
689
|
+
maxBits: MAX_ENCRYPTABLE_BITS,
|
|
690
|
+
items
|
|
691
|
+
}
|
|
617
692
|
});
|
|
618
693
|
}
|
|
619
|
-
const sealedBigInt = BigInt(result);
|
|
620
|
-
const sealingKeyBigInt = BigInt(permission.sealingKey);
|
|
621
|
-
const unsealed = sealedBigInt ^ sealingKeyBigInt;
|
|
622
|
-
return unsealed;
|
|
623
694
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
permit: permission
|
|
634
|
-
};
|
|
695
|
+
async function calcCtHashes(items, account, securityZone, publicClient) {
|
|
696
|
+
const calcCtHashesArgs = [
|
|
697
|
+
items.map(({ data }) => BigInt(data)),
|
|
698
|
+
items.map(({ utype }) => utype),
|
|
699
|
+
account,
|
|
700
|
+
securityZone,
|
|
701
|
+
BigInt(hardhat.id)
|
|
702
|
+
];
|
|
703
|
+
let ctHashes;
|
|
635
704
|
try {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
body: JSON.stringify(body)
|
|
705
|
+
ctHashes = await publicClient.readContract({
|
|
706
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
707
|
+
abi: MockZkVerifierAbi,
|
|
708
|
+
functionName: "zkVerifyCalcCtHashesPacked",
|
|
709
|
+
args: calcCtHashesArgs
|
|
642
710
|
});
|
|
643
|
-
|
|
644
|
-
sealed = sealOutputResult.sealed;
|
|
645
|
-
errorMessage = sealOutputResult.error_message;
|
|
646
|
-
} catch (e) {
|
|
711
|
+
} catch (err) {
|
|
647
712
|
throw new CofhesdkError({
|
|
648
|
-
code: "
|
|
649
|
-
message: `
|
|
650
|
-
|
|
651
|
-
cause: e instanceof Error ? e : void 0,
|
|
713
|
+
code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
|
|
714
|
+
message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
|
|
715
|
+
cause: err instanceof Error ? err : void 0,
|
|
652
716
|
context: {
|
|
653
|
-
|
|
654
|
-
|
|
717
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
718
|
+
items,
|
|
719
|
+
account,
|
|
720
|
+
securityZone,
|
|
721
|
+
publicClient,
|
|
722
|
+
calcCtHashesArgs
|
|
655
723
|
}
|
|
656
724
|
});
|
|
657
725
|
}
|
|
658
|
-
if (
|
|
726
|
+
if (ctHashes.length !== items.length) {
|
|
659
727
|
throw new CofhesdkError({
|
|
660
|
-
code: "
|
|
661
|
-
message: `
|
|
728
|
+
code: "ZK_MOCKS_CALC_CT_HASHES_FAILED" /* ZkMocksCalcCtHashesFailed */,
|
|
729
|
+
message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
|
|
662
730
|
context: {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
731
|
+
items,
|
|
732
|
+
account,
|
|
733
|
+
securityZone,
|
|
734
|
+
publicClient,
|
|
735
|
+
calcCtHashesArgs,
|
|
736
|
+
ctHashes
|
|
666
737
|
}
|
|
667
738
|
});
|
|
668
739
|
}
|
|
669
|
-
return
|
|
740
|
+
return items.map((item, index) => ({
|
|
741
|
+
...item,
|
|
742
|
+
ctHash: ctHashes[index]
|
|
743
|
+
}));
|
|
670
744
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
745
|
+
async function insertCtHashes(items, walletClient) {
|
|
746
|
+
const insertPackedCtHashesArgs = [items.map(({ ctHash }) => ctHash), items.map(({ data }) => BigInt(data))];
|
|
747
|
+
try {
|
|
748
|
+
const account = walletClient.account;
|
|
749
|
+
await walletClient.writeContract({
|
|
750
|
+
address: MOCKS_ZK_VERIFIER_ADDRESS,
|
|
751
|
+
abi: MockZkVerifierAbi,
|
|
752
|
+
functionName: "insertPackedCtHashes",
|
|
753
|
+
args: insertPackedCtHashesArgs,
|
|
754
|
+
chain: hardhat,
|
|
755
|
+
account
|
|
756
|
+
});
|
|
757
|
+
} catch (err) {
|
|
758
|
+
throw new CofhesdkError({
|
|
759
|
+
code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
|
|
760
|
+
message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
|
|
761
|
+
cause: err instanceof Error ? err : void 0,
|
|
762
|
+
context: {
|
|
763
|
+
items,
|
|
764
|
+
walletClient,
|
|
765
|
+
insertPackedCtHashesArgs
|
|
766
|
+
}
|
|
686
767
|
});
|
|
687
|
-
this.ctHash = params.ctHash;
|
|
688
|
-
this.utype = params.utype;
|
|
689
|
-
this.permitHash = params.permitHash;
|
|
690
|
-
this.permit = params.permit;
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
694
|
-
*
|
|
695
|
-
* If not provided, the chainId will be fetched from the connected publicClient.
|
|
696
|
-
*
|
|
697
|
-
* Example:
|
|
698
|
-
* ```typescript
|
|
699
|
-
* const unsealed = await decryptHandle(ctHash, utype)
|
|
700
|
-
* .setChainId(11155111)
|
|
701
|
-
* .decrypt();
|
|
702
|
-
* ```
|
|
703
|
-
*
|
|
704
|
-
* @returns The chainable DecryptHandlesBuilder instance.
|
|
705
|
-
*/
|
|
706
|
-
setChainId(chainId) {
|
|
707
|
-
this.chainId = chainId;
|
|
708
|
-
return this;
|
|
709
768
|
}
|
|
710
|
-
|
|
711
|
-
|
|
769
|
+
}
|
|
770
|
+
async function createProofSignatures(items, securityZone) {
|
|
771
|
+
let signatures = [];
|
|
772
|
+
let encInputSignerClient;
|
|
773
|
+
try {
|
|
774
|
+
encInputSignerClient = createMockZkVerifierSigner();
|
|
775
|
+
} catch (err) {
|
|
776
|
+
throw new CofhesdkError({
|
|
777
|
+
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
778
|
+
message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
|
|
779
|
+
cause: err instanceof Error ? err : void 0,
|
|
780
|
+
context: {
|
|
781
|
+
MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY
|
|
782
|
+
}
|
|
783
|
+
});
|
|
712
784
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
* .setAccount('0x1234567890123456789012345678901234567890')
|
|
722
|
-
* .decrypt();
|
|
723
|
-
* ```
|
|
724
|
-
*
|
|
725
|
-
* @returns The chainable DecryptHandlesBuilder instance.
|
|
726
|
-
*/
|
|
727
|
-
setAccount(account) {
|
|
728
|
-
this.account = account;
|
|
729
|
-
return this;
|
|
730
|
-
}
|
|
731
|
-
getAccount() {
|
|
732
|
-
return this.account;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
|
|
736
|
-
*
|
|
737
|
-
* If not provided, the active permit for the chainId and account will be used.
|
|
738
|
-
* If `setPermit()` is called, it will be used regardless of chainId, account, or permitHash.
|
|
739
|
-
*
|
|
740
|
-
* Example:
|
|
741
|
-
* ```typescript
|
|
742
|
-
* const unsealed = await decryptHandle(ctHash, utype)
|
|
743
|
-
* .setPermitHash('0x1234567890123456789012345678901234567890')
|
|
744
|
-
* .decrypt();
|
|
745
|
-
* ```
|
|
746
|
-
*
|
|
747
|
-
* @returns The chainable DecryptHandlesBuilder instance.
|
|
748
|
-
*/
|
|
749
|
-
setPermitHash(permitHash) {
|
|
750
|
-
this.permitHash = permitHash;
|
|
751
|
-
return this;
|
|
752
|
-
}
|
|
753
|
-
getPermitHash() {
|
|
754
|
-
return this.permitHash;
|
|
755
|
-
}
|
|
756
|
-
/**
|
|
757
|
-
* @param permit - Permit to decrypt values with. If provided, it will be used regardless of chainId, account, or permitHash.
|
|
758
|
-
*
|
|
759
|
-
* If not provided, the permit will be determined by chainId, account, and permitHash.
|
|
760
|
-
*
|
|
761
|
-
* Example:
|
|
762
|
-
* ```typescript
|
|
763
|
-
* const unsealed = await decryptHandle(ctHash, utype)
|
|
764
|
-
* .setPermit(permit)
|
|
765
|
-
* .decrypt();
|
|
766
|
-
* ```
|
|
767
|
-
*
|
|
768
|
-
* @returns The chainable DecryptHandlesBuilder instance.
|
|
769
|
-
*/
|
|
770
|
-
setPermit(permit) {
|
|
771
|
-
this.permit = permit;
|
|
772
|
-
return this;
|
|
773
|
-
}
|
|
774
|
-
getPermit() {
|
|
775
|
-
return this.permit;
|
|
776
|
-
}
|
|
777
|
-
getThresholdNetworkUrl(chainId) {
|
|
778
|
-
const config = this.getConfigOrThrow();
|
|
779
|
-
return getThresholdNetworkUrlOrThrow(config, chainId);
|
|
780
|
-
}
|
|
781
|
-
validateUtypeOrThrow() {
|
|
782
|
-
if (!isValidUtype(this.utype))
|
|
783
|
-
throw new CofhesdkError({
|
|
784
|
-
code: "INVALID_UTYPE" /* InvalidUtype */,
|
|
785
|
-
message: `Invalid utype to decrypt to`,
|
|
786
|
-
context: {
|
|
787
|
-
utype: this.utype
|
|
788
|
-
}
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
|
-
async getResolvedPermit() {
|
|
792
|
-
if (this.permit)
|
|
793
|
-
return this.permit;
|
|
794
|
-
const chainId = await this.getChainIdOrThrow();
|
|
795
|
-
const account = await this.getAccountOrThrow();
|
|
796
|
-
if (this.permitHash) {
|
|
797
|
-
const permit2 = await permits.getPermit(chainId, account, this.permitHash);
|
|
798
|
-
if (!permit2) {
|
|
799
|
-
throw new CofhesdkError({
|
|
800
|
-
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
801
|
-
message: `Permit with hash <${this.permitHash}> not found for account <${account}> and chainId <${chainId}>`,
|
|
802
|
-
hint: "Ensure the permit exists and is valid.",
|
|
803
|
-
context: {
|
|
804
|
-
chainId,
|
|
805
|
-
account,
|
|
806
|
-
permitHash: this.permitHash
|
|
807
|
-
}
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
return permit2;
|
|
811
|
-
}
|
|
812
|
-
const permit = await permits.getActivePermit(chainId, account);
|
|
813
|
-
if (!permit) {
|
|
814
|
-
throw new CofhesdkError({
|
|
815
|
-
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
816
|
-
message: `Active permit not found for chainId <${chainId}> and account <${account}>`,
|
|
817
|
-
hint: "Ensure a permit exists for this account on this chain.",
|
|
818
|
-
context: {
|
|
819
|
-
chainId,
|
|
820
|
-
account
|
|
821
|
-
}
|
|
785
|
+
try {
|
|
786
|
+
for (const item of items) {
|
|
787
|
+
const packedData = encodePacked(["uint256", "int32", "uint8"], [BigInt(item.data), securityZone, item.utype]);
|
|
788
|
+
const messageHash = keccak256(packedData);
|
|
789
|
+
const ethSignedHash = hashMessage({ raw: toBytes(messageHash) });
|
|
790
|
+
const signature = await encInputSignerClient.signMessage({
|
|
791
|
+
message: { raw: toBytes(ethSignedHash) },
|
|
792
|
+
account: encInputSignerClient.account
|
|
822
793
|
});
|
|
794
|
+
signatures.push(signature);
|
|
823
795
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.getPublicClientOrThrow(), mocksSealOutputDelay);
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
836
|
-
*/
|
|
837
|
-
async productionSealOutput(chainId, permit) {
|
|
838
|
-
const thresholdNetworkUrl = this.getThresholdNetworkUrl(chainId);
|
|
839
|
-
const permission = PermitUtils.getPermission(permit, true);
|
|
840
|
-
const sealed = await tnSealOutput(this.ctHash, chainId, permission, thresholdNetworkUrl);
|
|
841
|
-
return PermitUtils.unseal(permit, sealed);
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* Final step of the decryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
845
|
-
*
|
|
846
|
-
* This will:
|
|
847
|
-
* - Use a permit based on provided permit OR chainId + account + permitHash
|
|
848
|
-
* - Check permit validity
|
|
849
|
-
* - Call CoFHE `/sealoutput` with the permit, which returns a sealed (encrypted) item
|
|
850
|
-
* - Unseal the sealed item with the permit
|
|
851
|
-
* - Return the unsealed item
|
|
852
|
-
*
|
|
853
|
-
* Example:
|
|
854
|
-
* ```typescript
|
|
855
|
-
* const unsealed = await decryptHandle(ctHash, utype)
|
|
856
|
-
* .setChainId(11155111) // optional
|
|
857
|
-
* .setAccount('0x123...890') // optional
|
|
858
|
-
* .decrypt(); // execute
|
|
859
|
-
* ```
|
|
860
|
-
*
|
|
861
|
-
* @returns The unsealed item.
|
|
862
|
-
*/
|
|
863
|
-
decrypt() {
|
|
864
|
-
return resultWrapper(async () => {
|
|
865
|
-
await this.requireConnectedOrThrow();
|
|
866
|
-
this.validateUtypeOrThrow();
|
|
867
|
-
const permit = await this.getResolvedPermit();
|
|
868
|
-
await PermitUtils.validate(permit);
|
|
869
|
-
const chainId = permit._signedDomain.chainId;
|
|
870
|
-
let unsealed;
|
|
871
|
-
if (chainId === hardhat.id) {
|
|
872
|
-
unsealed = await this.mocksSealOutput(permit);
|
|
873
|
-
} else {
|
|
874
|
-
unsealed = await this.productionSealOutput(chainId, permit);
|
|
796
|
+
} catch (err) {
|
|
797
|
+
throw new CofhesdkError({
|
|
798
|
+
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
799
|
+
message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
|
|
800
|
+
cause: err instanceof Error ? err : void 0,
|
|
801
|
+
context: {
|
|
802
|
+
items,
|
|
803
|
+
securityZone
|
|
875
804
|
}
|
|
876
|
-
return convertViaUtype(this.utype, unsealed);
|
|
877
805
|
});
|
|
878
806
|
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
// core/encrypt/zkPackProveVerify.ts
|
|
882
|
-
var MAX_UINT8 = 255n;
|
|
883
|
-
var MAX_UINT16 = 65535n;
|
|
884
|
-
var MAX_UINT32 = 4294967295n;
|
|
885
|
-
var MAX_UINT64 = 18446744073709551615n;
|
|
886
|
-
var MAX_UINT128 = 340282366920938463463374607431768211455n;
|
|
887
|
-
var MAX_UINT160 = 1461501637330902918203684832716283019655932542975n;
|
|
888
|
-
var MAX_ENCRYPTABLE_BITS = 2048;
|
|
889
|
-
var zkPack = (items, builder) => {
|
|
890
|
-
let totalBits = 0;
|
|
891
|
-
for (const item of items) {
|
|
892
|
-
switch (item.utype) {
|
|
893
|
-
case 0 /* Bool */: {
|
|
894
|
-
builder.push_boolean(item.data);
|
|
895
|
-
totalBits += 1;
|
|
896
|
-
break;
|
|
897
|
-
}
|
|
898
|
-
case 2 /* Uint8 */: {
|
|
899
|
-
const bint = toBigIntOrThrow(item.data);
|
|
900
|
-
validateBigIntInRange(bint, MAX_UINT8);
|
|
901
|
-
builder.push_u8(parseInt(bint.toString()));
|
|
902
|
-
totalBits += 8;
|
|
903
|
-
break;
|
|
904
|
-
}
|
|
905
|
-
case 3 /* Uint16 */: {
|
|
906
|
-
const bint = toBigIntOrThrow(item.data);
|
|
907
|
-
validateBigIntInRange(bint, MAX_UINT16);
|
|
908
|
-
builder.push_u16(parseInt(bint.toString()));
|
|
909
|
-
totalBits += 16;
|
|
910
|
-
break;
|
|
911
|
-
}
|
|
912
|
-
case 4 /* Uint32 */: {
|
|
913
|
-
const bint = toBigIntOrThrow(item.data);
|
|
914
|
-
validateBigIntInRange(bint, MAX_UINT32);
|
|
915
|
-
builder.push_u32(parseInt(bint.toString()));
|
|
916
|
-
totalBits += 32;
|
|
917
|
-
break;
|
|
918
|
-
}
|
|
919
|
-
case 5 /* Uint64 */: {
|
|
920
|
-
const bint = toBigIntOrThrow(item.data);
|
|
921
|
-
validateBigIntInRange(bint, MAX_UINT64);
|
|
922
|
-
builder.push_u64(bint);
|
|
923
|
-
totalBits += 64;
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
case 6 /* Uint128 */: {
|
|
927
|
-
const bint = toBigIntOrThrow(item.data);
|
|
928
|
-
validateBigIntInRange(bint, MAX_UINT128);
|
|
929
|
-
builder.push_u128(bint);
|
|
930
|
-
totalBits += 128;
|
|
931
|
-
break;
|
|
932
|
-
}
|
|
933
|
-
case 7 /* Uint160 */: {
|
|
934
|
-
const bint = toBigIntOrThrow(item.data);
|
|
935
|
-
validateBigIntInRange(bint, MAX_UINT160);
|
|
936
|
-
builder.push_u160(bint);
|
|
937
|
-
totalBits += 160;
|
|
938
|
-
break;
|
|
939
|
-
}
|
|
940
|
-
default: {
|
|
941
|
-
throw new CofhesdkError({
|
|
942
|
-
code: "ZK_PACK_FAILED" /* ZkPackFailed */,
|
|
943
|
-
message: `Invalid utype: ${item.utype}`,
|
|
944
|
-
hint: `Ensure that the utype is valid, using the Encryptable type, for example: Encryptable.uint128(100n)`,
|
|
945
|
-
context: {
|
|
946
|
-
item
|
|
947
|
-
}
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
807
|
+
if (signatures.length !== items.length) {
|
|
953
808
|
throw new CofhesdkError({
|
|
954
|
-
code: "
|
|
955
|
-
message: `
|
|
956
|
-
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
809
|
+
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
810
|
+
message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
|
|
957
811
|
context: {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
items
|
|
812
|
+
items,
|
|
813
|
+
securityZone
|
|
961
814
|
}
|
|
962
815
|
});
|
|
963
816
|
}
|
|
964
|
-
return
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
817
|
+
return signatures;
|
|
818
|
+
}
|
|
819
|
+
async function cofheMocksZkVerifySign(items, account, securityZone, publicClient, walletClient, zkvWalletClient) {
|
|
820
|
+
const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
|
|
821
|
+
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
822
|
+
await insertCtHashes(encryptableItems, _walletClient);
|
|
823
|
+
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
824
|
+
return encryptableItems.map((item, index) => ({
|
|
825
|
+
ct_hash: item.ctHash.toString(),
|
|
826
|
+
signature: signatures[index]
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
829
|
+
var CofhesdkConfigSchema = z.object({
|
|
830
|
+
/** Environment that the SDK is running in */
|
|
831
|
+
environment: z.enum(["node", "hardhat", "web", "react"]).optional().default("node"),
|
|
832
|
+
/** List of supported chain configurations */
|
|
833
|
+
supportedChains: z.array(z.custom()),
|
|
834
|
+
/** How permits are generated */
|
|
835
|
+
permitGeneration: z.enum(["ON_CONNECT", "ON_DECRYPT_HANDLES", "MANUAL"]).optional().default("ON_CONNECT"),
|
|
836
|
+
/** Default permit expiration in seconds, default is 30 days */
|
|
837
|
+
defaultPermitExpiration: z.number().optional().default(60 * 60 * 24 * 30),
|
|
838
|
+
/** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
|
|
839
|
+
fheKeyStorage: z.object({
|
|
840
|
+
getItem: z.custom((val) => typeof val === "function", {
|
|
841
|
+
message: "getItem must be a function"
|
|
842
|
+
}),
|
|
843
|
+
setItem: z.custom((val) => typeof val === "function", {
|
|
844
|
+
message: "setItem must be a function"
|
|
845
|
+
}),
|
|
846
|
+
removeItem: z.custom((val) => typeof val === "function", {
|
|
847
|
+
message: "removeItem must be a function"
|
|
848
|
+
})
|
|
849
|
+
}).or(z.null()).default(null),
|
|
850
|
+
/** Whether to use Web Workers for ZK proof generation (web platform only) */
|
|
851
|
+
useWorkers: z.boolean().optional().default(true),
|
|
852
|
+
/** Mocks configs */
|
|
853
|
+
mocks: z.object({
|
|
854
|
+
sealOutputDelay: z.number().optional().default(0)
|
|
855
|
+
}).optional().default({ sealOutputDelay: 0 }),
|
|
856
|
+
/** Internal configuration */
|
|
857
|
+
_internal: z.object({
|
|
858
|
+
zkvWalletClient: z.any().optional()
|
|
859
|
+
}).optional()
|
|
860
|
+
});
|
|
861
|
+
function createCofhesdkConfigBase(config) {
|
|
862
|
+
const result = CofhesdkConfigSchema.safeParse(config);
|
|
863
|
+
if (!result.success) {
|
|
864
|
+
throw new Error(`Invalid cofhesdk configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
|
|
865
|
+
}
|
|
866
|
+
return result.data;
|
|
867
|
+
}
|
|
868
|
+
var getCofhesdkConfigItem = (config, key) => {
|
|
869
|
+
return config[key];
|
|
870
|
+
};
|
|
871
|
+
function getSupportedChainOrThrow(config, chainId) {
|
|
872
|
+
const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
|
|
873
|
+
if (!supportedChain) {
|
|
874
|
+
throw new CofhesdkError({
|
|
875
|
+
code: "UNSUPPORTED_CHAIN" /* UnsupportedChain */,
|
|
876
|
+
message: `Config does not support chain <${chainId}>`,
|
|
877
|
+
hint: "Ensure config passed to client has been created with this chain in the config.supportedChains array.",
|
|
878
|
+
context: {
|
|
879
|
+
chainId,
|
|
880
|
+
supportedChainIds: config.supportedChains.map((c) => c.id)
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
return supportedChain;
|
|
885
|
+
}
|
|
886
|
+
function getCoFheUrlOrThrow(config, chainId) {
|
|
887
|
+
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
888
|
+
const url = supportedChain.coFheUrl;
|
|
889
|
+
if (!url) {
|
|
890
|
+
throw new CofhesdkError({
|
|
891
|
+
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
892
|
+
message: `CoFHE URL is not configured for chain <${chainId}>`,
|
|
893
|
+
hint: "Ensure this chain config includes a coFheUrl property.",
|
|
894
|
+
context: { chainId }
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
return url;
|
|
898
|
+
}
|
|
899
|
+
function getZkVerifierUrlOrThrow(config, chainId) {
|
|
900
|
+
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
901
|
+
const url = supportedChain.verifierUrl;
|
|
902
|
+
if (!url) {
|
|
903
|
+
throw new CofhesdkError({
|
|
904
|
+
code: "ZK_VERIFIER_URL_UNINITIALIZED" /* ZkVerifierUrlUninitialized */,
|
|
905
|
+
message: `ZK verifier URL is not configured for chain <${chainId}>`,
|
|
906
|
+
hint: "Ensure this chain config includes a verifierUrl property.",
|
|
907
|
+
context: { chainId }
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
return url;
|
|
911
|
+
}
|
|
912
|
+
function getThresholdNetworkUrlOrThrow(config, chainId) {
|
|
913
|
+
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
914
|
+
const url = supportedChain.thresholdNetworkUrl;
|
|
915
|
+
if (!url) {
|
|
916
|
+
throw new CofhesdkError({
|
|
917
|
+
code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
|
|
918
|
+
message: `Threshold network URL is not configured for chain <${chainId}>`,
|
|
919
|
+
hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
|
|
920
|
+
context: { chainId }
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
return url;
|
|
924
|
+
}
|
|
925
|
+
function isValidPersistedState(state) {
|
|
926
|
+
if (state && typeof state === "object") {
|
|
927
|
+
if ("fhe" in state && "crs" in state) {
|
|
928
|
+
return true;
|
|
929
|
+
} else {
|
|
930
|
+
throw new Error(
|
|
931
|
+
"Invalid persisted state structure for KeysStore. Is object but doesn't contain required fields 'fhe' and 'crs'."
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return false;
|
|
936
|
+
}
|
|
937
|
+
var DEFAULT_KEYS_STORE = {
|
|
938
|
+
fhe: {},
|
|
939
|
+
crs: {}
|
|
940
|
+
};
|
|
941
|
+
function isStoreWithPersist(store) {
|
|
942
|
+
return "persist" in store;
|
|
943
|
+
}
|
|
944
|
+
function createKeysStore(storage) {
|
|
945
|
+
const keysStore = storage ? createStoreWithPersit(storage) : createStore()(() => ({
|
|
946
|
+
fhe: {},
|
|
947
|
+
crs: {}
|
|
948
|
+
}));
|
|
949
|
+
const getFheKey = (chainId, securityZone = 0) => {
|
|
950
|
+
if (chainId == null || securityZone == null)
|
|
951
|
+
return void 0;
|
|
952
|
+
const stored = keysStore.getState().fhe[chainId]?.[securityZone];
|
|
953
|
+
return stored;
|
|
1003
954
|
};
|
|
1004
|
-
const
|
|
955
|
+
const getCrs = (chainId) => {
|
|
956
|
+
if (chainId == null)
|
|
957
|
+
return void 0;
|
|
958
|
+
const stored = keysStore.getState().crs[chainId];
|
|
959
|
+
return stored;
|
|
960
|
+
};
|
|
961
|
+
const setFheKey = (chainId, securityZone, key) => {
|
|
962
|
+
keysStore.setState(
|
|
963
|
+
produce((state) => {
|
|
964
|
+
if (state.fhe[chainId] == null)
|
|
965
|
+
state.fhe[chainId] = {};
|
|
966
|
+
state.fhe[chainId][securityZone] = key;
|
|
967
|
+
})
|
|
968
|
+
);
|
|
969
|
+
};
|
|
970
|
+
const setCrs = (chainId, crs) => {
|
|
971
|
+
keysStore.setState(
|
|
972
|
+
produce((state) => {
|
|
973
|
+
state.crs[chainId] = crs;
|
|
974
|
+
})
|
|
975
|
+
);
|
|
976
|
+
};
|
|
977
|
+
const clearKeysStorage = async () => {
|
|
978
|
+
if (storage) {
|
|
979
|
+
await storage.removeItem("cofhesdk-keys");
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
const rehydrateKeysStore = async () => {
|
|
983
|
+
if (!isStoreWithPersist(keysStore))
|
|
984
|
+
return;
|
|
985
|
+
if (keysStore.persist.hasHydrated())
|
|
986
|
+
return;
|
|
987
|
+
await keysStore.persist.rehydrate();
|
|
988
|
+
};
|
|
989
|
+
return {
|
|
990
|
+
store: keysStore,
|
|
991
|
+
getFheKey,
|
|
992
|
+
getCrs,
|
|
993
|
+
setFheKey,
|
|
994
|
+
setCrs,
|
|
995
|
+
clearKeysStorage,
|
|
996
|
+
rehydrateKeysStore
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
function createStoreWithPersit(storage) {
|
|
1000
|
+
const result = createStore()(
|
|
1001
|
+
persist(() => DEFAULT_KEYS_STORE, {
|
|
1002
|
+
// because earleir tests were written with on-init hydration skipped (due to the error suppression in zustand), returning this flag to fix test (i.e. KeyStore > Storage Utilities > should rehydrate keys store)
|
|
1003
|
+
skipHydration: true,
|
|
1004
|
+
// if onRehydrateStorage is not passed here, the errors thrown by storage layer are swallowed by zustand here: https://github.com/pmndrs/zustand/blob/39a391b6c1ff9aa89b81694d9bdb21da37dd4ac6/src/middleware/persist.ts#L321
|
|
1005
|
+
onRehydrateStorage: () => (_state, _error) => {
|
|
1006
|
+
if (_error)
|
|
1007
|
+
throw new Error(`onRehydrateStorage: Error rehydrating keys store: ${_error}`);
|
|
1008
|
+
},
|
|
1009
|
+
name: "cofhesdk-keys",
|
|
1010
|
+
storage: createJSONStorage(() => storage),
|
|
1011
|
+
merge: (persistedState, currentState) => {
|
|
1012
|
+
const persisted = isValidPersistedState(persistedState) ? persistedState : DEFAULT_KEYS_STORE;
|
|
1013
|
+
const current = currentState;
|
|
1014
|
+
const mergedFhe = { ...persisted.fhe };
|
|
1015
|
+
const allChainIds = /* @__PURE__ */ new Set([...Object.keys(current.fhe), ...Object.keys(persisted.fhe)]);
|
|
1016
|
+
for (const chainId of allChainIds) {
|
|
1017
|
+
const persistedZones = persisted.fhe[chainId] || {};
|
|
1018
|
+
const currentZones = current.fhe[chainId] || {};
|
|
1019
|
+
mergedFhe[chainId] = { ...persistedZones, ...currentZones };
|
|
1020
|
+
}
|
|
1021
|
+
const mergedCrs = { ...persisted.crs, ...current.crs };
|
|
1022
|
+
return {
|
|
1023
|
+
fhe: mergedFhe,
|
|
1024
|
+
crs: mergedCrs
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
})
|
|
1028
|
+
);
|
|
1029
|
+
return result;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// core/fetchKeys.ts
|
|
1033
|
+
var PUBLIC_KEY_LENGTH_MIN = 15e3;
|
|
1034
|
+
var checkKeyValidity = (key, serializer) => {
|
|
1035
|
+
if (key == null || key.length === 0)
|
|
1036
|
+
return [false, `Key is null or empty <${key}>`];
|
|
1005
1037
|
try {
|
|
1006
|
-
|
|
1038
|
+
serializer(key);
|
|
1039
|
+
return [true, `Key is valid`];
|
|
1040
|
+
} catch (err) {
|
|
1041
|
+
return [false, `Serialization failed <${err}> key length <${key.length}>`];
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
var fetchFhePublicKey = async (coFheUrl, chainId, securityZone, tfhePublicKeyDeserializer, keysStorage) => {
|
|
1045
|
+
const storedKey = keysStorage?.getFheKey(chainId, securityZone);
|
|
1046
|
+
const [storedKeyValid] = checkKeyValidity(storedKey, tfhePublicKeyDeserializer);
|
|
1047
|
+
if (storedKeyValid)
|
|
1048
|
+
return [storedKey, false];
|
|
1049
|
+
let pk_data = void 0;
|
|
1050
|
+
try {
|
|
1051
|
+
const pk_res = await fetch(`${coFheUrl}/GetNetworkPublicKey`, {
|
|
1007
1052
|
method: "POST",
|
|
1008
1053
|
headers: {
|
|
1009
1054
|
"Content-Type": "application/json"
|
|
1010
1055
|
},
|
|
1011
|
-
body
|
|
1012
|
-
});
|
|
1013
|
-
if (!response.ok) {
|
|
1014
|
-
const errorBody = await response.text();
|
|
1015
|
-
throw new CofhesdkError({
|
|
1016
|
-
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
1017
|
-
message: `HTTP error! ZK proof verification failed - ${errorBody}`
|
|
1018
|
-
});
|
|
1019
|
-
}
|
|
1020
|
-
const json = await response.json();
|
|
1021
|
-
if (json.status !== "success") {
|
|
1022
|
-
throw new CofhesdkError({
|
|
1023
|
-
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
1024
|
-
message: `ZK proof verification response malformed - ${json.error}`
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
return json.data.map(({ ct_hash, signature, recid }) => {
|
|
1028
|
-
return {
|
|
1029
|
-
ct_hash,
|
|
1030
|
-
signature: concatSigRecid(signature, recid)
|
|
1031
|
-
};
|
|
1032
|
-
});
|
|
1033
|
-
} catch (e) {
|
|
1034
|
-
throw new CofhesdkError({
|
|
1035
|
-
code: "ZK_VERIFY_FAILED" /* ZkVerifyFailed */,
|
|
1036
|
-
message: `ZK proof verification failed`,
|
|
1037
|
-
cause: e instanceof Error ? e : void 0
|
|
1056
|
+
body: JSON.stringify({ securityZone })
|
|
1038
1057
|
});
|
|
1058
|
+
const json = await pk_res.json();
|
|
1059
|
+
pk_data = json.publicKey;
|
|
1060
|
+
} catch (err) {
|
|
1061
|
+
throw new Error(`Error fetching FHE publicKey; fetching from CoFHE failed with error ${err}`);
|
|
1039
1062
|
}
|
|
1063
|
+
if (pk_data == null || typeof pk_data !== "string") {
|
|
1064
|
+
throw new Error(`Error fetching FHE publicKey; fetched result invalid: missing or not a string`);
|
|
1065
|
+
}
|
|
1066
|
+
if (pk_data === "0x") {
|
|
1067
|
+
throw new Error("Error fetching FHE publicKey; provided chain is not FHE enabled / not found");
|
|
1068
|
+
}
|
|
1069
|
+
if (pk_data.length < PUBLIC_KEY_LENGTH_MIN) {
|
|
1070
|
+
throw new Error(
|
|
1071
|
+
`Error fetching FHE publicKey; got shorter than expected key length: ${pk_data.length}. Expected length >= ${PUBLIC_KEY_LENGTH_MIN}`
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
try {
|
|
1075
|
+
tfhePublicKeyDeserializer(pk_data);
|
|
1076
|
+
} catch (err) {
|
|
1077
|
+
throw new Error(`Error serializing FHE publicKey; ${err}`);
|
|
1078
|
+
}
|
|
1079
|
+
keysStorage?.setFheKey(chainId, securityZone, pk_data);
|
|
1080
|
+
return [pk_data, true];
|
|
1040
1081
|
};
|
|
1041
|
-
var
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
{
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
}
|
|
1096
|
-
],
|
|
1097
|
-
stateMutability: "nonpayable"
|
|
1098
|
-
},
|
|
1099
|
-
{
|
|
1100
|
-
type: "function",
|
|
1101
|
-
name: "zkVerifyCalcCtHash",
|
|
1102
|
-
inputs: [
|
|
1103
|
-
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
1104
|
-
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
1105
|
-
{ name: "user", type: "address", internalType: "address" },
|
|
1106
|
-
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
1107
|
-
{ name: "", type: "uint256", internalType: "uint256" }
|
|
1108
|
-
],
|
|
1109
|
-
outputs: [{ name: "ctHash", type: "uint256", internalType: "uint256" }],
|
|
1110
|
-
stateMutability: "view"
|
|
1111
|
-
},
|
|
1112
|
-
{
|
|
1113
|
-
type: "function",
|
|
1114
|
-
name: "zkVerifyCalcCtHashesPacked",
|
|
1115
|
-
inputs: [
|
|
1116
|
-
{ name: "values", type: "uint256[]", internalType: "uint256[]" },
|
|
1117
|
-
{ name: "utypes", type: "uint8[]", internalType: "uint8[]" },
|
|
1118
|
-
{ name: "user", type: "address", internalType: "address" },
|
|
1119
|
-
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
1120
|
-
{ name: "chainId", type: "uint256", internalType: "uint256" }
|
|
1121
|
-
],
|
|
1122
|
-
outputs: [{ name: "ctHashes", type: "uint256[]", internalType: "uint256[]" }],
|
|
1123
|
-
stateMutability: "view"
|
|
1124
|
-
},
|
|
1125
|
-
{
|
|
1126
|
-
type: "function",
|
|
1127
|
-
name: "zkVerifyPacked",
|
|
1128
|
-
inputs: [
|
|
1129
|
-
{ name: "values", type: "uint256[]", internalType: "uint256[]" },
|
|
1130
|
-
{ name: "utypes", type: "uint8[]", internalType: "uint8[]" },
|
|
1131
|
-
{ name: "user", type: "address", internalType: "address" },
|
|
1132
|
-
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
1133
|
-
{ name: "chainId", type: "uint256", internalType: "uint256" }
|
|
1134
|
-
],
|
|
1135
|
-
outputs: [
|
|
1136
|
-
{
|
|
1137
|
-
name: "inputs",
|
|
1138
|
-
type: "tuple[]",
|
|
1139
|
-
internalType: "struct EncryptedInput[]",
|
|
1140
|
-
components: [
|
|
1141
|
-
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1142
|
-
{ name: "securityZone", type: "uint8", internalType: "uint8" },
|
|
1143
|
-
{ name: "utype", type: "uint8", internalType: "uint8" },
|
|
1144
|
-
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
1145
|
-
]
|
|
1146
|
-
}
|
|
1147
|
-
],
|
|
1148
|
-
stateMutability: "nonpayable"
|
|
1149
|
-
},
|
|
1150
|
-
{ type: "error", name: "InvalidInputs", inputs: [] }
|
|
1151
|
-
];
|
|
1152
|
-
var MocksZkVerifierAddress = "0x0000000000000000000000000000000000000100";
|
|
1153
|
-
var MocksEncryptedInputSignerPkey = "0x6c8d7f768a6bb4aafe85e8a2f5a9680355239c7e14646ed62b044e39de154512";
|
|
1154
|
-
async function cofheMocksCheckEncryptableBits(items) {
|
|
1155
|
-
let totalBits = 0;
|
|
1156
|
-
for (const item of items) {
|
|
1157
|
-
switch (item.utype) {
|
|
1158
|
-
case 0 /* Bool */: {
|
|
1159
|
-
totalBits += 1;
|
|
1160
|
-
break;
|
|
1161
|
-
}
|
|
1162
|
-
case 2 /* Uint8 */: {
|
|
1163
|
-
totalBits += 8;
|
|
1164
|
-
break;
|
|
1165
|
-
}
|
|
1166
|
-
case 3 /* Uint16 */: {
|
|
1167
|
-
totalBits += 16;
|
|
1168
|
-
break;
|
|
1169
|
-
}
|
|
1170
|
-
case 4 /* Uint32 */: {
|
|
1171
|
-
totalBits += 32;
|
|
1172
|
-
break;
|
|
1173
|
-
}
|
|
1174
|
-
case 5 /* Uint64 */: {
|
|
1175
|
-
totalBits += 64;
|
|
1176
|
-
break;
|
|
1177
|
-
}
|
|
1178
|
-
case 6 /* Uint128 */: {
|
|
1179
|
-
totalBits += 128;
|
|
1180
|
-
break;
|
|
1181
|
-
}
|
|
1182
|
-
case 7 /* Uint160 */: {
|
|
1183
|
-
totalBits += 160;
|
|
1184
|
-
break;
|
|
1185
|
-
}
|
|
1082
|
+
var fetchCrs = async (coFheUrl, chainId, securityZone, compactPkeCrsDeserializer, keysStorage) => {
|
|
1083
|
+
const storedKey = keysStorage?.getCrs(chainId);
|
|
1084
|
+
const [storedKeyValid] = checkKeyValidity(storedKey, compactPkeCrsDeserializer);
|
|
1085
|
+
if (storedKeyValid)
|
|
1086
|
+
return [storedKey, false];
|
|
1087
|
+
let crs_data = void 0;
|
|
1088
|
+
try {
|
|
1089
|
+
const crs_res = await fetch(`${coFheUrl}/GetCrs`, {
|
|
1090
|
+
method: "POST",
|
|
1091
|
+
headers: {
|
|
1092
|
+
"Content-Type": "application/json"
|
|
1093
|
+
},
|
|
1094
|
+
body: JSON.stringify({ securityZone })
|
|
1095
|
+
});
|
|
1096
|
+
const json = await crs_res.json();
|
|
1097
|
+
crs_data = json.crs;
|
|
1098
|
+
} catch (err) {
|
|
1099
|
+
throw new Error(`Error fetching CRS; fetching failed with error ${err}`);
|
|
1100
|
+
}
|
|
1101
|
+
if (crs_data == null || typeof crs_data !== "string") {
|
|
1102
|
+
throw new Error(`Error fetching CRS; invalid: missing or not a string`);
|
|
1103
|
+
}
|
|
1104
|
+
try {
|
|
1105
|
+
compactPkeCrsDeserializer(crs_data);
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
console.error(`Error serializing CRS ${err}`);
|
|
1108
|
+
throw new Error(`Error serializing CRS; ${err}`);
|
|
1109
|
+
}
|
|
1110
|
+
keysStorage?.setCrs(chainId, crs_data);
|
|
1111
|
+
return [crs_data, true];
|
|
1112
|
+
};
|
|
1113
|
+
var fetchKeys = async (config, chainId, securityZone = 0, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, keysStorage) => {
|
|
1114
|
+
const coFheUrl = getCoFheUrlOrThrow(config, chainId);
|
|
1115
|
+
return await Promise.all([
|
|
1116
|
+
fetchFhePublicKey(coFheUrl, chainId, securityZone, tfhePublicKeyDeserializer, keysStorage),
|
|
1117
|
+
fetchCrs(coFheUrl, chainId, securityZone, compactPkeCrsDeserializer, keysStorage)
|
|
1118
|
+
]);
|
|
1119
|
+
};
|
|
1120
|
+
var BaseBuilder = class {
|
|
1121
|
+
config;
|
|
1122
|
+
publicClient;
|
|
1123
|
+
walletClient;
|
|
1124
|
+
chainId;
|
|
1125
|
+
account;
|
|
1126
|
+
constructor(params) {
|
|
1127
|
+
if (!params.config) {
|
|
1128
|
+
throw new CofhesdkError({
|
|
1129
|
+
code: "MISSING_CONFIG" /* MissingConfig */,
|
|
1130
|
+
message: "Builder config is undefined",
|
|
1131
|
+
hint: "Ensure client has been created with a config.",
|
|
1132
|
+
context: {
|
|
1133
|
+
config: params.config
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1186
1136
|
}
|
|
1137
|
+
this.config = params.config;
|
|
1138
|
+
this.publicClient = params.publicClient;
|
|
1139
|
+
this.walletClient = params.walletClient;
|
|
1140
|
+
this.chainId = params.chainId;
|
|
1141
|
+
this.account = params.account;
|
|
1142
|
+
params.requireConnected?.();
|
|
1187
1143
|
}
|
|
1188
|
-
|
|
1144
|
+
/**
|
|
1145
|
+
* Asserts that this.chainId is populated
|
|
1146
|
+
* @throws {CofhesdkError} If chainId is not set
|
|
1147
|
+
*/
|
|
1148
|
+
assertChainId() {
|
|
1149
|
+
if (this.chainId)
|
|
1150
|
+
return;
|
|
1189
1151
|
throw new CofhesdkError({
|
|
1190
|
-
code: "
|
|
1191
|
-
message:
|
|
1192
|
-
hint:
|
|
1152
|
+
code: "CHAIN_ID_UNINITIALIZED" /* ChainIdUninitialized */,
|
|
1153
|
+
message: "Chain ID is not set",
|
|
1154
|
+
hint: "Ensure client.connect() has been called and awaited, or use setChainId(...) to set the chainId explicitly.",
|
|
1193
1155
|
context: {
|
|
1194
|
-
|
|
1195
|
-
maxBits: MAX_ENCRYPTABLE_BITS,
|
|
1196
|
-
items
|
|
1156
|
+
chainId: this.chainId
|
|
1197
1157
|
}
|
|
1198
1158
|
});
|
|
1199
1159
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
account
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
functionName: "zkVerifyCalcCtHashesPacked",
|
|
1215
|
-
args: calcCtHashesArgs
|
|
1160
|
+
/**
|
|
1161
|
+
* Asserts that this.account is populated
|
|
1162
|
+
* @throws {CofhesdkError} If account is not set
|
|
1163
|
+
*/
|
|
1164
|
+
assertAccount() {
|
|
1165
|
+
if (this.account)
|
|
1166
|
+
return;
|
|
1167
|
+
throw new CofhesdkError({
|
|
1168
|
+
code: "ACCOUNT_UNINITIALIZED" /* AccountUninitialized */,
|
|
1169
|
+
message: "Account is not set",
|
|
1170
|
+
hint: "Ensure client.connect() has been called and awaited, or use setAccount(...) to set the account explicitly.",
|
|
1171
|
+
context: {
|
|
1172
|
+
account: this.account
|
|
1173
|
+
}
|
|
1216
1174
|
});
|
|
1217
|
-
}
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Asserts that this.publicClient is populated
|
|
1178
|
+
* @throws {CofhesdkError} If publicClient is not set
|
|
1179
|
+
*/
|
|
1180
|
+
assertPublicClient() {
|
|
1181
|
+
if (this.publicClient)
|
|
1182
|
+
return;
|
|
1218
1183
|
throw new CofhesdkError({
|
|
1219
|
-
code: "
|
|
1220
|
-
message:
|
|
1221
|
-
|
|
1184
|
+
code: "MISSING_PUBLIC_CLIENT" /* MissingPublicClient */,
|
|
1185
|
+
message: "Public client not found",
|
|
1186
|
+
hint: "Ensure client.connect() has been called with a publicClient.",
|
|
1222
1187
|
context: {
|
|
1223
|
-
|
|
1224
|
-
items,
|
|
1225
|
-
account,
|
|
1226
|
-
securityZone,
|
|
1227
|
-
publicClient,
|
|
1228
|
-
calcCtHashesArgs
|
|
1188
|
+
publicClient: this.publicClient
|
|
1229
1189
|
}
|
|
1230
1190
|
});
|
|
1231
1191
|
}
|
|
1232
|
-
|
|
1192
|
+
/**
|
|
1193
|
+
* Asserts that this.walletClient is populated
|
|
1194
|
+
* @throws {CofhesdkError} If walletClient is not set
|
|
1195
|
+
*/
|
|
1196
|
+
assertWalletClient() {
|
|
1197
|
+
if (this.walletClient)
|
|
1198
|
+
return;
|
|
1233
1199
|
throw new CofhesdkError({
|
|
1234
|
-
code: "
|
|
1235
|
-
message:
|
|
1200
|
+
code: "MISSING_WALLET_CLIENT" /* MissingWalletClient */,
|
|
1201
|
+
message: "Wallet client not found",
|
|
1202
|
+
hint: "Ensure client.connect() has been called with a walletClient.",
|
|
1236
1203
|
context: {
|
|
1237
|
-
|
|
1238
|
-
account,
|
|
1239
|
-
securityZone,
|
|
1240
|
-
publicClient,
|
|
1241
|
-
calcCtHashesArgs,
|
|
1242
|
-
ctHashes
|
|
1204
|
+
walletClient: this.walletClient
|
|
1243
1205
|
}
|
|
1244
1206
|
});
|
|
1245
1207
|
}
|
|
1246
|
-
|
|
1247
|
-
...item,
|
|
1248
|
-
ctHash: ctHashes[index]
|
|
1249
|
-
}));
|
|
1250
|
-
}
|
|
1251
|
-
async function insertCtHashes(items, walletClient) {
|
|
1252
|
-
const insertPackedCtHashesArgs = [items.map(({ ctHash }) => ctHash), items.map(({ data }) => BigInt(data))];
|
|
1253
|
-
try {
|
|
1254
|
-
const account = walletClient.account;
|
|
1255
|
-
await walletClient.writeContract({
|
|
1256
|
-
address: MocksZkVerifierAddress,
|
|
1257
|
-
abi: MockZkVerifierAbi,
|
|
1258
|
-
functionName: "insertPackedCtHashes",
|
|
1259
|
-
args: insertPackedCtHashesArgs,
|
|
1260
|
-
chain: hardhat$1,
|
|
1261
|
-
account
|
|
1262
|
-
});
|
|
1263
|
-
} catch (err) {
|
|
1264
|
-
throw new CofhesdkError({
|
|
1265
|
-
code: "ZK_MOCKS_INSERT_CT_HASHES_FAILED" /* ZkMocksInsertCtHashesFailed */,
|
|
1266
|
-
message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
|
|
1267
|
-
cause: err instanceof Error ? err : void 0,
|
|
1268
|
-
context: {
|
|
1269
|
-
items,
|
|
1270
|
-
walletClient,
|
|
1271
|
-
insertPackedCtHashesArgs
|
|
1272
|
-
}
|
|
1273
|
-
});
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
async function createProofSignatures(items, securityZone) {
|
|
1277
|
-
let signatures = [];
|
|
1278
|
-
let encInputSignerClient;
|
|
1279
|
-
try {
|
|
1280
|
-
encInputSignerClient = createWalletClient({
|
|
1281
|
-
chain: hardhat$1,
|
|
1282
|
-
transport: http(),
|
|
1283
|
-
account: privateKeyToAccount(MocksEncryptedInputSignerPkey)
|
|
1284
|
-
});
|
|
1285
|
-
} catch (err) {
|
|
1286
|
-
throw new CofhesdkError({
|
|
1287
|
-
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
1288
|
-
message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
|
|
1289
|
-
cause: err instanceof Error ? err : void 0,
|
|
1290
|
-
context: {
|
|
1291
|
-
MocksEncryptedInputSignerPkey
|
|
1292
|
-
}
|
|
1293
|
-
});
|
|
1294
|
-
}
|
|
1295
|
-
try {
|
|
1296
|
-
for (const item of items) {
|
|
1297
|
-
const packedData = encodePacked(["uint256", "int32", "uint8"], [BigInt(item.data), securityZone, item.utype]);
|
|
1298
|
-
const messageHash = keccak256(packedData);
|
|
1299
|
-
const ethSignedHash = hashMessage({ raw: toBytes(messageHash) });
|
|
1300
|
-
const signature = await encInputSignerClient.signMessage({
|
|
1301
|
-
message: { raw: toBytes(ethSignedHash) },
|
|
1302
|
-
account: encInputSignerClient.account
|
|
1303
|
-
});
|
|
1304
|
-
signatures.push(signature);
|
|
1305
|
-
}
|
|
1306
|
-
} catch (err) {
|
|
1307
|
-
throw new CofhesdkError({
|
|
1308
|
-
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
1309
|
-
message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
|
|
1310
|
-
cause: err instanceof Error ? err : void 0,
|
|
1311
|
-
context: {
|
|
1312
|
-
items,
|
|
1313
|
-
securityZone
|
|
1314
|
-
}
|
|
1315
|
-
});
|
|
1316
|
-
}
|
|
1317
|
-
if (signatures.length !== items.length) {
|
|
1318
|
-
throw new CofhesdkError({
|
|
1319
|
-
code: "ZK_MOCKS_CREATE_PROOF_SIGNATURE_FAILED" /* ZkMocksCreateProofSignatureFailed */,
|
|
1320
|
-
message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
|
|
1321
|
-
context: {
|
|
1322
|
-
items,
|
|
1323
|
-
securityZone
|
|
1324
|
-
}
|
|
1325
|
-
});
|
|
1326
|
-
}
|
|
1327
|
-
return signatures;
|
|
1328
|
-
}
|
|
1329
|
-
async function cofheMocksZkVerifySign(items, account, securityZone, publicClient, walletClient, zkvWalletClient) {
|
|
1330
|
-
const _walletClient = zkvWalletClient ?? walletClient;
|
|
1331
|
-
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
1332
|
-
await insertCtHashes(encryptableItems, _walletClient);
|
|
1333
|
-
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
1334
|
-
return encryptableItems.map((item, index) => ({
|
|
1335
|
-
ct_hash: item.ctHash.toString(),
|
|
1336
|
-
signature: signatures[index]
|
|
1337
|
-
}));
|
|
1338
|
-
}
|
|
1339
|
-
function createKeysStore(storage) {
|
|
1340
|
-
const keysStore = storage ? createStore()(
|
|
1341
|
-
persist(
|
|
1342
|
-
() => ({
|
|
1343
|
-
fhe: {},
|
|
1344
|
-
crs: {}
|
|
1345
|
-
}),
|
|
1346
|
-
{
|
|
1347
|
-
name: "cofhesdk-keys",
|
|
1348
|
-
storage: createJSONStorage(() => storage),
|
|
1349
|
-
merge: (persistedState, currentState) => {
|
|
1350
|
-
const persisted = persistedState;
|
|
1351
|
-
const current = currentState;
|
|
1352
|
-
const mergedFhe = { ...persisted.fhe };
|
|
1353
|
-
const allChainIds = /* @__PURE__ */ new Set([...Object.keys(current.fhe), ...Object.keys(persisted.fhe)]);
|
|
1354
|
-
for (const chainId of allChainIds) {
|
|
1355
|
-
const persistedZones = persisted.fhe[chainId] || {};
|
|
1356
|
-
const currentZones = current.fhe[chainId] || {};
|
|
1357
|
-
mergedFhe[chainId] = { ...persistedZones, ...currentZones };
|
|
1358
|
-
}
|
|
1359
|
-
const mergedCrs = { ...persisted.crs, ...current.crs };
|
|
1360
|
-
return {
|
|
1361
|
-
fhe: mergedFhe,
|
|
1362
|
-
crs: mergedCrs
|
|
1363
|
-
};
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
)
|
|
1367
|
-
) : createStore()(() => ({
|
|
1368
|
-
fhe: {},
|
|
1369
|
-
crs: {}
|
|
1370
|
-
}));
|
|
1371
|
-
const getFheKey = (chainId, securityZone = 0) => {
|
|
1372
|
-
if (chainId == null || securityZone == null)
|
|
1373
|
-
return void 0;
|
|
1374
|
-
const stored = keysStore.getState().fhe[chainId]?.[securityZone];
|
|
1375
|
-
return stored;
|
|
1376
|
-
};
|
|
1377
|
-
const getCrs = (chainId) => {
|
|
1378
|
-
if (chainId == null)
|
|
1379
|
-
return void 0;
|
|
1380
|
-
const stored = keysStore.getState().crs[chainId];
|
|
1381
|
-
return stored;
|
|
1382
|
-
};
|
|
1383
|
-
const setFheKey = (chainId, securityZone, key) => {
|
|
1384
|
-
keysStore.setState(
|
|
1385
|
-
produce((state) => {
|
|
1386
|
-
if (state.fhe[chainId] == null)
|
|
1387
|
-
state.fhe[chainId] = {};
|
|
1388
|
-
state.fhe[chainId][securityZone] = key;
|
|
1389
|
-
})
|
|
1390
|
-
);
|
|
1391
|
-
};
|
|
1392
|
-
const setCrs = (chainId, crs) => {
|
|
1393
|
-
keysStore.setState(
|
|
1394
|
-
produce((state) => {
|
|
1395
|
-
state.crs[chainId] = crs;
|
|
1396
|
-
})
|
|
1397
|
-
);
|
|
1398
|
-
};
|
|
1399
|
-
const clearKeysStorage = async () => {
|
|
1400
|
-
if (storage) {
|
|
1401
|
-
await storage.removeItem("cofhesdk-keys");
|
|
1402
|
-
}
|
|
1403
|
-
};
|
|
1404
|
-
const rehydrateKeysStore = async () => {
|
|
1405
|
-
if ("persist" in keysStore) {
|
|
1406
|
-
if (keysStore.persist.hasHydrated())
|
|
1407
|
-
return;
|
|
1408
|
-
await keysStore.persist.rehydrate();
|
|
1409
|
-
}
|
|
1410
|
-
};
|
|
1411
|
-
return {
|
|
1412
|
-
store: keysStore,
|
|
1413
|
-
getFheKey,
|
|
1414
|
-
getCrs,
|
|
1415
|
-
setFheKey,
|
|
1416
|
-
setCrs,
|
|
1417
|
-
clearKeysStorage,
|
|
1418
|
-
rehydrateKeysStore
|
|
1419
|
-
};
|
|
1420
|
-
}
|
|
1208
|
+
};
|
|
1421
1209
|
|
|
1422
1210
|
// core/encrypt/encryptInputsBuilder.ts
|
|
1423
1211
|
var EncryptInputsBuilder = class extends BaseBuilder {
|
|
@@ -1429,7 +1217,10 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1429
1217
|
compactPkeCrsDeserializer;
|
|
1430
1218
|
zkBuilderAndCrsGenerator;
|
|
1431
1219
|
initTfhe;
|
|
1220
|
+
zkProveWorkerFn;
|
|
1432
1221
|
keysStorage;
|
|
1222
|
+
// Worker configuration (from config, overrideable)
|
|
1223
|
+
useWorker;
|
|
1433
1224
|
stepTimestamps = {
|
|
1434
1225
|
["initTfhe" /* InitTfhe */]: 0,
|
|
1435
1226
|
["fetchKeys" /* FetchKeys */]: 0,
|
|
@@ -1449,11 +1240,43 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1449
1240
|
this.inputItems = params.inputs;
|
|
1450
1241
|
this.securityZone = params.securityZone ?? 0;
|
|
1451
1242
|
this.zkvWalletClient = params.zkvWalletClient;
|
|
1243
|
+
if (!params.tfhePublicKeyDeserializer) {
|
|
1244
|
+
throw new CofhesdkError({
|
|
1245
|
+
code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
|
|
1246
|
+
message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
|
|
1247
|
+
hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
|
|
1248
|
+
context: {
|
|
1249
|
+
tfhePublicKeyDeserializer: params.tfhePublicKeyDeserializer
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1452
1253
|
this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
|
|
1254
|
+
if (!params.compactPkeCrsDeserializer) {
|
|
1255
|
+
throw new CofhesdkError({
|
|
1256
|
+
code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
|
|
1257
|
+
message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
|
|
1258
|
+
hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
|
|
1259
|
+
context: {
|
|
1260
|
+
compactPkeCrsDeserializer: params.compactPkeCrsDeserializer
|
|
1261
|
+
}
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1453
1264
|
this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
|
|
1265
|
+
if (!params.zkBuilderAndCrsGenerator) {
|
|
1266
|
+
throw new CofhesdkError({
|
|
1267
|
+
code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
|
|
1268
|
+
message: "EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined",
|
|
1269
|
+
hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
|
|
1270
|
+
context: {
|
|
1271
|
+
zkBuilderAndCrsGenerator: params.zkBuilderAndCrsGenerator
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1454
1275
|
this.zkBuilderAndCrsGenerator = params.zkBuilderAndCrsGenerator;
|
|
1455
1276
|
this.initTfhe = params.initTfhe;
|
|
1277
|
+
this.zkProveWorkerFn = params.zkProveWorkerFn;
|
|
1456
1278
|
this.keysStorage = params.keysStorage;
|
|
1279
|
+
this.useWorker = params.config?.useWorkers ?? true;
|
|
1457
1280
|
}
|
|
1458
1281
|
/**
|
|
1459
1282
|
* @param account - Account that will create the tx using the encrypted inputs.
|
|
@@ -1518,6 +1341,40 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1518
1341
|
getSecurityZone() {
|
|
1519
1342
|
return this.securityZone;
|
|
1520
1343
|
}
|
|
1344
|
+
/**
|
|
1345
|
+
* @param useWorker - Whether to use Web Workers for ZK proof generation.
|
|
1346
|
+
*
|
|
1347
|
+
* Overrides the config-level useWorkers setting for this specific encryption.
|
|
1348
|
+
*
|
|
1349
|
+
* Example:
|
|
1350
|
+
* ```typescript
|
|
1351
|
+
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
1352
|
+
* .setUseWorker(false)
|
|
1353
|
+
* .encrypt();
|
|
1354
|
+
* ```
|
|
1355
|
+
*
|
|
1356
|
+
* @returns The chainable EncryptInputsBuilder instance.
|
|
1357
|
+
*/
|
|
1358
|
+
setUseWorker(useWorker) {
|
|
1359
|
+
this.useWorker = useWorker;
|
|
1360
|
+
return this;
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Gets the current worker configuration.
|
|
1364
|
+
*
|
|
1365
|
+
* @returns Whether Web Workers are enabled for this encryption.
|
|
1366
|
+
*
|
|
1367
|
+
* Example:
|
|
1368
|
+
* ```typescript
|
|
1369
|
+
* const builder = encryptInputs([Encryptable.uint128(10n)]);
|
|
1370
|
+
* console.log(builder.getUseWorker()); // true (from config)
|
|
1371
|
+
* builder.setUseWorker(false);
|
|
1372
|
+
* console.log(builder.getUseWorker()); // false (overridden)
|
|
1373
|
+
* ```
|
|
1374
|
+
*/
|
|
1375
|
+
getUseWorker() {
|
|
1376
|
+
return this.useWorker;
|
|
1377
|
+
}
|
|
1521
1378
|
/**
|
|
1522
1379
|
* @param callback - Function to be called with the encryption step.
|
|
1523
1380
|
*
|
|
@@ -1555,50 +1412,13 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1555
1412
|
const duration = Date.now() - this.stepTimestamps[step];
|
|
1556
1413
|
this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
|
|
1557
1414
|
}
|
|
1558
|
-
/**
|
|
1559
|
-
* tfhePublicKeyDeserializer is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
1560
|
-
* web/ uses zama "tfhe"
|
|
1561
|
-
* node/ uses zama "node-tfhe"
|
|
1562
|
-
* Users should not set this manually.
|
|
1563
|
-
*/
|
|
1564
|
-
getTfhePublicKeyDeserializerOrThrow() {
|
|
1565
|
-
if (this.tfhePublicKeyDeserializer)
|
|
1566
|
-
return this.tfhePublicKeyDeserializer;
|
|
1567
|
-
throw new CofhesdkError({
|
|
1568
|
-
code: "MISSING_TFHE_PUBLIC_KEY_DESERIALIZER" /* MissingTfhePublicKeyDeserializer */,
|
|
1569
|
-
message: "EncryptInputsBuilder tfhePublicKeyDeserializer is undefined",
|
|
1570
|
-
hint: "Ensure client has been created with a tfhePublicKeyDeserializer.",
|
|
1571
|
-
context: {
|
|
1572
|
-
tfhePublicKeyDeserializer: this.tfhePublicKeyDeserializer
|
|
1573
|
-
}
|
|
1574
|
-
});
|
|
1575
|
-
}
|
|
1576
|
-
/**
|
|
1577
|
-
* compactPkeCrsDeserializer is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
1578
|
-
* web/ uses zama "tfhe"
|
|
1579
|
-
* node/ uses zama "node-tfhe"
|
|
1580
|
-
* Users should not set this manually.
|
|
1581
|
-
*/
|
|
1582
|
-
getCompactPkeCrsDeserializerOrThrow() {
|
|
1583
|
-
if (this.compactPkeCrsDeserializer)
|
|
1584
|
-
return this.compactPkeCrsDeserializer;
|
|
1585
|
-
throw new CofhesdkError({
|
|
1586
|
-
code: "MISSING_COMPACT_PKE_CRS_DESERIALIZER" /* MissingCompactPkeCrsDeserializer */,
|
|
1587
|
-
message: "EncryptInputsBuilder compactPkeCrsDeserializer is undefined",
|
|
1588
|
-
hint: "Ensure client has been created with a compactPkeCrsDeserializer.",
|
|
1589
|
-
context: {
|
|
1590
|
-
compactPkeCrsDeserializer: this.compactPkeCrsDeserializer
|
|
1591
|
-
}
|
|
1592
|
-
});
|
|
1593
|
-
}
|
|
1594
1415
|
/**
|
|
1595
1416
|
* zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
|
|
1596
1417
|
* Users should generally not set this manually.
|
|
1597
1418
|
*/
|
|
1598
1419
|
async getZkVerifierUrl() {
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
return getZkVerifierUrlOrThrow(config, chainId);
|
|
1420
|
+
this.assertChainId();
|
|
1421
|
+
return getZkVerifierUrlOrThrow(this.config, this.chainId);
|
|
1602
1422
|
}
|
|
1603
1423
|
/**
|
|
1604
1424
|
* initTfhe is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
@@ -1626,10 +1446,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1626
1446
|
* If the key/crs already exists in the store it is returned, else it is fetched, stored, and returned
|
|
1627
1447
|
*/
|
|
1628
1448
|
async fetchFheKeyAndCrs() {
|
|
1629
|
-
|
|
1630
|
-
const chainId = await this.getChainIdOrThrow();
|
|
1631
|
-
const compactPkeCrsDeserializer = this.getCompactPkeCrsDeserializerOrThrow();
|
|
1632
|
-
const tfhePublicKeyDeserializer = this.getTfhePublicKeyDeserializerOrThrow();
|
|
1449
|
+
this.assertChainId();
|
|
1633
1450
|
const securityZone = this.getSecurityZone();
|
|
1634
1451
|
try {
|
|
1635
1452
|
await this.keysStorage?.rehydrateKeysStore();
|
|
@@ -1648,11 +1465,11 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1648
1465
|
let crsFetchedFromCoFHE = false;
|
|
1649
1466
|
try {
|
|
1650
1467
|
[[fheKey, fheKeyFetchedFromCoFHE], [crs, crsFetchedFromCoFHE]] = await fetchKeys(
|
|
1651
|
-
config,
|
|
1652
|
-
chainId,
|
|
1468
|
+
this.config,
|
|
1469
|
+
this.chainId,
|
|
1653
1470
|
securityZone,
|
|
1654
|
-
tfhePublicKeyDeserializer,
|
|
1655
|
-
compactPkeCrsDeserializer,
|
|
1471
|
+
this.tfhePublicKeyDeserializer,
|
|
1472
|
+
this.compactPkeCrsDeserializer,
|
|
1656
1473
|
this.keysStorage
|
|
1657
1474
|
);
|
|
1658
1475
|
} catch (error) {
|
|
@@ -1660,11 +1477,11 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1660
1477
|
code: "FETCH_KEYS_FAILED" /* FetchKeysFailed */,
|
|
1661
1478
|
message: `Failed to fetch FHE key and CRS`,
|
|
1662
1479
|
context: {
|
|
1663
|
-
config,
|
|
1664
|
-
chainId,
|
|
1480
|
+
config: this.config,
|
|
1481
|
+
chainId: this.chainId,
|
|
1665
1482
|
securityZone,
|
|
1666
|
-
compactPkeCrsDeserializer,
|
|
1667
|
-
tfhePublicKeyDeserializer
|
|
1483
|
+
compactPkeCrsDeserializer: this.compactPkeCrsDeserializer,
|
|
1484
|
+
tfhePublicKeyDeserializer: this.tfhePublicKeyDeserializer
|
|
1668
1485
|
}
|
|
1669
1486
|
});
|
|
1670
1487
|
}
|
|
@@ -1673,7 +1490,7 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1673
1490
|
code: "MISSING_FHE_KEY" /* MissingFheKey */,
|
|
1674
1491
|
message: `FHE key not found`,
|
|
1675
1492
|
context: {
|
|
1676
|
-
chainId,
|
|
1493
|
+
chainId: this.chainId,
|
|
1677
1494
|
securityZone
|
|
1678
1495
|
}
|
|
1679
1496
|
});
|
|
@@ -1683,34 +1500,12 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1683
1500
|
code: "MISSING_CRS" /* MissingCrs */,
|
|
1684
1501
|
message: `CRS not found for chainId <${this.chainId}>`,
|
|
1685
1502
|
context: {
|
|
1686
|
-
chainId
|
|
1503
|
+
chainId: this.chainId
|
|
1687
1504
|
}
|
|
1688
1505
|
});
|
|
1689
1506
|
}
|
|
1690
1507
|
return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
|
|
1691
1508
|
}
|
|
1692
|
-
/**
|
|
1693
|
-
* zkBuilderAndCrsGenerator is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
1694
|
-
* web/ uses zama "tfhe"
|
|
1695
|
-
* node/ uses zama "node-tfhe"
|
|
1696
|
-
* Users should not set this manually.
|
|
1697
|
-
*
|
|
1698
|
-
* Generates the zkBuilder and zkCrs from the fheKey and crs
|
|
1699
|
-
*/
|
|
1700
|
-
generateZkBuilderAndCrs(fheKey, crs) {
|
|
1701
|
-
const zkBuilderAndCrsGenerator = this.zkBuilderAndCrsGenerator;
|
|
1702
|
-
if (!zkBuilderAndCrsGenerator) {
|
|
1703
|
-
throw new CofhesdkError({
|
|
1704
|
-
code: "MISSING_ZK_BUILDER_AND_CRS_GENERATOR" /* MissingZkBuilderAndCrsGenerator */,
|
|
1705
|
-
message: `zkBuilderAndCrsGenerator is undefined`,
|
|
1706
|
-
hint: "Ensure client has been created with a zkBuilderAndCrsGenerator.",
|
|
1707
|
-
context: {
|
|
1708
|
-
zkBuilderAndCrsGenerator: this.zkBuilderAndCrsGenerator
|
|
1709
|
-
}
|
|
1710
|
-
});
|
|
1711
|
-
}
|
|
1712
|
-
return zkBuilderAndCrsGenerator(fheKey, crs);
|
|
1713
|
-
}
|
|
1714
1509
|
/**
|
|
1715
1510
|
* @dev Encrypt against the cofheMocks instead of CoFHE
|
|
1716
1511
|
*
|
|
@@ -1718,7 +1513,10 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1718
1513
|
* cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
|
|
1719
1514
|
* cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
|
|
1720
1515
|
*/
|
|
1721
|
-
async mocksEncrypt(
|
|
1516
|
+
async mocksEncrypt() {
|
|
1517
|
+
this.assertAccount();
|
|
1518
|
+
this.assertPublicClient();
|
|
1519
|
+
this.assertWalletClient();
|
|
1722
1520
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
1723
1521
|
await sleep(100);
|
|
1724
1522
|
this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted: false });
|
|
@@ -1736,10 +1534,10 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1736
1534
|
await sleep(500);
|
|
1737
1535
|
const signedResults = await cofheMocksZkVerifySign(
|
|
1738
1536
|
this.inputItems,
|
|
1739
|
-
account,
|
|
1537
|
+
this.account,
|
|
1740
1538
|
this.securityZone,
|
|
1741
|
-
this.
|
|
1742
|
-
this.
|
|
1539
|
+
this.publicClient,
|
|
1540
|
+
this.walletClient,
|
|
1743
1541
|
this.zkvWalletClient
|
|
1744
1542
|
);
|
|
1745
1543
|
const encryptedInputs = signedResults.map(({ ct_hash, signature }, index) => ({
|
|
@@ -1754,23 +1552,44 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1754
1552
|
/**
|
|
1755
1553
|
* In the production context, perform a true encryption with the CoFHE coprocessor.
|
|
1756
1554
|
*/
|
|
1757
|
-
async productionEncrypt(
|
|
1555
|
+
async productionEncrypt() {
|
|
1556
|
+
this.assertAccount();
|
|
1557
|
+
this.assertChainId();
|
|
1758
1558
|
this.fireStepStart("initTfhe" /* InitTfhe */);
|
|
1759
1559
|
const tfheInitializationExecuted = await this.initTfheOrThrow();
|
|
1760
1560
|
this.fireStepEnd("initTfhe" /* InitTfhe */, { tfheInitializationExecuted });
|
|
1761
1561
|
this.fireStepStart("fetchKeys" /* FetchKeys */);
|
|
1762
1562
|
const { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE } = await this.fetchFheKeyAndCrs();
|
|
1763
|
-
let { zkBuilder, zkCrs } = this.
|
|
1563
|
+
let { zkBuilder, zkCrs } = this.zkBuilderAndCrsGenerator(fheKey, crs);
|
|
1764
1564
|
this.fireStepEnd("fetchKeys" /* FetchKeys */, { fheKeyFetchedFromCoFHE, crsFetchedFromCoFHE });
|
|
1765
1565
|
this.fireStepStart("pack" /* Pack */);
|
|
1766
1566
|
zkBuilder = zkPack(this.inputItems, zkBuilder);
|
|
1767
1567
|
this.fireStepEnd("pack" /* Pack */);
|
|
1768
1568
|
this.fireStepStart("prove" /* Prove */);
|
|
1769
|
-
const
|
|
1770
|
-
|
|
1569
|
+
const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId);
|
|
1570
|
+
let proof = null;
|
|
1571
|
+
let usedWorker = false;
|
|
1572
|
+
let workerFailedError;
|
|
1573
|
+
if (this.useWorker && this.zkProveWorkerFn) {
|
|
1574
|
+
try {
|
|
1575
|
+
proof = await zkProveWithWorker(this.zkProveWorkerFn, fheKey, crs, this.inputItems, metadata);
|
|
1576
|
+
usedWorker = true;
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
workerFailedError = error instanceof Error ? error.message : String(error);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
if (proof == null) {
|
|
1582
|
+
proof = await zkProve(zkBuilder, zkCrs, metadata);
|
|
1583
|
+
usedWorker = false;
|
|
1584
|
+
}
|
|
1585
|
+
this.fireStepEnd("prove" /* Prove */, {
|
|
1586
|
+
useWorker: this.useWorker,
|
|
1587
|
+
usedWorker,
|
|
1588
|
+
workerFailedError
|
|
1589
|
+
});
|
|
1771
1590
|
this.fireStepStart("verify" /* Verify */);
|
|
1772
1591
|
const zkVerifierUrl = await this.getZkVerifierUrl();
|
|
1773
|
-
const verifyResults = await zkVerify(zkVerifierUrl, proof, account, this.securityZone, chainId);
|
|
1592
|
+
const verifyResults = await zkVerify(zkVerifierUrl, proof, this.account, this.securityZone, this.chainId);
|
|
1774
1593
|
const encryptedInputs = verifyResults.map(
|
|
1775
1594
|
({ ct_hash, signature }, index) => ({
|
|
1776
1595
|
ctHash: BigInt(ct_hash),
|
|
@@ -1802,307 +1621,722 @@ var EncryptInputsBuilder = class extends BaseBuilder {
|
|
|
1802
1621
|
* @returns The encrypted inputs.
|
|
1803
1622
|
*/
|
|
1804
1623
|
async encrypt() {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
const chainId = await this.getChainIdOrThrow();
|
|
1809
|
-
if (chainId === hardhat$1.id) {
|
|
1810
|
-
return await this.mocksEncrypt(account);
|
|
1811
|
-
}
|
|
1812
|
-
return await this.productionEncrypt(account, chainId);
|
|
1813
|
-
});
|
|
1624
|
+
if (this.chainId === hardhat.id)
|
|
1625
|
+
return this.mocksEncrypt();
|
|
1626
|
+
return this.productionEncrypt();
|
|
1814
1627
|
}
|
|
1815
1628
|
};
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
FheTypes2[FheTypes2["Uint8"] = 2] = "Uint8";
|
|
1822
|
-
FheTypes2[FheTypes2["Uint16"] = 3] = "Uint16";
|
|
1823
|
-
FheTypes2[FheTypes2["Uint32"] = 4] = "Uint32";
|
|
1824
|
-
FheTypes2[FheTypes2["Uint64"] = 5] = "Uint64";
|
|
1825
|
-
FheTypes2[FheTypes2["Uint128"] = 6] = "Uint128";
|
|
1826
|
-
FheTypes2[FheTypes2["Uint160"] = 7] = "Uint160";
|
|
1827
|
-
FheTypes2[FheTypes2["Uint256"] = 8] = "Uint256";
|
|
1828
|
-
FheTypes2[FheTypes2["Uint512"] = 9] = "Uint512";
|
|
1829
|
-
FheTypes2[FheTypes2["Uint1024"] = 10] = "Uint1024";
|
|
1830
|
-
FheTypes2[FheTypes2["Uint2048"] = 11] = "Uint2048";
|
|
1831
|
-
FheTypes2[FheTypes2["Uint2"] = 12] = "Uint2";
|
|
1832
|
-
FheTypes2[FheTypes2["Uint6"] = 13] = "Uint6";
|
|
1833
|
-
FheTypes2[FheTypes2["Uint10"] = 14] = "Uint10";
|
|
1834
|
-
FheTypes2[FheTypes2["Uint12"] = 15] = "Uint12";
|
|
1835
|
-
FheTypes2[FheTypes2["Uint14"] = 16] = "Uint14";
|
|
1836
|
-
FheTypes2[FheTypes2["Int2"] = 17] = "Int2";
|
|
1837
|
-
FheTypes2[FheTypes2["Int4"] = 18] = "Int4";
|
|
1838
|
-
FheTypes2[FheTypes2["Int6"] = 19] = "Int6";
|
|
1839
|
-
FheTypes2[FheTypes2["Int8"] = 20] = "Int8";
|
|
1840
|
-
FheTypes2[FheTypes2["Int10"] = 21] = "Int10";
|
|
1841
|
-
FheTypes2[FheTypes2["Int12"] = 22] = "Int12";
|
|
1842
|
-
FheTypes2[FheTypes2["Int14"] = 23] = "Int14";
|
|
1843
|
-
FheTypes2[FheTypes2["Int16"] = 24] = "Int16";
|
|
1844
|
-
FheTypes2[FheTypes2["Int32"] = 25] = "Int32";
|
|
1845
|
-
FheTypes2[FheTypes2["Int64"] = 26] = "Int64";
|
|
1846
|
-
FheTypes2[FheTypes2["Int128"] = 27] = "Int128";
|
|
1847
|
-
FheTypes2[FheTypes2["Int160"] = 28] = "Int160";
|
|
1848
|
-
FheTypes2[FheTypes2["Int256"] = 29] = "Int256";
|
|
1849
|
-
return FheTypes2;
|
|
1850
|
-
})(FheTypes || {});
|
|
1851
|
-
var FheUintUTypes = [
|
|
1852
|
-
2 /* Uint8 */,
|
|
1853
|
-
3 /* Uint16 */,
|
|
1854
|
-
4 /* Uint32 */,
|
|
1855
|
-
5 /* Uint64 */,
|
|
1856
|
-
6 /* Uint128 */
|
|
1857
|
-
// [U256-DISABLED]
|
|
1858
|
-
// FheTypes.Uint256,
|
|
1859
|
-
];
|
|
1860
|
-
var FheAllUTypes = [
|
|
1861
|
-
0 /* Bool */,
|
|
1862
|
-
2 /* Uint8 */,
|
|
1863
|
-
3 /* Uint16 */,
|
|
1864
|
-
4 /* Uint32 */,
|
|
1865
|
-
5 /* Uint64 */,
|
|
1866
|
-
6 /* Uint128 */,
|
|
1867
|
-
// [U256-DISABLED]
|
|
1868
|
-
// FheTypes.Uint256,
|
|
1869
|
-
7 /* Uint160 */
|
|
1870
|
-
];
|
|
1871
|
-
var Encryptable = {
|
|
1872
|
-
bool: (data, securityZone = 0) => ({ data, securityZone, utype: 0 /* Bool */ }),
|
|
1873
|
-
address: (data, securityZone = 0) => ({ data, securityZone, utype: 7 /* Uint160 */ }),
|
|
1874
|
-
uint8: (data, securityZone = 0) => ({ data, securityZone, utype: 2 /* Uint8 */ }),
|
|
1875
|
-
uint16: (data, securityZone = 0) => ({ data, securityZone, utype: 3 /* Uint16 */ }),
|
|
1876
|
-
uint32: (data, securityZone = 0) => ({ data, securityZone, utype: 4 /* Uint32 */ }),
|
|
1877
|
-
uint64: (data, securityZone = 0) => ({ data, securityZone, utype: 5 /* Uint64 */ }),
|
|
1878
|
-
uint128: (data, securityZone = 0) => ({ data, securityZone, utype: 6 /* Uint128 */ })
|
|
1879
|
-
// [U256-DISABLED]
|
|
1880
|
-
// uint256: (data: EncryptableUint256['data'], securityZone = 0) =>
|
|
1881
|
-
// ({ data, securityZone, utype: FheTypes.Uint256 }) as EncryptableUint256,
|
|
1629
|
+
var storeActivePermit = async (permit, publicClient, walletClient) => {
|
|
1630
|
+
const chainId = await publicClient.getChainId();
|
|
1631
|
+
const account = walletClient.account.address;
|
|
1632
|
+
permitStore.setPermit(chainId, account, permit);
|
|
1633
|
+
permitStore.setActivePermitHash(chainId, account, permit.hash);
|
|
1882
1634
|
};
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1635
|
+
var createPermitWithSign = async (options, publicClient, walletClient, permitMethod) => {
|
|
1636
|
+
const permit = await permitMethod(options, publicClient, walletClient);
|
|
1637
|
+
await storeActivePermit(permit, publicClient, walletClient);
|
|
1638
|
+
return permit;
|
|
1639
|
+
};
|
|
1640
|
+
var createSelf = async (options, publicClient, walletClient) => {
|
|
1641
|
+
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSelfAndSign);
|
|
1642
|
+
};
|
|
1643
|
+
var createSharing = async (options, publicClient, walletClient) => {
|
|
1644
|
+
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSharingAndSign);
|
|
1645
|
+
};
|
|
1646
|
+
var importShared = async (options, publicClient, walletClient) => {
|
|
1647
|
+
return createPermitWithSign(options, publicClient, walletClient, PermitUtils.importSharedAndSign);
|
|
1648
|
+
};
|
|
1649
|
+
var getHash = (permit) => {
|
|
1650
|
+
return PermitUtils.getHash(permit);
|
|
1651
|
+
};
|
|
1652
|
+
var serialize = (permit) => {
|
|
1653
|
+
return PermitUtils.serialize(permit);
|
|
1654
|
+
};
|
|
1655
|
+
var deserialize = (serialized) => {
|
|
1656
|
+
return PermitUtils.deserialize(serialized);
|
|
1657
|
+
};
|
|
1658
|
+
var getPermit = async (chainId, account, hash) => {
|
|
1659
|
+
return permitStore.getPermit(chainId, account, hash);
|
|
1660
|
+
};
|
|
1661
|
+
var getPermits = async (chainId, account) => {
|
|
1662
|
+
return permitStore.getPermits(chainId, account);
|
|
1663
|
+
};
|
|
1664
|
+
var getActivePermit = async (chainId, account) => {
|
|
1665
|
+
return permitStore.getActivePermit(chainId, account);
|
|
1666
|
+
};
|
|
1667
|
+
var getActivePermitHash = (chainId, account) => {
|
|
1668
|
+
return permitStore.getActivePermitHash(chainId, account);
|
|
1669
|
+
};
|
|
1670
|
+
var selectActivePermit = (chainId, account, hash) => {
|
|
1671
|
+
permitStore.setActivePermitHash(chainId, account, hash);
|
|
1672
|
+
};
|
|
1673
|
+
var getOrCreateSelfPermit = async (publicClient, walletClient, chainId, account, options) => {
|
|
1674
|
+
const _chainId = chainId ?? await publicClient.getChainId();
|
|
1675
|
+
const _account = account ?? walletClient.account.address;
|
|
1676
|
+
const activePermit = await getActivePermit(_chainId, _account);
|
|
1677
|
+
if (activePermit && activePermit.type === "self") {
|
|
1678
|
+
return activePermit;
|
|
1679
|
+
}
|
|
1680
|
+
return createSelf(options ?? { issuer: _account, name: "Autogenerated Self Permit" }, publicClient, walletClient);
|
|
1681
|
+
};
|
|
1682
|
+
var getOrCreateSharingPermit = async (publicClient, walletClient, options, chainId, account) => {
|
|
1683
|
+
const _chainId = chainId ?? await publicClient.getChainId();
|
|
1684
|
+
const _account = account ?? walletClient.account.address;
|
|
1685
|
+
const activePermit = await getActivePermit(_chainId, _account);
|
|
1686
|
+
if (activePermit && activePermit.type === "sharing") {
|
|
1687
|
+
return activePermit;
|
|
1688
|
+
}
|
|
1689
|
+
return createSharing(options, publicClient, walletClient);
|
|
1690
|
+
};
|
|
1691
|
+
var removePermit = async (chainId, account, hash) => permitStore.removePermit(chainId, account, hash);
|
|
1692
|
+
var removeActivePermit = async (chainId, account) => permitStore.removeActivePermitHash(chainId, account);
|
|
1693
|
+
var permits = {
|
|
1694
|
+
getSnapshot: permitStore.store.getState,
|
|
1695
|
+
subscribe: permitStore.store.subscribe,
|
|
1696
|
+
createSelf,
|
|
1697
|
+
createSharing,
|
|
1698
|
+
importShared,
|
|
1699
|
+
getOrCreateSelfPermit,
|
|
1700
|
+
getOrCreateSharingPermit,
|
|
1701
|
+
getHash,
|
|
1702
|
+
serialize,
|
|
1703
|
+
deserialize,
|
|
1704
|
+
getPermit,
|
|
1705
|
+
getPermits,
|
|
1706
|
+
getActivePermit,
|
|
1707
|
+
getActivePermitHash,
|
|
1708
|
+
removePermit,
|
|
1709
|
+
selectActivePermit,
|
|
1710
|
+
removeActivePermit
|
|
1711
|
+
};
|
|
1712
|
+
function uint160ToAddress(uint160) {
|
|
1713
|
+
const hexStr = uint160.toString(16).padStart(40, "0");
|
|
1714
|
+
return getAddress("0x" + hexStr);
|
|
1715
|
+
}
|
|
1716
|
+
var isValidUtype = (utype) => {
|
|
1717
|
+
return utype === 0 /* Bool */ || utype === 7 /* Uint160 */ || utype == null || FheUintUTypes.includes(utype);
|
|
1718
|
+
};
|
|
1719
|
+
var convertViaUtype = (utype, value) => {
|
|
1720
|
+
if (utype === 0 /* Bool */) {
|
|
1721
|
+
return !!value;
|
|
1722
|
+
} else if (utype === 7 /* Uint160 */) {
|
|
1723
|
+
return uint160ToAddress(value);
|
|
1724
|
+
} else if (utype == null || FheUintUTypes.includes(utype)) {
|
|
1725
|
+
return value;
|
|
1726
|
+
} else {
|
|
1727
|
+
throw new Error(`convertViaUtype :: invalid utype :: ${utype}`);
|
|
1728
|
+
}
|
|
1729
|
+
};
|
|
1730
|
+
|
|
1731
|
+
// core/decrypt/MockQueryDecrypterAbi.ts
|
|
1732
|
+
var MockQueryDecrypterAbi = [
|
|
1733
|
+
{
|
|
1734
|
+
type: "function",
|
|
1735
|
+
name: "acl",
|
|
1736
|
+
inputs: [],
|
|
1737
|
+
outputs: [{ name: "", type: "address", internalType: "contract ACL" }],
|
|
1738
|
+
stateMutability: "view"
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
type: "function",
|
|
1742
|
+
name: "decodeLowLevelReversion",
|
|
1743
|
+
inputs: [{ name: "data", type: "bytes", internalType: "bytes" }],
|
|
1744
|
+
outputs: [{ name: "error", type: "string", internalType: "string" }],
|
|
1745
|
+
stateMutability: "pure"
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
type: "function",
|
|
1749
|
+
name: "exists",
|
|
1750
|
+
inputs: [],
|
|
1751
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
1752
|
+
stateMutability: "pure"
|
|
1753
|
+
},
|
|
1754
|
+
{
|
|
1755
|
+
type: "function",
|
|
1756
|
+
name: "initialize",
|
|
1757
|
+
inputs: [
|
|
1758
|
+
{ name: "_taskManager", type: "address", internalType: "address" },
|
|
1759
|
+
{ name: "_acl", type: "address", internalType: "address" }
|
|
1760
|
+
],
|
|
1761
|
+
outputs: [],
|
|
1762
|
+
stateMutability: "nonpayable"
|
|
1763
|
+
},
|
|
1764
|
+
{
|
|
1765
|
+
type: "function",
|
|
1766
|
+
name: "queryDecrypt",
|
|
1767
|
+
inputs: [
|
|
1768
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1769
|
+
{ name: "", type: "uint256", internalType: "uint256" },
|
|
1770
|
+
{
|
|
1771
|
+
name: "permission",
|
|
1772
|
+
type: "tuple",
|
|
1773
|
+
internalType: "struct Permission",
|
|
1774
|
+
components: [
|
|
1775
|
+
{ name: "issuer", type: "address", internalType: "address" },
|
|
1776
|
+
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1777
|
+
{ name: "recipient", type: "address", internalType: "address" },
|
|
1778
|
+
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
1779
|
+
{
|
|
1780
|
+
name: "validatorContract",
|
|
1781
|
+
type: "address",
|
|
1782
|
+
internalType: "address"
|
|
1783
|
+
},
|
|
1784
|
+
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1785
|
+
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1786
|
+
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
1787
|
+
]
|
|
1788
|
+
}
|
|
1789
|
+
],
|
|
1790
|
+
outputs: [
|
|
1791
|
+
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
1792
|
+
{ name: "error", type: "string", internalType: "string" },
|
|
1793
|
+
{ name: "", type: "uint256", internalType: "uint256" }
|
|
1794
|
+
],
|
|
1795
|
+
stateMutability: "view"
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
type: "function",
|
|
1799
|
+
name: "querySealOutput",
|
|
1800
|
+
inputs: [
|
|
1801
|
+
{ name: "ctHash", type: "uint256", internalType: "uint256" },
|
|
1802
|
+
{ name: "", type: "uint256", internalType: "uint256" },
|
|
1803
|
+
{
|
|
1804
|
+
name: "permission",
|
|
1805
|
+
type: "tuple",
|
|
1806
|
+
internalType: "struct Permission",
|
|
1807
|
+
components: [
|
|
1808
|
+
{ name: "issuer", type: "address", internalType: "address" },
|
|
1809
|
+
{ name: "expiration", type: "uint64", internalType: "uint64" },
|
|
1810
|
+
{ name: "recipient", type: "address", internalType: "address" },
|
|
1811
|
+
{ name: "validatorId", type: "uint256", internalType: "uint256" },
|
|
1812
|
+
{
|
|
1813
|
+
name: "validatorContract",
|
|
1814
|
+
type: "address",
|
|
1815
|
+
internalType: "address"
|
|
1816
|
+
},
|
|
1817
|
+
{ name: "sealingKey", type: "bytes32", internalType: "bytes32" },
|
|
1818
|
+
{ name: "issuerSignature", type: "bytes", internalType: "bytes" },
|
|
1819
|
+
{ name: "recipientSignature", type: "bytes", internalType: "bytes" }
|
|
1820
|
+
]
|
|
1821
|
+
}
|
|
1822
|
+
],
|
|
1823
|
+
outputs: [
|
|
1824
|
+
{ name: "allowed", type: "bool", internalType: "bool" },
|
|
1825
|
+
{ name: "error", type: "string", internalType: "string" },
|
|
1826
|
+
{ name: "", type: "bytes32", internalType: "bytes32" }
|
|
1827
|
+
],
|
|
1828
|
+
stateMutability: "view"
|
|
1829
|
+
},
|
|
1830
|
+
{
|
|
1831
|
+
type: "function",
|
|
1832
|
+
name: "seal",
|
|
1833
|
+
inputs: [
|
|
1834
|
+
{ name: "input", type: "uint256", internalType: "uint256" },
|
|
1835
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" }
|
|
1836
|
+
],
|
|
1837
|
+
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
1838
|
+
stateMutability: "pure"
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
type: "function",
|
|
1842
|
+
name: "taskManager",
|
|
1843
|
+
inputs: [],
|
|
1844
|
+
outputs: [{ name: "", type: "address", internalType: "contract TaskManager" }],
|
|
1845
|
+
stateMutability: "view"
|
|
1846
|
+
},
|
|
1847
|
+
{
|
|
1848
|
+
type: "function",
|
|
1849
|
+
name: "unseal",
|
|
1850
|
+
inputs: [
|
|
1851
|
+
{ name: "hashed", type: "bytes32", internalType: "bytes32" },
|
|
1852
|
+
{ name: "key", type: "bytes32", internalType: "bytes32" }
|
|
1853
|
+
],
|
|
1854
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1855
|
+
stateMutability: "pure"
|
|
1856
|
+
},
|
|
1857
|
+
{ type: "error", name: "NotAllowed", inputs: [] },
|
|
1858
|
+
{ type: "error", name: "SealingKeyInvalid", inputs: [] },
|
|
1859
|
+
{ type: "error", name: "SealingKeyMissing", inputs: [] }
|
|
1860
|
+
];
|
|
1861
|
+
|
|
1862
|
+
// core/decrypt/cofheMocksSealOutput.ts
|
|
1863
|
+
async function cofheMocksSealOutput(ctHash, utype, permit, publicClient, mocksSealOutputDelay) {
|
|
1864
|
+
if (mocksSealOutputDelay > 0)
|
|
1865
|
+
await sleep(mocksSealOutputDelay);
|
|
1866
|
+
const permission = PermitUtils.getPermission(permit, true);
|
|
1867
|
+
const permissionWithBigInts = {
|
|
1868
|
+
...permission,
|
|
1869
|
+
expiration: BigInt(permission.expiration),
|
|
1870
|
+
validatorId: BigInt(permission.validatorId)
|
|
1871
|
+
};
|
|
1872
|
+
const [allowed, error, result] = await publicClient.readContract({
|
|
1873
|
+
address: MOCKS_QUERY_DECRYPTER_ADDRESS,
|
|
1874
|
+
abi: MockQueryDecrypterAbi,
|
|
1875
|
+
functionName: "querySealOutput",
|
|
1876
|
+
args: [ctHash, BigInt(utype), permissionWithBigInts]
|
|
1877
|
+
});
|
|
1878
|
+
if (error != "") {
|
|
1879
|
+
throw new CofhesdkError({
|
|
1880
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1881
|
+
message: `mocks querySealOutput call failed: ${error}`
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
if (allowed == false) {
|
|
1885
|
+
throw new CofhesdkError({
|
|
1886
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1887
|
+
message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
const sealedBigInt = BigInt(result);
|
|
1891
|
+
const sealingKeyBigInt = BigInt(permission.sealingKey);
|
|
1892
|
+
const unsealed = sealedBigInt ^ sealingKeyBigInt;
|
|
1893
|
+
return unsealed;
|
|
1891
1894
|
}
|
|
1892
|
-
var EncryptStep = /* @__PURE__ */ ((EncryptStep2) => {
|
|
1893
|
-
EncryptStep2["InitTfhe"] = "initTfhe";
|
|
1894
|
-
EncryptStep2["FetchKeys"] = "fetchKeys";
|
|
1895
|
-
EncryptStep2["Pack"] = "pack";
|
|
1896
|
-
EncryptStep2["Prove"] = "prove";
|
|
1897
|
-
EncryptStep2["Verify"] = "verify";
|
|
1898
|
-
return EncryptStep2;
|
|
1899
|
-
})(EncryptStep || {});
|
|
1900
1895
|
|
|
1901
|
-
// core/
|
|
1902
|
-
var
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
getItem: z.function().args(z.string()).returns(z.promise(z.any())),
|
|
1914
|
-
setItem: z.function().args(z.string(), z.any()).returns(z.promise(z.void())),
|
|
1915
|
-
removeItem: z.function().args(z.string()).returns(z.promise(z.void()))
|
|
1916
|
-
}).or(z.null()).default(null),
|
|
1917
|
-
/** Mocks configs */
|
|
1918
|
-
mocks: z.object({
|
|
1919
|
-
sealOutputDelay: z.number().optional().default(0)
|
|
1920
|
-
}).optional().default({ sealOutputDelay: 0 }),
|
|
1921
|
-
/** Internal configuration */
|
|
1922
|
-
_internal: z.object({
|
|
1923
|
-
zkvWalletClient: z.any().optional()
|
|
1924
|
-
}).optional()
|
|
1925
|
-
});
|
|
1926
|
-
function createCofhesdkConfigBase(config) {
|
|
1927
|
-
const result = CofhesdkConfigSchema.safeParse(config);
|
|
1928
|
-
if (!result.success) {
|
|
1929
|
-
throw new Error(`Invalid cofhesdk configuration: ${result.error.message}`);
|
|
1896
|
+
// core/decrypt/tnSealOutputV2.ts
|
|
1897
|
+
var POLL_INTERVAL_MS = 1e3;
|
|
1898
|
+
var POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
1899
|
+
function numberArrayToUint8Array(arr) {
|
|
1900
|
+
return new Uint8Array(arr);
|
|
1901
|
+
}
|
|
1902
|
+
function convertSealedData(sealed) {
|
|
1903
|
+
if (!sealed) {
|
|
1904
|
+
throw new CofhesdkError({
|
|
1905
|
+
code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
|
|
1906
|
+
message: "Sealed data is missing from completed response"
|
|
1907
|
+
});
|
|
1930
1908
|
}
|
|
1931
|
-
return
|
|
1909
|
+
return {
|
|
1910
|
+
data: numberArrayToUint8Array(sealed.data),
|
|
1911
|
+
public_key: numberArrayToUint8Array(sealed.public_key),
|
|
1912
|
+
nonce: numberArrayToUint8Array(sealed.nonce)
|
|
1913
|
+
};
|
|
1932
1914
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1915
|
+
async function submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission) {
|
|
1916
|
+
const body = {
|
|
1917
|
+
ct_tempkey: ctHash.toString(16).padStart(64, "0"),
|
|
1918
|
+
host_chain_id: chainId,
|
|
1919
|
+
permit: permission
|
|
1920
|
+
};
|
|
1921
|
+
let response;
|
|
1922
|
+
try {
|
|
1923
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput`, {
|
|
1924
|
+
method: "POST",
|
|
1925
|
+
headers: {
|
|
1926
|
+
"Content-Type": "application/json"
|
|
1927
|
+
},
|
|
1928
|
+
body: JSON.stringify(body)
|
|
1929
|
+
});
|
|
1930
|
+
} catch (e) {
|
|
1939
1931
|
throw new CofhesdkError({
|
|
1940
|
-
code: "
|
|
1941
|
-
message: `
|
|
1942
|
-
hint: "Ensure
|
|
1932
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1933
|
+
message: `sealOutput request failed`,
|
|
1934
|
+
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
1935
|
+
cause: e instanceof Error ? e : void 0,
|
|
1943
1936
|
context: {
|
|
1944
|
-
|
|
1945
|
-
|
|
1937
|
+
thresholdNetworkUrl,
|
|
1938
|
+
body
|
|
1946
1939
|
}
|
|
1947
1940
|
});
|
|
1948
1941
|
}
|
|
1949
|
-
|
|
1950
|
-
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1942
|
+
if (!response.ok) {
|
|
1943
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
1944
|
+
try {
|
|
1945
|
+
const errorBody = await response.json();
|
|
1946
|
+
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
1947
|
+
} catch {
|
|
1948
|
+
errorMessage = response.statusText || errorMessage;
|
|
1949
|
+
}
|
|
1955
1950
|
throw new CofhesdkError({
|
|
1956
|
-
code: "
|
|
1957
|
-
message: `
|
|
1958
|
-
hint: "
|
|
1959
|
-
context: {
|
|
1951
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1952
|
+
message: `sealOutput request failed: ${errorMessage}`,
|
|
1953
|
+
hint: "Check the threshold network URL and request parameters.",
|
|
1954
|
+
context: {
|
|
1955
|
+
thresholdNetworkUrl,
|
|
1956
|
+
status: response.status,
|
|
1957
|
+
statusText: response.statusText,
|
|
1958
|
+
body
|
|
1959
|
+
}
|
|
1960
1960
|
});
|
|
1961
1961
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
const url = supportedChain.verifierUrl;
|
|
1967
|
-
if (!url) {
|
|
1962
|
+
let submitResponse;
|
|
1963
|
+
try {
|
|
1964
|
+
submitResponse = await response.json();
|
|
1965
|
+
} catch (e) {
|
|
1968
1966
|
throw new CofhesdkError({
|
|
1969
|
-
code: "
|
|
1970
|
-
message: `
|
|
1971
|
-
|
|
1972
|
-
context: {
|
|
1967
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1968
|
+
message: `Failed to parse sealOutput submit response`,
|
|
1969
|
+
cause: e instanceof Error ? e : void 0,
|
|
1970
|
+
context: {
|
|
1971
|
+
thresholdNetworkUrl,
|
|
1972
|
+
body
|
|
1973
|
+
}
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
if (!submitResponse.request_id) {
|
|
1977
|
+
throw new CofhesdkError({
|
|
1978
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1979
|
+
message: `sealOutput submit response missing request_id`,
|
|
1980
|
+
context: {
|
|
1981
|
+
thresholdNetworkUrl,
|
|
1982
|
+
body,
|
|
1983
|
+
submitResponse
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
return submitResponse.request_id;
|
|
1988
|
+
}
|
|
1989
|
+
async function pollSealOutputStatus(thresholdNetworkUrl, requestId) {
|
|
1990
|
+
const startTime = Date.now();
|
|
1991
|
+
let completed = false;
|
|
1992
|
+
while (!completed) {
|
|
1993
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
1994
|
+
throw new CofhesdkError({
|
|
1995
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
1996
|
+
message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
|
|
1997
|
+
hint: "The request may still be processing. Try again later.",
|
|
1998
|
+
context: {
|
|
1999
|
+
thresholdNetworkUrl,
|
|
2000
|
+
requestId,
|
|
2001
|
+
timeoutMs: POLL_TIMEOUT_MS
|
|
2002
|
+
}
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
let response;
|
|
2006
|
+
try {
|
|
2007
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput/${requestId}`, {
|
|
2008
|
+
method: "GET",
|
|
2009
|
+
headers: {
|
|
2010
|
+
"Content-Type": "application/json"
|
|
2011
|
+
}
|
|
2012
|
+
});
|
|
2013
|
+
} catch (e) {
|
|
2014
|
+
throw new CofhesdkError({
|
|
2015
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2016
|
+
message: `sealOutput status poll failed`,
|
|
2017
|
+
hint: "Ensure the threshold network URL is valid and reachable.",
|
|
2018
|
+
cause: e instanceof Error ? e : void 0,
|
|
2019
|
+
context: {
|
|
2020
|
+
thresholdNetworkUrl,
|
|
2021
|
+
requestId
|
|
2022
|
+
}
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
if (response.status === 404) {
|
|
2026
|
+
throw new CofhesdkError({
|
|
2027
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2028
|
+
message: `sealOutput request not found: ${requestId}`,
|
|
2029
|
+
hint: "The request may have expired or been invalid.",
|
|
2030
|
+
context: {
|
|
2031
|
+
thresholdNetworkUrl,
|
|
2032
|
+
requestId
|
|
2033
|
+
}
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
if (!response.ok) {
|
|
2037
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
2038
|
+
try {
|
|
2039
|
+
const errorBody = await response.json();
|
|
2040
|
+
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
2041
|
+
} catch {
|
|
2042
|
+
errorMessage = response.statusText || errorMessage;
|
|
2043
|
+
}
|
|
2044
|
+
throw new CofhesdkError({
|
|
2045
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2046
|
+
message: `sealOutput status poll failed: ${errorMessage}`,
|
|
2047
|
+
context: {
|
|
2048
|
+
thresholdNetworkUrl,
|
|
2049
|
+
requestId,
|
|
2050
|
+
status: response.status,
|
|
2051
|
+
statusText: response.statusText
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
let statusResponse;
|
|
2056
|
+
try {
|
|
2057
|
+
statusResponse = await response.json();
|
|
2058
|
+
} catch (e) {
|
|
2059
|
+
throw new CofhesdkError({
|
|
2060
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2061
|
+
message: `Failed to parse sealOutput status response`,
|
|
2062
|
+
cause: e instanceof Error ? e : void 0,
|
|
2063
|
+
context: {
|
|
2064
|
+
thresholdNetworkUrl,
|
|
2065
|
+
requestId
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
if (statusResponse.status === "COMPLETED") {
|
|
2070
|
+
if (statusResponse.is_succeed === false) {
|
|
2071
|
+
const errorMessage = statusResponse.error_message || "Unknown error";
|
|
2072
|
+
throw new CofhesdkError({
|
|
2073
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2074
|
+
message: `sealOutput request failed: ${errorMessage}`,
|
|
2075
|
+
context: {
|
|
2076
|
+
thresholdNetworkUrl,
|
|
2077
|
+
requestId,
|
|
2078
|
+
statusResponse
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
if (!statusResponse.sealed) {
|
|
2083
|
+
throw new CofhesdkError({
|
|
2084
|
+
code: "SEAL_OUTPUT_RETURNED_NULL" /* SealOutputReturnedNull */,
|
|
2085
|
+
message: `sealOutput request completed but returned no sealed data`,
|
|
2086
|
+
context: {
|
|
2087
|
+
thresholdNetworkUrl,
|
|
2088
|
+
requestId,
|
|
2089
|
+
statusResponse
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
return convertSealedData(statusResponse.sealed);
|
|
2094
|
+
}
|
|
2095
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
2096
|
+
}
|
|
2097
|
+
throw new CofhesdkError({
|
|
2098
|
+
code: "SEAL_OUTPUT_FAILED" /* SealOutputFailed */,
|
|
2099
|
+
message: "Polling loop exited unexpectedly",
|
|
2100
|
+
context: {
|
|
2101
|
+
thresholdNetworkUrl,
|
|
2102
|
+
requestId
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
2106
|
+
async function tnSealOutputV2(ctHash, chainId, permission, thresholdNetworkUrl) {
|
|
2107
|
+
const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
2108
|
+
return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
// core/decrypt/decryptHandleBuilder.ts
|
|
2112
|
+
var DecryptHandlesBuilder = class extends BaseBuilder {
|
|
2113
|
+
ctHash;
|
|
2114
|
+
utype;
|
|
2115
|
+
permitHash;
|
|
2116
|
+
permit;
|
|
2117
|
+
constructor(params) {
|
|
2118
|
+
super({
|
|
2119
|
+
config: params.config,
|
|
2120
|
+
publicClient: params.publicClient,
|
|
2121
|
+
walletClient: params.walletClient,
|
|
2122
|
+
chainId: params.chainId,
|
|
2123
|
+
account: params.account,
|
|
2124
|
+
requireConnected: params.requireConnected
|
|
1973
2125
|
});
|
|
2126
|
+
this.ctHash = params.ctHash;
|
|
2127
|
+
this.utype = params.utype;
|
|
2128
|
+
this.permitHash = params.permitHash;
|
|
2129
|
+
this.permit = params.permit;
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* @param chainId - Chain to decrypt values from. Used to fetch the threshold network URL and use the correct permit.
|
|
2133
|
+
*
|
|
2134
|
+
* If not provided, the chainId will be fetched from the connected publicClient.
|
|
2135
|
+
*
|
|
2136
|
+
* Example:
|
|
2137
|
+
* ```typescript
|
|
2138
|
+
* const unsealed = await decryptHandle(ctHash, utype)
|
|
2139
|
+
* .setChainId(11155111)
|
|
2140
|
+
* .decrypt();
|
|
2141
|
+
* ```
|
|
2142
|
+
*
|
|
2143
|
+
* @returns The chainable DecryptHandlesBuilder instance.
|
|
2144
|
+
*/
|
|
2145
|
+
setChainId(chainId) {
|
|
2146
|
+
this.chainId = chainId;
|
|
2147
|
+
return this;
|
|
2148
|
+
}
|
|
2149
|
+
getChainId() {
|
|
2150
|
+
return this.chainId;
|
|
2151
|
+
}
|
|
2152
|
+
/**
|
|
2153
|
+
* @param account - Account to decrypt values from. Used to fetch the correct permit.
|
|
2154
|
+
*
|
|
2155
|
+
* If not provided, the account will be fetched from the connected walletClient.
|
|
2156
|
+
*
|
|
2157
|
+
* Example:
|
|
2158
|
+
* ```typescript
|
|
2159
|
+
* const unsealed = await decryptHandle(ctHash, utype)
|
|
2160
|
+
* .setAccount('0x1234567890123456789012345678901234567890')
|
|
2161
|
+
* .decrypt();
|
|
2162
|
+
* ```
|
|
2163
|
+
*
|
|
2164
|
+
* @returns The chainable DecryptHandlesBuilder instance.
|
|
2165
|
+
*/
|
|
2166
|
+
setAccount(account) {
|
|
2167
|
+
this.account = account;
|
|
2168
|
+
return this;
|
|
1974
2169
|
}
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
function getThresholdNetworkUrlOrThrow(config, chainId) {
|
|
1978
|
-
const supportedChain = getSupportedChainOrThrow(config, chainId);
|
|
1979
|
-
const url = supportedChain.thresholdNetworkUrl;
|
|
1980
|
-
if (!url) {
|
|
1981
|
-
throw new CofhesdkError({
|
|
1982
|
-
code: "THRESHOLD_NETWORK_URL_UNINITIALIZED" /* ThresholdNetworkUrlUninitialized */,
|
|
1983
|
-
message: `Threshold network URL is not configured for chain <${chainId}>`,
|
|
1984
|
-
hint: "Ensure this chain config includes a thresholdNetworkUrl property.",
|
|
1985
|
-
context: { chainId }
|
|
1986
|
-
});
|
|
2170
|
+
getAccount() {
|
|
2171
|
+
return this.account;
|
|
1987
2172
|
}
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2173
|
+
/**
|
|
2174
|
+
* @param permitHash - Permit hash to decrypt values from. Used to fetch the correct permit.
|
|
2175
|
+
*
|
|
2176
|
+
* If not provided, the active permit for the chainId and account will be used.
|
|
2177
|
+
* If `setPermit()` is called, it will be used regardless of chainId, account, or permitHash.
|
|
2178
|
+
*
|
|
2179
|
+
* Example:
|
|
2180
|
+
* ```typescript
|
|
2181
|
+
* const unsealed = await decryptHandle(ctHash, utype)
|
|
2182
|
+
* .setPermitHash('0x1234567890123456789012345678901234567890')
|
|
2183
|
+
* .decrypt();
|
|
2184
|
+
* ```
|
|
2185
|
+
*
|
|
2186
|
+
* @returns The chainable DecryptHandlesBuilder instance.
|
|
2187
|
+
*/
|
|
2188
|
+
setPermitHash(permitHash) {
|
|
2189
|
+
this.permitHash = permitHash;
|
|
2190
|
+
return this;
|
|
2001
2191
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
const storedKey = keysStorage?.getFheKey(chainId, securityZone);
|
|
2005
|
-
const [storedKeyValid] = checkKeyValidity(storedKey, tfhePublicKeyDeserializer);
|
|
2006
|
-
if (storedKeyValid)
|
|
2007
|
-
return [storedKey, false];
|
|
2008
|
-
let pk_data = void 0;
|
|
2009
|
-
try {
|
|
2010
|
-
const pk_res = await fetch(`${coFheUrl}/GetNetworkPublicKey`, {
|
|
2011
|
-
method: "POST",
|
|
2012
|
-
headers: {
|
|
2013
|
-
"Content-Type": "application/json"
|
|
2014
|
-
},
|
|
2015
|
-
body: JSON.stringify({ securityZone })
|
|
2016
|
-
});
|
|
2017
|
-
const json = await pk_res.json();
|
|
2018
|
-
pk_data = json.publicKey;
|
|
2019
|
-
} catch (err) {
|
|
2020
|
-
throw new Error(`Error fetching FHE publicKey; fetching from CoFHE failed with error ${err}`);
|
|
2192
|
+
getPermitHash() {
|
|
2193
|
+
return this.permitHash;
|
|
2021
2194
|
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2195
|
+
/**
|
|
2196
|
+
* @param permit - Permit to decrypt values with. If provided, it will be used regardless of chainId, account, or permitHash.
|
|
2197
|
+
*
|
|
2198
|
+
* If not provided, the permit will be determined by chainId, account, and permitHash.
|
|
2199
|
+
*
|
|
2200
|
+
* Example:
|
|
2201
|
+
* ```typescript
|
|
2202
|
+
* const unsealed = await decryptHandle(ctHash, utype)
|
|
2203
|
+
* .setPermit(permit)
|
|
2204
|
+
* .decrypt();
|
|
2205
|
+
* ```
|
|
2206
|
+
*
|
|
2207
|
+
* @returns The chainable DecryptHandlesBuilder instance.
|
|
2208
|
+
*/
|
|
2209
|
+
setPermit(permit) {
|
|
2210
|
+
this.permit = permit;
|
|
2211
|
+
return this;
|
|
2024
2212
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2213
|
+
getPermit() {
|
|
2214
|
+
return this.permit;
|
|
2027
2215
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
);
|
|
2216
|
+
async getThresholdNetworkUrl() {
|
|
2217
|
+
this.assertChainId();
|
|
2218
|
+
return getThresholdNetworkUrlOrThrow(this.config, this.chainId);
|
|
2032
2219
|
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2220
|
+
validateUtypeOrThrow() {
|
|
2221
|
+
if (!isValidUtype(this.utype))
|
|
2222
|
+
throw new CofhesdkError({
|
|
2223
|
+
code: "INVALID_UTYPE" /* InvalidUtype */,
|
|
2224
|
+
message: `Invalid utype to decrypt to`,
|
|
2225
|
+
context: {
|
|
2226
|
+
utype: this.utype
|
|
2227
|
+
}
|
|
2228
|
+
});
|
|
2037
2229
|
}
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2230
|
+
async getResolvedPermit() {
|
|
2231
|
+
if (this.permit)
|
|
2232
|
+
return this.permit;
|
|
2233
|
+
this.assertChainId();
|
|
2234
|
+
this.assertAccount();
|
|
2235
|
+
if (this.permitHash) {
|
|
2236
|
+
const permit2 = await permits.getPermit(this.chainId, this.account, this.permitHash);
|
|
2237
|
+
if (!permit2) {
|
|
2238
|
+
throw new CofhesdkError({
|
|
2239
|
+
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2240
|
+
message: `Permit with hash <${this.permitHash}> not found for account <${this.account}> and chainId <${this.chainId}>`,
|
|
2241
|
+
hint: "Ensure the permit exists and is valid.",
|
|
2242
|
+
context: {
|
|
2243
|
+
chainId: this.chainId,
|
|
2244
|
+
account: this.account,
|
|
2245
|
+
permitHash: this.permitHash
|
|
2246
|
+
}
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
return permit2;
|
|
2250
|
+
}
|
|
2251
|
+
const permit = await permits.getActivePermit(this.chainId, this.account);
|
|
2252
|
+
if (!permit) {
|
|
2253
|
+
throw new CofhesdkError({
|
|
2254
|
+
code: "PERMIT_NOT_FOUND" /* PermitNotFound */,
|
|
2255
|
+
message: `Active permit not found for chainId <${this.chainId}> and account <${this.account}>`,
|
|
2256
|
+
hint: "Ensure a permit exists for this account on this chain.",
|
|
2257
|
+
context: {
|
|
2258
|
+
chainId: this.chainId,
|
|
2259
|
+
account: this.account
|
|
2260
|
+
}
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
return permit;
|
|
2059
2264
|
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2265
|
+
/**
|
|
2266
|
+
* On hardhat, interact with MockZkVerifier contract instead of CoFHE
|
|
2267
|
+
*/
|
|
2268
|
+
async mocksSealOutput(permit) {
|
|
2269
|
+
this.assertPublicClient();
|
|
2270
|
+
const mocksSealOutputDelay = this.config.mocks.sealOutputDelay;
|
|
2271
|
+
return cofheMocksSealOutput(this.ctHash, this.utype, permit, this.publicClient, mocksSealOutputDelay);
|
|
2062
2272
|
}
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2273
|
+
/**
|
|
2274
|
+
* In the production context, perform a true decryption with the CoFHE coprocessor.
|
|
2275
|
+
*/
|
|
2276
|
+
async productionSealOutput(permit) {
|
|
2277
|
+
this.assertChainId();
|
|
2278
|
+
this.assertPublicClient();
|
|
2279
|
+
const thresholdNetworkUrl = await this.getThresholdNetworkUrl();
|
|
2280
|
+
const permission = PermitUtils.getPermission(permit, true);
|
|
2281
|
+
const sealed = await tnSealOutputV2(this.ctHash, this.chainId, permission, thresholdNetworkUrl);
|
|
2282
|
+
return PermitUtils.unseal(permit, sealed);
|
|
2283
|
+
}
|
|
2284
|
+
/**
|
|
2285
|
+
* Final step of the decryption process. MUST BE CALLED LAST IN THE CHAIN.
|
|
2286
|
+
*
|
|
2287
|
+
* This will:
|
|
2288
|
+
* - Use a permit based on provided permit OR chainId + account + permitHash
|
|
2289
|
+
* - Check permit validity
|
|
2290
|
+
* - Call CoFHE `/sealoutput` with the permit, which returns a sealed (encrypted) item
|
|
2291
|
+
* - Unseal the sealed item with the permit
|
|
2292
|
+
* - Return the unsealed item
|
|
2293
|
+
*
|
|
2294
|
+
* Example:
|
|
2295
|
+
* ```typescript
|
|
2296
|
+
* const unsealed = await decryptHandle(ctHash, utype)
|
|
2297
|
+
* .setChainId(11155111) // optional
|
|
2298
|
+
* .setAccount('0x123...890') // optional
|
|
2299
|
+
* .decrypt(); // execute
|
|
2300
|
+
* ```
|
|
2301
|
+
*
|
|
2302
|
+
* @returns The unsealed item.
|
|
2303
|
+
*/
|
|
2304
|
+
async decrypt() {
|
|
2305
|
+
this.validateUtypeOrThrow();
|
|
2306
|
+
const permit = await this.getResolvedPermit();
|
|
2307
|
+
PermitUtils.validate(permit);
|
|
2308
|
+
PermitUtils.isValid(permit);
|
|
2309
|
+
const chainId = permit._signedDomain.chainId;
|
|
2310
|
+
let unsealed;
|
|
2311
|
+
if (chainId === hardhat$1.id) {
|
|
2312
|
+
unsealed = await this.mocksSealOutput(permit);
|
|
2313
|
+
} else {
|
|
2314
|
+
unsealed = await this.productionSealOutput(permit);
|
|
2315
|
+
}
|
|
2316
|
+
return convertViaUtype(this.utype, unsealed);
|
|
2068
2317
|
}
|
|
2069
|
-
keysStorage?.setCrs(chainId, crs_data);
|
|
2070
|
-
return [crs_data, true];
|
|
2071
|
-
};
|
|
2072
|
-
var fetchKeys = async (config, chainId, securityZone = 0, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, keysStorage) => {
|
|
2073
|
-
const coFheUrl = getCoFheUrlOrThrow(config, chainId);
|
|
2074
|
-
return await Promise.all([
|
|
2075
|
-
fetchFhePublicKey(coFheUrl, chainId, securityZone, tfhePublicKeyDeserializer, keysStorage),
|
|
2076
|
-
fetchCrs(coFheUrl, chainId, securityZone, compactPkeCrsDeserializer, keysStorage)
|
|
2077
|
-
]);
|
|
2078
|
-
};
|
|
2079
|
-
var fetchMultichainKeys = async (config, securityZone = 0, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, keysStorage) => {
|
|
2080
|
-
await Promise.all(
|
|
2081
|
-
config.supportedChains.filter((chain) => chain.id !== hardhat.id).map(
|
|
2082
|
-
(chain) => fetchKeys(config, chain.id, securityZone, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, keysStorage)
|
|
2083
|
-
)
|
|
2084
|
-
);
|
|
2085
2318
|
};
|
|
2086
2319
|
|
|
2087
2320
|
// core/client.ts
|
|
2321
|
+
var InitialConnectStore = {
|
|
2322
|
+
connected: false,
|
|
2323
|
+
connecting: false,
|
|
2324
|
+
connectError: void 0,
|
|
2325
|
+
chainId: void 0,
|
|
2326
|
+
account: void 0,
|
|
2327
|
+
publicClient: void 0,
|
|
2328
|
+
walletClient: void 0
|
|
2329
|
+
};
|
|
2088
2330
|
function createCofhesdkClientBase(opts) {
|
|
2089
2331
|
const keysStorage = createKeysStore(opts.config.fheKeyStorage);
|
|
2090
|
-
|
|
2091
|
-
let
|
|
2092
|
-
const connectStore = createStore(() => ({
|
|
2093
|
-
connected: false,
|
|
2094
|
-
connecting: false,
|
|
2095
|
-
connectError: void 0,
|
|
2096
|
-
chainId: void 0,
|
|
2097
|
-
account: void 0
|
|
2098
|
-
}));
|
|
2332
|
+
const connectStore = createStore(() => InitialConnectStore);
|
|
2333
|
+
let connectAttemptId = 0;
|
|
2099
2334
|
const updateConnectState = (partial) => {
|
|
2100
2335
|
connectStore.setState((state) => ({ ...state, ...partial }));
|
|
2101
2336
|
};
|
|
2102
|
-
let _connectPromise = void 0;
|
|
2103
2337
|
const _requireConnected = () => {
|
|
2104
2338
|
const state = connectStore.getState();
|
|
2105
|
-
const notConnected = !state.connected || !
|
|
2339
|
+
const notConnected = !state.connected || !state.account || !state.chainId || !state.publicClient || !state.walletClient;
|
|
2106
2340
|
if (notConnected) {
|
|
2107
2341
|
throw new CofhesdkError({
|
|
2108
2342
|
code: "NOT_CONNECTED" /* NotConnected */,
|
|
@@ -2112,55 +2346,49 @@ function createCofhesdkClientBase(opts) {
|
|
|
2112
2346
|
connected: state.connected,
|
|
2113
2347
|
account: state.account,
|
|
2114
2348
|
chainId: state.chainId,
|
|
2115
|
-
publicClient:
|
|
2116
|
-
walletClient:
|
|
2349
|
+
publicClient: state.publicClient,
|
|
2350
|
+
walletClient: state.walletClient
|
|
2117
2351
|
}
|
|
2118
2352
|
});
|
|
2119
2353
|
}
|
|
2120
2354
|
};
|
|
2121
|
-
const keyFetchResult = resultWrapper(async () => {
|
|
2122
|
-
if (opts.config.fheKeysPrefetching === "SUPPORTED_CHAINS") {
|
|
2123
|
-
await fetchMultichainKeys(
|
|
2124
|
-
opts.config,
|
|
2125
|
-
0,
|
|
2126
|
-
opts.tfhePublicKeyDeserializer,
|
|
2127
|
-
opts.compactPkeCrsDeserializer,
|
|
2128
|
-
keysStorage
|
|
2129
|
-
);
|
|
2130
|
-
return true;
|
|
2131
|
-
}
|
|
2132
|
-
return false;
|
|
2133
|
-
});
|
|
2134
2355
|
async function connect(publicClient, walletClient) {
|
|
2135
2356
|
const state = connectStore.getState();
|
|
2136
|
-
if (state.connected &&
|
|
2137
|
-
return
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2357
|
+
if (state.connected && state.publicClient === publicClient && state.walletClient === walletClient)
|
|
2358
|
+
return;
|
|
2359
|
+
connectAttemptId += 1;
|
|
2360
|
+
const localAttemptId = connectAttemptId;
|
|
2361
|
+
updateConnectState({
|
|
2362
|
+
...InitialConnectStore,
|
|
2363
|
+
connecting: true
|
|
2364
|
+
});
|
|
2365
|
+
try {
|
|
2366
|
+
const chainId = await getPublicClientChainID(publicClient);
|
|
2367
|
+
const account = await getWalletClientAccount(walletClient);
|
|
2368
|
+
if (localAttemptId !== connectAttemptId)
|
|
2369
|
+
return;
|
|
2370
|
+
updateConnectState({
|
|
2371
|
+
connected: true,
|
|
2372
|
+
connecting: false,
|
|
2373
|
+
connectError: void 0,
|
|
2374
|
+
chainId,
|
|
2375
|
+
account,
|
|
2376
|
+
publicClient,
|
|
2377
|
+
walletClient
|
|
2378
|
+
});
|
|
2379
|
+
} catch (e) {
|
|
2380
|
+
if (localAttemptId !== connectAttemptId)
|
|
2381
|
+
return;
|
|
2382
|
+
updateConnectState({
|
|
2383
|
+
...InitialConnectStore,
|
|
2384
|
+
connectError: e
|
|
2385
|
+
});
|
|
2386
|
+
throw e;
|
|
2141
2387
|
}
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
_publicClient = publicClient;
|
|
2147
|
-
_walletClient = walletClient;
|
|
2148
|
-
const chainId = await getPublicClientChainID(publicClient);
|
|
2149
|
-
const account = await getWalletClientAccount(walletClient);
|
|
2150
|
-
updateConnectState({ connecting: false, connected: true, chainId, account });
|
|
2151
|
-
return true;
|
|
2152
|
-
},
|
|
2153
|
-
// catch
|
|
2154
|
-
(e) => {
|
|
2155
|
-
updateConnectState({ connecting: false, connected: false, connectError: e });
|
|
2156
|
-
return false;
|
|
2157
|
-
},
|
|
2158
|
-
// finally
|
|
2159
|
-
() => {
|
|
2160
|
-
_connectPromise = void 0;
|
|
2161
|
-
}
|
|
2162
|
-
);
|
|
2163
|
-
return _connectPromise;
|
|
2388
|
+
}
|
|
2389
|
+
function disconnect() {
|
|
2390
|
+
connectAttemptId += 1;
|
|
2391
|
+
updateConnectState({ ...InitialConnectStore });
|
|
2164
2392
|
}
|
|
2165
2393
|
function encryptInputs(inputs) {
|
|
2166
2394
|
const state = connectStore.getState();
|
|
@@ -2169,13 +2397,14 @@ function createCofhesdkClientBase(opts) {
|
|
|
2169
2397
|
account: state.account ?? void 0,
|
|
2170
2398
|
chainId: state.chainId ?? void 0,
|
|
2171
2399
|
config: opts.config,
|
|
2172
|
-
publicClient:
|
|
2173
|
-
walletClient:
|
|
2400
|
+
publicClient: state.publicClient ?? void 0,
|
|
2401
|
+
walletClient: state.walletClient ?? void 0,
|
|
2174
2402
|
zkvWalletClient: opts.config._internal?.zkvWalletClient,
|
|
2175
2403
|
tfhePublicKeyDeserializer: opts.tfhePublicKeyDeserializer,
|
|
2176
2404
|
compactPkeCrsDeserializer: opts.compactPkeCrsDeserializer,
|
|
2177
2405
|
zkBuilderAndCrsGenerator: opts.zkBuilderAndCrsGenerator,
|
|
2178
2406
|
initTfhe: opts.initTfhe,
|
|
2407
|
+
zkProveWorkerFn: opts.zkProveWorkerFn,
|
|
2179
2408
|
keysStorage,
|
|
2180
2409
|
requireConnected: _requireConnected
|
|
2181
2410
|
});
|
|
@@ -2188,8 +2417,8 @@ function createCofhesdkClientBase(opts) {
|
|
|
2188
2417
|
chainId: state.chainId ?? void 0,
|
|
2189
2418
|
account: state.account ?? void 0,
|
|
2190
2419
|
config: opts.config,
|
|
2191
|
-
publicClient:
|
|
2192
|
-
walletClient:
|
|
2420
|
+
publicClient: state.publicClient ?? void 0,
|
|
2421
|
+
walletClient: state.walletClient ?? void 0,
|
|
2193
2422
|
requireConnected: _requireConnected
|
|
2194
2423
|
});
|
|
2195
2424
|
}
|
|
@@ -2215,48 +2444,64 @@ function createCofhesdkClientBase(opts) {
|
|
|
2215
2444
|
getSnapshot: permits.getSnapshot,
|
|
2216
2445
|
subscribe: permits.subscribe,
|
|
2217
2446
|
// Creation methods (require connection)
|
|
2218
|
-
createSelf: async (options
|
|
2447
|
+
createSelf: async (options, clients) => {
|
|
2219
2448
|
_requireConnected();
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2449
|
+
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
2450
|
+
return permits.createSelf(options, publicClient, walletClient);
|
|
2451
|
+
},
|
|
2452
|
+
createSharing: async (options, clients) => {
|
|
2223
2453
|
_requireConnected();
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2454
|
+
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
2455
|
+
return permits.createSharing(options, publicClient, walletClient);
|
|
2456
|
+
},
|
|
2457
|
+
importShared: async (options, clients) => {
|
|
2227
2458
|
_requireConnected();
|
|
2228
|
-
|
|
2229
|
-
|
|
2459
|
+
const { publicClient, walletClient } = clients ?? connectStore.getState();
|
|
2460
|
+
return permits.importShared(options, publicClient, walletClient);
|
|
2461
|
+
},
|
|
2462
|
+
// Get or create methods (require connection)
|
|
2463
|
+
getOrCreateSelfPermit: async (chainId, account, options) => {
|
|
2464
|
+
_requireConnected();
|
|
2465
|
+
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2466
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
2467
|
+
return permits.getOrCreateSelfPermit(publicClient, walletClient, _chainId, _account, options);
|
|
2468
|
+
},
|
|
2469
|
+
getOrCreateSharingPermit: async (options, chainId, account) => {
|
|
2470
|
+
_requireConnected();
|
|
2471
|
+
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2472
|
+
const { publicClient, walletClient } = connectStore.getState();
|
|
2473
|
+
return permits.getOrCreateSharingPermit(publicClient, walletClient, options, _chainId, _account);
|
|
2474
|
+
},
|
|
2230
2475
|
// Retrieval methods (auto-fill chainId/account)
|
|
2231
|
-
getPermit: async (hash, chainId, account) =>
|
|
2476
|
+
getPermit: async (hash, chainId, account) => {
|
|
2232
2477
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2233
2478
|
return permits.getPermit(_chainId, _account, hash);
|
|
2234
|
-
}
|
|
2235
|
-
getPermits: async (chainId, account) =>
|
|
2479
|
+
},
|
|
2480
|
+
getPermits: async (chainId, account) => {
|
|
2236
2481
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2237
2482
|
return permits.getPermits(_chainId, _account);
|
|
2238
|
-
}
|
|
2239
|
-
getActivePermit: async (chainId, account) =>
|
|
2483
|
+
},
|
|
2484
|
+
getActivePermit: async (chainId, account) => {
|
|
2240
2485
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2241
2486
|
return permits.getActivePermit(_chainId, _account);
|
|
2242
|
-
}
|
|
2243
|
-
getActivePermitHash: async (chainId, account) =>
|
|
2487
|
+
},
|
|
2488
|
+
getActivePermitHash: async (chainId, account) => {
|
|
2244
2489
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2245
2490
|
return permits.getActivePermitHash(_chainId, _account);
|
|
2246
|
-
}
|
|
2491
|
+
},
|
|
2247
2492
|
// Mutation methods (auto-fill chainId/account)
|
|
2248
|
-
selectActivePermit:
|
|
2493
|
+
selectActivePermit: (hash, chainId, account) => {
|
|
2249
2494
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2250
2495
|
return permits.selectActivePermit(_chainId, _account, hash);
|
|
2251
|
-
}
|
|
2252
|
-
removePermit: async (hash, chainId, account) =>
|
|
2496
|
+
},
|
|
2497
|
+
removePermit: async (hash, chainId, account) => {
|
|
2253
2498
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2254
2499
|
return permits.removePermit(_chainId, _account, hash);
|
|
2255
|
-
}
|
|
2256
|
-
removeActivePermit: async (chainId, account) =>
|
|
2500
|
+
},
|
|
2501
|
+
removeActivePermit: async (chainId, account) => {
|
|
2257
2502
|
const { chainId: _chainId, account: _account } = _getChainIdAndAccount(chainId, account);
|
|
2258
2503
|
return permits.removeActivePermit(_chainId, _account);
|
|
2259
|
-
}
|
|
2504
|
+
},
|
|
2260
2505
|
// Utils (no context needed)
|
|
2261
2506
|
getHash: permits.getHash,
|
|
2262
2507
|
serialize: permits.serialize,
|
|
@@ -2266,10 +2511,6 @@ function createCofhesdkClientBase(opts) {
|
|
|
2266
2511
|
// Zustand reactive accessors (don't export store directly to prevent mutation)
|
|
2267
2512
|
getSnapshot: connectStore.getState,
|
|
2268
2513
|
subscribe: connectStore.subscribe,
|
|
2269
|
-
// initialization results
|
|
2270
|
-
initializationResults: {
|
|
2271
|
-
keyFetchResult
|
|
2272
|
-
},
|
|
2273
2514
|
// flags (read-only: reflect snapshot)
|
|
2274
2515
|
get connected() {
|
|
2275
2516
|
return connectStore.getState().connected;
|
|
@@ -2280,6 +2521,7 @@ function createCofhesdkClientBase(opts) {
|
|
|
2280
2521
|
// config & platform-specific (read-only)
|
|
2281
2522
|
config: opts.config,
|
|
2282
2523
|
connect,
|
|
2524
|
+
disconnect,
|
|
2283
2525
|
encryptInputs,
|
|
2284
2526
|
decryptHandle,
|
|
2285
2527
|
permits: clientPermits
|
|
@@ -2287,9 +2529,9 @@ function createCofhesdkClientBase(opts) {
|
|
|
2287
2529
|
// Example:
|
|
2288
2530
|
// async encryptData(data: unknown) {
|
|
2289
2531
|
// requireConnected();
|
|
2290
|
-
// // Use
|
|
2532
|
+
// // Use state.publicClient and state.walletClient for implementation
|
|
2291
2533
|
// },
|
|
2292
2534
|
};
|
|
2293
2535
|
}
|
|
2294
2536
|
|
|
2295
|
-
export { CofhesdkError, CofhesdkErrorCode, DecryptHandlesBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes,
|
|
2537
|
+
export { CofhesdkError, CofhesdkErrorCode, DecryptHandlesBuilder, EncryptInputsBuilder, EncryptStep, Encryptable, FheAllUTypes, FheTypes, FheUintUTypes, InitialConnectStore, assertCorrectEncryptedItemInput, createCofhesdkClientBase, createCofhesdkConfigBase, createKeysStore, fetchKeys, fheTypeToString, getCofhesdkConfigItem, isCofhesdkError, isEncryptableItem, isLastEncryptionStep, zkProveWithWorker };
|