@cofhe/sdk 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/adapters/ethers6.ts +28 -28
  3. package/adapters/hardhat.ts +0 -1
  4. package/adapters/index.test.ts +14 -19
  5. package/adapters/smartWallet.ts +81 -73
  6. package/adapters/test-utils.ts +45 -45
  7. package/adapters/types.ts +3 -3
  8. package/chains/chains/localcofhe.ts +14 -0
  9. package/chains/chains.test.ts +2 -1
  10. package/chains/defineChain.ts +2 -2
  11. package/chains/index.ts +3 -1
  12. package/chains/types.ts +3 -3
  13. package/core/baseBuilder.ts +30 -49
  14. package/core/client.test.ts +200 -72
  15. package/core/client.ts +152 -148
  16. package/core/clientTypes.ts +114 -0
  17. package/core/config.test.ts +30 -11
  18. package/core/config.ts +26 -13
  19. package/core/consts.ts +18 -0
  20. package/core/decrypt/cofheMocksSealOutput.ts +2 -4
  21. package/core/decrypt/decryptHandleBuilder.ts +51 -45
  22. package/core/decrypt/{tnSealOutput.ts → tnSealOutputV1.ts} +1 -1
  23. package/core/decrypt/tnSealOutputV2.ts +298 -0
  24. package/core/encrypt/cofheMocksZkVerifySign.ts +15 -16
  25. package/core/encrypt/encryptInputsBuilder.test.ts +132 -116
  26. package/core/encrypt/encryptInputsBuilder.ts +159 -111
  27. package/core/encrypt/encryptUtils.ts +6 -3
  28. package/core/encrypt/zkPackProveVerify.ts +70 -8
  29. package/core/error.ts +0 -2
  30. package/core/fetchKeys.test.ts +1 -18
  31. package/core/fetchKeys.ts +0 -26
  32. package/core/index.ts +37 -17
  33. package/core/keyStore.ts +65 -38
  34. package/core/permits.test.ts +255 -4
  35. package/core/permits.ts +83 -18
  36. package/core/types.ts +198 -152
  37. package/core/utils.ts +43 -1
  38. package/dist/adapters.d.cts +38 -20
  39. package/dist/adapters.d.ts +38 -20
  40. package/dist/chains.cjs +18 -8
  41. package/dist/chains.d.cts +31 -9
  42. package/dist/chains.d.ts +31 -9
  43. package/dist/chains.js +1 -1
  44. package/dist/{chunk-KFGPTJ6X.js → chunk-I5WFEYXX.js} +1768 -1526
  45. package/dist/{chunk-LU7BMUUT.js → chunk-R3B5TMVX.js} +330 -197
  46. package/dist/{chunk-GZCQQYVI.js → chunk-TBLR7NNE.js} +18 -9
  47. package/dist/{types-PhwGgQvs.d.ts → clientTypes-RqkgkV2i.d.ts} +331 -429
  48. package/dist/{types-bB7wLj0q.d.cts → clientTypes-e4filDzK.d.cts} +331 -429
  49. package/dist/core.cjs +3000 -2625
  50. package/dist/core.d.cts +113 -7
  51. package/dist/core.d.ts +113 -7
  52. package/dist/core.js +3 -3
  53. package/dist/node.cjs +2851 -2526
  54. package/dist/node.d.cts +4 -4
  55. package/dist/node.d.ts +4 -4
  56. package/dist/node.js +4 -3
  57. package/dist/{permit-S9CnI6MF.d.cts → permit-MZ502UBl.d.cts} +54 -41
  58. package/dist/{permit-S9CnI6MF.d.ts → permit-MZ502UBl.d.ts} +54 -41
  59. package/dist/permits.cjs +328 -195
  60. package/dist/permits.d.cts +113 -825
  61. package/dist/permits.d.ts +113 -825
  62. package/dist/permits.js +1 -1
  63. package/dist/types-YiAC4gig.d.cts +33 -0
  64. package/dist/types-YiAC4gig.d.ts +33 -0
  65. package/dist/web.cjs +3067 -2527
  66. package/dist/web.d.cts +22 -6
  67. package/dist/web.d.ts +22 -6
  68. package/dist/web.js +185 -9
  69. package/dist/zkProve.worker.cjs +93 -0
  70. package/dist/zkProve.worker.d.cts +2 -0
  71. package/dist/zkProve.worker.d.ts +2 -0
  72. package/dist/zkProve.worker.js +91 -0
  73. package/node/client.test.ts +20 -25
  74. package/node/encryptInputs.test.ts +18 -38
  75. package/node/index.ts +1 -0
  76. package/package.json +15 -15
  77. package/permits/index.ts +1 -0
  78. package/permits/localstorage.test.ts +9 -14
  79. package/permits/onchain-utils.ts +221 -0
  80. package/permits/permit.test.ts +76 -27
  81. package/permits/permit.ts +58 -95
  82. package/permits/sealing.test.ts +3 -3
  83. package/permits/sealing.ts +2 -2
  84. package/permits/store.test.ts +10 -50
  85. package/permits/store.ts +9 -21
  86. package/permits/test-utils.ts +11 -3
  87. package/permits/types.ts +39 -9
  88. package/permits/utils.ts +0 -5
  89. package/permits/validation.test.ts +29 -32
  90. package/permits/validation.ts +114 -176
  91. package/web/client.web.test.ts +20 -25
  92. package/web/config.web.test.ts +0 -2
  93. package/web/encryptInputs.web.test.ts +31 -54
  94. package/web/index.ts +65 -1
  95. package/web/storage.ts +19 -5
  96. package/web/worker.builder.web.test.ts +148 -0
  97. package/web/worker.config.web.test.ts +329 -0
  98. package/web/worker.output.web.test.ts +84 -0
  99. package/web/workerManager.test.ts +80 -0
  100. package/web/workerManager.ts +214 -0
  101. package/web/workerManager.web.test.ts +114 -0
  102. package/web/zkProve.worker.ts +133 -0
  103. package/core/result.test.ts +0 -180
  104. package/core/result.ts +0 -67
  105. package/core/test-utils.ts +0 -45
  106. package/dist/types-KImPrEIe.d.cts +0 -48
  107. package/dist/types-KImPrEIe.d.ts +0 -48
