@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
|
@@ -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,190 @@ 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_THRESHOLD_NETWORK_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
|
+
var MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d";
|
|
377
|
+
|
|
378
|
+
// permits/onchain-utils.ts
|
|
379
|
+
var getAclAddress = async (publicClient) => {
|
|
380
|
+
const ACL_IFACE = "function acl() view returns (address)";
|
|
381
|
+
const aclAbi = parseAbi([ACL_IFACE]);
|
|
382
|
+
return await publicClient.readContract({
|
|
383
|
+
address: TASK_MANAGER_ADDRESS,
|
|
384
|
+
abi: aclAbi,
|
|
385
|
+
functionName: "acl"
|
|
386
|
+
});
|
|
387
|
+
};
|
|
388
|
+
var getAclEIP712Domain = async (publicClient) => {
|
|
389
|
+
const aclAddress = await getAclAddress(publicClient);
|
|
390
|
+
const EIP712_DOMAIN_IFACE = "function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)";
|
|
391
|
+
const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
|
|
392
|
+
const domain = await publicClient.readContract({
|
|
393
|
+
address: aclAddress,
|
|
394
|
+
abi: domainAbi,
|
|
395
|
+
functionName: "eip712Domain"
|
|
396
|
+
});
|
|
397
|
+
const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
|
|
398
|
+
return {
|
|
399
|
+
name,
|
|
400
|
+
version,
|
|
401
|
+
chainId: Number(chainId),
|
|
402
|
+
verifyingContract
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
var checkPermitValidityOnChain = async (permission, publicClient) => {
|
|
406
|
+
const aclAddress = await getAclAddress(publicClient);
|
|
407
|
+
try {
|
|
408
|
+
await publicClient.simulateContract({
|
|
409
|
+
address: aclAddress,
|
|
410
|
+
abi: checkPermitValidityAbi,
|
|
411
|
+
functionName: "checkPermitValidity",
|
|
412
|
+
args: [
|
|
413
|
+
{
|
|
414
|
+
issuer: permission.issuer,
|
|
415
|
+
expiration: BigInt(permission.expiration),
|
|
416
|
+
recipient: permission.recipient,
|
|
417
|
+
validatorId: BigInt(permission.validatorId),
|
|
418
|
+
validatorContract: permission.validatorContract,
|
|
419
|
+
sealingKey: permission.sealingKey,
|
|
420
|
+
issuerSignature: permission.issuerSignature,
|
|
421
|
+
recipientSignature: permission.recipientSignature
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
});
|
|
425
|
+
return true;
|
|
426
|
+
} catch (err) {
|
|
427
|
+
if (err instanceof BaseError) {
|
|
428
|
+
const revertError = err.walk((err2) => err2 instanceof ContractFunctionRevertedError);
|
|
429
|
+
if (revertError instanceof ContractFunctionRevertedError) {
|
|
430
|
+
const errorName = revertError.data?.errorName ?? "";
|
|
431
|
+
throw new Error(errorName);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
|
|
435
|
+
if (customErrorName) {
|
|
436
|
+
throw new Error(customErrorName);
|
|
437
|
+
}
|
|
438
|
+
const hhDetailsData = extractReturnData(err);
|
|
439
|
+
if (hhDetailsData != null) {
|
|
440
|
+
const decoded = decodeErrorResult({
|
|
441
|
+
abi: checkPermitValidityAbi,
|
|
442
|
+
data: hhDetailsData
|
|
443
|
+
});
|
|
444
|
+
throw new Error(decoded.errorName);
|
|
445
|
+
}
|
|
446
|
+
throw err;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
function extractCustomErrorFromDetails(err, abi) {
|
|
450
|
+
const anyErr = err;
|
|
451
|
+
const details = anyErr?.details ?? anyErr?.cause?.details;
|
|
452
|
+
if (typeof details === "string") {
|
|
453
|
+
const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
|
|
454
|
+
if (customErrorMatch) {
|
|
455
|
+
const errorName = customErrorMatch[1];
|
|
456
|
+
const errorExists = abi.some((item) => item.type === "error" && item.name === errorName);
|
|
457
|
+
if (errorExists) {
|
|
458
|
+
return errorName;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return void 0;
|
|
463
|
+
}
|
|
464
|
+
function extractReturnData(err) {
|
|
465
|
+
const anyErr = err;
|
|
466
|
+
const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
|
|
467
|
+
return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1];
|
|
468
|
+
}
|
|
469
|
+
var checkPermitValidityAbi = [
|
|
470
|
+
{
|
|
471
|
+
type: "function",
|
|
472
|
+
name: "checkPermitValidity",
|
|
473
|
+
inputs: [
|
|
474
|
+
{
|
|
475
|
+
name: "permission",
|
|
476
|
+
type: "tuple",
|
|
477
|
+
internalType: "struct Permission",
|
|
478
|
+
components: [
|
|
479
|
+
{
|
|
480
|
+
name: "issuer",
|
|
481
|
+
type: "address",
|
|
482
|
+
internalType: "address"
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
name: "expiration",
|
|
486
|
+
type: "uint64",
|
|
487
|
+
internalType: "uint64"
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "recipient",
|
|
491
|
+
type: "address",
|
|
492
|
+
internalType: "address"
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
name: "validatorId",
|
|
496
|
+
type: "uint256",
|
|
497
|
+
internalType: "uint256"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
name: "validatorContract",
|
|
501
|
+
type: "address",
|
|
502
|
+
internalType: "address"
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: "sealingKey",
|
|
506
|
+
type: "bytes32",
|
|
507
|
+
internalType: "bytes32"
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
name: "issuerSignature",
|
|
511
|
+
type: "bytes",
|
|
512
|
+
internalType: "bytes"
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
name: "recipientSignature",
|
|
516
|
+
type: "bytes",
|
|
517
|
+
internalType: "bytes"
|
|
518
|
+
}
|
|
519
|
+
]
|
|
520
|
+
}
|
|
521
|
+
],
|
|
522
|
+
outputs: [
|
|
523
|
+
{
|
|
524
|
+
name: "",
|
|
525
|
+
type: "bool",
|
|
526
|
+
internalType: "bool"
|
|
527
|
+
}
|
|
528
|
+
],
|
|
529
|
+
stateMutability: "view"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
type: "error",
|
|
533
|
+
name: "PermissionInvalid_Disabled",
|
|
534
|
+
inputs: []
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
type: "error",
|
|
538
|
+
name: "PermissionInvalid_Expired",
|
|
539
|
+
inputs: []
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
type: "error",
|
|
543
|
+
name: "PermissionInvalid_IssuerSignature",
|
|
544
|
+
inputs: []
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
type: "error",
|
|
548
|
+
name: "PermissionInvalid_RecipientSignature",
|
|
549
|
+
inputs: []
|
|
550
|
+
}
|
|
551
|
+
];
|
|
552
|
+
|
|
393
553
|
// permits/permit.ts
|
|
394
554
|
var PermitUtils = {
|
|
395
555
|
/**
|
|
@@ -397,14 +557,10 @@ var PermitUtils = {
|
|
|
397
557
|
*/
|
|
398
558
|
createSelf: (options) => {
|
|
399
559
|
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
560
|
const sealingPair = GenerateSealingKey();
|
|
406
561
|
const permit = {
|
|
407
|
-
|
|
562
|
+
hash: PermitUtils.getHash(validation),
|
|
563
|
+
...validation,
|
|
408
564
|
sealingPair,
|
|
409
565
|
_signedDomain: void 0
|
|
410
566
|
};
|
|
@@ -415,14 +571,10 @@ var PermitUtils = {
|
|
|
415
571
|
*/
|
|
416
572
|
createSharing: (options) => {
|
|
417
573
|
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
574
|
const sealingPair = GenerateSealingKey();
|
|
424
575
|
const permit = {
|
|
425
|
-
|
|
576
|
+
hash: PermitUtils.getHash(validation),
|
|
577
|
+
...validation,
|
|
426
578
|
sealingPair,
|
|
427
579
|
_signedDomain: void 0
|
|
428
580
|
};
|
|
@@ -437,27 +589,21 @@ var PermitUtils = {
|
|
|
437
589
|
try {
|
|
438
590
|
parsedOptions = JSON.parse(options);
|
|
439
591
|
} catch (error) {
|
|
440
|
-
throw new Error(`
|
|
592
|
+
throw new Error(`Failed to parse JSON string: ${error}`);
|
|
441
593
|
}
|
|
442
594
|
} else if (typeof options === "object" && options !== null) {
|
|
443
595
|
parsedOptions = options;
|
|
444
596
|
} else {
|
|
445
|
-
throw new Error(
|
|
446
|
-
"PermitUtils :: importShared :: Invalid input type, expected ImportSharedPermitOptions, object, or string"
|
|
447
|
-
);
|
|
597
|
+
throw new Error("Invalid input type, expected ImportSharedPermitOptions, object, or string");
|
|
448
598
|
}
|
|
449
599
|
if (parsedOptions.type != null && parsedOptions.type !== "sharing") {
|
|
450
|
-
throw new Error(`
|
|
600
|
+
throw new Error(`Invalid permit type <${parsedOptions.type}>, must be "sharing"`);
|
|
451
601
|
}
|
|
452
602
|
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
603
|
const sealingPair = GenerateSealingKey();
|
|
459
604
|
const permit = {
|
|
460
|
-
|
|
605
|
+
hash: PermitUtils.getHash(validation),
|
|
606
|
+
...validation,
|
|
461
607
|
sealingPair,
|
|
462
608
|
_signedDomain: void 0
|
|
463
609
|
};
|
|
@@ -469,11 +615,11 @@ var PermitUtils = {
|
|
|
469
615
|
sign: async (permit, publicClient, walletClient) => {
|
|
470
616
|
if (walletClient == null || walletClient.account == null) {
|
|
471
617
|
throw new Error(
|
|
472
|
-
"
|
|
618
|
+
"Missing walletClient, you must pass in a `walletClient` for the connected user to create a permit signature"
|
|
473
619
|
);
|
|
474
620
|
}
|
|
475
621
|
const primaryType = SignatureUtils.getPrimaryType(permit.type);
|
|
476
|
-
const domain = await
|
|
622
|
+
const domain = await getAclEIP712Domain(publicClient);
|
|
477
623
|
const { types, message } = SignatureUtils.getSignatureParams(PermitUtils.getPermission(permit, true), primaryType);
|
|
478
624
|
const signature = await walletClient.signTypedData({
|
|
479
625
|
domain,
|
|
@@ -533,6 +679,7 @@ var PermitUtils = {
|
|
|
533
679
|
*/
|
|
534
680
|
serialize: (permit) => {
|
|
535
681
|
return {
|
|
682
|
+
hash: permit.hash,
|
|
536
683
|
name: permit.name,
|
|
537
684
|
type: permit.type,
|
|
538
685
|
issuer: permit.issuer,
|
|
@@ -557,7 +704,7 @@ var PermitUtils = {
|
|
|
557
704
|
} else if (permit.type === "recipient") {
|
|
558
705
|
return validateImportPermit(permit);
|
|
559
706
|
} else {
|
|
560
|
-
throw new Error("
|
|
707
|
+
throw new Error("Invalid permit type");
|
|
561
708
|
}
|
|
562
709
|
},
|
|
563
710
|
/**
|
|
@@ -565,12 +712,7 @@ var PermitUtils = {
|
|
|
565
712
|
*/
|
|
566
713
|
getPermission: (permit, skipValidation = false) => {
|
|
567
714
|
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
|
-
}
|
|
715
|
+
PermitUtils.validate(permit);
|
|
574
716
|
}
|
|
575
717
|
return {
|
|
576
718
|
issuer: permit.issuer,
|
|
@@ -651,28 +793,7 @@ var PermitUtils = {
|
|
|
651
793
|
* Fetch EIP712 domain from the blockchain
|
|
652
794
|
*/
|
|
653
795
|
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
|
-
};
|
|
796
|
+
return getAclEIP712Domain(publicClient);
|
|
676
797
|
},
|
|
677
798
|
/**
|
|
678
799
|
* Check if permit's signed domain matches the provided domain
|
|
@@ -686,8 +807,15 @@ var PermitUtils = {
|
|
|
686
807
|
checkSignedDomainValid: async (permit, publicClient) => {
|
|
687
808
|
if (permit._signedDomain == null)
|
|
688
809
|
return false;
|
|
689
|
-
const domain = await
|
|
810
|
+
const domain = await getAclEIP712Domain(publicClient);
|
|
690
811
|
return PermitUtils.matchesDomain(permit, domain);
|
|
812
|
+
},
|
|
813
|
+
/**
|
|
814
|
+
* Check if permit passes the on-chain validation
|
|
815
|
+
*/
|
|
816
|
+
checkValidityOnChain: async (permit, publicClient) => {
|
|
817
|
+
const permission = PermitUtils.getPermission(permit);
|
|
818
|
+
return checkPermitValidityOnChain(permission, publicClient);
|
|
691
819
|
}
|
|
692
820
|
};
|
|
693
821
|
var PERMIT_STORE_DEFAULTS = {
|
|
@@ -741,11 +869,11 @@ var setPermit = (chainId, account, permit) => {
|
|
|
741
869
|
state.permits[chainId] = {};
|
|
742
870
|
if (state.permits[chainId][account] == null)
|
|
743
871
|
state.permits[chainId][account] = {};
|
|
744
|
-
state.permits[chainId][account][
|
|
872
|
+
state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
|
|
745
873
|
})
|
|
746
874
|
);
|
|
747
875
|
};
|
|
748
|
-
var removePermit = (chainId, account, hash
|
|
876
|
+
var removePermit = (chainId, account, hash) => {
|
|
749
877
|
clearStaleStore();
|
|
750
878
|
_permitStore.setState(
|
|
751
879
|
produce((state) => {
|
|
@@ -759,15 +887,7 @@ var removePermit = (chainId, account, hash, force) => {
|
|
|
759
887
|
if (accountPermits[hash] == null)
|
|
760
888
|
return;
|
|
761
889
|
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
|
-
}
|
|
890
|
+
state.activePermitHash[chainId][account] = void 0;
|
|
771
891
|
}
|
|
772
892
|
accountPermits[hash] = void 0;
|
|
773
893
|
})
|
|
@@ -815,4 +935,4 @@ var permitStore = {
|
|
|
815
935
|
resetStore
|
|
816
936
|
};
|
|
817
937
|
|
|
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 };
|
|
938
|
+
export { GenerateSealingKey, ImportPermitOptionsValidator, ImportPermitValidator, MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY, MOCKS_THRESHOLD_NETWORK_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 };
|