@cofhe/sdk 0.6.0 → 0.7.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.
Files changed (114) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/acps/acp.ts +411 -0
  3. package/acps/index.ts +70 -0
  4. package/{permits → acps}/onchain-utils.ts +49 -24
  5. package/acps/sealing.ts +90 -0
  6. package/acps/signature.ts +89 -0
  7. package/acps/store.ts +172 -0
  8. package/acps/test/acp.test.ts +615 -0
  9. package/acps/test/localstorage.test.ts +105 -0
  10. package/acps/test/sealing.test.ts +77 -0
  11. package/acps/test/store.test.ts +88 -0
  12. package/acps/test/validation.test.ts +361 -0
  13. package/acps/test-utils.ts +32 -0
  14. package/acps/types.ts +252 -0
  15. package/acps/validation.ts +392 -0
  16. package/adapters/test/ethers5.test.ts +4 -1
  17. package/adapters/test/ethers6.test.ts +4 -1
  18. package/adapters/test/wagmi.test.ts +5 -2
  19. package/chains/chains/stagingCofhe.ts +21 -0
  20. package/chains/index.ts +3 -1
  21. package/chains/test/chains.test.ts +2 -1
  22. package/core/acps.ts +625 -0
  23. package/core/client.ts +136 -39
  24. package/core/clientTypes.ts +52 -41
  25. package/core/config.ts +66 -5
  26. package/core/debug.ts +72 -0
  27. package/core/decrypt/MockThresholdNetworkAbi.ts +20 -11
  28. package/core/decrypt/apiError.ts +104 -0
  29. package/core/decrypt/cofheMocksDecryptForTx.ts +11 -11
  30. package/core/decrypt/cofheMocksDecryptForView.ts +7 -7
  31. package/core/decrypt/decryptForTxBuilder.ts +102 -102
  32. package/core/decrypt/decryptForViewBuilder.ts +90 -90
  33. package/core/decrypt/submitRetry.ts +38 -30
  34. package/core/decrypt/tnDecryptV1.ts +5 -5
  35. package/core/decrypt/tnDecryptV2.ts +45 -34
  36. package/core/decrypt/tnSealOutputV1.ts +4 -3
  37. package/core/decrypt/tnSealOutputV2.ts +44 -31
  38. package/core/encrypt/cofheMocksZkVerifySign.ts +59 -74
  39. package/core/encrypt/encryptInputsBuilder.ts +86 -52
  40. package/core/encrypt/zkPackProveVerify.ts +25 -18
  41. package/core/error.ts +34 -6
  42. package/core/index.ts +14 -14
  43. package/core/test/acpDefaults.test.ts +52 -0
  44. package/core/test/acps.test.ts +596 -0
  45. package/core/test/apiError.test.ts +130 -0
  46. package/core/test/client.test.ts +22 -19
  47. package/core/test/config.test.ts +25 -5
  48. package/core/test/decrypt.test.ts +40 -35
  49. package/core/test/decryptBuilders.test.ts +68 -68
  50. package/core/test/decryptErrorCodes.test.ts +217 -0
  51. package/core/test/encryptInputsBuilder.test.ts +72 -41
  52. package/core/test/pollCallbacks.test.ts +89 -18
  53. package/core/test/stagingRedirect.ts +18 -0
  54. package/core/test/submitRetry.test.ts +182 -0
  55. package/core/types.ts +9 -69
  56. package/dist/acp-Wi6isVQI.d.cts +407 -0
  57. package/dist/acp-Wi6isVQI.d.ts +407 -0
  58. package/dist/acps.cjs +1081 -0
  59. package/dist/acps.d.cts +480 -0
  60. package/dist/acps.d.ts +480 -0
  61. package/dist/acps.js +2 -0
  62. package/dist/chains.cjs +14 -1
  63. package/dist/chains.d.cts +30 -1
  64. package/dist/chains.d.ts +30 -1
  65. package/dist/chains.js +1 -1
  66. package/dist/{chunk-PE5V5CCV.js → chunk-43USWPEH.js} +1000 -604
  67. package/dist/{chunk-MTRAXQXC.js → chunk-N6IDQRRU.js} +14 -2
  68. package/dist/chunk-Q7CBWGQX.js +1029 -0
  69. package/dist/{clientTypes-CyUvRRzA.d.ts → clientTypes-BN3nbzYM.d.ts} +342 -165
  70. package/dist/{clientTypes-BDy1qIBu.d.cts → clientTypes-CYZjFznO.d.cts} +342 -165
  71. package/dist/core.cjs +1431 -1026
  72. package/dist/core.d.cts +55 -10
  73. package/dist/core.d.ts +55 -10
  74. package/dist/core.js +3 -3
  75. package/dist/node.cjs +1356 -976
  76. package/dist/node.d.cts +2 -2
  77. package/dist/node.d.ts +2 -2
  78. package/dist/node.js +3 -3
  79. package/dist/web.cjs +1356 -976
  80. package/dist/web.d.cts +2 -2
  81. package/dist/web.d.ts +2 -2
  82. package/dist/web.js +3 -3
  83. package/node/test/inherited.test.ts +75 -65
  84. package/node/test/tfheinit.test.ts +23 -8
  85. package/package.json +6 -6
  86. package/web/test/client.web.test.ts +5 -1
  87. package/web/test/inherited.web.test.ts +75 -65
  88. package/web/test/tfheinit.web.test.ts +14 -5
  89. package/web/test/worker.config.web.test.ts +38 -23
  90. package/web/test/worker.output.web.test.ts +25 -24
  91. package/core/encrypt/encryptUtils.ts +0 -67
  92. package/core/permits.ts +0 -206
  93. package/core/test/permits.test.ts +0 -534
  94. package/dist/chunk-VB62WYPL.js +0 -978
  95. package/dist/permit-DnVMDT5h.d.cts +0 -376
  96. package/dist/permit-DnVMDT5h.d.ts +0 -376
  97. package/dist/permits.cjs +0 -1026
  98. package/dist/permits.d.cts +0 -353
  99. package/dist/permits.d.ts +0 -353
  100. package/dist/permits.js +0 -2
  101. package/permits/index.ts +0 -68
  102. package/permits/permit.ts +0 -385
  103. package/permits/sealing.ts +0 -131
  104. package/permits/signature.ts +0 -79
  105. package/permits/store.ts +0 -157
  106. package/permits/test/localstorage.test.ts +0 -113
  107. package/permits/test/permit.test.ts +0 -557
  108. package/permits/test/sealing.test.ts +0 -84
  109. package/permits/test/store.test.ts +0 -88
  110. package/permits/test/validation.test.ts +0 -361
  111. package/permits/test-utils.ts +0 -28
  112. package/permits/types.ts +0 -204
  113. package/permits/validation.ts +0 -327
  114. /package/{permits → acps}/utils.ts +0 -0
