@cofhe/sdk 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/chains/defineChain.ts +2 -2
  3. package/chains/types.ts +3 -3
  4. package/core/baseBuilder.ts +18 -18
  5. package/core/client.test.ts +155 -41
  6. package/core/client.ts +72 -32
  7. package/core/clientTypes.ts +28 -18
  8. package/core/config.test.ts +40 -33
  9. package/core/config.ts +56 -51
  10. package/core/consts.ts +22 -0
  11. package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
  12. package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
  13. package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -14
  14. package/core/decrypt/decryptForTxBuilder.ts +340 -0
  15. package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
  16. package/core/decrypt/tnDecrypt.ts +232 -0
  17. package/core/decrypt/tnSealOutputV1.ts +5 -5
  18. package/core/decrypt/tnSealOutputV2.ts +27 -27
  19. package/core/encrypt/cofheMocksZkVerifySign.ts +19 -26
  20. package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
  21. package/core/encrypt/encryptInputsBuilder.ts +65 -42
  22. package/core/encrypt/zkPackProveVerify.ts +11 -11
  23. package/core/error.ts +18 -18
  24. package/core/fetchKeys.test.ts +3 -3
  25. package/core/fetchKeys.ts +3 -3
  26. package/core/index.ts +22 -11
  27. package/core/permits.test.ts +5 -6
  28. package/core/permits.ts +5 -4
  29. package/core/utils.ts +10 -10
  30. package/dist/chains.cjs +4 -7
  31. package/dist/chains.d.cts +12 -12
  32. package/dist/chains.d.ts +12 -12
  33. package/dist/chains.js +1 -1
  34. package/dist/{chunk-WGCRJCBR.js → chunk-2TPSCOW3.js} +820 -224
  35. package/dist/{chunk-UGBVZNRT.js → chunk-NWDKXBIP.js} +309 -189
  36. package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
  37. package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-6aTZPQ_4.d.ts} +233 -173
  38. package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-Bhq7pCSA.d.cts} +233 -173
  39. package/dist/core.cjs +1138 -418
  40. package/dist/core.d.cts +37 -24
  41. package/dist/core.d.ts +37 -24
  42. package/dist/core.js +3 -3
  43. package/dist/node.cjs +1082 -370
  44. package/dist/node.d.cts +12 -12
  45. package/dist/node.d.ts +12 -12
  46. package/dist/node.js +8 -8
  47. package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
  48. package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
  49. package/dist/permits.cjs +305 -187
  50. package/dist/permits.d.cts +111 -812
  51. package/dist/permits.d.ts +111 -812
  52. package/dist/permits.js +1 -1
  53. package/dist/types-YiAC4gig.d.cts +33 -0
  54. package/dist/types-YiAC4gig.d.ts +33 -0
  55. package/dist/web.cjs +1085 -373
  56. package/dist/web.d.cts +13 -13
  57. package/dist/web.d.ts +13 -13
  58. package/dist/web.js +10 -10
  59. package/node/client.test.ts +34 -34
  60. package/node/config.test.ts +11 -11
  61. package/node/encryptInputs.test.ts +29 -29
  62. package/node/index.ts +15 -15
  63. package/package.json +3 -3
  64. package/permits/localstorage.test.ts +9 -13
  65. package/permits/onchain-utils.ts +221 -0
  66. package/permits/permit.test.ts +51 -5
  67. package/permits/permit.ts +28 -74
  68. package/permits/store.test.ts +10 -50
  69. package/permits/store.ts +4 -14
  70. package/permits/test-utils.ts +10 -2
  71. package/permits/types.ts +22 -9
  72. package/permits/utils.ts +0 -4
  73. package/permits/validation.test.ts +29 -32
  74. package/permits/validation.ts +112 -194
  75. package/web/client.web.test.ts +34 -34
  76. package/web/config.web.test.ts +11 -11
  77. package/web/encryptInputs.web.test.ts +29 -29
  78. package/web/index.ts +19 -19
  79. package/web/worker.builder.web.test.ts +28 -28
  80. package/web/worker.config.web.test.ts +47 -47
  81. package/web/worker.output.web.test.ts +10 -10
  82. package/dist/types-KImPrEIe.d.cts +0 -48
  83. package/dist/types-KImPrEIe.d.ts +0 -48
