@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.
Files changed (107) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/adapters/ethers6.ts +28 -28
  3. package/adapters/hardhat.ts +0 -1
  4. package/adapters/index.test.ts +14 -19
  5. package/adapters/smartWallet.ts +81 -73
  6. package/adapters/test-utils.ts +45 -45
  7. package/adapters/types.ts +3 -3
  8. package/chains/chains/localcofhe.ts +14 -0
  9. package/chains/chains.test.ts +2 -1
  10. package/chains/defineChain.ts +2 -2
  11. package/chains/index.ts +3 -1
  12. package/chains/types.ts +3 -3
  13. package/core/baseBuilder.ts +30 -49
  14. package/core/client.test.ts +200 -72
  15. package/core/client.ts +152 -148
  16. package/core/clientTypes.ts +114 -0
  17. package/core/config.test.ts +30 -11
  18. package/core/config.ts +26 -13
  19. package/core/consts.ts +18 -0
  20. package/core/decrypt/cofheMocksSealOutput.ts +2 -4
  21. package/core/decrypt/decryptHandleBuilder.ts +51 -45
  22. package/core/decrypt/{tnSealOutput.ts → tnSealOutputV1.ts} +1 -1
  23. package/core/decrypt/tnSealOutputV2.ts +298 -0
  24. package/core/encrypt/cofheMocksZkVerifySign.ts +15 -16
  25. package/core/encrypt/encryptInputsBuilder.test.ts +132 -116
  26. package/core/encrypt/encryptInputsBuilder.ts +159 -111
  27. package/core/encrypt/encryptUtils.ts +6 -3
  28. package/core/encrypt/zkPackProveVerify.ts +70 -8
  29. package/core/error.ts +0 -2
  30. package/core/fetchKeys.test.ts +1 -18
  31. package/core/fetchKeys.ts +0 -26
  32. package/core/index.ts +37 -17
  33. package/core/keyStore.ts +65 -38
  34. package/core/permits.test.ts +255 -4
  35. package/core/permits.ts +83 -18
  36. package/core/types.ts +198 -152
  37. package/core/utils.ts +43 -1
  38. package/dist/adapters.d.cts +38 -20
  39. package/dist/adapters.d.ts +38 -20
  40. package/dist/chains.cjs +18 -8
  41. package/dist/chains.d.cts +31 -9
  42. package/dist/chains.d.ts +31 -9
  43. package/dist/chains.js +1 -1
  44. package/dist/{chunk-KFGPTJ6X.js → chunk-I5WFEYXX.js} +1768 -1526
  45. package/dist/{chunk-LU7BMUUT.js → chunk-R3B5TMVX.js} +330 -197
  46. package/dist/{chunk-GZCQQYVI.js → chunk-TBLR7NNE.js} +18 -9
  47. package/dist/{types-PhwGgQvs.d.ts → clientTypes-RqkgkV2i.d.ts} +331 -429
  48. package/dist/{types-bB7wLj0q.d.cts → clientTypes-e4filDzK.d.cts} +331 -429
  49. package/dist/core.cjs +3000 -2625
  50. package/dist/core.d.cts +113 -7
  51. package/dist/core.d.ts +113 -7
  52. package/dist/core.js +3 -3
  53. package/dist/node.cjs +2851 -2526
  54. package/dist/node.d.cts +4 -4
  55. package/dist/node.d.ts +4 -4
  56. package/dist/node.js +4 -3
  57. package/dist/{permit-S9CnI6MF.d.cts → permit-MZ502UBl.d.cts} +54 -41
  58. package/dist/{permit-S9CnI6MF.d.ts → permit-MZ502UBl.d.ts} +54 -41
  59. package/dist/permits.cjs +328 -195
  60. package/dist/permits.d.cts +113 -825
  61. package/dist/permits.d.ts +113 -825
  62. package/dist/permits.js +1 -1
  63. package/dist/types-YiAC4gig.d.cts +33 -0
  64. package/dist/types-YiAC4gig.d.ts +33 -0
  65. package/dist/web.cjs +3067 -2527
  66. package/dist/web.d.cts +22 -6
  67. package/dist/web.d.ts +22 -6
  68. package/dist/web.js +185 -9
  69. package/dist/zkProve.worker.cjs +93 -0
  70. package/dist/zkProve.worker.d.cts +2 -0
  71. package/dist/zkProve.worker.d.ts +2 -0
  72. package/dist/zkProve.worker.js +91 -0
  73. package/node/client.test.ts +20 -25
  74. package/node/encryptInputs.test.ts +18 -38
  75. package/node/index.ts +1 -0
  76. package/package.json +15 -15
  77. package/permits/index.ts +1 -0
  78. package/permits/localstorage.test.ts +9 -14
  79. package/permits/onchain-utils.ts +221 -0
  80. package/permits/permit.test.ts +76 -27
  81. package/permits/permit.ts +58 -95
  82. package/permits/sealing.test.ts +3 -3
  83. package/permits/sealing.ts +2 -2
  84. package/permits/store.test.ts +10 -50
  85. package/permits/store.ts +9 -21
  86. package/permits/test-utils.ts +11 -3
  87. package/permits/types.ts +39 -9
  88. package/permits/utils.ts +0 -5
  89. package/permits/validation.test.ts +29 -32
  90. package/permits/validation.ts +114 -176
  91. package/web/client.web.test.ts +20 -25
  92. package/web/config.web.test.ts +0 -2
  93. package/web/encryptInputs.web.test.ts +31 -54
  94. package/web/index.ts +65 -1
  95. package/web/storage.ts +19 -5
  96. package/web/worker.builder.web.test.ts +148 -0
  97. package/web/worker.config.web.test.ts +329 -0
  98. package/web/worker.output.web.test.ts +84 -0
  99. package/web/workerManager.test.ts +80 -0
  100. package/web/workerManager.ts +214 -0
  101. package/web/workerManager.web.test.ts +114 -0
  102. package/web/zkProve.worker.ts +133 -0
  103. package/core/result.test.ts +0 -180
  104. package/core/result.ts +0 -67
  105. package/core/test-utils.ts +0 -45
  106. package/dist/types-KImPrEIe.d.cts +0 -48
  107. 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;