@@ -1,327 +0,0 @@
1
- import { z } from 'zod';
2
- import { getAddress, isAddress, isHex, zeroAddress, type Hex } from 'viem';
3
- import type { Permit, ValidationResult } from './types.js';
4
-
5
- const SerializedSealingPair = z.object({
6
- privateKey: z.string(),
7
- publicKey: z.string(),
8
- });
9
-
10
- export const addressSchema = z
11
- .string()
12
- .refine((val) => isAddress(val), {
13
- error: 'Invalid address',
14
- })
15
- .transform((val): Hex => getAddress(val));
16
-
17
- export const addressNotZeroSchema = addressSchema.refine((val) => val !== zeroAddress, {
18
- error: 'Must not be zeroAddress',
19
- });
20
-
21
- export const bytesSchema = z.custom<Hex>(
22
- (val) => {
23
- return typeof val === 'string' && isHex(val);
24
- },
25
- {
26
- message: 'Invalid hex value',
27
- }
28
- );
29
-
30
- export const bytesNotEmptySchema = bytesSchema.refine((val) => val !== '0x', {
31
- error: 'Must not be empty',
32
- });
33
-
34
- const DEFAULT_EXPIRATION_FN = () => Math.round(Date.now() / 1000) + 7 * 24 * 60 * 60; // 7 days from now
35
-
36
- const zPermitWithDefaults = z.object({
37
- name: z.string().optional().default('Unnamed Permit'),
38
- type: z.enum(['self', 'sharing', 'recipient']),
39
- issuer: addressNotZeroSchema,
40
- expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
41
- recipient: addressSchema.optional().default(zeroAddress),
42
- validatorId: z.int().optional().default(0),
43
- validatorContract: addressSchema.optional().default(zeroAddress),
44
- issuerSignature: bytesSchema.optional().default('0x'),
45
- recipientSignature: bytesSchema.optional().default('0x'),
46
- });
47
-
48
- const zPermitWithSealingPair = zPermitWithDefaults.extend({
49
- sealingPair: SerializedSealingPair.optional(),
50
- });
51
-
52
- type zPermitType = z.infer<typeof zPermitWithDefaults>;
53
-
54
- /**
55
- * Permits allow a hook into an optional external validator contract,
56
- * this check ensures that IF an external validator is applied, that both `validatorId` and `validatorContract` are populated,
57
- * ELSE ensures that both `validatorId` and `validatorContract` are empty
58
- */
59
- const ExternalValidatorRefinement = [
60
- (data: zPermitType) =>
61
- (data.validatorId !== 0 && data.validatorContract !== zeroAddress) ||
62
- (data.validatorId === 0 && data.validatorContract === zeroAddress),
63
- {
64
- error: 'Permit external validator :: validatorId and validatorContract must either both be set or both be unset.',
65
- path: ['validatorId', 'validatorContract'] as string[],
66
- },
67
- ] as const;
68
-
69
- /**
70
- * Prevents sharable permit from having the same issuer and recipient
71
- */
72
- const RecipientRefinement = [
73
- (data: zPermitType) => data.issuer !== data.recipient,
74
- {
75
- error: 'Sharing permit :: issuer and recipient must not be the same',
76
- path: ['issuer', 'recipient'] as string[],
77
- },
78
- ] as const;
79
-
80
- // ============================================================================
81
- // SELF PERMIT VALIDATORS
82
- // ============================================================================
83
-
84
- /**
85
- * Validator for self permit creation options
86
- */
87
- export const SelfPermitOptionsValidator = z
88
- .object({
89
- type: z.literal('self').optional().default('self'),
90
- issuer: addressNotZeroSchema,
91
- name: z.string().optional().default('Unnamed Permit'),
92
- expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
93
- recipient: addressSchema.optional().default(zeroAddress),
94
- validatorId: z.int().optional().default(0),
95
- validatorContract: addressSchema.optional().default(zeroAddress),
96
- issuerSignature: bytesSchema.optional().default('0x'),
97
- recipientSignature: bytesSchema.optional().default('0x'),
98
- })
99
- .refine(...ExternalValidatorRefinement);
100
-
101
- /**
102
- * Validator for fully formed self permits
103
- */
104
- export const SelfPermitValidator = zPermitWithSealingPair
105
- .refine((data) => data.type === 'self', {
106
- error: "Type must be 'self'",
107
- })
108
- .refine((data) => data.recipient === zeroAddress, {
109
- error: 'Recipient must be zeroAddress',
110
- })
111
- .refine((data) => data.issuerSignature !== '0x', {
112
- error: 'IssuerSignature must be populated',
113
- })
114
- .refine((data) => data.recipientSignature === '0x', {
115
- error: 'RecipientSignature must be empty',
116
- })
117
- .refine(...ExternalValidatorRefinement);
118
-
119
- // ============================================================================
120
- // SHARING PERMIT VALIDATORS
121
- // ============================================================================
122
-
123
- /**
124
- * Validator for sharing permit creation options
125
- */
126
- export const SharingPermitOptionsValidator = z
127
- .object({
128
- type: z.literal('sharing').optional().default('sharing'),
129
- issuer: addressNotZeroSchema,
130
- recipient: addressNotZeroSchema,
131
- name: z.string().optional().default('Unnamed Permit'),
132
- expiration: z.int().optional().default(DEFAULT_EXPIRATION_FN),
133
- validatorId: z.int().optional().default(0),
134
- validatorContract: addressSchema.optional().default(zeroAddress),
135
- issuerSignature: bytesSchema.optional().default('0x'),
136
- recipientSignature: bytesSchema.optional().default('0x'),
137
- })
138
- .refine(...RecipientRefinement)
139
- .refine(...ExternalValidatorRefinement);
140
-
141
- /**
142
- * Validator for fully formed sharing permits
143
- */
144
- export const SharingPermitValidator = zPermitWithSealingPair
145
- .refine((data) => data.type === 'sharing', {
146
- error: "Type must be 'sharing'",
147
- })
148
- .refine((data) => data.recipient !== zeroAddress, {
149
- error: 'Recipient must not be zeroAddress',
150
- })
151
- .refine((data) => data.issuerSignature !== '0x', {
152
- error: 'IssuerSignature must be populated',
153
- })
154
- .refine((data) => data.recipientSignature === '0x', {
155
- error: 'RecipientSignature must be empty',
156
- })
157
- .refine(...ExternalValidatorRefinement);
158
-
159
- // ============================================================================
160
- // IMPORT/RECIPIENT PERMIT VALIDATORS
161
- // ============================================================================
162
-
163
- /**
164
- * Validator for import permit creation options (recipient receiving shared permit)
165
- */
166
- export const ImportPermitOptionsValidator = z
167
- .object({
168
- type: z.literal('recipient').optional().default('recipient'),
169
- issuer: addressNotZeroSchema,
170
- recipient: addressNotZeroSchema,
171
- name: z.string().optional().default('Unnamed Permit'),
172
- expiration: z.int(),
173
- validatorId: z.int().optional().default(0),
174
- validatorContract: addressSchema.optional().default(zeroAddress),
175
- issuerSignature: bytesNotEmptySchema,
176
- recipientSignature: bytesSchema.optional().default('0x'),
177
- })
178
- .refine(...ExternalValidatorRefinement);
179
-
180
- /**
181
- * Validator for fully formed import/recipient permits
182
- */
183
- export const ImportPermitValidator = zPermitWithSealingPair
184
- .refine((data) => data.type === 'recipient', {
185
- error: "Type must be 'recipient'",
186
- })
187
- .refine((data) => data.recipient !== zeroAddress, {
188
- error: 'Recipient must not be zeroAddress',
189
- })
190
- .refine((data) => data.issuerSignature !== '0x', {
191
- error: 'IssuerSignature must be populated',
192
- })
193
- .refine((data) => data.recipientSignature !== '0x', {
194
- error: 'RecipientSignature must be populated',
195
- })
196
- .refine(...ExternalValidatorRefinement);
197
-
198
- // ============================================================================
199
- // VALIDATION FUNCTIONS
200
- // ============================================================================
201
-
202
- const safeParseAndThrowFormatted = <T extends z.ZodTypeAny>(schema: T, data: unknown, message: string): z.output<T> => {
203
- const result = schema.safeParse(data);
204
- if (!result.success) {
205
- throw new Error(`${message}: ${z.prettifyError(result.error)}`, { cause: result.error });
206
- }
207
- return result.data;
208
- };
209
-
210
- /**
211
- * Validates self permit creation options
212
- */
213
- export const validateSelfPermitOptions = (options: any) => {
214
- return safeParseAndThrowFormatted(SelfPermitOptionsValidator, options, 'Invalid self permit options');
215
- };
216
- /**
217
- * Validates sharing permit creation options
218
- */
219
- export const validateSharingPermitOptions = (options: any) => {
220
- return safeParseAndThrowFormatted(SharingPermitOptionsValidator, options, 'Invalid sharing permit options');
221
- };
222
-
223
- /**
224
- * Validates import permit creation options
225
- */
226
- export const validateImportPermitOptions = (options: any) => {
227
- return safeParseAndThrowFormatted(ImportPermitOptionsValidator, options, 'Invalid import permit options');
228
- };
229
-
230
- /**
231
- * Validates a fully formed self permit
232
- */
233
- export const validateSelfPermit = (permit: any) => {
234
- return safeParseAndThrowFormatted(SelfPermitValidator, permit, 'Invalid self permit');
235
- };
236
-
237
- /**
238
- * Validates a fully formed sharing permit
239
- */
240
- export const validateSharingPermit = (permit: any) => {
241
- return safeParseAndThrowFormatted(SharingPermitValidator, permit, 'Invalid sharing permit');
242
- };
243
-
244
- /**
245
- * Validates a fully formed import/recipient permit
246
- */
247
- export const validateImportPermit = (permit: any) => {
248
- return safeParseAndThrowFormatted(ImportPermitValidator, permit, 'Invalid import permit');
249
- };
250
-
251
- /**
252
- * Simple validation functions for common checks
253
- */
254
- export const ValidationUtils = {
255
- /**
256
- * Check if permit is expired
257
- */
258
- isExpired: (permit: Permit): boolean => {
259
- return permit.expiration < Math.floor(Date.now() / 1000);
260
- },
261
-
262
- /**
263
- * Check if permit is signed by the active party
264
- */
265
- isSigned: (permit: Permit): boolean => {
266
- if (permit.type === 'self' || permit.type === 'sharing') {
267
- return permit.issuerSignature !== '0x';
268
- }
269
- if (permit.type === 'recipient') {
270
- return permit.recipientSignature !== '0x';
271
- }
272
- return false;
273
- },
274
-
275
- /**
276
- * Checks that a permit is signed and not expired.
277
- */
278
- isSignedAndNotExpired: (permit: Permit): ValidationResult => {
279
- if (ValidationUtils.isExpired(permit)) {
280
- return { valid: false, error: 'expired' };
281
- }
282
- if (!ValidationUtils.isSigned(permit)) {
283
- return { valid: false, error: 'not-signed' };
284
- }
285
- return { valid: true, error: null };
286
- },
287
-
288
- /**
289
- * Asserts that a permit is signed and not expired.
290
- *
291
- * Throws `Error` with message:
292
- * - `Permit is expired`
293
- * - `Permit is not signed`
294
- */
295
- assertSignedAndNotExpired: (permit: Permit): void => {
296
- const result = ValidationUtils.isSignedAndNotExpired(permit);
297
- if (result.valid) return;
298
-
299
- if (result.error === 'expired') {
300
- throw new Error('Permit is expired');
301
- }
302
- if (result.error === 'not-signed') {
303
- throw new Error('Permit is not signed');
304
- }
305
-
306
- // Should be unreachable, but keeps this future-proof.
307
- throw new Error('Permit is invalid');
308
- },
309
-
310
- isValid: (permit: Permit): ValidationResult => {
311
- const schema =
312
- permit.type === 'self'
313
- ? SelfPermitValidator
314
- : permit.type === 'sharing'
315
- ? SharingPermitValidator
316
- : permit.type === 'recipient'
317
- ? ImportPermitValidator
318
- : null;
319
-
320
- if (schema == null) return { valid: false, error: 'invalid-schema' };
321
-
322
- const schemaResult = schema.safeParse(permit);
323
- if (!schemaResult.success) return { valid: false, error: 'invalid-schema' };
324
-
325
- return ValidationUtils.isSignedAndNotExpired(permit);
326
- },
327
- };
File without changes