@cofhe/sdk 0.2.0 → 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.
- package/CHANGELOG.md +8 -0
- package/chains/defineChain.ts +2 -2
- package/chains/types.ts +3 -3
- package/core/client.test.ts +111 -0
- package/core/client.ts +22 -2
- package/core/clientTypes.ts +7 -1
- package/core/config.test.ts +8 -0
- package/core/config.ts +10 -4
- package/core/consts.ts +18 -0
- package/core/decrypt/cofheMocksSealOutput.ts +2 -4
- package/core/encrypt/cofheMocksZkVerifySign.ts +4 -11
- package/core/index.ts +9 -1
- package/core/permits.test.ts +5 -6
- package/core/permits.ts +5 -4
- 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-I5WFEYXX.js} +33 -19
- package/dist/{chunk-UGBVZNRT.js → chunk-R3B5TMVX.js} +308 -189
- package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
- package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-RqkgkV2i.d.ts} +34 -93
- package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-e4filDzK.d.cts} +34 -93
- package/dist/core.cjs +343 -208
- package/dist/core.d.cts +17 -6
- package/dist/core.d.ts +17 -6
- package/dist/core.js +3 -3
- package/dist/node.cjs +337 -208
- package/dist/node.d.cts +3 -3
- package/dist/node.d.ts +3 -3
- package/dist/node.js +3 -3
- 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 +337 -208
- package/dist/web.d.cts +3 -3
- package/dist/web.d.ts +3 -3
- package/dist/web.js +3 -3
- 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/dist/types-KImPrEIe.d.cts +0 -48
- package/dist/types-KImPrEIe.d.ts +0 -48
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isAddress, zeroAddress, keccak256, toHex, parseAbi } from 'viem';
|
|
1
|
+
import { isAddress, getAddress, zeroAddress, isHex, keccak256, toHex, parseAbi, BaseError, ContractFunctionRevertedError, decodeErrorResult } from 'viem';
|
|
2
2
|
import * as nacl from 'tweetnacl';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { createStore } from 'zustand/vanilla';
|
|
@@ -54,9 +54,6 @@ function isBigIntOrNumber(value) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
function is0xPrefixed(value) {
|
|
58
|
-
return value.startsWith("0x");
|
|
59
|
-
}
|
|
60
57
|
|
|
61
58
|
// permits/sealing.ts
|
|
62
59
|
var PRIVATE_KEY_LENGTH = 64;
|
|
@@ -144,158 +141,137 @@ var SerializedSealingPair = z.object({
|
|
|
144
141
|
privateKey: z.string(),
|
|
145
142
|
publicKey: z.string()
|
|
146
143
|
});
|
|
144
|
+
var addressSchema = z.string().refine((val) => isAddress(val), {
|
|
145
|
+
error: "Invalid address"
|
|
146
|
+
}).transform((val) => getAddress(val));
|
|
147
|
+
var addressNotZeroSchema = addressSchema.refine((val) => val !== zeroAddress, {
|
|
148
|
+
error: "Must not be zeroAddress"
|
|
149
|
+
});
|
|
150
|
+
var bytesSchema = z.custom(
|
|
151
|
+
(val) => {
|
|
152
|
+
return typeof val === "string" && isHex(val);
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
message: "Invalid hex value"
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
var bytesNotEmptySchema = bytesSchema.refine((val) => val !== "0x", {
|
|
159
|
+
error: "Must not be empty"
|
|
160
|
+
});
|
|
147
161
|
var DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1e3) + 7 * 24 * 60 * 60;
|
|
148
162
|
var zPermitWithDefaults = z.object({
|
|
149
163
|
name: z.string().optional().default("Unnamed Permit"),
|
|
150
164
|
type: z.enum(["self", "sharing", "recipient"]),
|
|
151
|
-
issuer:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
message: "Permit recipient :: invalid address"
|
|
159
|
-
}),
|
|
160
|
-
validatorId: z.number().optional().default(0),
|
|
161
|
-
validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
|
|
162
|
-
message: "Permit validatorContract :: invalid address"
|
|
163
|
-
}),
|
|
164
|
-
issuerSignature: z.string().optional().default("0x"),
|
|
165
|
-
recipientSignature: z.string().optional().default("0x")
|
|
165
|
+
issuer: addressNotZeroSchema,
|
|
166
|
+
expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
|
|
167
|
+
recipient: addressSchema.optional().default(zeroAddress),
|
|
168
|
+
validatorId: z.int().optional().default(0),
|
|
169
|
+
validatorContract: addressSchema.optional().default(zeroAddress),
|
|
170
|
+
issuerSignature: bytesSchema.optional().default("0x"),
|
|
171
|
+
recipientSignature: bytesSchema.optional().default("0x")
|
|
166
172
|
});
|
|
167
173
|
var zPermitWithSealingPair = zPermitWithDefaults.extend({
|
|
168
174
|
sealingPair: SerializedSealingPair.optional()
|
|
169
175
|
});
|
|
170
|
-
var
|
|
176
|
+
var ExternalValidatorRefinement = [
|
|
171
177
|
(data) => data.validatorId !== 0 && data.validatorContract !== zeroAddress || data.validatorId === 0 && data.validatorContract === zeroAddress,
|
|
172
178
|
{
|
|
173
|
-
|
|
179
|
+
error: "Permit external validator :: validatorId and validatorContract must either both be set or both be unset.",
|
|
174
180
|
path: ["validatorId", "validatorContract"]
|
|
175
181
|
}
|
|
176
182
|
];
|
|
183
|
+
var RecipientRefinement = [
|
|
184
|
+
(data) => data.issuer !== data.recipient,
|
|
185
|
+
{
|
|
186
|
+
error: "Sharing permit :: issuer and recipient must not be the same",
|
|
187
|
+
path: ["issuer", "recipient"]
|
|
188
|
+
}
|
|
189
|
+
];
|
|
177
190
|
var SelfPermitOptionsValidator = z.object({
|
|
178
191
|
type: z.literal("self").optional().default("self"),
|
|
179
|
-
issuer:
|
|
180
|
-
message: "Self permit issuer :: invalid address"
|
|
181
|
-
}).refine((val) => is0xPrefixed(val), {
|
|
182
|
-
message: "Self permit issuer :: must be 0x prefixed"
|
|
183
|
-
}).refine((val) => val !== zeroAddress, {
|
|
184
|
-
message: "Self permit issuer :: must not be zeroAddress"
|
|
185
|
-
}),
|
|
192
|
+
issuer: addressNotZeroSchema,
|
|
186
193
|
name: z.string().optional().default("Unnamed Permit"),
|
|
187
|
-
expiration: z.
|
|
188
|
-
recipient:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}),
|
|
195
|
-
validatorId: z.number().optional().default(0),
|
|
196
|
-
validatorContract: z.string().optional().default(zeroAddress).refine((val) => isAddress(val), {
|
|
197
|
-
message: "Self permit validatorContract :: invalid address"
|
|
198
|
-
}),
|
|
199
|
-
issuerSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
|
|
200
|
-
message: "Self permit issuerSignature :: must be 0x prefixed"
|
|
201
|
-
}),
|
|
202
|
-
recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
|
|
203
|
-
message: "Self permit recipientSignature :: must be 0x prefixed"
|
|
204
|
-
})
|
|
205
|
-
}).refine(...ValidatorContractRefinement);
|
|
194
|
+
expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
|
|
195
|
+
recipient: addressSchema.optional().default(zeroAddress),
|
|
196
|
+
validatorId: z.int().optional().default(0),
|
|
197
|
+
validatorContract: addressSchema.optional().default(zeroAddress),
|
|
198
|
+
issuerSignature: bytesSchema.optional().default("0x"),
|
|
199
|
+
recipientSignature: bytesSchema.optional().default("0x")
|
|
200
|
+
}).refine(...ExternalValidatorRefinement);
|
|
206
201
|
var SelfPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "self", {
|
|
207
|
-
|
|
202
|
+
error: "Type must be 'self'"
|
|
208
203
|
}).refine((data) => data.recipient === zeroAddress, {
|
|
209
|
-
|
|
204
|
+
error: "Recipient must be zeroAddress"
|
|
210
205
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
211
|
-
|
|
206
|
+
error: "IssuerSignature must be populated"
|
|
212
207
|
}).refine((data) => data.recipientSignature === "0x", {
|
|
213
|
-
|
|
214
|
-
}).refine(...
|
|
208
|
+
error: "RecipientSignature must be empty"
|
|
209
|
+
}).refine(...ExternalValidatorRefinement);
|
|
215
210
|
var SharingPermitOptionsValidator = z.object({
|
|
216
211
|
type: z.literal("sharing").optional().default("sharing"),
|
|
217
|
-
issuer:
|
|
218
|
-
|
|
219
|
-
}).refine((val) => is0xPrefixed(val), {
|
|
220
|
-
message: "Sharing permit issuer :: must be 0x prefixed"
|
|
221
|
-
}).refine((val) => val !== zeroAddress, {
|
|
222
|
-
message: "Sharing permit issuer :: must not be zeroAddress"
|
|
223
|
-
}),
|
|
224
|
-
recipient: z.string().refine((val) => isAddress(val), {
|
|
225
|
-
message: "Sharing permit recipient :: invalid address"
|
|
226
|
-
}).refine((val) => is0xPrefixed(val), {
|
|
227
|
-
message: "Sharing permit recipient :: must be 0x prefixed"
|
|
228
|
-
}).refine((val) => val !== zeroAddress, {
|
|
229
|
-
message: "Sharing permit recipient :: must not be zeroAddress"
|
|
230
|
-
}),
|
|
212
|
+
issuer: addressNotZeroSchema,
|
|
213
|
+
recipient: addressNotZeroSchema,
|
|
231
214
|
name: z.string().optional().default("Unnamed Permit"),
|
|
232
|
-
expiration: z.
|
|
233
|
-
validatorId: z.
|
|
234
|
-
validatorContract:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
message: "Sharing permit issuerSignature :: must be 0x prefixed"
|
|
239
|
-
}),
|
|
240
|
-
recipientSignature: z.string().optional().default("0x").refine((val) => is0xPrefixed(val), {
|
|
241
|
-
message: "Sharing permit recipientSignature :: must be 0x prefixed"
|
|
242
|
-
})
|
|
243
|
-
}).refine(...ValidatorContractRefinement);
|
|
215
|
+
expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
|
|
216
|
+
validatorId: z.int().optional().default(0),
|
|
217
|
+
validatorContract: addressSchema.optional().default(zeroAddress),
|
|
218
|
+
issuerSignature: bytesSchema.optional().default("0x"),
|
|
219
|
+
recipientSignature: bytesSchema.optional().default("0x")
|
|
220
|
+
}).refine(...RecipientRefinement).refine(...ExternalValidatorRefinement);
|
|
244
221
|
var SharingPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "sharing", {
|
|
245
|
-
|
|
222
|
+
error: "Type must be 'sharing'"
|
|
246
223
|
}).refine((data) => data.recipient !== zeroAddress, {
|
|
247
|
-
|
|
224
|
+
error: "Recipient must not be zeroAddress"
|
|
248
225
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
249
|
-
|
|
226
|
+
error: "IssuerSignature must be populated"
|
|
250
227
|
}).refine((data) => data.recipientSignature === "0x", {
|
|
251
|
-
|
|
252
|
-
}).refine(...
|
|
228
|
+
error: "RecipientSignature must be empty"
|
|
229
|
+
}).refine(...ExternalValidatorRefinement);
|
|
253
230
|
var ImportPermitOptionsValidator = z.object({
|
|
254
231
|
type: z.literal("recipient").optional().default("recipient"),
|
|
255
|
-
issuer:
|
|
256
|
-
|
|
257
|
-
}).refine((val) => is0xPrefixed(val), {
|
|
258
|
-
message: "Import permit issuer :: must be 0x prefixed"
|
|
259
|
-
}).refine((val) => val !== zeroAddress, {
|
|
260
|
-
message: "Import permit issuer :: must not be zeroAddress"
|
|
261
|
-
}),
|
|
262
|
-
recipient: z.string().refine((val) => isAddress(val), {
|
|
263
|
-
message: "Import permit recipient :: invalid address"
|
|
264
|
-
}).refine((val) => is0xPrefixed(val), {
|
|
265
|
-
message: "Import permit recipient :: must be 0x prefixed"
|
|
266
|
-
}).refine((val) => val !== zeroAddress, {
|
|
267
|
-
message: "Import permit recipient :: must not be zeroAddress"
|
|
268
|
-
}),
|
|
269
|
-
issuerSignature: z.string().refine((val) => is0xPrefixed(val), {
|
|
270
|
-
message: "Import permit issuerSignature :: must be 0x prefixed"
|
|
271
|
-
}).refine((val) => val !== "0x", {
|
|
272
|
-
message: "Import permit :: issuerSignature must be provided"
|
|
273
|
-
}),
|
|
232
|
+
issuer: addressNotZeroSchema,
|
|
233
|
+
recipient: addressNotZeroSchema,
|
|
274
234
|
name: z.string().optional().default("Unnamed Permit"),
|
|
275
|
-
expiration: z.
|
|
276
|
-
validatorId: z.
|
|
277
|
-
validatorContract:
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
message: "Import permit recipientSignature :: must be 0x prefixed"
|
|
282
|
-
})
|
|
283
|
-
}).refine(...ValidatorContractRefinement);
|
|
235
|
+
expiration: z.int(),
|
|
236
|
+
validatorId: z.int().optional().default(0),
|
|
237
|
+
validatorContract: addressSchema.optional().default(zeroAddress),
|
|
238
|
+
issuerSignature: bytesNotEmptySchema,
|
|
239
|
+
recipientSignature: bytesSchema.optional().default("0x")
|
|
240
|
+
}).refine(...ExternalValidatorRefinement);
|
|
284
241
|
var ImportPermitValidator = zPermitWithSealingPair.refine((data) => data.type === "recipient", {
|
|
285
|
-
|
|
242
|
+
error: "Type must be 'recipient'"
|
|
286
243
|
}).refine((data) => data.recipient !== zeroAddress, {
|
|
287
|
-
|
|
244
|
+
error: "Recipient must not be zeroAddress"
|
|
288
245
|
}).refine((data) => data.issuerSignature !== "0x", {
|
|
289
|
-
|
|
246
|
+
error: "IssuerSignature must be populated"
|
|
290
247
|
}).refine((data) => data.recipientSignature !== "0x", {
|
|
291
|
-
|
|
292
|
-
}).refine(...
|
|
293
|
-
var
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
248
|
+
error: "RecipientSignature must be populated"
|
|
249
|
+
}).refine(...ExternalValidatorRefinement);
|
|
250
|
+
var safeParseAndThrowFormatted = (schema, data, message) => {
|
|
251
|
+
const result = schema.safeParse(data);
|
|
252
|
+
if (!result.success) {
|
|
253
|
+
throw new Error(`${message}: ${z.prettifyError(result.error)}`, { cause: result.error });
|
|
254
|
+
}
|
|
255
|
+
return result.data;
|
|
256
|
+
};
|
|
257
|
+
var validateSelfPermitOptions = (options) => {
|
|
258
|
+
return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, "Invalid self permit options");
|
|
259
|
+
};
|
|
260
|
+
var validateSharingPermitOptions = (options) => {
|
|
261
|
+
return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, "Invalid sharing permit options");
|
|
262
|
+
};
|
|
263
|
+
var validateImportPermitOptions = (options) => {
|
|
264
|
+
return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, "Invalid import permit options");
|
|
265
|
+
};
|
|
266
|
+
var validateSelfPermit = (permit) => {
|
|
267
|
+
return safeParseAndThrowFormatted(SelfPermitValidator, permit, "Invalid self permit");
|
|
268
|
+
};
|
|
269
|
+
var validateSharingPermit = (permit) => {
|
|
270
|
+
return safeParseAndThrowFormatted(SharingPermitValidator, permit, "Invalid sharing permit");
|
|
271
|
+
};
|
|
272
|
+
var validateImportPermit = (permit) => {
|
|
273
|
+
return safeParseAndThrowFormatted(ImportPermitValidator, permit, "Invalid import permit");
|
|
274
|
+
};
|
|
299
275
|
var ValidationUtils = {
|
|
300
276
|
/**
|
|
301
277
|
* Check if permit is expired
|
|
@@ -390,6 +366,189 @@ var SignatureUtils = {
|
|
|
390
366
|
}
|
|
391
367
|
};
|
|
392
368
|
|
|
369
|
+
// core/consts.ts
|
|
370
|
+
var TASK_MANAGER_ADDRESS = "0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9";
|
|
371
|
+
var MOCKS_ZK_VERIFIER_ADDRESS = "0x0000000000000000000000000000000000005001";
|
|
372
|
+
var MOCKS_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
|
+
|
|
393
552
|
// permits/permit.ts
|
|
394
553
|
var PermitUtils = {
|
|
395
554
|
/**
|
|
@@ -397,14 +556,10 @@ var PermitUtils = {
|
|
|
397
556
|
*/
|
|
398
557
|
createSelf: (options) => {
|
|
399
558
|
const validation = validateSelfPermitOptions(options);
|
|
400
|
-
if (!validation.success) {
|
|
401
|
-
throw new Error(
|
|
402
|
-
"PermitUtils :: createSelf :: Parsing SelfPermitOptions failed " + JSON.stringify(validation.error, null, 2)
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
559
|
const sealingPair = GenerateSealingKey();
|
|
406
560
|
const permit = {
|
|
407
|
-
|
|
561
|
+
hash: PermitUtils.getHash(validation),
|
|
562
|
+
...validation,
|
|
408
563
|
sealingPair,
|
|
409
564
|
_signedDomain: void 0
|
|
410
565
|
};
|
|
@@ -415,14 +570,10 @@ var PermitUtils = {
|
|
|
415
570
|
*/
|
|
416
571
|
createSharing: (options) => {
|
|
417
572
|
const validation = validateSharingPermitOptions(options);
|
|
418
|
-
if (!validation.success) {
|
|
419
|
-
throw new Error(
|
|
420
|
-
"PermitUtils :: createSharing :: Parsing SharingPermitOptions failed " + JSON.stringify(validation.error, null, 2)
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
573
|
const sealingPair = GenerateSealingKey();
|
|
424
574
|
const permit = {
|
|
425
|
-
|
|
575
|
+
hash: PermitUtils.getHash(validation),
|
|
576
|
+
...validation,
|
|
426
577
|
sealingPair,
|
|
427
578
|
_signedDomain: void 0
|
|
428
579
|
};
|
|
@@ -437,27 +588,21 @@ var PermitUtils = {
|
|
|
437
588
|
try {
|
|
438
589
|
parsedOptions = JSON.parse(options);
|
|
439
590
|
} catch (error) {
|
|
440
|
-
throw new Error(`
|
|
591
|
+
throw new Error(`Failed to parse JSON string: ${error}`);
|
|
441
592
|
}
|
|
442
593
|
} else if (typeof options === "object" && options !== null) {
|
|
443
594
|
parsedOptions = options;
|
|
444
595
|
} else {
|
|
445
|
-
throw new Error(
|
|
446
|
-
"PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
|
|
447
|
-
);
|
|
596
|
+
throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
|
|
448
597
|
}
|
|
449
598
|
if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
|
|
450
|
-
throw new Error(`
|
|
599
|
+
throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
|
|
451
600
|
}
|
|
452
601
|
const validation = validateImportPermitOptions({ ...parsedOptions, type: "recipient" });
|
|
453
|
-
if (!validation.success) {
|
|
454
|
-
throw new Error(
|
|
455
|
-
"PermitUtils :: importShared :: Parsing ImportPermitOptions failed " + JSON.stringify(validation.error, null, 2)
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
602
|
const sealingPair = GenerateSealingKey();
|
|
459
603
|
const permit = {
|
|
460
|
-
|
|
604
|
+
hash: PermitUtils.getHash(validation),
|
|
605
|
+
...validation,
|
|
461
606
|
sealingPair,
|
|
462
607
|
_signedDomain: void 0
|
|
463
608
|
};
|
|
@@ -469,11 +614,11 @@ var PermitUtils = {
|
|
|
469
614
|
sign: async (permit, publicClient, walletClient) => {
|
|
470
615
|
if (walletClient == null || walletClient.account == null) {
|
|
471
616
|
throw new Error(
|
|
472
|
-
"
|
|
617
|
+
"Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
|
|
473
618
|
);
|
|
474
619
|
}
|
|
475
620
|
const primaryType = SignatureUtils.getPrimaryType(permit.type);
|
|
476
|
-
const domain = await
|
|
621
|
+
const domain = await getAclEIP712Domain(publicClient);
|
|
477
622
|
const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
|
|
478
623
|
const signature = await walletClient.signTypedData({
|
|
479
624
|
domain,
|
|
@@ -533,6 +678,7 @@ var PermitUtils = {
|
|
|
533
678
|
*/
|
|
534
679
|
serialize: (permit) => {
|
|
535
680
|
return {
|
|
681
|
+
hash: permit.hash,
|
|
536
682
|
name: permit.name,
|
|
537
683
|
type: permit.type,
|
|
538
684
|
issuer: permit.issuer,
|
|
@@ -557,7 +703,7 @@ var PermitUtils = {
|
|
|
557
703
|
} else if (permit.type === "recipient") {
|
|
558
704
|
return validateImportPermit(permit);
|
|
559
705
|
} else {
|
|
560
|
-
throw new Error("
|
|
706
|
+
throw new Error("Invalid permit type");
|
|
561
707
|
}
|
|
562
708
|
},
|
|
563
709
|
/**
|
|
@@ -565,12 +711,7 @@ var PermitUtils = {
|
|
|
565
711
|
*/
|
|
566
712
|
getPermission: (permit, skipValidation = false) => {
|
|
567
713
|
if (!skipValidation) {
|
|
568
|
-
|
|
569
|
-
if (!validationResult.success) {
|
|
570
|
-
throw new Error(
|
|
571
|
-
`PermitUtils :: getPermission :: permit validation failed - ${JSON.stringify(validationResult.error, null, 2)} ${JSON.stringify(permit, null, 2)}`
|
|
572
|
-
);
|
|
573
|
-
}
|
|
714
|
+
PermitUtils.validate(permit);
|
|
574
715
|
}
|
|
575
716
|
return {
|
|
576
717
|
issuer: permit.issuer,
|
|
@@ -651,28 +792,7 @@ var PermitUtils = {
|
|
|
651
792
|
* Fetch EIP712 domain from the blockchain
|
|
652
793
|
*/
|
|
653
794
|
fetchEIP712Domain: async (publicClient) => {
|
|
654
|
-
|
|
655
|
-
const ACL_IFACE = "function acl() view returns (address)";
|
|
656
|
-
const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
|
|
657
|
-
const aclAbi = parseAbi([ACL_IFACE]);
|
|
658
|
-
const aclAddress = await publicClient.readContract({
|
|
659
|
-
address: TASK_MANAGER_ADDRESS,
|
|
660
|
-
abi: aclAbi,
|
|
661
|
-
functionName: "acl"
|
|
662
|
-
});
|
|
663
|
-
const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
|
|
664
|
-
const domain = await publicClient.readContract({
|
|
665
|
-
address: aclAddress,
|
|
666
|
-
abi: domainAbi,
|
|
667
|
-
functionName: "eip712Domain"
|
|
668
|
-
});
|
|
669
|
-
const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
|
|
670
|
-
return {
|
|
671
|
-
name,
|
|
672
|
-
version,
|
|
673
|
-
chainId: Number(chainId),
|
|
674
|
-
verifyingContract
|
|
675
|
-
};
|
|
795
|
+
return getAclEIP712Domain(publicClient);
|
|
676
796
|
},
|
|
677
797
|
/**
|
|
678
798
|
* Check if permit's signed domain matches the provided domain
|
|
@@ -686,8 +806,15 @@ var PermitUtils = {
|
|
|
686
806
|
checkSignedDomainValid: async (permit, publicClient) => {
|
|
687
807
|
if (permit._signedDomain == null)
|
|
688
808
|
return false;
|
|
689
|
-
const domain = await
|
|
809
|
+
const domain = await getAclEIP712Domain(publicClient);
|
|
690
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);
|
|
691
818
|
}
|
|
692
819
|
};
|
|
693
820
|
var PERMIT_STORE_DEFAULTS = {
|
|
@@ -741,11 +868,11 @@ var setPermit = (chainId, account, permit) => {
|
|
|
741
868
|
state.permits[chainId] = {};
|
|
742
869
|
if (state.permits[chainId][account] == null)
|
|
743
870
|
state.permits[chainId][account] = {};
|
|
744
|
-
state.permits[chainId][account][
|
|
871
|
+
state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
|
|
745
872
|
})
|
|
746
873
|
);
|
|
747
874
|
};
|
|
748
|
-
var removePermit = (chainId, account, hash
|
|
875
|
+
var removePermit = (chainId, account, hash) => {
|
|
749
876
|
clearStaleStore();
|
|
750
877
|
_permitStore.setState(
|
|
751
878
|
produce((state) => {
|
|
@@ -759,15 +886,7 @@ var removePermit = (chainId, account, hash, force) => {
|
|
|
759
886
|
if (accountPermits[hash] == null)
|
|
760
887
|
return;
|
|
761
888
|
if (state.activePermitHash[chainId][account] === hash) {
|
|
762
|
-
|
|
763
|
-
if (otherPermitHash) {
|
|
764
|
-
state.activePermitHash[chainId][account] = otherPermitHash;
|
|
765
|
-
} else {
|
|
766
|
-
if (!force) {
|
|
767
|
-
throw new Error("Cannot remove the last permit without force flag");
|
|
768
|
-
}
|
|
769
|
-
state.activePermitHash[chainId][account] = void 0;
|
|
770
|
-
}
|
|
889
|
+
state.activePermitHash[chainId][account] = void 0;
|
|
771
890
|
}
|
|
772
891
|
accountPermits[hash] = void 0;
|
|
773
892
|
})
|
|
@@ -815,4 +934,4 @@ var permitStore = {
|
|
|
815
934
|
resetStore
|
|
816
935
|
};
|
|
817
936
|
|
|
818
|
-
export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, PERMIT_STORE_DEFAULTS, PermitUtils, SealingKey, SelfPermitOptionsValidator, SelfPermitValidator, SharingPermitOptionsValidator, SharingPermitValidator, SignatureTypes, SignatureUtils, ValidationUtils, _permitStore, clearStaleStore, getActivePermit, getActivePermitHash, getPermit, getPermits, getSignatureTypesAndMessage, permitStore, removeActivePermitHash, removePermit, resetStore, setActivePermitHash, setPermit, validateImportPermit, validateImportPermitOptions, validateSelfPermit, validateSelfPermitOptions, validateSharingPermit, validateSharingPermitOptions };
|
|
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 };
|