@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
@@ -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;
@@ -136,7 +133,7 @@ var SealingKey = class _SealingKey {
136
133
  };
137
134
  };
138
135
  };
139
- var GenerateSealingKey = async () => {
136
+ var GenerateSealingKey = () => {
140
137
  const sodiumKeypair = nacl.box.keyPair();
141
138
  return new SealingKey(toHexString(sodiumKeypair.secretKey), toHexString(sodiumKeypair.publicKey));
142
139
  };
@@ -144,145 +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
+ });
161
+ var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
147
162
  var zPermitWithDefaults = z.object({
148
163
  name: z.string().optional().default("Unnamed Permit"),
149
164
  type: z.enum(["self", "sharing", "recipient"]),
150
- issuer: z.string().refine((val) => isAddress(val), {
151
- message: "Permit issuer :: invalid address"
152
- }).refine((val) => val !== zeroAddress, {
153
- message: "Permit issuer :: must not be zeroAddress"
154
- }),
155
- expiration: z.number().optional().default(1e12),
156
- recipient: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
157
- message: "Permit recipient :: invalid address"
158
- }),
159
- validatorId: z.number().optional().default(0),
160
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
161
- message: "Permit validatorContract :: invalid address"
162
- }),
163
- issuerSignature: z.string().optional().default("0x"),
164
- 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")
165
172
  });
166
173
  var zPermitWithSealingPair = zPermitWithDefaults.extend({
167
174
  sealingPair: SerializedSealingPair.optional()
168
175
  });
169
- var ValidatorContractRefinement = [
176
+ var ExternalValidatorRefinement = [
170
177
  (data) => data.validatorId !== 0 && data.validatorContract !== zeroAddress || data.validatorId === 0 && data.validatorContract === zeroAddress,
171
178
  {
172
- 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.",
173
180
  path: ["validatorId", "validatorContract"]
174
181
  }
175
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
+ ];
176
190
  var SelfPermitOptionsValidator = z.object({
177
191
  type: z.literal("self").optional().default("self"),
178
- issuer: z.string().refine((val) => isAddress(val), {
179
- message: "Self permit issuer :: invalid address"
180
- }).refine((val) => val !== zeroAddress, {
181
- message: "Self permit issuer :: must not be zeroAddress"
182
- }),
192
+ issuer: addressNotZeroSchema,
183
193
  name: z.string().optional().default("Unnamed Permit"),
184
- expiration: z.number().optional().default(1e12),
185
- recipient: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
186
- message: "Self permit recipient :: invalid address"
187
- }).refine((val) => val === zeroAddress, {
188
- message: "Self permit recipient :: must be zeroAddress"
189
- }),
190
- validatorId: z.number().optional().default(0),
191
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
192
- message: "Self permit validatorContract :: invalid address"
193
- }),
194
- issuerSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
195
- message: "Self permit issuerSignature :: must be 0x prefixed"
196
- }),
197
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
198
- message: "Self permit recipientSignature :: must be 0x prefixed"
199
- })
200
- }).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);
201
201
  var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
