@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.
- package/CHANGELOG.md +36 -0
- package/chains/defineChain.ts +2 -2
- package/chains/types.ts +3 -3
- package/core/baseBuilder.ts +18 -18
- package/core/client.test.ts +155 -41
- package/core/client.ts +72 -32
- package/core/clientTypes.ts +28 -18
- package/core/config.test.ts +40 -33
- package/core/config.ts +56 -51
- package/core/consts.ts +22 -0
- package/core/decrypt/{MockQueryDecrypterAbi.ts → MockThresholdNetworkAbi.ts} +71 -21
- package/core/decrypt/cofheMocksDecryptForTx.ts +142 -0
- package/core/decrypt/{cofheMocksSealOutput.ts → cofheMocksDecryptForView.ts} +12 -14
- package/core/decrypt/decryptForTxBuilder.ts +340 -0
- package/core/decrypt/{decryptHandleBuilder.ts → decryptForViewBuilder.ts} +75 -42
- package/core/decrypt/tnDecrypt.ts +232 -0
- package/core/decrypt/tnSealOutputV1.ts +5 -5
- package/core/decrypt/tnSealOutputV2.ts +27 -27
- package/core/encrypt/cofheMocksZkVerifySign.ts +19 -26
- package/core/encrypt/encryptInputsBuilder.test.ts +57 -61
- package/core/encrypt/encryptInputsBuilder.ts +65 -42
- package/core/encrypt/zkPackProveVerify.ts +11 -11
- package/core/error.ts +18 -18
- package/core/fetchKeys.test.ts +3 -3
- package/core/fetchKeys.ts +3 -3
- package/core/index.ts +22 -11
- package/core/permits.test.ts +5 -6
- package/core/permits.ts +5 -4
- package/core/utils.ts +10 -10
- package/dist/chains.cjs +4 -7
- package/dist/chains.d.cts +12 -12
- package/dist/chains.d.ts +12 -12
- package/dist/chains.js +1 -1
- package/dist/{chunk-WGCRJCBR.js → chunk-2TPSCOW3.js} +820 -224
- package/dist/{chunk-UGBVZNRT.js → chunk-NWDKXBIP.js} +309 -189
- package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
- package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-6aTZPQ_4.d.ts} +233 -173
- package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-Bhq7pCSA.d.cts} +233 -173
- package/dist/core.cjs +1138 -418
- package/dist/core.d.cts +37 -24
- package/dist/core.d.ts +37 -24
- package/dist/core.js +3 -3
- package/dist/node.cjs +1082 -370
- package/dist/node.d.cts +12 -12
- package/dist/node.d.ts +12 -12
- package/dist/node.js +8 -8
- package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
- package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
- package/dist/permits.cjs +305 -187
- package/dist/permits.d.cts +111 -812
- package/dist/permits.d.ts +111 -812
- package/dist/permits.js +1 -1
- package/dist/types-YiAC4gig.d.cts +33 -0
- package/dist/types-YiAC4gig.d.ts +33 -0
- package/dist/web.cjs +1085 -373
- package/dist/web.d.cts +13 -13
- package/dist/web.d.ts +13 -13
- package/dist/web.js +10 -10
- package/node/client.test.ts +34 -34
- package/node/config.test.ts +11 -11
- package/node/encryptInputs.test.ts +29 -29
- package/node/index.ts +15 -15
- package/package.json +3 -3
- package/permits/localstorage.test.ts +9 -13
- package/permits/onchain-utils.ts +221 -0
- package/permits/permit.test.ts +51 -5
- package/permits/permit.ts +28 -74
- package/permits/store.test.ts +10 -50
- package/permits/store.ts +4 -14
- package/permits/test-utils.ts +10 -2
- package/permits/types.ts +22 -9
- package/permits/utils.ts +0 -4
- package/permits/validation.test.ts +29 -32
- package/permits/validation.ts +112 -194
- package/web/client.web.test.ts +34 -34
- package/web/config.web.test.ts +11 -11
- package/web/encryptInputs.web.test.ts +29 -29
- package/web/index.ts +19 -19
- package/web/worker.builder.web.test.ts +28 -28
- package/web/worker.config.web.test.ts +47 -47
- package/web/worker.output.web.test.ts +10 -10
- package/dist/types-KImPrEIe.d.cts +0 -48
- 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:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
|
198
|
+
var ExternalValidatorRefinement = [
|
|
193
199
|
(data) => data.validatorId !== 0 && data.validatorContract !== viem.zeroAddress || data.validatorId === 0 && data.validatorContract === viem.zeroAddress,
|
|
194
200
|
{
|
|
195
|
-
|
|
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:
|
|
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.
|
|
210
|
-
recipient:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
224
|
+
error: "Type must be 'self'"
|
|
230
225
|
}).refine((data) => data.recipient === viem.zeroAddress, {
|
|
231
|
-
|
|
226
|
+
error: "Recipient must be zeroAddress"
|
|
232
227
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
233
|
-
|
|
228
|
+
error: "IssuerSignature must be populated"
|
|
234
229
|
}).refine((data) => data.recipientSignature === "0x", {
|
|
235
|
-
|
|
236
|
-
}).refine(...
|
|
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:
|
|
240
|
-
|
|
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.
|
|
255
|
-
validatorId: zod.z.
|
|
256
|
-
validatorContract:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
244
|
+
error: "Type must be 'sharing'"
|
|
268
245
|
}).refine((data) => data.recipient !== viem.zeroAddress, {
|
|
269
|
-
|
|
246
|
+
error: "Recipient must not be zeroAddress"
|
|
270
247
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
271
|
-
|
|
248
|
+
error: "IssuerSignature must be populated"
|
|
272
249
|
}).refine((data) => data.recipientSignature === "0x", {
|
|
273
|
-
|
|
274
|
-
}).refine(...
|
|
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:
|
|
278
|
-
|
|
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.
|
|
298
|
-
validatorId: zod.z.
|
|
299
|
-
validatorContract:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
264
|
+
error: "Type must be 'recipient'"
|
|
308
265
|
}).refine((data) => data.recipient !== viem.zeroAddress, {
|
|
309
|
-
|
|
266
|
+
error: "Recipient must not be zeroAddress"
|
|
310
267
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
311
|
-
|
|
268
|
+
error: "IssuerSignature must be populated"
|
|
312
269
|
}).refine((data) => data.recipientSignature !== "0x", {
|
|
313
|
-
|
|
314
|
-
}).refine(...
|
|
315
|
-
var
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(`
|
|
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(`
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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][
|
|
888
|
+
state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
|
|
767
889
|
})
|
|
768
890
|
);
|
|
769
891
|
};
|
|
770
|
-
var removePermit = (chainId, account, hash
|
|
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
|
-
|
|
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;
|