@@ -1,4 +1,4 @@
1
- import { isAddress, zeroAddress, keccak256, toHex, parseAbi } from 'viem';
1
+ import { isAddress, getAddress, zeroAddress, isHex, keccak256, toHex, parseAbi, BaseError, ContractFunctionRevertedError, decodeErrorResult } from 'viem';
2
2
  import * as nacl from 'tweetnacl';
3
3
  import { z } from 'zod';
4
4
  import { createStore } from 'zustand/vanilla';
@@ -54,9 +54,6 @@ function isBigIntOrNumber(value) {
54
54
  }
55
55
  }
56
56
  }
57
- function is0xPrefixed(value) {
58
- return value.startsWith("0x");
59
- }
60
57
 
61
58
  // permits/sealing.ts
62
59
  var PRIVATE_KEY_LENGTH = 64;
@@ -144,158 +141,137 @@ var SerializedSealingPair = z.object({
144
141
  privateKey: z.string(),
145
142
  publicKey: z.string()
146
143
  });
144
+ var addressSchema = z.string().refine((val) => isAddress(val), {
145
+ error: "Invalid address"
146
+ }).transform((val) => getAddress(val));
147
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== zeroAddress, {
148
+ error: "Must not be zeroAddress"
149
+ });
150
+ var bytesSchema = z.custom(
151
+ (val) => {
152
+ return typeof val === "string" && isHex(val);
153
+ },
154
+ {
155
+ message: "Invalid hex value"
156
+ }
157
+ );
158
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
159
+ error: "Must not be empty"
160
+ });
147
161
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
148
162
  var zPermitWithDefaults = z.object({
149
163
  name: z.string().optional().default("Unnamed Permit"),
150
164
  type: z.enum(["self", "sharing", "recipient"]),
151
- issuer: z.string().refine((val) => isAddress(val), {
152
- message: "Permit issuer :: invalid address"
153
- }).refine((val) => val !== zeroAddress, {
154
- message: "Permit issuer :: must not be zeroAddress"
155
- }),
156
- expiration: z.number().optional().default(DEFAULT_EXPIRATION_FN),
157
- recipient: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
158
- message: "Permit recipient :: invalid address"
159
- }),
160
- validatorId: z.number().optional().default(0),
161
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
162
- message: "Permit validatorContract :: invalid address"
163
- }),
164
- issuerSignature: z.string().optional().default("0x"),
165
- recipientSignature: z.string().optional().default("0x")
165
+ issuer: addressNotZeroSchema,
166
+ expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
167
+ recipient: addressSchema.optional().default(zeroAddress),
168
+ validatorId: z.int().optional().default(0),
169
+ validatorContract: addressSchema.optional().default(zeroAddress),
170
+ issuerSignature: bytesSchema.optional().default("0x"),
171
+ recipientSignature: bytesSchema.optional().default("0x")
166
172
  });
167
173
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
168
174
  sealingPair: SerializedSealingPair.optional()
169
175
  });
