@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.
Files changed (57) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/chains/defineChain.ts +2 -2
  3. package/chains/types.ts +3 -3
  4. package/core/client.test.ts +111 -0
  5. package/core/client.ts +22 -2
  6. package/core/clientTypes.ts +7 -1
  7. package/core/config.test.ts +8 -0
  8. package/core/config.ts +10 -4
  9. package/core/consts.ts +18 -0
  10. package/core/decrypt/cofheMocksSealOutput.ts +2 -4
  11. package/core/encrypt/cofheMocksZkVerifySign.ts +4 -11
  12. package/core/index.ts +9 -1
  13. package/core/permits.test.ts +5 -6
  14. package/core/permits.ts +5 -4
  15. package/dist/chains.cjs +4 -7
  16. package/dist/chains.d.cts +12 -12
  17. package/dist/chains.d.ts +12 -12
  18. package/dist/chains.js +1 -1
  19. package/dist/{chunk-WGCRJCBR.js → chunk-I5WFEYXX.js} +33 -19
  20. package/dist/{chunk-UGBVZNRT.js → chunk-R3B5TMVX.js} +308 -189
  21. package/dist/{chunk-WEAZ25JO.js → chunk-TBLR7NNE.js} +4 -7
  22. package/dist/{clientTypes-Es7fyi65.d.ts → clientTypes-RqkgkV2i.d.ts} +34 -93
  23. package/dist/{clientTypes-5_1nwtUe.d.cts → clientTypes-e4filDzK.d.cts} +34 -93
  24. package/dist/core.cjs +343 -208
  25. package/dist/core.d.cts +17 -6
  26. package/dist/core.d.ts +17 -6
  27. package/dist/core.js +3 -3
  28. package/dist/node.cjs +337 -208
  29. package/dist/node.d.cts +3 -3
  30. package/dist/node.d.ts +3 -3
  31. package/dist/node.js +3 -3
  32. package/dist/{permit-fUSe6KKq.d.cts → permit-MZ502UBl.d.cts} +30 -33
  33. package/dist/{permit-fUSe6KKq.d.ts → permit-MZ502UBl.d.ts} +30 -33
  34. package/dist/permits.cjs +305 -187
  35. package/dist/permits.d.cts +111 -812
  36. package/dist/permits.d.ts +111 -812
  37. package/dist/permits.js +1 -1
  38. package/dist/types-YiAC4gig.d.cts +33 -0
  39. package/dist/types-YiAC4gig.d.ts +33 -0
  40. package/dist/web.cjs +337 -208
  41. package/dist/web.d.cts +3 -3
  42. package/dist/web.d.ts +3 -3
  43. package/dist/web.js +3 -3
  44. package/package.json +3 -3
  45. package/permits/localstorage.test.ts +9 -13
  46. package/permits/onchain-utils.ts +221 -0
  47. package/permits/permit.test.ts +51 -5
  48. package/permits/permit.ts +28 -74
  49. package/permits/store.test.ts +10 -50
  50. package/permits/store.ts +4 -14
  51. package/permits/test-utils.ts +10 -2
  52. package/permits/types.ts +22 -9
  53. package/permits/utils.ts +0 -4
  54. package/permits/validation.test.ts +29 -32
  55. package/permits/validation.ts +112 -194
  56. package/dist/types-KImPrEIe.d.cts +0 -48
  57. package/dist/types-KImPrEIe.d.ts +0 -48
package/dist/web.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofhesdkInputConfig, a as CofhesdkConfig, b as CofhesdkClient, E as EncryptableItem } from './clientTypes-5_1nwtUe.cjs';
1
+ import { C as CofhesdkInputConfig, a as CofhesdkConfig, b as CofhesdkClient, E as EncryptableItem } from './clientTypes-e4filDzK.cjs';
2
2
  import 'viem';
3
- import './types-KImPrEIe.cjs';
3
+ import './types-YiAC4gig.cjs';
4
4
  import 'zod';
