@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
package/dist/permits.cjs CHANGED
@@ -76,9 +76,6 @@ function isBigIntOrNumber(value) {
76
76
  }
77
77
  }
78
78
  }
79
- function is0xPrefixed(value) {
80
- return value.startsWith("0x");
81
- }
82
79
 
83
80
  // permits/sealing.ts
84
81
  var PRIVATE_KEY_LENGTH = 64;
@@ -166,158 +163,137 @@ var SerializedSealingPair = zod.z.object({
166
163
  privateKey: zod.z.string(),
167
164
  publicKey: zod.z.string()
168
165
  });
166
+ var addressSchema = zod.z.string().refine((val) => viem.isAddress(val), {
167
+ error: "Invalid address"
168
+ }).transform((val) => viem.getAddress(val));
169
+ var addressNotZeroSchema = addressSchema.refine((val) => val !== viem.zeroAddress, {
170
+ error: "Must not be zeroAddress"
171
+ });
172
+ var bytesSchema = zod.z.custom(
173
+ (val) => {
174
+ return typeof val === "string" && viem.isHex(val);
175
+ },
176
+ {
177
+ message: "Invalid hex value"
178
+ }
179
+ );
180
+ var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
181
+ error: "Must not be empty"
182
+ });
169
183
  var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
170
184
  var zPermitWithDefaults = zod.z.object({
171
185
  name: zod.z.string().optional().default("Unnamed Permit"),
172
186
  type: zod.z.enum(["self", "sharing", "recipient"]),
173
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
174
- message: "Permit issuer :: invalid address"
175
- }).refine((val) => val !== viem.zeroAddress, {
176
- message: "Permit issuer :: must not be zeroAddress"
177
- }),
178
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
179
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
180
- message: "Permit recipient :: invalid address"
181
- }),
182
- validatorId: zod.z.number().optional().default(0),
183
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
184
- message: "Permit validatorContract :: invalid address"
185
- }),
186
- issuerSignature: zod.z.string().optional().default("0x"),
187
- recipientSignature: zod.z.string().optional().default("0x")
187
+ issuer: addressNotZeroSchema,
188
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
189
+ recipient: addressSchema.optional().default(viem.zeroAddress),
190
+ validatorId: zod.z.int().optional().default(0),
191
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
192
+ issuerSignature: bytesSchema.optional().default("0x"),
193
+ recipientSignature: bytesSchema.optional().default("0x")
188
194
  });
189
195
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
190
196
  sealingPair: SerializedSealingPair.optional()
191
197
  });