@@ -32,10 +32,9 @@ describe('Storage Tests', () => {
32
32
  describe('Permit Storage', () => {
33
33
  it('should store and retrieve permits', async () => {
34
34
  const permit = await createMockPermit();
35
- const hash = PermitUtils.getHash(permit);
36
35
 
37
36
  setPermit(chainId, account, permit);
38
- const retrieved = getPermit(chainId, account, hash);
37
+ const retrieved = getPermit(chainId, account, permit.hash);
39
38
 
40
39
  expect(retrieved).toBeDefined();
41
40
  expect(PermitUtils.serialize(retrieved!)).toEqual(PermitUtils.serialize(permit));
@@ -43,13 +42,9 @@ describe('Storage Tests', () => {
43
42
 
44
43
  it('should handle multiple permits per account', async () => {
45
44
  const permit1 = await createMockPermit();
46
- const permit2 = {
47
- ...(await createMockPermit()),
45
+ const permit2 = await createMockPermit({
48
46
  issuer: '0x0987654321098765432109876543210987654321' as `0x${string}`,
49
- };
50
-
51
- const hash1 = PermitUtils.getHash(permit1);
52
- const hash2 = PermitUtils.getHash(permit2);
47
+ });
53
48
 
54
49
  setPermit(chainId, account, permit1);
55
50
  setPermit(chainId, account, permit2);
@@ -57,19 +52,18 @@ describe('Storage Tests', () => {
57
52
  const permits = getPermits(chainId, account);
58
53
  expect(Object.keys(permits)).toHaveLength(2);
59
54
 
60
- expect(PermitUtils.serialize(permits[hash1])).toEqual(PermitUtils.serialize(permit1));
61
- expect(PermitUtils.serialize(permits[hash2])).toEqual(PermitUtils.serialize(permit2));
55
+ expect(PermitUtils.serialize(permits[permit1.hash])).toEqual(PermitUtils.serialize(permit1));
56
+ expect(PermitUtils.serialize(permits[permit2.hash])).toEqual(PermitUtils.serialize(permit2));
62
57
  });
63
58
 
64
59
  it('should handle active permit hash', async () => {
65
60
  const permit = await createMockPermit();
66
- const hash = PermitUtils.getHash(permit);
67
61
 
68
62
  setPermit(chainId, account, permit);
69
- setActivePermitHash(chainId, account, hash);
63
+ setActivePermitHash(chainId, account, permit.hash);
70
64
 
71
65
  const activeHash = getActivePermitHash(chainId, account);
72
- expect(activeHash).toBe(hash);
66
+ expect(activeHash).toBe(permit.hash);
73
67
 
74
68
  const activePermit = getActivePermit(chainId, account);
75
69
  expect(activePermit).toBeDefined();
@@ -78,51 +72,17 @@ describe('Storage Tests', () => {
78
72
 
79
73
  it('should remove permits', async () => {
80
74
  const permit = await createMockPermit();
81
- const hash = PermitUtils.getHash(permit);
82
75
 
83
76
  setPermit(chainId, account, permit);
84
- setActivePermitHash(chainId, account, hash);
77
+ setActivePermitHash(chainId, account, permit.hash);
85
78
 
86
- removePermit(chainId, account, hash, true);
79
+ removePermit(chainId, account, permit.hash);
87
80
 
88
- const retrieved = getPermit(chainId, account, hash);
81
+ const retrieved = getPermit(chainId, account, permit.hash);
89
82
  expect(retrieved).toBeUndefined();
90
83
 
91
84
  const activeHash = getActivePermitHash(chainId, account);
92
85
  expect(activeHash).toBeUndefined();
93
86
  });
94
-
95
- it('should prevent removing last permit without force', async () => {
96
- const permit = await createMockPermit();
97
- const hash = PermitUtils.getHash(permit);
98
-
99
- setPermit(chainId, account, permit);
100
- setActivePermitHash(chainId, account, hash);
101
-
102
- expect(() => {
103
- removePermit(chainId, account, hash, false);
104
- }).toThrow('Cannot remove the last permit without force flag');
105
- });
106
-
107
- it('should switch active permit when removing current active', async () => {
108
- const permit1 = await createMockPermit();
109
- const permit2 = {
110
- ...(await createMockPermit()),
111
- name: 'Second Permit',
112
- issuer: '0x0987654321098765432109876543210987654321' as `0x${string}`, // Different issuer
113
- };
114
-
115
- const hash1 = PermitUtils.getHash(permit1);
116
- const hash2 = PermitUtils.getHash(permit2);
117
-
118
- setPermit(chainId, account, permit1);
119
- setPermit(chainId, account, permit2);
120
- setActivePermitHash(chainId, account, hash1);
121
-
122
- removePermit(chainId, account, hash1, false);
123
-
124
- const activeHash = getActivePermitHash(chainId, account);
125
- expect(activeHash).toBe(hash2);
126
- });
127
87
  });
128
88
  });
package/permits/store.ts CHANGED
@@ -15,14 +15,12 @@ type PermitsStore = {
15
15
 
16
16
  // Stores generated permits for each user, a hash indicating the active permit for each user
17
17
  // Can be used to create reactive hooks
18
+ export const PERMIT_STORE_DEFAULTS: PermitsStore = {
19
+ permits: {},
20
+ activePermitHash: {},
21
+ };
18
22
  export const _permitStore = createStore<PermitsStore>()(
19
- persist(
20
- () => ({
21
- permits: {},
22
- activePermitHash: {},
23
- }),
24
- { name: 'cofhesdk-permits' }
25
- )
23
+ persist(() => PERMIT_STORE_DEFAULTS, { name: 'cofhesdk-permits' })
26
24
  );
27
25
 
28
26
  export const clearStaleStore = () => {
@@ -84,12 +82,12 @@ export const setPermit = (chainId: number, account: string, permit: Permit) => {
84
82
  produce<PermitsStore>((state) => {
85
83
  if (state.permits[chainId] == null) state.permits[chainId] = {};
86
84
  if (state.permits[chainId][account] == null) state.permits[chainId][account] = {};
87
- state.permits[chainId][account][PermitUtils.getHash(permit)] = PermitUtils.serialize(permit);
85
+ state.permits[chainId][account][permit.hash] = PermitUtils.serialize(permit);
88
86
  })
89
87
  );
90
88
  };
91
89
 
92
- export const removePermit = (chainId: number, account: string, hash: string, force?: boolean) => {
90
+ export const removePermit = (chainId: number, account: string, hash: string) => {
93
91
  clearStaleStore();
94
92
  _permitStore.setState(
95
93
  produce<PermitsStore>((state) => {
@@ -102,18 +100,8 @@ export const removePermit = (chainId: number, account: string, hash: string, for
102
100
  if (accountPermits[hash] == null) return;
103
101
 
104
102
  if (state.activePermitHash[chainId][account] === hash) {
105
- // Find other permits before removing
106
- const otherPermitHash = Object.keys(accountPermits).find((key) => key !== hash && accountPermits[key] != null);
107
-
108
- if (otherPermitHash) {
109
- state.activePermitHash[chainId][account] = otherPermitHash;
110
- } else {
111
- if (!force) {
112
- throw new Error('Cannot remove the last permit without force flag');
113
- }
114
- // Clear the active hash when removing the last permit with force
115
- state.activePermitHash[chainId][account] = undefined;
116
- }
103
+ // if the active permit is the one to be removed - unset it
104
+ state.activePermitHash[chainId][account] = undefined;
117
105
  }
118
106
  // Remove the permit
119
107
  accountPermits[hash] = undefined;
@@ -1,9 +1,10 @@
1
1
  import { type Permit, type SerializedPermit, GenerateSealingKey, PermitUtils } from './index.js';
2
2
 
3
3
  // Mock permit for testing - using Bob's address as issuer
4
- export const createMockPermit = async (): Promise<Permit> => {
5
- const sealingPair = await GenerateSealingKey();
6
- const serializedPermit: SerializedPermit = {
4
+ export const createMockPermit = async (overrides: Partial<Permit> = {}): Promise<Permit> => {
5
+ const sealingPair = GenerateSealingKey();
6
+
7
+ const fields = {
7
8
  name: 'Test Permit',
8
9
  type: 'self',
9
10
  issuer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // Bob's address
@@ -15,6 +16,13 @@ export const createMockPermit = async (): Promise<Permit> => {
15
16
  issuerSignature: '0x',
16
17
  recipientSignature: '0x',
17
18
  _signedDomain: undefined,
19
+ ...overrides,
20
+ } as const;
21
+
22
+ const serializedPermit: SerializedPermit = {
23
+ hash: PermitUtils.getHash(fields),
24
+ ...fields,
18
25
  };
26
+
19
27
  return PermitUtils.deserialize(serializedPermit);
20
28
  };
package/permits/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { SealingKey as SealingKeyClass, type EthEncryptedData } from './sealing.js';
2
+ import { type Hex } from 'viem';
2
3
 
3
4
  /**
4
5
  * EIP712 related types
@@ -9,7 +10,7 @@ export type EIP712Message = Record<string, string>;
9
10
  export type EIP712Domain = {
10
11
  chainId: number;
11
12
  name: string;
12
- verifyingContract: `0x${string}`;
13
+ verifyingContract: Hex;
13
14
  version: string;
14
15
  };
15
16
 
@@ -29,6 +30,10 @@ export type { EthEncryptedData };
29
30
  * Core Permit interface - immutable design for React compatibility
30
31
  */
31
32
  export interface Permit {
33
+ /**
34
+ * Stable hash of relevant permit data, used as key in storage
35
+ */
36
+ hash: string;
32
37
  /**
33
38
  * Name for this permit, for organization and UI usage, not included in signature.
34
39
  */
@@ -43,7 +48,7 @@ export interface Permit {
43
48
  /**
44
49
  * (base) User that initially created the permission, target of data fetching
45
50
  */
46
- issuer: `0x${string}`;
51
+ issuer: Hex;
47
52
  /**
48
53
  * (base) Expiration timestamp
49
54
  */
@@ -52,7 +57,7 @@ export interface Permit {
52
57
  * (sharing) The user that this permission will be shared with
53
58
  * ** optional, use `address(0)` to disable **
54
59
  */
55
- recipient: `0x${string}`;
60
+ recipient: Hex;
56
61
  /**
57
62
  * (issuer defined validation) An id used to query a contract to check this permissions validity
58
63
  * ** optional, use `0` to disable **
@@ -62,7 +67,7 @@ export interface Permit {
62
67
  * (issuer defined validation) The contract to query to determine permission validity
63
68
  * ** optional, user `address(0)` to disable **
64
69
  */
65
- validatorContract: `0x${string}`;
70
+ validatorContract: Hex;
66
71
  /**
67
72
  * (base) The publicKey of a sealingPair used to re-encrypt `issuer`s confidential data
68
73
  * (non-sharing) Populated by `issuer`
@@ -75,13 +80,13 @@ export interface Permit {
75
80
  * (non-sharing) < issuer, expiration, recipient, validatorId, validatorContract, sealingKey >
76
81
  * (sharing) < issuer, expiration, recipient, validatorId, validatorContract >
77
82
  */
78
- issuerSignature: `0x${string}`;
83
+ issuerSignature: Hex;
79
84
  /**
80
85
  * (sharing) `signTypedData` signature created by `recipient` with format:
81
86
  * (sharing) < sealingKey, issuerSignature>
82
87
  * ** required for shared permits **
83
88
  */
84
- recipientSignature: `0x${string}`;
89
+ recipientSignature: Hex;
85
90
  /**
86
91
  * EIP712 domain used to sign this permit.
87
92
  * Should not be set manually, included in metadata as part of serialization flows.
@@ -89,6 +94,23 @@ export interface Permit {
89
94
  _signedDomain?: EIP712Domain;
90
95
  }
91
96
 
97
+ /**
98
+ * Permit discriminant helpers
99
+ */
100
+ export type PermitType = Permit['type'];
101
+
102
+ /**
103
+ * Utility type to narrow a permit to a specific discriminant.
104
+ *
105
+ * Note: this only narrows the `type` field. Runtime/validation constraints
106
+ * (e.g. recipient == zeroAddress for self permits) are enforced elsewhere.
107
+ */
108
+ export type PermitOf<T extends PermitType> = Expand<Omit<Permit, 'type'> & { type: T }>;
109
+
110
+ export type SelfPermit = PermitOf<'self'>;
111
+ export type SharingPermit = PermitOf<'sharing'>;
112
+ export type RecipientPermit = PermitOf<'recipient'>;
113
+
92
114
  /**
93
115
  * Optional additional metadata of a Permit
94
116
  * Can be passed into the constructor, but not necessary
@@ -132,7 +154,7 @@ export type ImportSharedPermitOptions = {
132
154
  recipient: string;
133
155
  issuerSignature: string;
134
156
  name?: string;
135
- expiration?: number;
157
+ expiration: number;
136
158
  validatorId?: number;
137
159
  validatorContract?: string;
138
160
  };
@@ -149,11 +171,19 @@ export type SerializedPermit = Omit<Permit, 'sealingPair'> & {
149
171
  * A type representing the Permission struct that is passed to Permissioned.sol to grant encrypted data access.
150
172
  */
151
173
  export type Permission = Expand<
152
- Omit<Permit, 'name' | 'type' | 'sealingPair'> & {
153
- sealingKey: `0x${string}`;
174
+ Omit<Permit, 'name' | 'type' | 'sealingPair' | 'hash'> & {
175
+ sealingKey: Hex;
154
176
  }
155
177
  >;
156
178
 
179
+ /**
180
+ * A type representing the permit fields that are used to generate the hash
181
+ */
182
+ export type PermitHashFields = Pick<
183
+ Permit,
184
+ 'type' | 'issuer' | 'expiration' | 'recipient' | 'validatorId' | 'validatorContract'
185
+ >;
186
+
157
187
  /**
158
188
  * Validation result type
159
189
  */
package/permits/utils.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  // Utility functions for sealing key operations
2
2
 
3
- // eslint-disable-next-line no-unused-vars
4
3
  declare const BigInt: (value: string | number | bigint) => bigint;
5
4
 
6
5
  export const fromHexString = (hexString: string): Uint8Array => {
@@ -57,7 +56,3 @@ export function isBigIntOrNumber(value: unknown) {
57
56
  }
58
57
  }
59
58
  }
60
-
61
- export function is0xPrefixed(value: string): value is `0x${string}` {
62
- return value.startsWith('0x');
63
- }
@@ -23,9 +23,9 @@ describe('Validation Tests', () => {
23
23
  name: 'Test Permit',
24
24
  };
25
25
 
26
+ expect(() => validateSelfPermitOptions(options)).not.toThrow();
26
27
  const result = validateSelfPermitOptions(options);
27
- expect(result.success).toBe(true);
28
- expect(result.data).toBeDefined();
28
+ expect(result).toBeDefined();
29
29
  });
30
30
 
31
31
  it('should reject invalid address', () => {
@@ -35,9 +35,7 @@ describe('Validation Tests', () => {
35
35
  name: 'Test Permit',
36
36
  };
37
37
 
38
- const result = validateSelfPermitOptions(options);
39
- expect(result.success).toBe(false);
40
- expect(result.error).toBeDefined();
38
+ expect(() => validateSelfPermitOptions(options)).toThrow();
41
39
  });
42
40
 
43
41
  it('should reject zero address', () => {
@@ -47,9 +45,7 @@ describe('Validation Tests', () => {
47
45
  name: 'Test Permit',
48
46
  };
49
47
 
50
- const result = validateSelfPermitOptions(options);
51
- expect(result.success).toBe(false);
52
- expect(result.error).toBeDefined();
48
+ expect(() => validateSelfPermitOptions(options)).toThrow();
53
49
  });
54
50
  });
55
51
 
@@ -62,8 +58,7 @@ describe('Validation Tests', () => {
62
58
  name: 'Sharing Permit',
63
59
  };
64
60
 
65
- const result = validateSharingPermitOptions(options);
66
- expect(result.success).toBe(true);
61
+ expect(() => validateSharingPermitOptions(options)).not.toThrow();
67
62
  });
68
63
 
69
64
  it('should reject sharing permit with zero recipient', () => {
@@ -74,8 +69,7 @@ describe('Validation Tests', () => {
74
69
  name: 'Sharing Permit',
75
70
  };
76
71
 
77
- const result = validateSharingPermitOptions(options);
78
- expect(result.success).toBe(false);
72
+ expect(() => validateSharingPermitOptions(options)).toThrow();
79
73
  });
80
74
 
81
75
  it('should reject sharing permit with invalid recipient', () => {
@@ -86,8 +80,7 @@ describe('Validation Tests', () => {
86
80
  name: 'Sharing Permit',
87
81
  };
88
82
 
89
- const result = validateSharingPermitOptions(options);
90
- expect(result.success).toBe(false);
83
+ expect(() => validateSharingPermitOptions(options)).toThrow();
91
84
  });
92
85
  });
93
86
 
@@ -95,37 +88,47 @@ describe('Validation Tests', () => {
95
88
  it('should validate valid import permit options', () => {
96
89
  const options: ImportSharedPermitOptions = {
97
90
  issuer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // Bob's address
91
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
98
92
  recipient: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // Alice's address
99
93
  issuerSignature: '0x1234567890abcdef',
100
94
  name: 'Import Permit',
101
95
  };
102
96
 
103
- const result = validateImportPermitOptions(options);
104
- expect(result.success).toBe(true);
97
+ expect(() => validateImportPermitOptions(options)).not.toThrow();
98
+ });
99
+
100
+ it('should reject import permit with missing expiration', () => {
101
+ const options = {
102
+ issuer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // Bob's address
103
+ recipient: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // Alice's address
104
+ issuerSignature: '0x1234567890abcdef',
105
+ name: 'Import Permit',
106
+ };
107
+ expect(() => validateImportPermitOptions(options)).toThrow();
105
108
  });
106
109
 
107
110
  it('should reject import permit with empty signature', () => {
108
111
  const options: ImportSharedPermitOptions = {
109
112
  issuer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // Bob's address
113
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
110
114
  recipient: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // Alice's address
111
115
  issuerSignature: '0x',
112
116
  name: 'Import Permit',
113
117
  };
114
118
 
115
- const result = validateImportPermitOptions(options);
116
- expect(result.success).toBe(false);
119
+ expect(() => validateImportPermitOptions(options)).toThrow();
117
120
  });
118
121
 
119
122
  it('should reject import permit with invalid signature', () => {
120
123
  const options: ImportSharedPermitOptions = {
121
124
  issuer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // Bob's address
125
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
122
126
  recipient: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // Alice's address
123
127
  issuerSignature: '0x',
124
128
  name: 'Import Permit',
125
129
  };
126
130
 
127
- const result = validateImportPermitOptions(options);
128
- expect(result.success).toBe(false);
131
+ expect(() => validateImportPermitOptions(options)).toThrow();
129
132
  });
130
133
  });
131
134
 
@@ -135,15 +138,13 @@ describe('Validation Tests', () => {
135
138
  permit.type = 'self';
136
139
  permit.issuerSignature = '0x1234567890abcdef';
137
140
 
138
- const result = validateSelfPermit(permit);
139
- expect(result.success).toBe(true);
141
+ expect(() => validateSelfPermit(permit)).not.toThrow();
140
142
  });
141
143
 
142
144
  it('should reject self permit with missing sealing pair', async () => {
143
145
  const permit = { ...(await createMockPermit()), sealingPair: undefined };
144
146
  permit.type = 'self';
145
- const result = validateSelfPermit(permit as unknown as Permit);
146
- expect(result.success).toBe(false);
147
+ expect(() => validateSelfPermit(permit as unknown as Permit)).toThrow();
147
148
  });
148
149
  });
149
150
 
@@ -154,8 +155,7 @@ describe('Validation Tests', () => {
154
155
  permit.issuerSignature = '0x1234567890abcdef';
155
156
  permit.recipient = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'; // Alice's address
156
157
 
157
- const result = validateSharingPermit(permit);
158
- expect(result.success).toBe(true);
158
+ expect(() => validateSharingPermit(permit)).not.toThrow();
159
159
  });
160
160
 
161
161
  it('should reject sharing permit with zero recipient', async () => {
@@ -164,8 +164,7 @@ describe('Validation Tests', () => {
164
164
  permit.issuerSignature = '0x1234567890abcdef';
165
165
  permit.recipient = '0x0000000000000000000000000000000000000000';
166
166
 
167
- const result = validateSharingPermit(permit);
168
- expect(result.success).toBe(false);
167
+ expect(() => validateSharingPermit(permit)).toThrow();
169
168
  });
170
169
  });
171
170
 
@@ -177,8 +176,7 @@ describe('Validation Tests', () => {
177
176
  permit.recipient = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'; // Alice's address
178
177
  permit.recipientSignature = '0xabcdef1234567890';
179
178
 
180
- const result = validateImportPermit(permit);
181
- expect(result.success).toBe(true);
179
+ expect(() => validateImportPermit(permit)).not.toThrow();
182
180
  });
183
181
 
184
182
  it('should reject import permit with empty recipient signature', async () => {
@@ -188,8 +186,7 @@ describe('Validation Tests', () => {
188
186
  permit.recipient = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'; // Alice's address
189
187
  permit.recipientSignature = '0x';
190
188
 
191
- const result = validateImportPermit(permit);
192
- expect(result.success).toBe(false);
189
+ expect(() => validateImportPermit(permit)).toThrow();
193
190
  });
194
191
  });
195
192