202
- message: "Self permit :: type must be 'self'"
202
+ error: "Type must be 'self'"
203
203
  }).refine((data) => data.recipient === zeroAddress, {
204
- message: "Self permit :: recipient must be zeroAddress"
204
+ error: "Recipient must be zeroAddress"
205
205
  }).refine((data) => data.issuerSignature !== "0x", {
206
- message: "Self permit :: issuerSignature must be populated"
206
+ error: "IssuerSignature must be populated"
207
207
  }).refine((data) => data.recipientSignature === "0x", {
208
- message: "Self permit :: recipientSignature must be empty"
209
- }).refine(...ValidatorContractRefinement);
208
+ error: "RecipientSignature must be empty"
209
+ }).refine(...ExternalValidatorRefinement);
210
210
  var SharingPermitOptionsValidator = z.object({
211
211
  type: z.literal("sharing").optional().default("sharing"),
212
- issuer: z.string().refine((val) => isAddress(val), {
213
- message: "Sharing permit issuer :: invalid address"
214
- }).refine((val) => val !== zeroAddress, {
215
- message: "Sharing permit issuer :: must not be zeroAddress"
216
- }),
217
- recipient: z.string().refine((val) => isAddress(val), {
218
- message: "Sharing permit recipient :: invalid address"
219
- }).refine((val) => val !== zeroAddress, {
220
- message: "Sharing permit recipient :: must not be zeroAddress"
221
- }),
212
+ issuer: addressNotZeroSchema,
213
+ recipient: addressNotZeroSchema,
222
214
  name: z.string().optional().default("Unnamed Permit"),
223
- expiration: z.number().optional().default(1e12),
224
- validatorId: z.number().optional().default(0),
225
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
226
- message: "Sharing permit validatorContract :: invalid address"
227
- }),
228
- issuerSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
229
- message: "Sharing permit issuerSignature :: must be 0x prefixed"
230
- }),
231
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
232
- message: "Sharing permit recipientSignature :: must be 0x prefixed"
233
- })
234
- }).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);
235
221
  var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
236
- message: "Sharing permit :: type must be 'sharing'"
222
+ error: "Type must be 'sharing'"
237
223
  }).refine((data) => data.recipient !== zeroAddress, {
238
- message: "Sharing permit :: recipient must not be zeroAddress"
224
+ error: "Recipient must not be zeroAddress"
239
225
  }).refine((data) => data.issuerSignature !== "0x", {
240
- message: "Sharing permit :: issuerSignature must be populated"
226
+ error: "IssuerSignature must be populated"
241
227
  }).refine((data) => data.recipientSignature === "0x", {
242
- message: "Sharing permit :: recipientSignature must be empty"
243
- }).refine(...ValidatorContractRefinement);
228
+ error: "RecipientSignature must be empty"
229
+ }).refine(...ExternalValidatorRefinement);
244
230
  var ImportPermitOptionsValidator = z.object({
245
231
  type: z.literal("recipient").optional().default("recipient"),
246
- issuer: z.string().refine((val) => isAddress(val), {
247
- message: "Import permit issuer :: invalid address"
248
- }).refine((val) => val !== zeroAddress, {
249
- message: "Import permit issuer :: must not be zeroAddress"
250
- }),
251
- recipient: z.string().refine((val) => isAddress(val), {
252
- message: "Import permit recipient :: invalid address"
253
- }).refine((val) => val !== zeroAddress, {
254
- message: "Import permit recipient :: must not be zeroAddress"
255
- }),
256
- issuerSignature: z.string().refine((val) => is0xPrefixed(val), {
257
- message: "Import permit issuerSignature :: must be 0x prefixed"
258
- }).refine((val) => val !== "0x", {
259
- message: "Import permit :: issuerSignature must be provided"
260
- }),
232
+ issuer: addressNotZeroSchema,
233
+ recipient: addressNotZeroSchema,
261
234
  name: z.string().optional().default("Unnamed Permit"),
262
- expiration: z.number().optional().default(1e12),
263
- validatorId: z.number().optional().default(0),
264
- validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
265
- message: "Import permit validatorContract :: invalid address"
266
- }),
267
- recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
268
- message: "Import permit recipientSignature :: must be 0x prefixed"
269
- })
270
- }).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);
271
241
  var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