@@ -158,7 +155,7 @@ var SealingKey = class _SealingKey {
158
155
  };
159
156
  };
160
157
  };
161
- var GenerateSealingKey = async () => {
158
+ var GenerateSealingKey = () => {
162
159
  const sodiumKeypair = nacl__namespace.box.keyPair();
163
160
  return new SealingKey(toHexString(sodiumKeypair.secretKey), toHexString(sodiumKeypair.publicKey));
164
161
  };
@@ -166,145 +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
+ });
183
+ var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
169
184
  var zPermitWithDefaults = zod.z.object({
170
185
  name: zod.z.string().optional().default("Unnamed Permit"),
171
186
  type: zod.z.enum(["self", "sharing", "recipient"]),
172
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
173
- message: "Permit issuer :: invalid address"
174
- }).refine((val) => val !== viem.zeroAddress, {
175
- message: "Permit issuer :: must not be zeroAddress"
176
- }),
177
- expiration: zod.z.number().optional().default(1e12),
178
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
179
- message: "Permit recipient :: invalid address"
180
- }),
181
- validatorId: zod.z.number().optional().default(0),
182
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
183
- message: "Permit validatorContract :: invalid address"
184
- }),
185
- issuerSignature: zod.z.string().optional().default("0x"),
186
- 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")
187
194
  });
188
195
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
189
196
  sealingPair: SerializedSealingPair.optional()
190
197
  });