5
- import './permit-fUSe6KKq.cjs';
5
+ import './permit-MZ502UBl.cjs';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/web.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofhesdkInputConfig, a as CofhesdkConfig, b as CofhesdkClient, E as EncryptableItem } from './clientTypes-Es7fyi65.js';
1
+ import { C as CofhesdkInputConfig, a as CofhesdkConfig, b as CofhesdkClient, E as EncryptableItem } from './clientTypes-RqkgkV2i.js';
2
2
  import 'viem';
3
- import './types-KImPrEIe.js';
3
+ import './types-YiAC4gig.js';
4
4
  import 'zod';
5
- import './permit-fUSe6KKq.js';
5
+ import './permit-MZ502UBl.js';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/web.js CHANGED
@@ -1,6 +1,6 @@
1
- import { createCofhesdkConfigBase, createCofhesdkClientBase, fheTypeToString } from './chunk-WGCRJCBR.js';
2
- import './chunk-WEAZ25JO.js';
3
- import './chunk-UGBVZNRT.js';
1
+ import { createCofhesdkConfigBase, createCofhesdkClientBase, fheTypeToString } from './chunk-I5WFEYXX.js';
2
+ import './chunk-TBLR7NNE.js';
3
+ import './chunk-R3B5TMVX.js';
4
4
  import { constructClient } from 'iframe-shared-storage';
5
5
  import init, { init_panic_hook, TfheCompactPublicKey, CompactPkeCrs, ProvenCompactCiphertextList } from 'tfhe';
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofhe/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "SDK for Fhenix COFHE coprocessor interaction",
6
6
  "main": "./dist/core.cjs",
@@ -63,7 +63,7 @@
63
63
  "tfhe": "0.11.1",
64
64
  "tweetnacl": "^1.0.3",
65
65
  "viem": "^2.38.6",
66
- "zod": "^3.22.0",
66
+ "zod": "^4.0.0",
67
67
  "zustand": "^5.0.1"
68
68
  },
