@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,4 +1,5 @@
1
- import { arbSepolia as cofheArbSepolia } from '@/chains';
1
+ import { STAGING_TESTS, stagingViemChain } from '../../core/test/stagingRedirect';
2
+ import { arbSepolia as cofheArbSepolia, stagingCofhe } from '@/chains';
2
3
  import { Encryptable } from '@/core';
3
4
 
4
5
  import { describe, it, expect, beforeAll } from 'vitest';
@@ -10,33 +11,38 @@ import { createCofheClient, createCofheConfig } from '../index.js';
10
11
 
11
12
  const TEST_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
12
13
 
14
+ const testViemChain = STAGING_TESTS ? stagingViemChain : viemArbitrumSepolia;
15
+ const testCofheChain = STAGING_TESTS ? stagingCofhe : cofheArbSepolia;
16
+
13
17
  describe('@cofhe/sdk/web - Worker vs Main Thread Output Validation', () => {
14
18
  let publicClient: PublicClient;
15
19
  let walletClient: WalletClient;
20
+ let consumingContract: `0x${string}`;
16
21
 
17
22
  beforeAll(() => {
18
23
  publicClient = createPublicClient({
19
- chain: viemArbitrumSepolia,
24
+ chain: testViemChain,
20
25
  transport: http(),
21
26
  });
22
27
 
23
28
  const account = privateKeyToAccount(TEST_PRIVATE_KEY);
24
29
  walletClient = createWalletClient({
25
- chain: viemArbitrumSepolia,
30
+ chain: testViemChain,
26
31
  transport: http(),
27
32
  account,
28
33
  });
34
+ consumingContract = account.address;
29
35
  });
30
36
 
31
37
  it('should produce consistent output format regardless of worker usage', async () => {
32
38
  // Create two clients - one with workers, one without
33
39
  const configWithWorker = createCofheConfig({
34
- supportedChains: [cofheArbSepolia],
40
+ supportedChains: [testCofheChain],
35
41
  useWorkers: true,
36
42
  });
37
43
 
38
44
  const configWithoutWorker = createCofheConfig({
39
- supportedChains: [cofheArbSepolia],
45
+ supportedChains: [testCofheChain],
40
46
  useWorkers: false,
41
47
  });
42
48
 
@@ -49,34 +55,29 @@ describe('@cofhe/sdk/web - Worker vs Main Thread Output Validation', () => {
49
55
  const value = Encryptable.uint128(12345n);
50
56
 
51
57
  const [resultWithWorker, resultWithoutWorker] = await Promise.all([
52
- clientWithWorker.encryptInputs([value]).execute(),
53
- clientWithoutWorker.encryptInputs([value]).execute(),
58
+ clientWithWorker.encryptInputs([value]).setConsumingContract(consumingContract).execute(),
59
+ clientWithoutWorker.encryptInputs([value]).setConsumingContract(consumingContract).execute(),
54
60
  ]);
55
61
 
56
62
  // Both should succeed
57
63
  expect(resultWithWorker).toBeDefined();
58
64
  expect(resultWithoutWorker).toBeDefined();
59
65
 
60
- // Both should have same structure (but different encrypted values)
61
- const withWorker = resultWithWorker[0];
62
- const withoutWorker = resultWithoutWorker[0];
66
+ // Both should have same structure (but different encrypted values):
67
+ // [hash, signature] - one hash per input, followed by the shared batch signature.
68
+ expect(resultWithWorker.length).toBe(2);
69
+ expect(resultWithoutWorker.length).toBe(2);
63
70
 
64
- expect(withWorker).toHaveProperty('ctHash');
65
- expect(withWorker).toHaveProperty('signature');
66
- expect(withWorker).toHaveProperty('utype');
67
- expect(withWorker).toHaveProperty('securityZone');
68
- expect(withoutWorker).toHaveProperty('ctHash');
69
- expect(withoutWorker).toHaveProperty('signature');
70
- expect(withoutWorker).toHaveProperty('utype');
71
- expect(withoutWorker).toHaveProperty('securityZone');
71
+ const [hashWithWorker, signatureWithWorker] = resultWithWorker;
72
+ const [hashWithoutWorker, signatureWithoutWorker] = resultWithoutWorker;
72
73
 
73
74
  // Format should be identical
74
- expect(typeof withWorker.ctHash).toBe('bigint');
75
- expect(typeof withoutWorker.ctHash).toBe('bigint');
76
- expect(withWorker.signature.startsWith('0x')).toBe(true);
77
- expect(withoutWorker.signature.startsWith('0x')).toBe(true);
78
- expect(typeof withWorker.utype).toBe('number');
79
- expect(typeof withoutWorker.utype).toBe('number');
75
+ expect(typeof hashWithWorker).toBe('string');
76
+ expect(typeof hashWithoutWorker).toBe('string');
77
+ expect(hashWithWorker.startsWith('0x')).toBe(true);
78
+ expect(hashWithoutWorker.startsWith('0x')).toBe(true);
79
+ expect(signatureWithWorker.startsWith('0x')).toBe(true);
80
+ expect(signatureWithoutWorker.startsWith('0x')).toBe(true);
80
81
 
81
82
  // Note: The actual encrypted values will differ because of randomness
82
83
  // in the encryption process, so we don't check equality
@@ -1,67 +0,0 @@
1
- /* eslint-disable no-redeclare */
2
- import {
3
- type EncryptableItem,
4
- isEncryptableItem,
5
- type EncryptedItemInput,
6
- type EncryptedItemInputs,
7
- } from '../types.js';
8
-
9
- export function encryptExtract<T>(item: T): EncryptableItem[];
10
- export function encryptExtract<T extends any[]>(item: [...T]): EncryptableItem[];
11
- export function encryptExtract<T>(item: T) {
12
- if (isEncryptableItem(item)) {
13
- return item;
14
- }
15
-
16
- // Object | Array
17
- if (typeof item === 'object' && item !== null) {
18
- if (Array.isArray(item)) {
19
- // Array - recurse
20
- return item.flatMap((nestedItem) => encryptExtract(nestedItem));
21
- } else {
22
- // Object - recurse
23
- return Object.values(item).flatMap((value) => encryptExtract(value));
24
- }
25
- }
26
-
27
- return [];
28
- }
29
-
30
- export function encryptReplace<T>(
31
- item: T,
32
- encryptedItems: EncryptedItemInput[]
33
- ): [EncryptedItemInputs<T>, EncryptedItemInput[]];
34
- export function encryptReplace<T extends any[]>(
35
- item: [...T],
36
- encryptedItems: EncryptedItemInput[]
37
- ): [...EncryptedItemInputs<T>, EncryptedItemInput[]];
38
- export function encryptReplace<T>(item: T, encryptedItems: EncryptedItemInput[]) {
39
- if (isEncryptableItem(item)) {
40
- return [encryptedItems[0], encryptedItems.slice(1)];
41
- }
42
-
43
- // Object | Array
44
- if (typeof item === 'object' && item !== null) {
45
- if (Array.isArray(item)) {
46
- // Array - recurse
47
- return item.reduce<[any[], EncryptedItemInput[]]>(
48
- ([acc, remaining], item) => {
49
- const [newItem, newRemaining] = encryptReplace(item, remaining);
50
- return [[...acc, newItem], newRemaining];
51
- },
52
- [[], encryptedItems]
53
- );
54
- } else {
55
- // Object - recurse
56
- return Object.entries(item).reduce<[Record<string, any>, EncryptedItemInput[]]>(
57
- ([acc, remaining], [key, value]) => {
58
- const [newValue, newRemaining] = encryptReplace(value, remaining);
59
- return [{ ...acc, [key]: newValue }, newRemaining];
60
- },
61
- [{}, encryptedItems]
62
- );
63
- }
64
- }
65
-
66
- return [item, encryptedItems];
67
- }
package/core/permits.ts DELETED
@@ -1,206 +0,0 @@
1
- import {
2
- type ImportSharedPermitOptions,
3
- PermitUtils,
4
- type CreateSelfPermitOptions,
5
- type CreateSharingPermitOptions,
6
- type Permit,
7
- permitStore,
8
- type SerializedPermit,
9
- type SelfPermit,
10
- type RecipientPermit,
11
- type SharingPermit,
12
- type PermitHashFields,
13
- } from '@/permits';
14
-
15
- import { type PublicClient, type WalletClient } from 'viem';
16
-
17
- // HELPERS
18
-
19
- // Helper function to store permit as active permit
20
- const storeActivePermit = async (permit: Permit, publicClient: any, walletClient: any) => {
21
- const chainId = await publicClient.getChainId();
22
- const account = walletClient.account!.address;
23
-
24
- permitStore.setPermit(chainId, account, permit);
25
- permitStore.setActivePermitHash(chainId, account, permit.hash);
26
- };
27
-
28
- // Generic function to handle permit creation with error handling
29
- const createPermitWithSign = async <T, TPermit extends Permit>(
30
- options: T,
31
- publicClient: PublicClient,
32
- walletClient: WalletClient,
33
- permitMethod: (options: T, publicClient: PublicClient, walletClient: WalletClient) => Promise<TPermit>
34
- ): Promise<TPermit> => {
35
- const permit = await permitMethod(options, publicClient, walletClient);
36
- await storeActivePermit(permit, publicClient, walletClient);
37
- return permit;
38
- };
39
-
40
- // CREATE
41
-
42
- /**
43
- * Create a permit usable by the connected user
44
- * Stores the permit and selects it as the active permit
45
- * @param options - The options for creating a self permit
46
- * @returns The created permit or error
47
- */
48
- const createSelf = async (
49
- options: CreateSelfPermitOptions,
50
- publicClient: PublicClient,
51
- walletClient: WalletClient
52
- ): Promise<SelfPermit> => {
53
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSelfAndSign);
54
- };
55
-
56
- const createSharing = async (
57
- options: CreateSharingPermitOptions,
58
- publicClient: PublicClient,
59
- walletClient: WalletClient
60
- ): Promise<SharingPermit> => {
61
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.createSharingAndSign);
62
- };
63
-
64
- const importShared = async (
65
- options: ImportSharedPermitOptions | string,
66
- publicClient: PublicClient,
67
- walletClient: WalletClient
68
- ): Promise<RecipientPermit> => {
69
- return createPermitWithSign(options, publicClient, walletClient, PermitUtils.importSharedAndSign);
70
- };
71
-
72
- // PERMIT UTILS
73
-
74
- const getHash = (permit: PermitHashFields) => {
75
- return PermitUtils.getHash(permit);
76
- };
77
-
78
- const exportShared = (permit: Permit) => {
79
- return PermitUtils.export(permit);
80
- };
81
-
82
- const serialize = (permit: Permit) => {
83
- return PermitUtils.serialize(permit);
84
- };
85
-
86
- const deserialize = (serialized: SerializedPermit) => {
87
- return PermitUtils.deserialize(serialized);
88
- };
89
-
90
- // GET
91
-
92
- const getPermit = (chainId: number, account: string, hash: string): Permit | undefined => {
93
- return permitStore.getPermit(chainId, account, hash);
94
- };
95
-
96
- const getPermits = (chainId: number, account: string): Record<string, Permit> => {
97
- return permitStore.getPermits(chainId, account);
98
- };
99
-
100
- const getActivePermit = (chainId: number, account: string): Permit | undefined => {
101
- return permitStore.getActivePermit(chainId, account);
102
- };
103
-
104
- const getActivePermitHash = (chainId: number, account: string): string | undefined => {
105
- return permitStore.getActivePermitHash(chainId, account);
106
- };
107
-
108
- const selectActivePermit = (chainId: number, account: string, hash: string): void => {
109
- permitStore.setActivePermitHash(chainId, account, hash);
110
- };
111
-
112
- // GET OR CREATE
113
-
114
- /**
115
- * Get the active self permit or create a new one if it doesn't exist
116
- * @param publicClient - The public client
117
- * @param walletClient - The wallet client
118
- * @param chainId - Optional chain ID (will use publicClient if not provided)
119
- * @param account - Optional account (will use walletClient if not provided)
120
- * @param options - The options for creating a self permit
121
- * @returns The existing or newly created permit
122
- */
123
- const getOrCreateSelfPermit = async (
124
- publicClient: PublicClient,
125
- walletClient: WalletClient,
126
- chainId?: number,
127
- account?: string,
128
- options?: CreateSelfPermitOptions
129
- ): Promise<Permit> => {
130
- const _chainId = chainId ?? (await publicClient.getChainId());
131
- const _account = account ?? walletClient.account!.address;
132
-
133
- // Try to get active permit first
134
- const activePermit = await getActivePermit(_chainId, _account);
135
-
136
- if (activePermit && activePermit.type === 'self') {
137
- return activePermit;
138
- }
139
-
140
- // No active permit or wrong type, create new one
141
- return createSelf(options ?? { issuer: _account, name: 'Autogenerated Self Permit' }, publicClient, walletClient);
142
- };
143
-
144
- /**
145
- * Get the active sharing permit or create a new one if it doesn't exist
146
- * @param publicClient - The public client
147
- * @param walletClient - The wallet client
148
- * @param options - The options for creating a sharing permit (required)
149
- * @param chainId - Optional chain ID (will use publicClient if not provided)
150
- * @param account - Optional account (will use walletClient if not provided)
151
- * @returns The existing or newly created permit
152
- */
153
- const getOrCreateSharingPermit = async (
154
- publicClient: PublicClient,
155
- walletClient: WalletClient,
156
- options: CreateSharingPermitOptions,
157
- chainId?: number,
158
- account?: string
159
- ): Promise<Permit> => {
160
- const _chainId = chainId ?? (await publicClient.getChainId());
161
- const _account = account ?? walletClient.account!.address;
162
-
163
- // Try to get active permit first
164
- const activePermit = await getActivePermit(_chainId, _account);
165
-
166
- if (activePermit && activePermit.type === 'sharing') {
167
- return activePermit;
168
- }
169
-
170
- return createSharing(options, publicClient, walletClient);
171
- };
172
-
173
- // REMOVE
174
-
175
- const removePermit = async (chainId: number, account: string, hash: string): Promise<void> =>
176
- permitStore.removePermit(chainId, account, hash);
177
-
178
- const removeActivePermit = async (chainId: number, account: string): Promise<void> =>
179
- permitStore.removeActivePermitHash(chainId, account);
180
-
181
- // EXPORT
182
-
183
- export const permits = {
184
- getSnapshot: permitStore.store.getState,
185
- subscribe: permitStore.store.subscribe,
186
-
187
- createSelf,
188
- createSharing,
189
- importShared,
190
-
191
- getOrCreateSelfPermit,
192
- getOrCreateSharingPermit,
193
-
194
- getHash,
195
- export: exportShared,
196
- serialize,
197
- deserialize,
198
-
199
- getPermit,
200
- getPermits,
201
- getActivePermit,
202
- getActivePermitHash,
203
- removePermit,
204
- selectActivePermit,
205
- removeActivePermit,
206
- };