191
- var ValidatorContractRefinement = [
198
+ var ExternalValidatorRefinement = [
192
199
  (data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
193
200
  {
194
- 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.",
195
202
  path: ["validatorId", "validatorContract"]
196
203
  }
197
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
+ ];
198
212
  var SelfPermitOptionsValidator = zod.z.object({
199
213
  type: zod.z.literal("self").optional().default("self"),
200
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
201
- message: "Self permit issuer :: invalid address"
202
- }).refine((val) => val !== viem.zeroAddress, {
203
- message: "Self permit issuer :: must not be zeroAddress"
204
- }),
214
+ issuer: addressNotZeroSchema,
205
215
  name: zod.z.string().optional().default("Unnamed Permit"),
206
- expiration: zod.z.number().optional().default(1e12),
207
- recipient: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
208
- message: "Self permit recipient :: invalid address"
209
- }).refine((val) => val === viem.zeroAddress, {
210
- message: "Self permit recipient :: must be zeroAddress"
211
- }),
212
- validatorId: zod.z.number().optional().default(0),
213
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
214
- message: "Self permit validatorContract :: invalid address"
215
- }),
216
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
217
- message: "Self permit issuerSignature :: must be 0x prefixed"
218
- }),
219
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
220
- message: "Self permit recipientSignature :: must be 0x prefixed"
221
- })
222
- }).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);
223
223
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
224
- message: "Self permit :: type must be 'self'"
224
+ error: "Type must be 'self'"
225
225
  }).refine((data) => data.recipient === viem.zeroAddress, {
226
- message: "Self permit :: recipient must be zeroAddress"
226
+ error: "Recipient must be zeroAddress"
227
227
  }).refine((data) => data.issuerSignature !== "0x", {
228
- message: "Self permit :: issuerSignature must be populated"
228
+ error: "IssuerSignature must be populated"
229
229
  }).refine((data) => data.recipientSignature === "0x", {
230
- message: "Self permit :: recipientSignature must be empty"
231
- }).refine(...ValidatorContractRefinement);
230
+ error: "RecipientSignature must be empty"
231
+ }).refine(...ExternalValidatorRefinement);
232
232
  var SharingPermitOptionsValidator = zod.z.object({
233
233
  type: zod.z.literal("sharing").optional().default("sharing"),
234
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
235
- message: "Sharing permit issuer :: invalid address"
236
- }).refine((val) => val !== viem.zeroAddress, {
237
- message: "Sharing permit issuer :: must not be zeroAddress"
238
- }),
239
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
240
- message: "Sharing permit recipient :: invalid address"
241
- }).refine((val) => val !== viem.zeroAddress, {
242
- message: "Sharing permit recipient :: must not be zeroAddress"
243
- }),
234
+ issuer: addressNotZeroSchema,
235
+ recipient: addressNotZeroSchema,
244
236
  name: zod.z.string().optional().default("Unnamed Permit"),