69
69
  "peerDependencies": {
@@ -111,7 +111,7 @@
111
111
  "build": "tsup",
112
112
  "dev": "tsup --watch",
113
113
  "lint": "eslint \"**/*.ts*\"",
114
- "type-check": "tsc --noEmit",
114
+ "check:types": "tsc --noEmit",
115
115
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
116
116
  "test": "vitest run",
117
117
  "test:watch": "vitest",
@@ -39,7 +39,6 @@ describe('Permits localStorage Tests', () => {
39
39
 
40
40
  it('should persist permits to localStorage', async () => {
41
41
  const permit = await createMockPermit();
42
- const hash = PermitUtils.getHash(permit);
43
42
 
44
43
  setPermit(chainId, account, permit);
45
44
 
@@ -48,40 +47,38 @@ describe('Permits localStorage Tests', () => {
48
47
  expect(storedData).toBeDefined();
49
48
 
50
49
  const parsedData = JSON.parse(storedData!);
51
- expect(parsedData.state.permits[chainId][account][hash]).toBeDefined();
50
+ expect(parsedData.state.permits[chainId][account][permit.hash]).toBeDefined();
52
51
  });
53
52
 
54
53
  it('should persist active permit hash to localStorage', async () => {
55
54
  const permit = await createMockPermit();
56
- const hash = PermitUtils.getHash(permit);
57
55
 
58
56
  setPermit(chainId, account, permit);
59
- setActivePermitHash(chainId, account, hash);
57
+ setActivePermitHash(chainId, account, permit.hash);
60
58
 
61
59
  // Verify active permit hash is stored
62
60
  const storedData = localStorage.getItem('cofhesdk-permits');
63
61
  expect(storedData).toBeDefined();
64
62
 
65
63
  const parsedData = JSON.parse(storedData!);
66
- expect(parsedData.state.activePermitHash[chainId][account]).toBe(hash);
64
+ expect(parsedData.state.activePermitHash[chainId][account]).toBe(permit.hash);
67
65
  });
68
66
 
69
67
  it('should restore permits from localStorage', async () => {
70
68
  const permit = await createMockPermit();
71
- const hash = PermitUtils.getHash(permit);
72
69
 
73
70
  // Add permit to localStorage
74
71
  setPermit(chainId, account, permit);
75
- setActivePermitHash(chainId, account, hash);
72
+ setActivePermitHash(chainId, account, permit.hash);
76
73
  const serializedPermit = PermitUtils.serialize(permit);
77
74
 
78
75
  // Verify data is restored
79
- const retrievedPermit = getPermit(chainId, account, hash);
76
+ const retrievedPermit = getPermit(chainId, account, permit.hash);
80
77
  expect(retrievedPermit).toBeDefined();
81
78
  expect(PermitUtils.serialize(retrievedPermit!)).toEqual(serializedPermit);
82
79
 
83
80
  const activeHash = getActivePermitHash(chainId, account);
84
- expect(activeHash).toBe(hash);
81
+ expect(activeHash).toBe(permit.hash);
85
82
  });
86
83
 
87
84
  it('should handle corrupted localStorage data gracefully', () => {
@@ -96,22 +93,21 @@ describe('Permits localStorage Tests', () => {
96
93
 
97
94
  it('should clean up localStorage when permits are removed', async () => {
98
95
  const permit = await createMockPermit();
99
- const hash = PermitUtils.getHash(permit);
100
96
 
101
97
  setPermit(chainId, account, permit);
102
- setActivePermitHash(chainId, account, hash);
98
+ setActivePermitHash(chainId, account, permit.hash);
103
99
 
104
100
  // Verify data exists
105
101
  let storedData = localStorage.getItem('cofhesdk-permits');
106
102
  expect(storedData).toBeDefined();
107
103
 
108
104
  // Remove permit
109
- removePermit(chainId, account, hash, true);
105
+ removePermit(chainId, account, permit.hash);
110
106
 
111
107
  // Verify data is cleaned up
112
108
  storedData = localStorage.getItem('cofhesdk-permits');
113
109
  const parsedData = JSON.parse(storedData!);
114
- expect(parsedData.state.permits[chainId][account][hash]).toBeUndefined();
110
+ expect(parsedData.state.permits[chainId][account][permit.hash]).toBeUndefined();
115
111
  expect(parsedData.state.activePermitHash[chainId][account]).toBeUndefined();
116
112
  });
117
113
  });
@@ -0,0 +1,221 @@
1
+ import {
2
+ BaseError,
3
+ ContractFunctionRevertedError,
4
+ type Hex,
5
+ type PublicClient,
6
+ decodeErrorResult,
7
+ parseAbi,
8
+ } from 'viem';
9
+ import type { EIP712Domain, Permission } from './types';
10
+ import { TASK_MANAGER_ADDRESS } from '../core/consts.js';
11
+
12
+ export const getAclAddress = async (publicClient: PublicClient): Promise<Hex> => {
13
+ const ACL_IFACE = 'function acl() view returns (address)';
14
+
15
+ // Parse the ABI for the ACL function
16
+ const aclAbi = parseAbi([ACL_IFACE]);
17
+
18
+ // Get the ACL address
19
+ return (await publicClient.readContract({
20
+ address: TASK_MANAGER_ADDRESS as `0x${string}`,
21
+ abi: aclAbi,
22
+ functionName: 'acl',
23
+ })) as `0x${string}`;
24
+ };
25
+
26
+ export const getAclEIP712Domain = async (publicClient: PublicClient): Promise<EIP712Domain> => {
27
+ const aclAddress = await getAclAddress(publicClient);
28
+ const EIP712_DOMAIN_IFACE =
29
+ 'function eip712Domain() public view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)';
30
+
31
+ // Parse the ABI for the EIP712 domain function
32
+ const domainAbi = parseAbi([EIP712_DOMAIN_IFACE]);
33
+
34
+ // Get the EIP712 domain
35
+ const domain = await publicClient.readContract({
36
+ address: aclAddress,
37
+ abi: domainAbi,
38
+ functionName: 'eip712Domain',
39
+ });
40
+
41
+ // eslint-disable-next-line no-unused-vars
42
+ const [_fields, name, version, chainId, verifyingContract, _salt, _extensions] = domain;
43
+
44
+ return {
45
+ name,
46
+ version,
47
+ chainId: Number(chainId),
48
+ verifyingContract,
49
+ };
50
+ };
51
+
52
+ export const checkPermitValidityOnChain = async (
53
+ permission: Permission,
54
+ publicClient: PublicClient
55
+ ): Promise<boolean> => {
56
+ const aclAddress = await getAclAddress(publicClient);
57
+
58
+ // Check if the permit is valid
59
+ try {
60
+ await publicClient.simulateContract({
61
+ address: aclAddress,
62
+ abi: checkPermitValidityAbi,
63
+ functionName: 'checkPermitValidity',
64
+ args: [
65
+ {
66
+ issuer: permission.issuer,
67
+ expiration: BigInt(permission.expiration),
68
+ recipient: permission.recipient,
69
+ validatorId: BigInt(permission.validatorId),
70
+ validatorContract: permission.validatorContract,
71
+ sealingKey: permission.sealingKey,
72
+ issuerSignature: permission.issuerSignature,
73
+ recipientSignature: permission.recipientSignature,
74
+ },
75
+ ],
76
+ });
77
+ return true;
78
+ } catch (err: any) {
79
+ // Viem default handling
80
+ if (err instanceof BaseError) {
81
+ const revertError = err.walk((err: any) => err instanceof ContractFunctionRevertedError);
82
+ if (revertError instanceof ContractFunctionRevertedError) {
83
+ const errorName = revertError.data?.errorName ?? '';
84
+ throw new Error(errorName);
85
+ }
86
+ }
87
+
88
+ // Check details field for custom error names (e.g., from Hardhat test nodes)
89
+ const customErrorName = extractCustomErrorFromDetails(err, checkPermitValidityAbi);
90
+ if (customErrorName) {
91
+ throw new Error(customErrorName);
92
+ }
93
+
94
+ // Hardhat wrapped error will need to be unwrapped to get the return data
95
+ const hhDetailsData = extractReturnData(err);
96
+ if (hhDetailsData != null) {
97
+ const decoded = decodeErrorResult({
98
+ abi: checkPermitValidityAbi,
99
+ data: hhDetailsData,
100
+ });
101
+
102
+ throw new Error(decoded.errorName);
103
+ }
104
+
105
+ // Fallback throw the original error
106
+ throw err;
107
+ }
108
+ };
109
+
110
+ function extractCustomErrorFromDetails(err: unknown, abi: readonly any[]): string | undefined {
111
+ // Check details field for custom error names (e.g., from Hardhat test nodes)
112
+ const anyErr = err as any;
113
+ const details = anyErr?.details ?? anyErr?.cause?.details;
114
+
115
+ if (typeof details === 'string') {
116
+ // Match pattern: "reverted with custom error 'ErrorName()'"
117
+ const customErrorMatch = details.match(/reverted with custom error '(\w+)\(\)'/);
118
+ if (customErrorMatch) {
119
+ const errorName = customErrorMatch[1];
120
+ // Check if this error exists in our ABI
121
+ const errorExists = abi.some((item) => item.type === 'error' && item.name === errorName);
122
+ if (errorExists) {
123
+ return errorName;
124
+ }
125
+ }
126
+ }
127
+
128
+ return undefined;
129
+ }
130
+
131
+ function extractReturnData(err: unknown): `0x${string}` | undefined {
132
+ // viem BaseError has `details`, but fall back to any message-like string we can find
133
+ const anyErr = err as any;
134
+ const s = anyErr?.details ?? anyErr?.cause?.details ?? anyErr?.shortMessage ?? anyErr?.message ?? String(err);
135
+
136
+ return s.match(/return data:\s*(0x[a-fA-F0-9]+)/)?.[1] as `0x${string}` | undefined;
137
+ }
138
+
139
+ const checkPermitValidityAbi = [
140
+ {
141
+ type: 'function',
142
+ name: 'checkPermitValidity',
143
+ inputs: [
144
+ {
145
+ name: 'permission',
146
+ type: 'tuple',
147
+ internalType: 'struct Permission',
148
+ components: [
149
+ {
150
+ name: 'issuer',
151
+ type: 'address',
152
+ internalType: 'address',
153
+ },
154
+ {
155
+ name: 'expiration',
156
+ type: 'uint64',
157
+ internalType: 'uint64',
158
+ },
159
+ {
160
+ name: 'recipient',
161
+ type: 'address',
162
+ internalType: 'address',
163
+ },
164
+ {
165
+ name: 'validatorId',
166
+ type: 'uint256',
167
+ internalType: 'uint256',
168
+ },
169
+ {
170
+ name: 'validatorContract',
171
+ type: 'address',
172
+ internalType: 'address',
173
+ },
174
+ {
175
+ name: 'sealingKey',
176
+ type: 'bytes32',
177
+ internalType: 'bytes32',
178
+ },
179
+ {
180
+ name: 'issuerSignature',
181
+ type: 'bytes',
182
+ internalType: 'bytes',
183
+ },
184
+ {
185
+ name: 'recipientSignature',
186
+ type: 'bytes',
187
+ internalType: 'bytes',
188
+ },
189
+ ],
190
+ },
191
+ ],
192
+ outputs: [
193
+ {
194
+ name: '',
195
+ type: 'bool',
196
+ internalType: 'bool',
197
+ },
198
+ ],
199
+ stateMutability: 'view',
200
+ },
201
+ {
202
+ type: 'error',
203
+ name: 'PermissionInvalid_Disabled',
204
+ inputs: [],
205
+ },
206
+ {
207
+ type: 'error',
208
+ name: 'PermissionInvalid_Expired',
209
+ inputs: [],
210
+ },
211
+ {
212
+ type: 'error',
213
+ name: 'PermissionInvalid_IssuerSignature',
214
+ inputs: [],
215
+ },
216
+ {
217
+ type: 'error',
218
+ name: 'PermissionInvalid_RecipientSignature',
219
+ inputs: [],
220
+ },
221
+ ] as const;
@@ -46,6 +46,7 @@ describe('PermitUtils Tests', () => {
46
46
 
47
47
  const permit = PermitUtils.createSelf(options);
48
48
 
49
+ expect(permit.hash).toBe(PermitUtils.getHash(permit));
49
50
  expect(permit.type).toBe('self');
50
51
  expect(permit.name).toBe('Test Permit');
51
52
  expect(permit.type).toBe('self');
@@ -81,6 +82,7 @@ describe('PermitUtils Tests', () => {
81
82
 
82
83
  const permit = PermitUtils.createSharing(options);
83
84
 
85
+ expect(permit.hash).toBe(PermitUtils.getHash(permit));
84
86
  expect(permit.type).toBe('sharing');
85
87
  expect(permit.name).toBe('Test Sharing Permit');
86
88
  expect(permit.type).toBe('sharing');
@@ -111,6 +113,7 @@ describe('PermitUtils Tests', () => {
111
113
  it('should import a shared permit with valid options', async () => {
112
114
  const options: ImportSharedPermitOptions = {
113
115
  issuer: bobAddress,
116
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
114
117
  recipient: aliceAddress,
115
118
  issuerSignature: '0x1234567890abcdef',
116
119
  name: 'Test Import Permit',
@@ -118,6 +121,7 @@ describe('PermitUtils Tests', () => {
118
121
 
119
122
  const permit = PermitUtils.importShared(options);
120
123
 
124
+ expect(permit.hash).toBe(PermitUtils.getHash(permit));
121
125
  expect(permit.type).toBe('recipient');
122
126
  expect(permit.name).toBe('Test Import Permit');
123
127
  expect(permit.issuer).toBe(bobAddress);
@@ -134,6 +138,7 @@ describe('PermitUtils Tests', () => {
134
138
  it('should import a shared permit with valid options as string', async () => {
135
139
  const options: ImportSharedPermitOptions = {
136
140
  issuer: bobAddress,
141
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
137
142
  recipient: aliceAddress,
138
143
  issuerSignature: '0x1234567890abcdef',
139
144
  };
@@ -168,6 +173,7 @@ describe('PermitUtils Tests', () => {
168
173
  it('should throw error for missing issuerSignature', async () => {
169
174
  const options: ImportSharedPermitOptions = {
170
175
  issuer: bobAddress,
176
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
171
177
  recipient: aliceAddress,
172
178
  issuerSignature: '0x', // Invalid empty signature
173
179
  name: 'Test Import Permit',
@@ -175,6 +181,15 @@ describe('PermitUtils Tests', () => {
175
181
 
176
182
  expect(() => PermitUtils.importShared(options)).toThrow();
177
183
  });
184
+
185
+ it('should throw error for missing expiration', async () => {
186
+ const options = {
187
+ issuer: bobAddress,
188
+ recipient: aliceAddress,
189
+ issuerSignature: '0x1234567890abcdef',
190
+ } as unknown as ImportSharedPermitOptions;
191
+ expect(() => PermitUtils.importShared(options)).toThrow();
192
+ });
178
193
  });
179
194
 
180
195
  describe('createSelfAndSign', () => {
@@ -217,6 +232,7 @@ describe('PermitUtils Tests', () => {
217
232
  const options: ImportSharedPermitOptions = {
218
233
  issuer: bobAddress,
219
234
  recipient: aliceAddress,
235
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
220
236
  issuerSignature: '0x1234567890abcdef',
221
237
  name: 'Test Import Permit',
222
238
  };
@@ -233,6 +249,7 @@ describe('PermitUtils Tests', () => {
233
249
  const options: ImportSharedPermitOptions = {
234
250
  issuer: bobAddress,
235
251
  recipient: aliceAddress,
252
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
236
253
  issuerSignature: '0x1234567890abcdef',
237
254
  };
238
255
 
@@ -250,6 +267,7 @@ describe('PermitUtils Tests', () => {
250
267
  const options: ImportSharedPermitOptions = {
251
268
  issuer: bobAddress,
252
269
  recipient: aliceAddress,
270
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
253
271
  issuerSignature: '0x1234567890abcdef',
254
272
  };
255
273
 
@@ -283,7 +301,8 @@ describe('PermitUtils Tests', () => {
283
301
  const permit = PermitUtils.importShared({
284
302
  issuer: bobAddress,
285
303
  recipient: aliceAddress,
286
- issuerSignature: '0xexisting-signature',
304
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
305
+ issuerSignature: '0x1111111111111111111111111111111111111111111111111111111111111111',
287
306
  name: 'Test Permit',
288
307
  });
289
308
 
@@ -361,10 +380,7 @@ describe('PermitUtils Tests', () => {
361
380
  name: 'Test Permit',
362
381
  });
363
382
 
364
- const hash1 = PermitUtils.getHash(permit1);
365
- const hash2 = PermitUtils.getHash(permit2);
366
-
367
- expect(hash1).toBe(hash2);
383
+ expect(permit1.hash).toBe(permit2.hash);
368
384
  });
369
385
  });
370
386
 
@@ -473,5 +489,35 @@ describe('PermitUtils Tests', () => {
473
489
 
474
490
  expect(typeof isValid).toBe('boolean');
475
491
  }, 10000); // 10 second timeout for network call
492
+
493
+ // TODO: Uncomment when updated ACL with checkPermitValidity function is deployed
494
+
495
+ // it('should check permit validity on chain with real contract data', async () => {
496
+ // const permit = PermitUtils.createSelf({
497
+ // type: 'self',
498
+ // issuer: bobAddress,
499
+ // name: 'Test Permit',
500
+ // });
501
+
502
+ // const signedPermit = await PermitUtils.sign(permit, publicClient, bobWalletClient);
503
+
504
+ // const isValid = await PermitUtils.checkValidityOnChain(signedPermit, publicClient);
505
+
506
+ // expect(typeof isValid).toBe('boolean');
507
+ // expect(isValid).toBe(true);
508
+
509
+ // const permitInvalid = PermitUtils.createSelf({
510
+ // type: 'self',
511
+ // issuer: bobAddress,
512
+ // name: 'Test Permit',
513
+ // expiration: Math.floor(Date.now() / 1000) - 3600, // 1 hour ago
514
+ // });
515
+
516
+ // const signedPermitInvalid = await PermitUtils.sign(permitInvalid, publicClient, bobWalletClient);
517
+ // const isValidInvalid = await PermitUtils.checkValidityOnChain(signedPermitInvalid, publicClient);
518
+
519
+ // expect(typeof isValidInvalid).toBe('boolean');
520
+ // expect(isValidInvalid).toBe(false);
521
+ // });
476
522
  });
477
523
  });