272
- message: "Import permit :: type must be 'recipient'"
242
+ error: "Type must be 'recipient'"
273
243
  }).refine((data) => data.recipient !== zeroAddress, {
274
- message: "Import permit :: recipient must not be zeroAddress"
244
+ error: "Recipient must not be zeroAddress"
275
245
  }).refine((data) => data.issuerSignature !== "0x", {
276
- message: "Import permit :: issuerSignature must be populated"
246
+ error: "IssuerSignature must be populated"
277
247
  }).refine((data) => data.recipientSignature !== "0x", {
278
- message: "Import permit :: recipientSignature must be populated"
279
- }).refine(...ValidatorContractRefinement);
280
- var validateSelfPermitOptions = (options) => SelfPermitOptionsValidator.safeParse(options);
281
- var validateSharingPermitOptions = (options) => SharingPermitOptionsValidator.safeParse(options);
282
- var validateImportPermitOptions = (options) => ImportPermitOptionsValidator.safeParse(options);
283
- var validateSelfPermit = (permit) => SelfPermitValidator.safeParse(permit);
284
- var validateSharingPermit = (permit) => SharingPermitValidator.safeParse(permit);
285
- 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
+ };
286
275
  var ValidationUtils = {
287
276
  /**
288
277
  * Check if permit is expired
@@ -377,75 +366,247 @@ var SignatureUtils = {
377
366
  }
378
367
  };
379
368
 
369
+ // core/consts.ts
370
+ var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
371
+ var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
372
+ var MOCKS_QUERY_DECRYPTER_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
+
377
+ // permits/onchain-utils.ts
378
+ var getAclAddress = async (publicClient) => {
379
+ const ACL_IFACE = "function acl() view returns (address)";
380
+ const aclAbi = parseAbi([ACL_IFACE]);
381
+ return await publicClient.readContract({
382
+ address: TASK_MANAGER_ADDRESS,
383
+ abi: aclAbi,
384
+ functionName: "acl"
385
+ });
386
+ };
387
+ var getAclEIP712Domain = async (publicClient) => {
388
+ const aclAddress = await getAclAddress(publicClient);
389
+ const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
390
+ const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
391
+ const domain = await publicClient.readContract({
392
+ address: aclAddress,
393
+ abi: domainAbi,
394
+ functionName: "eip712Domain"
395
+ });
396
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
397
+ return {
398
+ name,
399
+ version,
400
+ chainId: Number(chainId),
401
+ verifyingContract
402
+ };
403
+ };
404
+ var checkPermitValidityOnChain = async (permission, publicClient) => {
405
+ const aclAddress = await getAclAddress(publicClient);
406
+ try {
407
+ await publicClient.simulateContract({
408
+ address: aclAddress,
409
+ abi: checkPermitValidityAbi,
410
+ functionName: "checkPermitValidity",
411
+ args: [
412
+ {
413
+ issuer: permission.issuer,
414
+ expiration: BigInt(permission.expiration),
415
+ recipient: permission.recipient,
416
+ validatorId: BigInt(permission.validatorId),
417
+ validatorContract: permission.validatorContract,
418
+ sealingKey: permission.sealingKey,
419
+ issuerSignature: permission.issuerSignature,
420
+ recipientSignature: permission.recipientSignature
421
+ }
422
+ ]
423
+ });
424
+ return true;
425
+ } catch (err) {
426
+ if (err instanceof BaseError) {
427
+ const revertError = err.walk((err2) => err2 instanceof ContractFunctionRevertedError);
428
+ if (revertError instanceof ContractFunctionRevertedError) {
429
+ const errorName = revertError.data?.errorName ?? "";
430
+ throw new Error(errorName);
431
+ }
432
+ }
433
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
434
+ if (customErrorName) {
435
+ throw new Error(customErrorName);
436
+ }
437
+ const hhDetailsData = extractReturnData(err);
438
+ if (hhDetailsData != null) {
439
+ const decoded = decodeErrorResult({
440
+ abi: checkPermitValidityAbi,
441
+ data: hhDetailsData
442
+ });
443
+ throw new Error(decoded.errorName);
444
+ }
445
+ throw err;
446
+ }
447
+ };
448
+ function extractCustomErrorFromDetails(err, abi) {
449
+ const anyErr = err;
450
+ const details = anyErr?.details ?? anyErr?.cause?.details;
451
+ if (typeof details === "string") {
452
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
453
+ if (customErrorMatch) {
454
+ const errorName = customErrorMatch[1];
455
+ const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
456
+ if (errorExists) {
457
+ return errorName;
458
+ }
459
+ }
460
+ }
461
+ return void 0;
462
+ }
463
+ function extractReturnData(err) {
464
+ const anyErr = err;
465
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
466
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
467
+ }
468
+ var checkPermitValidityAbi = [
469
+ {
470
+ type: "function",
471
+ name: "checkPermitValidity",
472
+ inputs: [
473
+ {
474
+ name: "permission",
475
+ type: "tuple",
476
+ internalType: "struct Permission",
477
+ components: [
478
+ {
479
+ name: "issuer",
480
+ type: "address",
481
+ internalType: "address"
482
+ },
483
+ {
484
+ name: "expiration",
485
+ type: "uint64",
486
+ internalType: "uint64"
487
+ },
488
+ {
489
+ name: "recipient",
490
+ type: "address",
491
+ internalType: "address"
492
+ },
493
+ {
494
+ name: "validatorId",
495
+ type: "uint256",
496
+ internalType: "uint256"
497
+ },
498
+ {
499
+ name: "validatorContract",
500
+ type: "address",
501
+ internalType: "address"
502
+ },
503
+ {
504
+ name: "sealingKey",
505
+ type: "bytes32",
506
+ internalType: "bytes32"
507
+ },
508
+ {
509
+ name: "issuerSignature",
510
+ type: "bytes",
511
+ internalType: "bytes"
512
+ },
513
+ {
514
+ name: "recipientSignature",
515
+ type: "bytes",
516
+ internalType: "bytes"
517
+ }
518
+ ]
519
+ }
520
+ ],
521
+ outputs: [
522
+ {
523
+ name: "",
524
+ type: "bool",
525
+ internalType: "bool"
526
+ }
527
+ ],
528
+ stateMutability: "view"
529
+ },
530
+ {
531
+ type: "error",
532
+ name: "PermissionInvalid_Disabled",
533
+ inputs: []
534
+ },
535
+ {
536
+ type: "error",
537
+ name: "PermissionInvalid_Expired",
538
+ inputs: []
539
+ },
540
+ {
541
+ type: "error",
542
+ name: "PermissionInvalid_IssuerSignature",
543
+ inputs: []
544
+ },
545
+ {
546
+ type: "error",
547
+ name: "PermissionInvalid_RecipientSignature",
548
+ inputs: []
549
+ }
550
+ ];
551
+
380
552
  // permits/permit.ts
381
553
  var PermitUtils = {
382
554
  /**
383
555
  * Create a self permit for personal use
384
556
  */
385
- createSelf: async (options) => {
557
+ createSelf: (options) => {
386
558
  const validation = validateSelfPermitOptions(options);
387
- if (!validation.success) {
388
- throw new Error(
389
- "PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
390
- );
391
- }
392
- const sealingPair = await GenerateSealingKey();
393
- return {
394
- ...validation.data,
559
+ const sealingPair = GenerateSealingKey();
560
+ const permit = {
561
+ hash: PermitUtils.getHash(validation),
562
+ ...validation,
395
563
  sealingPair,
396
564
  _signedDomain: void 0
397
565
  };
566
+ return permit;
398
567
  },
399
568
  /**
400
569
  * Create a sharing permit to be shared with another user
401
570
  */
402
- createSharing: async (options) => {
571
+ createSharing: (options) => {
403
572
  const validation = validateSharingPermitOptions(options);
404
- if (!validation.success) {
405
- throw new Error(
406
- "PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
407
- );
408
- }
409
- const sealingPair = await GenerateSealingKey();
410
- return {
411
- ...validation.data,
573
+ const sealingPair = GenerateSealingKey();
574
+ const permit = {
575
+ hash: PermitUtils.getHash(validation),
576
+ ...validation,
412
577
  sealingPair,
413
578
  _signedDomain: void 0
414
579
  };
580
+ return permit;
415
581
  },
416
582
  /**
417
583
  * Import a shared permit from various input formats
418
584
  */
419
- importShared: async (options) => {
585
+ importShared: (options) => {
420
586
  let parsedOptions;
421
587
  if (typeof options === "string") {
422
588
  try {
423
589
  parsedOptions = JSON.parse(options);
424
590
  } catch (error) {
425
- throw new Error(`PermitUtils :: importShared :: Failed to parse JSON string: ${error}`);
591
+ throw new Error(`Failed to parse JSON string: ${error}`);
426
592
  }
427
593
  } else if (typeof options === "object" && options !== null) {
428
594
  parsedOptions = options;
429
595
  } else {
430
- throw new Error(
431
- "PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
432
- );
596
+ throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
433
597
  }
434
598
  if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
435
- throw new Error(`PermitUtils :: importShared :: Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
599
+ throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
436
600
  }
437
601
  const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
438
- if (!validation.success) {
439
- throw new Error(
440
- "PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
441
- );
442
- }
443
- const sealingPair = await GenerateSealingKey();
444
- return {
445
- ...validation.data,
602
+ const sealingPair = GenerateSealingKey();
603
+ const permit = {
604
+ hash: PermitUtils.getHash(validation),
605
+ ...validation,
446
606
  sealingPair,
447
607
  _signedDomain: void 0
448
608
  };
609
+ return permit;
449
610
  },
450
611
  /**
451
612
  * Sign a permit with the provided wallet client
@@ -453,11 +614,11 @@ var PermitUtils = {
453
614
  sign: async (permit, publicClient, walletClient) => {
454
615
  if (walletClient == null || walletClient.account == null) {
455
616
  throw new Error(
456
- "PermitUtils :: sign - walletClient undefined, you must pass in a `walletClient` for the connected user to create a permit signature"
617
+ "Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
457
618
  );
458
619
  }
459
620
  const primaryType = SignatureUtils.getPrimaryType(permit.type);
460
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
621
+ const domain = await getAclEIP712Domain(publicClient);
461
622
  const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
462
623
  const signature = await walletClient.signTypedData({
463
624
  domain,
@@ -486,21 +647,21 @@ var PermitUtils = {
486
647
  * Create and sign a self permit in one operation
487
648
  */
488
649
  createSelfAndSign: async (options, publicClient, walletClient) => {
489
- const permit = await PermitUtils.createSelf(options);
650
+ const permit = PermitUtils.createSelf(options);
490
651
  return PermitUtils.sign(permit, publicClient, walletClient);
491
652
  },
492
653
  /**
493
654
  * Create and sign a sharing permit in one operation
494
655
  */
495
656
  createSharingAndSign: async (options, publicClient, walletClient) => {
496
- const permit = await PermitUtils.createSharing(options);
657
+ const permit = PermitUtils.createSharing(options);
497
658
  return PermitUtils.sign(permit, publicClient, walletClient);
498
659
  },
499
660
  /**
500
661
  * Import and sign a shared permit in one operation from various input formats
501
662
  */
502
663
  importSharedAndSign: async (options, publicClient, walletClient) => {
503
- const permit = await PermitUtils.importShared(options);
664
+ const permit = PermitUtils.importShared(options);
504
665
  return PermitUtils.sign(permit, publicClient, walletClient);
505
666
  },
506
667
  /**
@@ -517,6 +678,7 @@ var PermitUtils = {
517
678
  */
518
679
  serialize: (permit) => {
519
680
  return {
681
+ hash: permit.hash,
520
682
  name: permit.name,
521
683
  type: permit.type,
522
684
  issuer: permit.issuer,
@@ -541,7 +703,7 @@ var PermitUtils = {
541
703
  } else if (permit.type === "recipient") {
542
704
  return validateImportPermit(permit);
543
705
  } else {
544
- throw new Error("PermitUtils :: validate :: Invalid permit type");
706
+ throw new Error("Invalid permit type");
545
707
  }
546
708
  },
547
709
  /**
@@ -549,12 +711,7 @@ var PermitUtils = {
549
711
  */
550
712
  getPermission: (permit, skipValidation = false) => {
551
713
  if (!skipValidation) {
552
- const validationResult = PermitUtils.validate(permit);
553
- if (!validationResult.success) {
554
- throw new Error(
555
- `PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
556
- );
557
- }
714
+ PermitUtils.validate(permit);
558
715
  }
559
716
  return {
560
717
  issuer: permit.issuer,
@@ -635,28 +792,7 @@ var PermitUtils = {
635
792
  * Fetch EIP712 domain from the blockchain
636
793
  */
637
794
  fetchEIP712Domain: async (publicClient) => {
638
- const TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
639
- const ACL_IFACE = "function acl() view returns (address)";
640
- const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
641
- const aclAbi = parseAbi([ACL_IFACE]);
642
- const aclAddress = await publicClient.readContract({
643
- address: TASK_MANAGER_ADDRESS,
644
- abi: aclAbi,
645
- functionName: "acl"
646
- });
647
- const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
648
- const domain = await publicClient.readContract({
649
- address: aclAddress,
650
- abi: domainAbi,
651
- functionName: "eip712Domain"
652
- });
653
- const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
654
- return {
655
- name,
656
- version,
657
- chainId: Number(chainId),
658
- verifyingContract
659
- };
795
+ return getAclEIP712Domain(publicClient);
660
796
  },
661
797
  /**
662
798
  * Check if permit's signed domain matches the provided domain
@@ -670,18 +806,23 @@ var PermitUtils = {
670
806
  checkSignedDomainValid: async (permit, publicClient) => {
671
807
  if (permit._signedDomain == null)
672
808
  return false;
673
- const domain = await PermitUtils.fetchEIP712Domain(publicClient);
809
+ const domain = await getAclEIP712Domain(publicClient);
674
810
  return PermitUtils.matchesDomain(permit, domain);
811
+ },
812
+ /**
813
+ * Check if permit passes the on-chain validation
814
+ */
815
+ checkValidityOnChain: async (permit, publicClient) => {
816
+ const permission = PermitUtils.getPermission(permit);
817
+ return checkPermitValidityOnChain(permission, publicClient);
675
818
  }
676
819
  };
820
+ var PERMIT_STORE_DEFAULTS = {
821
+ permits: {},
822
+ activePermitHash: {}
823
+ };
677
824
  var _permitStore = createStore()(
678
- persist(
679
- () => ({
680
- permits: {},
681
- activePermitHash: {}
682
- }),
683
- { name: "cofhesdk-permits" }
684
- )
825
+ persist(() => PERMIT_STORE_DEFAULTS, { name: "cofhesdk-permits" })
685
826
  );
686
827
  var clearStaleStore = () => {
687
828
  const state = _permitStore.getState();
@@ -727,11 +868,11 @@ var setPermit = (chainId, account, permit) => {
727
868
  state.permits[chainId] = {};
728
869
  if (state.permits[chainId][account] == null)
729
870
  state.permits[chainId][account] = {};
730
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
871
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
731
872
  })
732
873
  );
733
874
  };
734
- var removePermit = (chainId, account, hash, force) => {
875
+ var removePermit = (chainId, account, hash) => {
735
876
  clearStaleStore();
736
877
  _permitStore.setState(
737
878
  produce((state) => {
@@ -745,15 +886,7 @@ var removePermit = (chainId, account, hash, force) => {
745
886
  if (accountPermits[hash] == null)
746
887
  return;
747
888
  if (state.activePermitHash[chainId][account] === hash) {
748
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
749
- if (otherPermitHash) {
750
- state.activePermitHash[chainId][account] = otherPermitHash;
751
- } else {
752
- if (!force) {
753
- throw new Error("Cannot remove the last permit without force flag");
754
- }
755
- state.activePermitHash[chainId][account] = void 0;
756
- }
889
+ state.activePermitHash[chainId][account] = void 0;
757
890
  }
758
891
  accountPermits[hash] = void 0;
759
892
  })
@@ -801,4 +934,4 @@ var permitStore = {
801
934
  resetStore
802
935
  };
803
936
 
804
- export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, 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 };
937
+ export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, MOCKS_QUERY_DECRYPTER_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 };