245
- expiration: zod.z.number().optional().default(1e12),
246
- validatorId: zod.z.number().optional().default(0),
247
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
248
- message: "Sharing permit validatorContract :: invalid address"
249
- }),
250
- issuerSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
251
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
252
- }),
253
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
254
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
255
- })
256
- }).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);
257
243
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
258
- message: "Sharing permit :: type must be 'sharing'"
244
+ error: "Type must be 'sharing'"
259
245
  }).refine((data) => data.recipient !== viem.zeroAddress, {
260
- message: "Sharing permit :: recipient must not be zeroAddress"
246
+ error: "Recipient must not be zeroAddress"
261
247
  }).refine((data) => data.issuerSignature !== "0x", {
262
- message: "Sharing permit :: issuerSignature must be populated"
248
+ error: "IssuerSignature must be populated"
263
249
  }).refine((data) => data.recipientSignature === "0x", {
264
- message: "Sharing permit :: recipientSignature must be empty"
265
- }).refine(...ValidatorContractRefinement);
250
+ error: "RecipientSignature must be empty"
251
+ }).refine(...ExternalValidatorRefinement);
266
252
  var ImportPermitOptionsValidator = zod.z.object({
267
253
  type: zod.z.literal("recipient").optional().default("recipient"),
268
- issuer: zod.z.string().refine((val) => viem.isAddress(val), {
269
- message: "Import permit issuer :: invalid address"
270
- }).refine((val) => val !== viem.zeroAddress, {
271
- message: "Import permit issuer :: must not be zeroAddress"
272
- }),
273
- recipient: zod.z.string().refine((val) => viem.isAddress(val), {
274
- message: "Import permit recipient :: invalid address"
275
- }).refine((val) => val !== viem.zeroAddress, {
276
- message: "Import permit recipient :: must not be zeroAddress"
277
- }),
278
- issuerSignature: zod.z.string().refine((val) => is0xPrefixed(val), {
279
- message: "Import permit issuerSignature :: must be 0x prefixed"
280
- }).refine((val) => val !== "0x", {
281
- message: "Import permit :: issuerSignature must be provided"
282
- }),
254
+ issuer: addressNotZeroSchema,
255
+ recipient: addressNotZeroSchema,
283
256
  name: zod.z.string().optional().default("Unnamed Permit"),
284
- expiration: zod.z.number().optional().default(1e12),
285
- validatorId: zod.z.number().optional().default(0),
286
- validatorContract: zod.z.string().optional().default(viem.zeroAddress).refine((val) => viem.isAddress(val), {
287
- message: "Import permit validatorContract :: invalid address"
288
- }),
289
- recipientSignature: zod.z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
290
- message: "Import permit recipientSignature :: must be 0x prefixed"
291
- })
292
- }).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);
293
263
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
294
- message: "Import permit :: type must be 'recipient'"
264
+ error: "Type must be 'recipient'"
295
265
  }).refine((data) => data.recipient !== viem.zeroAddress, {
296
- message: "Import permit :: recipient must not be zeroAddress"
266
+ error: "Recipient must not be zeroAddress"
297
267
  }).refine((data) => data.issuerSignature !== "0x", {
298
- message: "Import permit :: issuerSignature must be populated"
268
+ error: "IssuerSignature must be populated"
299
269
  }).refine((data) => data.recipientSignature !== "0x", {
300
- message: "Import permit :: recipientSignature must be populated"
301
- }).refine(...ValidatorContractRefinement);
302
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
303
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
304
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
305
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
306
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
307
- 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
+ };
308
297
  var ValidationUtils = {
309
298
  /**
310
299
  * Check if permit is expired
@@ -399,75 +388,242 @@ var SignatureUtils = {
399
388
  }
400
389
  };
401
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
+
402
569
  // permits/permit.ts
403
570
  var PermitUtils = {
404
571
  /**
405
572
  * Create a self permit for personal use
406
573
  */
407
- createSelf: async (options) => {
574
+ createSelf: (options) => {
408
575
  const validation = validateSelfPermitOptions(options);
409
- if (!validation.success) {
410
- throw new Error(
411
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
412
- );
413
- }
414
- const sealingPair = await GenerateSealingKey();
415
- return {
416
- ...validation.data,
576
+ const sealingPair = GenerateSealingKey();
577
+ const permit = {
578
+ hash: PermitUtils.getHash(validation),
579
+ ...validation,
417
580
  sealingPair,
418
581
  _signedDomain: void 0
419
582
  };
583
+ return permit;
420
584
  },
421
585
  /**
422
586
  * Create a sharing permit to be shared with another user
423
587
  */
424
- createSharing: async (options) => {
588
+ createSharing: (options) => {
425
589
  const validation = validateSharingPermitOptions(options);
426
- if (!validation.success) {
427
- throw new Error(
428
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
429
- );
430
- }
431
- const sealingPair = await GenerateSealingKey();
432
- return {
433
- ...validation.data,
590
+ const sealingPair = GenerateSealingKey();
591
+ const permit = {
592
+ hash: PermitUtils.getHash(validation),
593
+ ...validation,
434
594
  sealingPair,
435
595
  _signedDomain: void 0
436
596
  };
597
+ return permit;
437
598
  },
438
599
  /**
439
600
  * Import a shared permit from various input formats
440
601
  */
441
- importShared: async (options) => {
602
+ importShared: (options) => {
442
603
  let parsedOptions;
443
604
  if (typeof options === "string") {
444
605
  try {
445
606
  parsedOptions = JSON.parse(options);
446
607
  } catch (error) {
447
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
608
+ throw new Error(`Failed to parse JSON string: ${error}`);
448
609
  }
449
610
  } else if (typeof options === "object" && options !== null) {
450
611
  parsedOptions = options;
451
612
  } else {
452
- throw new Error(
453
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
454
- );
613
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
455
614
  }
456
615
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
457
- 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"`);
458
617
  }
459
618
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
460
- if (!validation.success) {
461
- throw new Error(
462
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
463
- );
464
- }
465
- const sealingPair = await GenerateSealingKey();
466
- return {
467
- ...validation.data,
619
+ const sealingPair = GenerateSealingKey();
620
+ const permit = {
621
+ hash: PermitUtils.getHash(validation),
622
+ ...validation,
468
623
  sealingPair,
469
624
  _signedDomain: void 0
470
625
  };
626
+ return permit;
471
627
  },
472
628
  /**
473
629
  * Sign a permit with the provided wallet client
@@ -475,11 +631,11 @@ var PermitUtils = {
475
631
  sign: async (permit, publicClient, walletClient) => {
476
632
  if (walletClient == null || walletClient.account == null) {
477
633
  throw new Error(
478
- "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"
479
635
  );
480
636
  }
481
637
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
482
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
638
+ const domain = await getAclEIP712Domain(publicClient);
483
639
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
484
640
  const signature = await walletClient.signTypedData({
485
641
  domain,
@@ -508,21 +664,21 @@ var PermitUtils = {
508
664
  * Create and sign a self permit in one operation
509
665
  */
510
666
  createSelfAndSign: async (options, publicClient, walletClient) => {
511
- const permit = await PermitUtils.createSelf(options);
667
+ const permit = PermitUtils.createSelf(options);
512
668
  return PermitUtils.sign(permit, publicClient, walletClient);
513
669
  },
514
670
  /**
515
671
  * Create and sign a sharing permit in one operation
516
672
  */
517
673
  createSharingAndSign: async (options, publicClient, walletClient) => {
518
- const permit = await PermitUtils.createSharing(options);
674
+ const permit = PermitUtils.createSharing(options);
519
675
  return PermitUtils.sign(permit, publicClient, walletClient);
520
676
  },
521
677
  /**
522
678
  * Import and sign a shared permit in one operation from various input formats
523
679
  */
524
680
  importSharedAndSign: async (options, publicClient, walletClient) => {
525
- const permit = await PermitUtils.importShared(options);
681
+ const permit = PermitUtils.importShared(options);
526
682
  return PermitUtils.sign(permit, publicClient, walletClient);
527
683
  },
528
684
  /**
@@ -539,6 +695,7 @@ var PermitUtils = {
539
695
  */
540
696
  serialize: (permit) => {
541
697
  return {
698
+ hash: permit.hash,
542
699
  name: permit.name,
543
700
  type: permit.type,
544
701
  issuer: permit.issuer,
@@ -563,7 +720,7 @@ var PermitUtils = {
563
720
  } else if (permit.type === "recipient") {
564
721
  return validateImportPermit(permit);
565
722
  } else {
566
- throw new Error("PermitUtils :: validate :: Invalid permit type");
723
+ throw new Error("Invalid permit type");
567
724
  }
568
725
  },
569
726
  /**
@@ -571,12 +728,7 @@ var PermitUtils = {
571
728
  */
572
729
  getPermission: (permit, skipValidation = false) => {
573
730
  if (!skipValidation) {
574
- const validationResult = PermitUtils.validate(permit);
575
- if (!validationResult.success) {
576
- throw new Error(
577
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
578
- );
579
- }
731
+ PermitUtils.validate(permit);
580
732
  }
581
733
  return {
582
734
  issuer: permit.issuer,
@@ -657,28 +809,7 @@ var PermitUtils = {
657
809
  * Fetch EIP712 domain from the blockchain
658
810
  */
659
811
  fetchEIP712Domain: async (publicClient) => {
660
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
661
- const ACL_IFACE = "function acl() view returns (address)";
662
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
663
- const aclAbi = viem.parseAbi([ACL_IFACE]);
664
- const aclAddress = await publicClient.readContract({
665
- address: TASK_MANAGER_ADDRESS,
666
- abi: aclAbi,
667
- functionName: "acl"
668
- });
669
- const domainAbi = viem.parseAbi([EIP712_DOMAIN_IFACE]);
670
- const domain = await publicClient.readContract({
671
- address: aclAddress,
672
- abi: domainAbi,
673
- functionName: "eip712Domain"
674
- });
675
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
676
- return {
677
- name,
678
- version,
679
- chainId: Number(chainId),
680
- verifyingContract
681
- };
812
+ return getAclEIP712Domain(publicClient);
682
813
  },
683
814
  /**
684
815
  * Check if permit's signed domain matches the provided domain
@@ -692,18 +823,23 @@ var PermitUtils = {
692
823
  checkSignedDomainValid: async (permit, publicClient) => {
693
824
  if (permit._signedDomain == null)
694
825
  return false;
695
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
826
+ const domain = await getAclEIP712Domain(publicClient);
696
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);
697
835
  }
698
836
  };
837
+ var PERMIT_STORE_DEFAULTS = {
838
+ permits: {},
839
+ activePermitHash: {}
840
+ };
699
841
  var _permitStore = vanilla.createStore()(
700
- middleware.persist(
701
- () => ({
702
- permits: {},
703
- activePermitHash: {}
704
- }),
705
- { name: "cofhesdk-permits" }
706
- )
842
+ middleware.persist(() => PERMIT_STORE_DEFAULTS, { name: "cofhesdk-permits" })
707
843
  );
708
844
  var clearStaleStore = () => {
709
845
  const state = _permitStore.getState();
@@ -749,11 +885,11 @@ var setPermit = (chainId, account, permit) => {
749
885
  state.permits[chainId] = {};
750
886
  if (state.permits[chainId][account] == null)
751
887
  state.permits[chainId][account] = {};
752
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
888
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
753
889
  })
754
890
  );
755
891
  };
756
- var removePermit = (chainId, account, hash, force) => {
892
+ var removePermit = (chainId, account, hash) => {
757
893
  clearStaleStore();
758
894
  _permitStore.setState(
759
895
  immer.produce((state) => {
@@ -767,15 +903,7 @@ var removePermit = (chainId, account, hash, force) => {
767
903
  if (accountPermits[hash] == null)
768
904
  return;
769
905
  if (state.activePermitHash[chainId][account] === hash) {
770
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
771
- if (otherPermitHash) {
772
- state.activePermitHash[chainId][account] = otherPermitHash;
773
- } else {
774
- if (!force) {
775
- throw new Error("Cannot remove the last permit without force flag");
776
- }
777
- state.activePermitHash[chainId][account] = void 0;
778
- }
906
+ state.activePermitHash[chainId][account] = void 0;
779
907
  }
780
908
  accountPermits[hash] = void 0;
781
909
  })
@@ -826,6 +954,7 @@ var permitStore = {
826
954
  exports.GenerateSealingKey = GenerateSealingKey;
827
955
  exports.ImportPermitOptionsValidator = ImportPermitOptionsValidator;
828
956
  exports.ImportPermitValidator = ImportPermitValidator;
957
+ exports.PERMIT_STORE_DEFAULTS = PERMIT_STORE_DEFAULTS;
829
958
  exports.PermitUtils = PermitUtils;
830
959
  exports.SealingKey = SealingKey;
831
960
  exports.SelfPermitOptionsValidator = SelfPermitOptionsValidator;
@@ -836,6 +965,10 @@ exports.SignatureTypes = SignatureTypes;
836
965
  exports.SignatureUtils = SignatureUtils;
837
966
  exports.ValidationUtils = ValidationUtils;
838
967
  exports._permitStore = _permitStore;
968
+ exports.addressNotZeroSchema = addressNotZeroSchema;
969
+ exports.addressSchema = addressSchema;
970
+ exports.bytesNotEmptySchema = bytesNotEmptySchema;
971
+ exports.bytesSchema = bytesSchema;
839
972
  exports.clearStaleStore = clearStaleStore;
840
973
  exports.getActivePermit = getActivePermit;
841
974
  exports.getActivePermitHash = getActivePermitHash;