170
- var ValidatorContractRefinement = [
176
+ var ExternalValidatorRefinement = [
171
177
  (data) => data.validatorId !== 0 && data.validatorContract !== zeroAddress || data.validatorId === 0 && data.validatorContract === zeroAddress,
172
178
  {
173
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
179
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
174
180
  path: ["validatorId", "validatorContract"]
175
181
  }
176
182
  ];
183
+ var RecipientRefinement = [
184
+ (data) => data.issuer !== data.recipient,
185
+ {
186
+ error: "Sharing permit :: issuer and recipient must not be the same",
187
+ path: ["issuer", "recipient"]
188
+ }
189
+ ];
177
190
  var SelfPermitOptionsValidator = z.object({
178
191
  type: z.literal("self").optional().default("self"),
179
- issuer: z.string().refine((val) => isAddress(val), {
180
- message: "Self permit issuer :: invalid address"
181
- }).refine((val) => is0xPrefixed(val), {
182
- message: "Self permit issuer :: must be 0x prefixed"
183
- }).refine((val) => val !== zeroAddress, {
184
- message: "Self permit issuer :: must not be zeroAddress"
185
- }),
192
+ issuer: addressNotZeroSchema,
186
193
  name: z.string().optional().default("Unnamed Permit"),
187
- expiration: z.number().optional().default(DEFAULT_EXPIRATION_FN),
188
- recipient: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
189
- message: "Self permit recipient :: invalid address"
190
- }).refine((val) => is0xPrefixed(val), {
191
- message: "Self permit recipient :: must be 0x prefixed"
192
- }).refine((val) => val === zeroAddress, {
193
- message: "Self permit recipient :: must be zeroAddress"
194
- }),
195
- validatorId: z.number().optional().default(0),
196
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
197
- message: "Self permit validatorContract :: invalid address"
198
- }),
199
- issuerSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
200
- message: "Self permit issuerSignature :: must be 0x prefixed"
201
- }),
202
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
203
- message: "Self permit recipientSignature :: must be 0x prefixed"
204
- })
205
- }).refine(...ValidatorContractRefinement);
194
+ expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
195
+ recipient: addressSchema.optional().default(zeroAddress),
196
+ validatorId: z.int().optional().default(0),
197
+ validatorContract: addressSchema.optional().default(zeroAddress),
198
+ issuerSignature: bytesSchema.optional().default("0x"),
199
+ recipientSignature: bytesSchema.optional().default("0x")
200
+ }).refine(...ExternalValidatorRefinement);
206
201
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
207
- message: "Self permit :: type must be 'self'"
202
+ error: "Type must be 'self'"
208
203
  }).refine((data) => data.recipient === zeroAddress, {
209
- message: "Self permit :: recipient must be zeroAddress"
204
+ error: "Recipient must be zeroAddress"
210
205
  }).refine((data) => data.issuerSignature !== "0x", {
211
- message: "Self permit :: issuerSignature must be populated"
206
+ error: "IssuerSignature must be populated"
212
207
  }).refine((data) => data.recipientSignature === "0x", {
213
- message: "Self permit :: recipientSignature must be empty"
214
- }).refine(...ValidatorContractRefinement);
208
+ error: "RecipientSignature must be empty"
209
+ }).refine(...ExternalValidatorRefinement);
215
210
  var SharingPermitOptionsValidator = z.object({
216
211
  type: z.literal("sharing").optional().default("sharing"),
217
- issuer: z.string().refine((val) => isAddress(val), {
218
- message: "Sharing permit issuer :: invalid address"
219
- }).refine((val) => is0xPrefixed(val), {
220
- message: "Sharing permit issuer :: must be 0x prefixed"
221
- }).refine((val) => val !== zeroAddress, {
222
- message: "Sharing permit issuer :: must not be zeroAddress"
223
- }),
224
- recipient: z.string().refine((val) => isAddress(val), {
225
- message: "Sharing permit recipient :: invalid address"
226
- }).refine((val) => is0xPrefixed(val), {
227
- message: "Sharing permit recipient :: must be 0x prefixed"
228
- }).refine((val) => val !== zeroAddress, {
229
- message: "Sharing permit recipient :: must not be zeroAddress"
230
- }),
212
+ issuer: addressNotZeroSchema,
213
+ recipient: addressNotZeroSchema,
231
214
  name: z.string().optional().default("Unnamed Permit"),
232
- expiration: z.number().optional().default(DEFAULT_EXPIRATION_FN),
233
- validatorId: z.number().optional().default(0),
234
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
235
- message: "Sharing permit validatorContract :: invalid address"
236
- }),
237
- issuerSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
238
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
239
- }),
240
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
241
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
242
- })
243
- }).refine(...ValidatorContractRefinement);
215
+ expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
216
+ validatorId: z.int().optional().default(0),
217
+ validatorContract: addressSchema.optional().default(zeroAddress),
218
+ issuerSignature: bytesSchema.optional().default("0x"),
219
+ recipientSignature: bytesSchema.optional().default("0x")
220
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
244
221
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
245
- message: "Sharing permit :: type must be 'sharing'"
222
+ error: "Type must be 'sharing'"
246
223
  }).refine((data) => data.recipient !== zeroAddress, {
247
- message: "Sharing permit :: recipient must not be zeroAddress"
224
+ error: "Recipient must not be zeroAddress"
248
225
  }).refine((data) => data.issuerSignature !== "0x", {
249
- message: "Sharing permit :: issuerSignature must be populated"
226
+ error: "IssuerSignature must be populated"
250
227
  }).refine((data) => data.recipientSignature === "0x", {
251
- message: "Sharing permit :: recipientSignature must be empty"
252
- }).refine(...ValidatorContractRefinement);
228
+ error: "RecipientSignature must be empty"
229
+ }).refine(...ExternalValidatorRefinement);
253
230
  var ImportPermitOptionsValidator = z.object({
254
231
  type: z.literal("recipient").optional().default("recipient"),
255
- issuer: z.string().refine((val) => isAddress(val), {
256
- message: "Import permit issuer :: invalid address"
257
- }).refine((val) => is0xPrefixed(val), {
258
- message: "Import permit issuer :: must be 0x prefixed"
259
- }).refine((val) => val !== zeroAddress, {
260
- message: "Import permit issuer :: must not be zeroAddress"
261
- }),
262
- recipient: z.string().refine((val) => isAddress(val), {
263
- message: "Import permit recipient :: invalid address"
264
- }).refine((val) => is0xPrefixed(val), {
265
- message: "Import permit recipient :: must be 0x prefixed"
266
- }).refine((val) => val !== zeroAddress, {
267
- message: "Import permit recipient :: must not be zeroAddress"
268
- }),
269
- issuerSignature: z.string().refine((val) => is0xPrefixed(val), {
270
- message: "Import permit issuerSignature :: must be 0x prefixed"
271
- }).refine((val) => val !== "0x", {
272
- message: "Import permit :: issuerSignature must be provided"
273
- }),
232
+ issuer: addressNotZeroSchema,
233
+ recipient: addressNotZeroSchema,
274
234
  name: z.string().optional().default("Unnamed Permit"),
275
- expiration: z.number().optional().default(DEFAULT_EXPIRATION_FN),
276
- validatorId: z.number().optional().default(0),
277
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
278
- message: "Import permit validatorContract :: invalid address"
279
- }),
280
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
281
- message: "Import permit recipientSignature :: must be 0x prefixed"
282
- })
283
- }).refine(...ValidatorContractRefinement);
235
+ expiration: z.int(),
236
+ validatorId: z.int().optional().default(0),
237
+ validatorContract: addressSchema.optional().default(zeroAddress),
238
+ issuerSignature: bytesNotEmptySchema,
239
+ recipientSignature: bytesSchema.optional().default("0x")
240
+ }).refine(...ExternalValidatorRefinement);
284
241
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
285
- message: "Import permit :: type must be 'recipient'"
242
+ error: "Type must be 'recipient'"
286
243
  }).refine((data) => data.recipient !== zeroAddress, {
287
- message: "Import permit :: recipient must not be zeroAddress"
244
+ error: "Recipient must not be zeroAddress"
288
245
  }).refine((data) => data.issuerSignature !== "0x", {
289
- message: "Import permit :: issuerSignature must be populated"
246
+ error: "IssuerSignature must be populated"
290
247
  }).refine((data) => data.recipientSignature !== "0x", {
291
- message: "Import permit :: recipientSignature must be populated"
292
- }).refine(...ValidatorContractRefinement);
293
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
294
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
295
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
296
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
297
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
298
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
248
+ error: "RecipientSignature must be populated"
249
+ }).refine(...ExternalValidatorRefinement);
250
+ var safeParseAndThrowFormatted = (schema, data, message) => {
251
+ const result = schema.safeParse(data);
252
+ if (!result.success) {
253
+ throw new Error(`${message}: ${z.prettifyError(result.error)}`, { cause: result.error });
254
+ }
255
+ return result.data;
256
+ };
257
+ var validateSelfPermitOptions = (options) => {
258
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
259
+ };
260
+ var validateSharingPermitOptions = (options) => {
261
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
262
+ };
263
+ var validateImportPermitOptions = (options) => {
264
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
265
+ };
266
+ var validateSelfPermit = (permit) => {
267
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
268
+ };
269
+ var validateSharingPermit = (permit) => {
270
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
271
+ };
272
+ var validateImportPermit = (permit) => {
273
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
274
+ };
299
275
  var ValidationUtils = {
300
276
  /**
301
277
  * Check if permit is expired
@@ -390,6 +366,190 @@ var SignatureUtils = {
390
366
  }
391
367
  };
392
368
 
369
+ // core/consts.ts
370
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
371
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
372
+ var MOCKS_THRESHOLD_NETWORK_ADDRESS = "0x0000000000000000000000000000000000005002";
373
+ var TEST_BED_ADDRESS = "0x0000000000000000000000000000000000005003";
374
+ var MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY = "0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512";
375
+ var MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = "0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2";
376
+ var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
377
+
378
+ // permits/onchain-utils.ts
379
+ var getAclAddress = async (publicClient) => {
380
+ const ACL_IFACE = "function acl() view returns (address)";
381
+ const aclAbi = parseAbi([ACL_IFACE]);
382
+ return await publicClient.readContract({
383
+ address: TASK_MANAGER_ADDRESS,
384
+ abi: aclAbi,
385
+ functionName: "acl"
386
+ });
387
+ };
388
+ var getAclEIP712Domain = async (publicClient) => {
389
+ const aclAddress = await getAclAddress(publicClient);
390
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
391
+ const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
392
+ const domain = await publicClient.readContract({
393
+ address: aclAddress,
394
+ abi: domainAbi,
395
+ functionName: "eip712Domain"
396
+ });
397
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
398
+ return {
399
+ name,
400
+ version,
401
+ chainId: Number(chainId),
402
+ verifyingContract
403
+ };
404
+ };
405
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
406
+ const aclAddress = await getAclAddress(publicClient);
407
+ try {
408
+ await publicClient.simulateContract({
409
+ address: aclAddress,
410
+ abi: checkPermitValidityAbi,
411
+ functionName: "checkPermitValidity",
412
+ args: [
413
+ {
414
+ issuer: permission.issuer,
415
+ expiration: BigInt(permission.expiration),
416
+ recipient: permission.recipient,
417
+ validatorId: BigInt(permission.validatorId),
418
+ validatorContract: permission.validatorContract,
419
+ sealingKey: permission.sealingKey,
420
+ issuerSignature: permission.issuerSignature,
421
+ recipientSignature: permission.recipientSignature
422
+ }
423
+ ]
424
+ });
425
+ return true;
426
+ } catch (err) {
427
+ if (err instanceof BaseError) {
428
+ const revertError = err.walk((err2) => err2 instanceof ContractFunctionRevertedError);
429
+ if (revertError instanceof ContractFunctionRevertedError) {
430
+ const errorName = revertError.data?.errorName ?? "";
431
+ throw new Error(errorName);
432
+ }
433
+ }
434
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
435
+ if (customErrorName) {
436
+ throw new Error(customErrorName);
437
+ }
438
+ const hhDetailsData = extractReturnData(err);
439
+ if (hhDetailsData != null) {
440
+ const decoded = decodeErrorResult({
441
+ abi: checkPermitValidityAbi,
442
+ data: hhDetailsData
443
+ });
444
+ throw new Error(decoded.errorName);
445
+ }
446
+ throw err;
447
+ }
448
+ };
449
+ function extractCustomErrorFromDetails(err, abi) {
450
+ const anyErr = err;
451
+ const details = anyErr?.details ?? anyErr?.cause?.details;
452
+ if (typeof details === "string") {
453
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
454
+ if (customErrorMatch) {
455
+ const errorName = customErrorMatch[1];
456
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
457
+ if (errorExists) {
458
+ return errorName;
459
+ }
460
+ }
461
+ }
462
+ return void 0;
463
+ }
464
+ function extractReturnData(err) {
465
+ const anyErr = err;
466
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
467
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
468
+ }
469
+ var checkPermitValidityAbi = [
470
+ {
471
+ type: "function",
472
+ name: "checkPermitValidity",
473
+ inputs: [
474
+ {
475
+ name: "permission",
476
+ type: "tuple",
477
+ internalType: "struct Permission",
478
+ components: [
479
+ {
480
+ name: "issuer",
481
+ type: "address",
482
+ internalType: "address"
483
+ },
484
+ {
485
+ name: "expiration",
486
+ type: "uint64",
487
+ internalType: "uint64"
488
+ },
489
+ {
490
+ name: "recipient",
491
+ type: "address",
492
+ internalType: "address"
493
+ },
494
+ {
495
+ name: "validatorId",
496
+ type: "uint256",
497
+ internalType: "uint256"
498
+ },
499
+ {
500
+ name: "validatorContract",
501
+ type: "address",
502
+ internalType: "address"
503
+ },
504
+ {
505
+ name: "sealingKey",
506
+ type: "bytes32",
507
+ internalType: "bytes32"
508
+ },
509
+ {
510
+ name: "issuerSignature",
511
+ type: "bytes",
512
+ internalType: "bytes"
513
+ },
514
+ {
515
+ name: "recipientSignature",
516
+ type: "bytes",
517
+ internalType: "bytes"
518
+ }
519
+ ]
520
+ }
521
+ ],
522
+ outputs: [
523
+ {
524
+ name: "",
525
+ type: "bool",
526
+ internalType: "bool"
527
+ }
528
+ ],
529
+ stateMutability: "view"
530
+ },
531
+ {
532
+ type: "error",
533
+ name: "PermissionInvalid_Disabled",
534
+ inputs: []
535
+ },
536
+ {
537
+ type: "error",
538
+ name: "PermissionInvalid_Expired",
539
+ inputs: []
540
+ },
541
+ {
542
+ type: "error",
543
+ name: "PermissionInvalid_IssuerSignature",
544
+ inputs: []
545
+ },
546
+ {
547
+ type: "error",
548
+ name: "PermissionInvalid_RecipientSignature",
549
+ inputs: []
550
+ }
551
+ ];
552
+
393
553
  // permits/permit.ts
394
554
  var PermitUtils = {
395
555
  /**
@@ -397,14 +557,10 @@ var PermitUtils = {
397
557
  */
398
558
  createSelf: (options) => {
399
559
  const validation = validateSelfPermitOptions(options);
400
- if (!validation.success) {
401
- throw new Error(
402
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
403
- );
404
- }
405
560
  const sealingPair = GenerateSealingKey();
406
561
  const permit = {
407
- ...validation.data,
562
+ hash: PermitUtils.getHash(validation),
563
+ ...validation,
408
564
  sealingPair,
409
565
  _signedDomain: void 0
410
566
  };
@@ -415,14 +571,10 @@ var PermitUtils = {
415
571
  */
416
572
  createSharing: (options) => {
417
573
  const validation = validateSharingPermitOptions(options);
418
- if (!validation.success) {
419
- throw new Error(
420
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
421
- );
422
- }
423
574
  const sealingPair = GenerateSealingKey();
424
575
  const permit = {
425
- ...validation.data,
576
+ hash: PermitUtils.getHash(validation),
577
+ ...validation,
426
578
  sealingPair,
427
579
  _signedDomain: void 0
428
580
  };
@@ -437,27 +589,21 @@ var PermitUtils = {
437
589
  try {
438
590
  parsedOptions = JSON.parse(options);
439
591
  } catch (error) {
440
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
592
+ throw new Error(`Failed to parse JSON string: ${error}`);
441
593
  }
442
594
  } else if (typeof options === "object" && options !== null) {
443
595
  parsedOptions = options;
444
596
  } else {
445
- throw new Error(
446
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
447
- );
597
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
448
598
  }
449
599
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
450
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
600
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
451
601
  }
452
602
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
453
- if (!validation.success) {
454
- throw new Error(
455
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
456
- );
457
- }
458
603
  const sealingPair = GenerateSealingKey();
459
604
  const permit = {
460
- ...validation.data,
605
+ hash: PermitUtils.getHash(validation),
606
+ ...validation,
461
607
  sealingPair,
462
608
  _signedDomain: void 0
463
609
  };
@@ -469,11 +615,11 @@ var PermitUtils = {
469
615
  sign: async (permit, publicClient, walletClient) => {
470
616
  if (walletClient == null || walletClient.account == null) {
471
617
  throw new Error(
472
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
618
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
473
619
  );
474
620
  }
475
621
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
476
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
622
+ const domain = await getAclEIP712Domain(publicClient);
477
623
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
478
624
  const signature = await walletClient.signTypedData({
479
625
  domain,
@@ -533,6 +679,7 @@ var PermitUtils = {
533
679
  */
534
680
  serialize: (permit) => {
535
681
  return {
682
+ hash: permit.hash,
536
683
  name: permit.name,
537
684
  type: permit.type,
538
685
  issuer: permit.issuer,
@@ -557,7 +704,7 @@ var PermitUtils = {
557
704
  } else if (permit.type === "recipient") {
558
705
  return validateImportPermit(permit);
559
706
  } else {
560
- throw new Error("PermitUtils :: validate :: Invalid permit type");
707
+ throw new Error("Invalid permit type");
561
708
  }
562
709
  },
563
710
  /**
@@ -565,12 +712,7 @@ var PermitUtils = {
565
712
  */
566
713
  getPermission: (permit, skipValidation = false) => {
567
714
  if (!skipValidation) {
568
- const validationResult = PermitUtils.validate(permit);
569
- if (!validationResult.success) {
570
- throw new Error(
571
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
572
- );
573
- }
715
+ PermitUtils.validate(permit);
574
716
  }
575
717
  return {
576
718
  issuer: permit.issuer,
@@ -651,28 +793,7 @@ var PermitUtils = {
651
793
  * Fetch EIP712 domain from the blockchain
652
794
  */
653
795
  fetchEIP712Domain: async (publicClient) => {
654
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
655
- const ACL_IFACE = "function acl() view returns (address)";
656
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
657
- const aclAbi = parseAbi([ACL_IFACE]);
658
- const aclAddress = await publicClient.readContract({
659
- address: TASK_MANAGER_ADDRESS,
660
- abi: aclAbi,
661
- functionName: "acl"
662
- });
663
- const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
664
- const domain = await publicClient.readContract({
665
- address: aclAddress,
666
- abi: domainAbi,
667
- functionName: "eip712Domain"
668
- });
669
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
670
- return {
671
- name,
672
- version,
673
- chainId: Number(chainId),
674
- verifyingContract
675
- };
796
+ return getAclEIP712Domain(publicClient);
676
797
  },
677
798
  /**
678
799
  * Check if permit's signed domain matches the provided domain
@@ -686,8 +807,15 @@ var PermitUtils = {
686
807
  checkSignedDomainValid: async (permit, publicClient) => {
687
808
  if (permit._signedDomain == null)
688
809
  return false;
689
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
810
+ const domain = await getAclEIP712Domain(publicClient);
690
811
  return PermitUtils.matchesDomain(permit, domain);
812
+ },
813
+ /**
814
+ * Check if permit passes the on-chain validation
815
+ */
816
+ checkValidityOnChain: async (permit, publicClient) => {
817
+ const permission = PermitUtils.getPermission(permit);
818
+ return checkPermitValidityOnChain(permission, publicClient);
691
819
  }
692
820
  };
693
821
  var PERMIT_STORE_DEFAULTS = {
@@ -741,11 +869,11 @@ var setPermit = (chainId, account, permit) => {
741
869
  state.permits[chainId] = {};
742
870
  if (state.permits[chainId][account] == null)
743
871
  state.permits[chainId][account] = {};
744
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
872
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
745
873
  })
746
874
  );
747
875
  };
748
- var removePermit = (chainId, account, hash, force) => {
876
+ var removePermit = (chainId, account, hash) => {
749
877
  clearStaleStore();
750
878
  _permitStore.setState(
751
879
  produce((state) => {
@@ -759,15 +887,7 @@ var removePermit = (chainId, account, hash, force) => {
759
887
  if (accountPermits[hash] == null)
760
888
  return;
761
889
  if (state.activePermitHash[chainId][account] === hash) {
762
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
763
- if (otherPermitHash) {
764
- state.activePermitHash[chainId][account] = otherPermitHash;
765
- } else {
766
- if (!force) {
767
- throw new Error("Cannot remove the last permit without force flag");
768
- }
769
- state.activePermitHash[chainId][account] = void 0;
770
- }
890
+ state.activePermitHash[chainId][account] = void 0;
771
891
  }
772
892
  accountPermits[hash] = void 0;
773
893
  })
@@ -815,4 +935,4 @@ var permitStore = {
815
935
  resetStore
816
936
  };
817
937
 
818
- export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, PERMIT_STORE_DEFAULTS, PermitUtils, SealingKey, SelfPermitOptionsValidator, SelfPermitValidator, SharingPermitOptionsValidator, SharingPermitValidator, SignatureTypes, SignatureUtils, ValidationUtils, _permitStore, clearStaleStore, getActivePermit, getActivePermitHash, getPermit, getPermits, getSignatureTypesAndMessage, permitStore, removeActivePermitHash, removePermit, resetStore, setActivePermitHash, setPermit, validateImportPermit, validateImportPermitOptions, validateSelfPermit, validateSelfPermitOptions, validateSharingPermit, validateSharingPermitOptions };
938
+ export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_THRESHOLD_NETWORK_ADDRESS, MOCKS_ZK_VERIFIER_ADDRESS, MOCKS_ZK_VERIFIER_SIGNER_ADDRESS, MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, PERMIT_STORE_DEFAULTS, PermitUtils, SealingKey, SelfPermitOptionsValidator, SelfPermitValidator, SharingPermitOptionsValidator, SharingPermitValidator, SignatureTypes, SignatureUtils, TASK_MANAGER_ADDRESS, TEST_BED_ADDRESS, ValidationUtils, _permitStore, addressNotZeroSchema, addressSchema, bytesNotEmptySchema, bytesSchema, clearStaleStore, getActivePermit, getActivePermitHash, getPermit, getPermits, getSignatureTypesAndMessage, permitStore, removeActivePermitHash, removePermit, resetStore, setActivePermitHash, setPermit, validateImportPermit, validateImportPermitOptions, validateSelfPermit, validateSelfPermitOptions, validateSharingPermit, validateSharingPermitOptions };