192
- var ValidatorContractRefinement = [
198
+ var ExternalValidatorRefinement = [
193
199
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
194
200
  {
195
- message: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
201
+ error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
196
202
  path: ["validatorId", "validatorContract"]
197
203
  }
198
204
  ];
205
+ var RecipientRefinement = [
206
+ (data) => data.issuer !== data.recipient,
207
+ {
208
+ error: "Sharing permit :: issuer and recipient must not be the same",
209
+ path: ["issuer", "recipient"]
210
+ }
211
+ ];
199
212
  var SelfPermitOptionsValidator = zod.z.object({
200
213
  type: zod.z.literal("self").optional().default("self"),
201
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
202
- message: "Self permit issuer :: invalid address"
203
- }).refine((val) => is0xPrefixed(val), {
204
- message: "Self permit issuer :: must be 0x prefixed"
205
- }).refine((val) => val !== viem.zeroAddress, {
206
- message: "Self permit issuer :: must not be zeroAddress"
207
- }),
214
+ issuer: addressNotZeroSchema,
208
215
  name: zod.z.string().optional().default("Unnamed Permit"),
209
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
210
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
211
- message: "Self permit recipient :: invalid address"
212
- }).refine((val) => is0xPrefixed(val), {
213
- message: "Self permit recipient :: must be 0x prefixed"
214
- }).refine((val) => val === viem.zeroAddress, {
215
- message: "Self permit recipient :: must be zeroAddress"
216
- }),
217
- validatorId: zod.z.number().optional().default(0),
218
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
219
- message: "Self permit validatorContract :: invalid address"
220
- }),
221
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
222
- message: "Self permit issuerSignature :: must be 0x prefixed"
223
- }),
224
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
225
- message: "Self permit recipientSignature :: must be 0x prefixed"
226
- })
227
- }).refine(...ValidatorContractRefinement);
216
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
217
+ recipient: addressSchema.optional().default(viem.zeroAddress),
218
+ validatorId: zod.z.int().optional().default(0),
219
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
220
+ issuerSignature: bytesSchema.optional().default("0x"),
221
+ recipientSignature: bytesSchema.optional().default("0x")
222
+ }).refine(...ExternalValidatorRefinement);
228
223
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
229
- message: "Self permit :: type must be 'self'"
224
+ error: "Type must be 'self'"
230
225
  }).refine((data) => data.recipient === viem.zeroAddress, {
231
- message: "Self permit :: recipient must be zeroAddress"
226
+ error: "Recipient must be zeroAddress"
232
227
  }).refine((data) => data.issuerSignature !== "0x", {
233
- message: "Self permit :: issuerSignature must be populated"
228
+ error: "IssuerSignature must be populated"
234
229
  }).refine((data) => data.recipientSignature === "0x", {
235
- message: "Self permit :: recipientSignature must be empty"
236
- }).refine(...ValidatorContractRefinement);
230
+ error: "RecipientSignature must be empty"
231
+ }).refine(...ExternalValidatorRefinement);
237
232
  var SharingPermitOptionsValidator = zod.z.object({
238
233
  type: zod.z.literal("sharing").optional().default("sharing"),
239
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
240
- message: "Sharing permit issuer :: invalid address"
241
- }).refine((val) => is0xPrefixed(val), {
242
- message: "Sharing permit issuer :: must be 0x prefixed"
243
- }).refine((val) => val !== viem.zeroAddress, {
244
- message: "Sharing permit issuer :: must not be zeroAddress"
245
- }),
246
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
247
- message: "Sharing permit recipient :: invalid address"
248
- }).refine((val) => is0xPrefixed(val), {
249
- message: "Sharing permit recipient :: must be 0x prefixed"
250
- }).refine((val) => val !== viem.zeroAddress, {
251
- message: "Sharing permit recipient :: must not be zeroAddress"
252
- }),
234
+ issuer: addressNotZeroSchema,
235
+ recipient: addressNotZeroSchema,
253
236
  name: zod.z.string().optional().default("Unnamed Permit"),
254
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
255
- validatorId: zod.z.number().optional().default(0),
256
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
257
- message: "Sharing permit validatorContract :: invalid address"
258
- }),
259
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
260
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
261
- }),
262
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
263
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
264
- })
265
- }).refine(...ValidatorContractRefinement);
237
+ expiration: zod.z.int().optional().default(DEFAULT_EXPIRATION_FN),
238
+ validatorId: zod.z.int().optional().default(0),
239
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
240
+ issuerSignature: bytesSchema.optional().default("0x"),
241
+ recipientSignature: bytesSchema.optional().default("0x")
242
+ }).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
266
243
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
267
- message: "Sharing permit :: type must be 'sharing'"
244
+ error: "Type must be 'sharing'"
268
245
  }).refine((data) => data.recipient !== viem.zeroAddress, {
269
- message: "Sharing permit :: recipient must not be zeroAddress"
246
+ error: "Recipient must not be zeroAddress"
270
247
  }).refine((data) => data.issuerSignature !== "0x", {
271
- message: "Sharing permit :: issuerSignature must be populated"
248
+ error: "IssuerSignature must be populated"
272
249
  }).refine((data) => data.recipientSignature === "0x", {
273
- message: "Sharing permit :: recipientSignature must be empty"
274
- }).refine(...ValidatorContractRefinement);
250
+ error: "RecipientSignature must be empty"
251
+ }).refine(...ExternalValidatorRefinement);
275
252
  var ImportPermitOptionsValidator = zod.z.object({
276
253
  type: zod.z.literal("recipient").optional().default("recipient"),
277
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
278
- message: "Import permit issuer :: invalid address"
279
- }).refine((val) => is0xPrefixed(val), {
280
- message: "Import permit issuer :: must be 0x prefixed"
281
- }).refine((val) => val !== viem.zeroAddress, {
282
- message: "Import permit issuer :: must not be zeroAddress"
283
- }),
284
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
285
- message: "Import permit recipient :: invalid address"
286
- }).refine((val) => is0xPrefixed(val), {
287
- message: "Import permit recipient :: must be 0x prefixed"
288
- }).refine((val) => val !== viem.zeroAddress, {
289
- message: "Import permit recipient :: must not be zeroAddress"
290
- }),
291
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
292
- message: "Import permit issuerSignature :: must be 0x prefixed"
293
- }).refine((val) => val !== "0x", {
294
- message: "Import permit :: issuerSignature must be provided"
295
- }),
254
+ issuer: addressNotZeroSchema,
255
+ recipient: addressNotZeroSchema,
296
256
  name: zod.z.string().optional().default("Unnamed Permit"),
297
- expiration: zod.z.number().optional().default(DEFAULT_EXPIRATION_FN),
298
- validatorId: zod.z.number().optional().default(0),
299
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
300
- message: "Import permit validatorContract :: invalid address"
301
- }),
302
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
303
- message: "Import permit recipientSignature :: must be 0x prefixed"
304
- })
305
- }).refine(...ValidatorContractRefinement);
257
+ expiration: zod.z.int(),
258
+ validatorId: zod.z.int().optional().default(0),
259
+ validatorContract: addressSchema.optional().default(viem.zeroAddress),
260
+ issuerSignature: bytesNotEmptySchema,
261
+ recipientSignature: bytesSchema.optional().default("0x")
262
+ }).refine(...ExternalValidatorRefinement);
306
263
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
307
- message: "Import permit :: type must be 'recipient'"
264
+ error: "Type must be 'recipient'"
308
265
  }).refine((data) => data.recipient !== viem.zeroAddress, {
309
- message: "Import permit :: recipient must not be zeroAddress"
266
+ error: "Recipient must not be zeroAddress"
310
267
  }).refine((data) => data.issuerSignature !== "0x", {
311
- message: "Import permit :: issuerSignature must be populated"
268
+ error: "IssuerSignature must be populated"
312
269
  }).refine((data) => data.recipientSignature !== "0x", {
313
- message: "Import permit :: recipientSignature must be populated"
314
- }).refine(...ValidatorContractRefinement);
315
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
316
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
317
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
318
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
319
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
320
- var validateImportPermit = (permit) => ImportPermitValidator.safeParse(permit);
270
+ error: "RecipientSignature must be populated"
271
+ }).refine(...ExternalValidatorRefinement);
272
+ var safeParseAndThrowFormatted = (schema, data, message) => {
273
+ const result = schema.safeParse(data);
274
+ if (!result.success) {
275
+ throw new Error(`${message}: ${zod.z.prettifyError(result.error)}`, { cause: result.error });
276
+ }
277
+ return result.data;
278
+ };
279
+ var validateSelfPermitOptions = (options) => {
280
+ return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
281
+ };
282
+ var validateSharingPermitOptions = (options) => {
283
+ return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
284
+ };
285
+ var validateImportPermitOptions = (options) => {
286
+ return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
287
+ };
288
+ var validateSelfPermit = (permit) => {
289
+ return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
290
+ };
291
+ var validateSharingPermit = (permit) => {
292
+ return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
293
+ };
294
+ var validateImportPermit = (permit) => {
295
+ return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
296
+ };
321
297
  var ValidationUtils = {
322
298
  /**
323
299
  * Check if permit is expired
@@ -412,6 +388,184 @@ var SignatureUtils = {
412
388
  }
413
389
  };
414
390
 
391
+ // core/consts.ts
392
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
393
+
394
+ // permits/onchain-utils.ts
395
+ var getAclAddress = async (publicClient) => {
396
+ const ACL_IFACE = "function acl() view returns (address)";
397
+ const aclAbi = viem.parseAbi([ACL_IFACE]);
398
+ return await publicClient.readContract({
399
+ address: TASK_MANAGER_ADDRESS,
400
+ abi: aclAbi,
401
+ functionName: "acl"
402
+ });
403
+ };
404
+ var getAclEIP712Domain = async (publicClient) => {
405
+ const aclAddress = await getAclAddress(publicClient);
406
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
407
+ const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
408
+ const domain = await publicClient.readContract({
409
+ address: aclAddress,
410
+ abi: domainAbi,
411
+ functionName: "eip712Domain"
412
+ });
413
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
414
+ return {
415
+ name,
416
+ version,
417
+ chainId: Number(chainId),
418
+ verifyingContract
419
+ };
420
+ };
421
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
422
+ const aclAddress = await getAclAddress(publicClient);
423
+ try {
424
+ await publicClient.simulateContract({
425
+ address: aclAddress,
426
+ abi: checkPermitValidityAbi,
427
+ functionName: "checkPermitValidity",
428
+ args: [
429
+ {
430
+ issuer: permission.issuer,
431
+ expiration: BigInt(permission.expiration),
432
+ recipient: permission.recipient,
433
+ validatorId: BigInt(permission.validatorId),
434
+ validatorContract: permission.validatorContract,
435
+ sealingKey: permission.sealingKey,
436
+ issuerSignature: permission.issuerSignature,
437
+ recipientSignature: permission.recipientSignature
438
+ }
439
+ ]
440
+ });
441
+ return true;
442
+ } catch (err) {
443
+ if (err instanceof viem.BaseError) {
444
+ const revertError = err.walk((err2) => err2 instanceof viem.ContractFunctionRevertedError);
445
+ if (revertError instanceof viem.ContractFunctionRevertedError) {
446
+ const errorName = revertError.data?.errorName ?? "";
447
+ throw new Error(errorName);
448
+ }
449
+ }
450
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
451
+ if (customErrorName) {
452
+ throw new Error(customErrorName);
453
+ }
454
+ const hhDetailsData = extractReturnData(err);
455
+ if (hhDetailsData != null) {
456
+ const decoded = viem.decodeErrorResult({
457
+ abi: checkPermitValidityAbi,
458
+ data: hhDetailsData
459
+ });
460
+ throw new Error(decoded.errorName);
461
+ }
462
+ throw err;
463
+ }
464
+ };
465
+ function extractCustomErrorFromDetails(err, abi) {
466
+ const anyErr = err;
467
+ const details = anyErr?.details ?? anyErr?.cause?.details;
468
+ if (typeof details === "string") {
469
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
470
+ if (customErrorMatch) {
471
+ const errorName = customErrorMatch[1];
472
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
473
+ if (errorExists) {
474
+ return errorName;
475
+ }
476
+ }
477
+ }
478
+ return void 0;
479
+ }
480
+ function extractReturnData(err) {
481
+ const anyErr = err;
482
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
483
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
484
+ }
485
+ var checkPermitValidityAbi = [
486
+ {
487
+ type: "function",
488
+ name: "checkPermitValidity",
489
+ inputs: [
490
+ {
491
+ name: "permission",
492
+ type: "tuple",
493
+ internalType: "struct Permission",
494
+ components: [
495
+ {
496
+ name: "issuer",
497
+ type: "address",
498
+ internalType: "address"
499
+ },
500
+ {
501
+ name: "expiration",
502
+ type: "uint64",
503
+ internalType: "uint64"
504
+ },
505
+ {
506
+ name: "recipient",
507
+ type: "address",
508
+ internalType: "address"
509
+ },
510
+ {
511
+ name: "validatorId",
512
+ type: "uint256",
513
+ internalType: "uint256"
514
+ },
515
+ {
516
+ name: "validatorContract",
517
+ type: "address",
518
+ internalType: "address"
519
+ },
520
+ {
521
+ name: "sealingKey",
522
+ type: "bytes32",
523
+ internalType: "bytes32"
524
+ },
525
+ {
526
+ name: "issuerSignature",
527
+ type: "bytes",
528
+ internalType: "bytes"
529
+ },
530
+ {
531
+ name: "recipientSignature",
532
+ type: "bytes",
533
+ internalType: "bytes"
534
+ }
535
+ ]
536
+ }
537
+ ],
538
+ outputs: [
539
+ {
540
+ name: "",
541
+ type: "bool",
542
+ internalType: "bool"
543
+ }
544
+ ],
545
+ stateMutability: "view"
546
+ },
547
+ {
548
+ type: "error",
549
+ name: "PermissionInvalid_Disabled",
550
+ inputs: []
551
+ },
552
+ {
553
+ type: "error",
554
+ name: "PermissionInvalid_Expired",
555
+ inputs: []
556
+ },
557
+ {
558
+ type: "error",
559
+ name: "PermissionInvalid_IssuerSignature",
560
+ inputs: []
561
+ },
562
+ {
563
+ type: "error",
564
+ name: "PermissionInvalid_RecipientSignature",
565
+ inputs: []
566
+ }
567
+ ];
568
+
415
569
  // permits/permit.ts
416
570
  var PermitUtils = {
417
571
  /**
@@ -419,14 +573,10 @@ var PermitUtils = {
419
573
  */
420
574
  createSelf: (options) => {
421
575
  const validation = validateSelfPermitOptions(options);
422
- if (!validation.success) {
423
- throw new Error(
424
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
425
- );
426
- }
427
576
  const sealingPair = GenerateSealingKey();
428
577
  const permit = {
429
- ...validation.data,
578
+ hash: PermitUtils.getHash(validation),
579
+ ...validation,
430
580
  sealingPair,
431
581
  _signedDomain: void 0
432
582
  };
@@ -437,14 +587,10 @@ var PermitUtils = {
437
587
  */
438
588
  createSharing: (options) => {
439
589
  const validation = validateSharingPermitOptions(options);
440
- if (!validation.success) {
441
- throw new Error(
442
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
443
- );
444
- }
445
590
  const sealingPair = GenerateSealingKey();
446
591
  const permit = {
447
- ...validation.data,
592
+ hash: PermitUtils.getHash(validation),
593
+ ...validation,
448
594
  sealingPair,
449
595
  _signedDomain: void 0
450
596
  };
@@ -459,27 +605,21 @@ var PermitUtils = {
459
605
  try {
460
606
  parsedOptions = JSON.parse(options);
461
607
  } catch (error) {
462
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
608
+ throw new Error(`Failed to parse JSON string: ${error}`);
463
609
  }
464
610
  } else if (typeof options === "object" && options !== null) {
465
611
  parsedOptions = options;
466
612
  } else {
467
- throw new Error(
468
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
469
- );
613
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
470
614
  }
471
615
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
472
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
616
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
473
617
  }
474
618
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
475
- if (!validation.success) {
476
- throw new Error(
477
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
478
- );
479
- }
480
619
  const sealingPair = GenerateSealingKey();
481
620
  const permit = {
482
- ...validation.data,
621
+ hash: PermitUtils.getHash(validation),
622
+ ...validation,
483
623
  sealingPair,
484
624
  _signedDomain: void 0
485
625
  };
@@ -491,11 +631,11 @@ var PermitUtils = {
491
631
  sign: async (permit, publicClient, walletClient) => {
492
632
  if (walletClient == null || walletClient.account == null) {
493
633
  throw new Error(
494
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
634
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
495
635
  );
496
636
  }
497
637
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
498
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
638
+ const domain = await getAclEIP712Domain(publicClient);
499
639
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
500
640
  const signature = await walletClient.signTypedData({
501
641
  domain,
@@ -555,6 +695,7 @@ var PermitUtils = {
555
695
  */
556
696
  serialize: (permit) => {
557
697
  return {
698
+ hash: permit.hash,
558
699
  name: permit.name,
559
700
  type: permit.type,
560
701
  issuer: permit.issuer,
@@ -579,7 +720,7 @@ var PermitUtils = {
579
720
  } else if (permit.type === "recipient") {
580
721
  return validateImportPermit(permit);
581
722
  } else {
582
- throw new Error("PermitUtils :: validate :: Invalid permit type");
723
+ throw new Error("Invalid permit type");
583
724
  }
584
725
  },
585
726
  /**
@@ -587,12 +728,7 @@ var PermitUtils = {
587
728
  */
588
729
  getPermission: (permit, skipValidation = false) => {
589
730
  if (!skipValidation) {
590
- const validationResult = PermitUtils.validate(permit);
591
- if (!validationResult.success) {
592
- throw new Error(
593
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
594
- );
595
- }
731
+ PermitUtils.validate(permit);
596
732
  }
597
733
  return {
598
734
  issuer: permit.issuer,
@@ -673,28 +809,7 @@ var PermitUtils = {
673
809
  * Fetch EIP712 domain from the blockchain
674
810
  */
675
811
  fetchEIP712Domain: async (publicClient) => {
676
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
677
- const ACL_IFACE = "function acl() view returns (address)";
678
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
679
- const aclAbi = viem.parseAbi([ACL_IFACE]);
680
- const aclAddress = await publicClient.readContract({
681
- address: TASK_MANAGER_ADDRESS,
682
- abi: aclAbi,
683
- functionName: "acl"
684
- });
685
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
686
- const domain = await publicClient.readContract({
687
- address: aclAddress,
688
- abi: domainAbi,
689
- functionName: "eip712Domain"
690
- });
691
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
692
- return {
693
- name,
694
- version,
695
- chainId: Number(chainId),
696
- verifyingContract
697
- };
812
+ return getAclEIP712Domain(publicClient);
698
813
  },
699
814
  /**
700
815
  * Check if permit's signed domain matches the provided domain
@@ -708,8 +823,15 @@ var PermitUtils = {
708
823
  checkSignedDomainValid: async (permit, publicClient) => {
709
824
  if (permit._signedDomain == null)
710
825
  return false;
711
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
826
+ const domain = await getAclEIP712Domain(publicClient);
712
827
  return PermitUtils.matchesDomain(permit, domain);
828
+ },
829
+ /**
830
+ * Check if permit passes the on-chain validation
831
+ */
832
+ checkValidityOnChain: async (permit, publicClient) => {
833
+ const permission = PermitUtils.getPermission(permit);
834
+ return checkPermitValidityOnChain(permission, publicClient);
713
835
  }
714
836
  };
715
837
  var PERMIT_STORE_DEFAULTS = {
@@ -763,11 +885,11 @@ var setPermit = (chainId, account, permit) => {
763
885
  state.permits[chainId] = {};
764
886
  if (state.permits[chainId][account] == null)
765
887
  state.permits[chainId][account] = {};
766
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
888
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
767
889
  })
768
890
  );
769
891
  };
770
- var removePermit = (chainId, account, hash, force) => {
892
+ var removePermit = (chainId, account, hash) => {
771
893
  clearStaleStore();
772
894
  _permitStore.setState(
773
895
  immer.produce((state) => {
@@ -781,15 +903,7 @@ var removePermit = (chainId, account, hash, force) => {
781
903
  if (accountPermits[hash] == null)
782
904
  return;
783
905
  if (state.activePermitHash[chainId][account] === hash) {
784
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
785
- if (otherPermitHash) {
786
- state.activePermitHash[chainId][account] = otherPermitHash;
787
- } else {
788
- if (!force) {
789
- throw new Error("Cannot remove the last permit without force flag");
790
- }
791
- state.activePermitHash[chainId][account] = void 0;
792
- }
906
+ state.activePermitHash[chainId][account] = void 0;
793
907
  }
794
908
  accountPermits[hash] = void 0;
795
909
  })
@@ -851,6 +965,10 @@ exports.SignatureTypes = SignatureTypes;
851
965
  exports.SignatureUtils = SignatureUtils;
852
966
  exports.ValidationUtils = ValidationUtils;
853
967
  exports._permitStore = _permitStore;
968
+ exports.addressNotZeroSchema = addressNotZeroSchema;
969
+ exports.addressSchema = addressSchema;
970
+ exports.bytesNotEmptySchema = bytesNotEmptySchema;
971
+ exports.bytesSchema = bytesSchema;
854
972
  exports.clearStaleStore = clearStaleStore;
855
973
  exports.getActivePermit = getActivePermit;
856
974
  exports.getActivePermitHash = getActivePermitHash;