@cofhe/sdk 0.0.0-alpha-20260409113701

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 (132) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/adapters/ethers5.test.ts +174 -0
  3. package/adapters/ethers5.ts +36 -0
  4. package/adapters/ethers6.test.ts +169 -0
  5. package/adapters/ethers6.ts +36 -0
  6. package/adapters/hardhat-node.ts +167 -0
  7. package/adapters/hardhat.hh2.test.ts +159 -0
  8. package/adapters/hardhat.ts +36 -0
  9. package/adapters/index.test.ts +20 -0
  10. package/adapters/index.ts +5 -0
  11. package/adapters/smartWallet.ts +99 -0
  12. package/adapters/test-utils.ts +53 -0
  13. package/adapters/types.ts +6 -0
  14. package/adapters/wagmi.test.ts +156 -0
  15. package/adapters/wagmi.ts +17 -0
  16. package/chains/chains/arbSepolia.ts +14 -0
  17. package/chains/chains/baseSepolia.ts +14 -0
  18. package/chains/chains/hardhat.ts +15 -0
  19. package/chains/chains/localcofhe.ts +14 -0
  20. package/chains/chains/sepolia.ts +14 -0
  21. package/chains/chains.test.ts +50 -0
  22. package/chains/defineChain.ts +18 -0
  23. package/chains/index.ts +35 -0
  24. package/chains/types.ts +32 -0
  25. package/core/baseBuilder.ts +119 -0
  26. package/core/client.test.ts +429 -0
  27. package/core/client.ts +341 -0
  28. package/core/clientTypes.ts +119 -0
  29. package/core/config.test.ts +242 -0
  30. package/core/config.ts +225 -0
  31. package/core/consts.ts +22 -0
  32. package/core/decrypt/MockThresholdNetworkAbi.ts +179 -0
  33. package/core/decrypt/cofheMocksDecryptForTx.ts +84 -0
  34. package/core/decrypt/cofheMocksDecryptForView.ts +48 -0
  35. package/core/decrypt/decryptForTxBuilder.ts +359 -0
  36. package/core/decrypt/decryptForViewBuilder.ts +332 -0
  37. package/core/decrypt/decryptUtils.ts +28 -0
  38. package/core/decrypt/pollCallbacks.test.ts +194 -0
  39. package/core/decrypt/polling.ts +14 -0
  40. package/core/decrypt/tnDecryptUtils.ts +65 -0
  41. package/core/decrypt/tnDecryptV1.ts +171 -0
  42. package/core/decrypt/tnDecryptV2.ts +365 -0
  43. package/core/decrypt/tnSealOutputV1.ts +59 -0
  44. package/core/decrypt/tnSealOutputV2.ts +324 -0
  45. package/core/decrypt/verifyDecryptResult.ts +52 -0
  46. package/core/encrypt/MockZkVerifierAbi.ts +106 -0
  47. package/core/encrypt/cofheMocksZkVerifySign.ts +281 -0
  48. package/core/encrypt/encryptInputsBuilder.test.ts +747 -0
  49. package/core/encrypt/encryptInputsBuilder.ts +583 -0
  50. package/core/encrypt/encryptUtils.ts +67 -0
  51. package/core/encrypt/zkPackProveVerify.ts +335 -0
  52. package/core/error.ts +168 -0
  53. package/core/fetchKeys.test.ts +195 -0
  54. package/core/fetchKeys.ts +144 -0
  55. package/core/index.ts +106 -0
  56. package/core/keyStore.test.ts +226 -0
  57. package/core/keyStore.ts +154 -0
  58. package/core/permits.test.ts +493 -0
  59. package/core/permits.ts +201 -0
  60. package/core/types.ts +419 -0
  61. package/core/utils.ts +130 -0
  62. package/dist/adapters.cjs +88 -0
  63. package/dist/adapters.d.cts +14576 -0
  64. package/dist/adapters.d.ts +14576 -0
  65. package/dist/adapters.js +83 -0
  66. package/dist/chains.cjs +111 -0
  67. package/dist/chains.d.cts +121 -0
  68. package/dist/chains.d.ts +121 -0
  69. package/dist/chains.js +1 -0
  70. package/dist/chunk-36FBWLUS.js +3310 -0
  71. package/dist/chunk-7HLGHV67.js +990 -0
  72. package/dist/chunk-TBLR7NNE.js +102 -0
  73. package/dist/clientTypes-AVSCBet7.d.cts +998 -0
  74. package/dist/clientTypes-flH1ju82.d.ts +998 -0
  75. package/dist/core.cjs +4362 -0
  76. package/dist/core.d.cts +138 -0
  77. package/dist/core.d.ts +138 -0
  78. package/dist/core.js +3 -0
  79. package/dist/node.cjs +4225 -0
  80. package/dist/node.d.cts +22 -0
  81. package/dist/node.d.ts +22 -0
  82. package/dist/node.js +91 -0
  83. package/dist/permit-jRirYqFt.d.cts +376 -0
  84. package/dist/permit-jRirYqFt.d.ts +376 -0
  85. package/dist/permits.cjs +1025 -0
  86. package/dist/permits.d.cts +353 -0
  87. package/dist/permits.d.ts +353 -0
  88. package/dist/permits.js +1 -0
  89. package/dist/types-YiAC4gig.d.cts +33 -0
  90. package/dist/types-YiAC4gig.d.ts +33 -0
  91. package/dist/web.cjs +4434 -0
  92. package/dist/web.d.cts +42 -0
  93. package/dist/web.d.ts +42 -0
  94. package/dist/web.js +256 -0
  95. package/dist/zkProve.worker.cjs +93 -0
  96. package/dist/zkProve.worker.d.cts +2 -0
  97. package/dist/zkProve.worker.d.ts +2 -0
  98. package/dist/zkProve.worker.js +91 -0
  99. package/node/client.test.ts +159 -0
  100. package/node/config.test.ts +68 -0
  101. package/node/encryptInputs.test.ts +155 -0
  102. package/node/index.ts +97 -0
  103. package/node/storage.ts +51 -0
  104. package/package.json +121 -0
  105. package/permits/index.ts +68 -0
  106. package/permits/localstorage.test.ts +113 -0
  107. package/permits/onchain-utils.ts +221 -0
  108. package/permits/permit.test.ts +534 -0
  109. package/permits/permit.ts +386 -0
  110. package/permits/sealing.test.ts +84 -0
  111. package/permits/sealing.ts +131 -0
  112. package/permits/signature.ts +79 -0
  113. package/permits/store.test.ts +88 -0
  114. package/permits/store.ts +156 -0
  115. package/permits/test-utils.ts +28 -0
  116. package/permits/types.ts +204 -0
  117. package/permits/utils.ts +58 -0
  118. package/permits/validation.test.ts +361 -0
  119. package/permits/validation.ts +327 -0
  120. package/web/client.web.test.ts +159 -0
  121. package/web/config.web.test.ts +69 -0
  122. package/web/const.ts +2 -0
  123. package/web/encryptInputs.web.test.ts +172 -0
  124. package/web/index.ts +166 -0
  125. package/web/storage.ts +49 -0
  126. package/web/worker.builder.web.test.ts +148 -0
  127. package/web/worker.config.web.test.ts +329 -0
  128. package/web/worker.output.web.test.ts +84 -0
  129. package/web/workerManager.test.ts +80 -0
  130. package/web/workerManager.ts +214 -0
  131. package/web/workerManager.web.test.ts +114 -0
  132. package/web/zkProve.worker.ts +133 -0
package/core/config.ts ADDED
@@ -0,0 +1,225 @@
1
+ import { type CofheChain } from '@/chains';
2
+
3
+ import { z } from 'zod';
4
+ import { type WalletClient } from 'viem';
5
+ import { CofheError, CofheErrorCode } from './error.js';
6
+ import { type IStorage } from './types.js';
7
+
8
+ export type CofheEnvironment = 'node' | 'hardhat' | 'web' | 'react';
9
+
10
+ /**
11
+ * Usable config type inferred from the schema
12
+ */
13
+ export type CofheConfig = {
14
+ /** Environment that the SDK is running in */
15
+ environment: 'node' | 'hardhat' | 'web' | 'react';
16
+ /** List of supported chains */
17
+ supportedChains: CofheChain[];
18
+ /** Default permit expiration in seconds, default is 30 days */
19
+ defaultPermitExpiration: number;
20
+ /**
21
+ * Storage scheme for the fetched fhe keys
22
+ * FHE keys are large, and caching prevents re-fetching them on each encryptInputs call
23
+ * (defaults to indexedDB on web, filesystem on node)
24
+ */
25
+ fheKeyStorage: IStorage | null;
26
+ /**
27
+ * Whether to use Web Workers for ZK proof generation (web platform only)
28
+ * When enabled, heavy WASM computation is offloaded to prevent UI freezing
29
+ * Default: true
30
+ */
31
+ useWorkers: boolean;
32
+ /** Mocks configs */
33
+ mocks: {
34
+ /**
35
+ * Length of the simulated seal output delay in milliseconds
36
+ * Default 1000ms on web
37
+ * Default 0ms on hardhat (will be called during tests no need for fake delay)
38
+ */
39
+ decryptDelay: number;
40
+ /**
41
+ * Simulated delay(s) in milliseconds for each step of encryptInputs in mock mode.
42
+ * A single number applies the same delay to all five steps (InitTfhe, FetchKeys, Pack, Prove, Verify).
43
+ * A tuple of five numbers applies a per-step delay: [InitTfhe, FetchKeys, Pack, Prove, Verify].
44
+ * Default: [100, 100, 100, 500, 500]
45
+ */
46
+ encryptDelay: number | [number, number, number, number, number];
47
+ };
48
+ _internal?: CofheInternalConfig;
49
+ };
50
+
51
+ export type CofheInternalConfig = {
52
+ zkvWalletClient?: WalletClient;
53
+ };
54
+
55
+ /**
56
+ * Zod schema for configuration validation
57
+ */
58
+ export const CofheConfigSchema = z.object({
59
+ /** Environment that the SDK is running in */
60
+ environment: z.enum(['node', 'hardhat', 'web', 'react']).optional().default('node'),
61
+ /** List of supported chain configurations */
62
+ supportedChains: z.array(z.custom<CofheChain>()),
63
+ /** Default permit expiration in seconds, default is 30 days */
64
+ defaultPermitExpiration: z
65
+ .number()
66
+ .optional()
67
+ .default(60 * 60 * 24 * 30),
68
+ /** Storage method for fhe keys (defaults to indexedDB on web, filesystem on node) */
69
+ fheKeyStorage: z
70
+ .object({
71
+ getItem: z.custom<IStorage['getItem']>((val) => typeof val === 'function', {
72
+ message: 'getItem must be a function',
73
+ }),
74
+ setItem: z.custom<IStorage['setItem']>((val) => typeof val === 'function', {
75
+ message: 'setItem must be a function',
76
+ }),
77
+ removeItem: z.custom<IStorage['removeItem']>((val) => typeof val === 'function', {
78
+ message: 'removeItem must be a function',
79
+ }),
80
+ })
81
+ .or(z.null())
82
+ .default(null),
83
+ /** Whether to use Web Workers for ZK proof generation (web platform only) */
84
+ useWorkers: z.boolean().optional().default(true),
85
+ /** Mocks configs */
86
+ mocks: z
87
+ .object({
88
+ decryptDelay: z.number().optional().default(0),
89
+ encryptDelay: z
90
+ .union([z.number(), z.tuple([z.number(), z.number(), z.number(), z.number(), z.number()])])
91
+ .optional()
92
+ .default([100, 100, 100, 500, 500]),
93
+ })
94
+ .optional()
95
+ .default({ decryptDelay: 0, encryptDelay: [100, 100, 100, 500, 500] }),
96
+ /** Internal configuration */
97
+ _internal: z
98
+ .object({
99
+ zkvWalletClient: z.any().optional(),
100
+ })
101
+ .optional(),
102
+ });
103
+
104
+ /**
105
+ * Input config type inferred from the schema
106
+ */
107
+ export type CofheInputConfig = z.input<typeof CofheConfigSchema>;
108
+
109
+ /**
110
+ * Creates and validates a cofhe configuration (base implementation)
111
+ * @param config - The configuration object to validate
112
+ * @returns The validated configuration
113
+ * @throws {Error} If the configuration is invalid
114
+ */
115
+ export function createCofheConfigBase(config: CofheInputConfig): CofheConfig {
116
+ const result = CofheConfigSchema.safeParse(config);
117
+
118
+ if (!result.success) {
119
+ throw new Error(`Invalid cofhe configuration: ${z.prettifyError(result.error)}`, { cause: result.error });
120
+ }
121
+
122
+ return result.data;
123
+ }
124
+
125
+ /**
126
+ * Access the CofheConfig object directly by providing the key.
127
+ * This is powerful when you use OnchainKit utilities outside of the React context.
128
+ */
129
+ export const getCofheConfigItem = <K extends keyof CofheConfig>(config: CofheConfig, key: K): CofheConfig[K] => {
130
+ return config[key];
131
+ };
132
+
133
+ /**
134
+ * Gets a supported chain from config by chainId, throws if not found
135
+ * @param config - The cofhe configuration
136
+ * @param chainId - The chain ID to look up
137
+ * @returns The supported chain configuration
138
+ * @throws {CofheError} If the chain is not found in the config
139
+ */
140
+ export function getSupportedChainOrThrow(config: CofheConfig, chainId: number): CofheChain {
141
+ const supportedChain = config.supportedChains.find((chain) => chain.id === chainId);
142
+
143
+ if (!supportedChain) {
144
+ throw new CofheError({
145
+ code: CofheErrorCode.UnsupportedChain,
146
+ message: `Config does not support chain <${chainId}>`,
147
+ hint: 'Ensure config passed to client has been created with this chain in the config.supportedChains array.',
148
+ context: {
149
+ chainId,
150
+ supportedChainIds: config.supportedChains.map((c) => c.id),
151
+ },
152
+ });
153
+ }
154
+
155
+ return supportedChain;
156
+ }
157
+
158
+ /**
159
+ * Gets the CoFHE URL for a chain, throws if not found
160
+ * @param config - The cofhe configuration
161
+ * @param chainId - The chain ID to look up
162
+ * @returns The CoFHE URL for the chain
163
+ * @throws {CofheError} If the chain or URL is not found
164
+ */
165
+ export function getCoFheUrlOrThrow(config: CofheConfig, chainId: number): string {
166
+ const supportedChain = getSupportedChainOrThrow(config, chainId);
167
+ const url = supportedChain.coFheUrl;
168
+
169
+ if (!url) {
170
+ throw new CofheError({
171
+ code: CofheErrorCode.MissingConfig,
172
+ message: `CoFHE URL is not configured for chain <${chainId}>`,
173
+ hint: 'Ensure this chain config includes a coFheUrl property.',
174
+ context: { chainId },
175
+ });
176
+ }
177
+
178
+ return url;
179
+ }
180
+
181
+ /**
182
+ * Gets the ZK verifier URL for a chain, throws if not found
183
+ * @param config - The cofhe configuration
184
+ * @param chainId - The chain ID to look up
185
+ * @returns The ZK verifier URL for the chain
186
+ * @throws {CofheError} If the chain or URL is not found
187
+ */
188
+ export function getZkVerifierUrlOrThrow(config: CofheConfig, chainId: number): string {
189
+ const supportedChain = getSupportedChainOrThrow(config, chainId);
190
+ const url = supportedChain.verifierUrl;
191
+
192
+ if (!url) {
193
+ throw new CofheError({
194
+ code: CofheErrorCode.ZkVerifierUrlUninitialized,
195
+ message: `ZK verifier URL is not configured for chain <${chainId}>`,
196
+ hint: 'Ensure this chain config includes a verifierUrl property.',
197
+ context: { chainId },
198
+ });
199
+ }
200
+
201
+ return url;
202
+ }
203
+
204
+ /**
205
+ * Gets the threshold network URL for a chain, throws if not found
206
+ * @param config - The cofhe configuration
207
+ * @param chainId - The chain ID to look up
208
+ * @returns The threshold network URL for the chain
209
+ * @throws {CofheError} If the chain or URL is not found
210
+ */
211
+ export function getThresholdNetworkUrlOrThrow(config: CofheConfig, chainId: number): string {
212
+ const supportedChain = getSupportedChainOrThrow(config, chainId);
213
+ const url = supportedChain.thresholdNetworkUrl;
214
+
215
+ if (!url) {
216
+ throw new CofheError({
217
+ code: CofheErrorCode.ThresholdNetworkUrlUninitialized,
218
+ message: `Threshold network URL is not configured for chain <${chainId}>`,
219
+ hint: 'Ensure this chain config includes a thresholdNetworkUrl property.',
220
+ context: { chainId },
221
+ });
222
+ }
223
+
224
+ return url;
225
+ }
package/core/consts.ts ADDED
@@ -0,0 +1,22 @@
1
+ /** Main Task Manager contract address */
2
+ export const TASK_MANAGER_ADDRESS = '0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9' as const;
3
+
4
+ /** Mock ZK Verifier contract address (used for testing) */
5
+ export const MOCKS_ZK_VERIFIER_ADDRESS = '0x0000000000000000000000000000000000005001' as const;
6
+
7
+ /** Mock Threshold Network contract address (used for testing) */
8
+ export const MOCKS_THRESHOLD_NETWORK_ADDRESS = '0x0000000000000000000000000000000000005002' as const;
9
+
10
+ /** Test Bed contract address (used for testing) */
11
+ export const TEST_BED_ADDRESS = '0x0000000000000000000000000000000000005003' as const;
12
+
13
+ /** Private key for the Mock ZK Verifier signer account */
14
+ export const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY =
15
+ '0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512' as const;
16
+
17
+ /** Address for the Mock ZK Verifier signer account */
18
+ export const MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = '0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2' as const;
19
+
20
+ /** Private key for the Mock decrypt result signer account */
21
+ export const MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY =
22
+ '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' as const;
@@ -0,0 +1,179 @@
1
+ export const MockThresholdNetworkAbi = [
2
+ {
3
+ type: 'function',
4
+ name: 'acl',
5
+ inputs: [],
6
+ outputs: [{ name: '', type: 'address', internalType: 'contract ACL' }],
7
+ stateMutability: 'view',
8
+ },
9
+ {
10
+ type: 'function',
11
+ name: 'decodeLowLevelReversion',
12
+ inputs: [{ name: 'data', type: 'bytes', internalType: 'bytes' }],
13
+ outputs: [{ name: 'error', type: 'string', internalType: 'string' }],
14
+ stateMutability: 'pure',
15
+ },
16
+ {
17
+ type: 'function',
18
+ name: 'exists',
19
+ inputs: [],
20
+ outputs: [{ name: '', type: 'bool', internalType: 'bool' }],
21
+ stateMutability: 'pure',
22
+ },
23
+ {
24
+ type: 'function',
25
+ name: 'initialize',
26
+ inputs: [
27
+ { name: '_taskManager', type: 'address', internalType: 'address' },
28
+ { name: '_acl', type: 'address', internalType: 'address' },
29
+ ],
30
+ outputs: [],
31
+ stateMutability: 'nonpayable',
32
+ },
33
+ {
34
+ type: 'function',
35
+ name: 'queryDecrypt',
36
+ inputs: [
37
+ { name: 'ctHash', type: 'uint256', internalType: 'uint256' },
38
+ { name: '', type: 'uint256', internalType: 'uint256' },
39
+ {
40
+ name: 'permission',
41
+ type: 'tuple',
42
+ internalType: 'struct Permission',
43
+ components: [
44
+ { name: 'issuer', type: 'address', internalType: 'address' },
45
+ { name: 'expiration', type: 'uint64', internalType: 'uint64' },
46
+ { name: 'recipient', type: 'address', internalType: 'address' },
47
+ { name: 'validatorId', type: 'uint256', internalType: 'uint256' },
48
+ { name: 'validatorContract', type: 'address', internalType: 'address' },
49
+ { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' },
50
+ { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' },
51
+ { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' },
52
+ ],
53
+ },
54
+ ],
55
+ outputs: [
56
+ { name: 'allowed', type: 'bool', internalType: 'bool' },
57
+ { name: 'error', type: 'string', internalType: 'string' },
58
+ { name: '', type: 'uint256', internalType: 'uint256' },
59
+ ],
60
+ stateMutability: 'view',
61
+ },
62
+ {
63
+ type: 'function',
64
+ name: 'querySealOutput',
65
+ inputs: [
66
+ { name: 'ctHash', type: 'uint256', internalType: 'uint256' },
67
+ { name: '', type: 'uint256', internalType: 'uint256' },
68
+ {
69
+ name: 'permission',
70
+ type: 'tuple',
71
+ internalType: 'struct Permission',
72
+ components: [
73
+ { name: 'issuer', type: 'address', internalType: 'address' },
74
+ { name: 'expiration', type: 'uint64', internalType: 'uint64' },
75
+ { name: 'recipient', type: 'address', internalType: 'address' },
76
+ { name: 'validatorId', type: 'uint256', internalType: 'uint256' },
77
+ { name: 'validatorContract', type: 'address', internalType: 'address' },
78
+ { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' },
79
+ { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' },
80
+ { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' },
81
+ ],
82
+ },
83
+ ],
84
+ outputs: [
85
+ { name: 'allowed', type: 'bool', internalType: 'bool' },
86
+ { name: 'error', type: 'string', internalType: 'string' },
87
+ { name: '', type: 'bytes32', internalType: 'bytes32' },
88
+ ],
89
+ stateMutability: 'view',
90
+ },
91
+ {
92
+ type: 'function',
93
+ name: 'seal',
94
+ inputs: [
95
+ { name: 'input', type: 'uint256', internalType: 'uint256' },
96
+ { name: 'key', type: 'bytes32', internalType: 'bytes32' },
97
+ ],
98
+ outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }],
99
+ stateMutability: 'pure',
100
+ },
101
+ {
102
+ type: 'function',
103
+ name: 'unseal',
104
+ inputs: [
105
+ { name: 'hashed', type: 'bytes32', internalType: 'bytes32' },
106
+ { name: 'key', type: 'bytes32', internalType: 'bytes32' },
107
+ ],
108
+ outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }],
109
+ stateMutability: 'pure',
110
+ },
111
+ {
112
+ type: 'function',
113
+ name: 'mockAcl',
114
+ inputs: [],
115
+ outputs: [{ name: '', type: 'address', internalType: 'contract MockACL' }],
116
+ stateMutability: 'view',
117
+ },
118
+ {
119
+ type: 'function',
120
+ name: 'mockTaskManager',
121
+ inputs: [],
122
+ outputs: [{ name: '', type: 'address', internalType: 'contract MockTaskManager' }],
123
+ stateMutability: 'view',
124
+ },
125
+ {
126
+ type: 'function',
127
+ name: 'mockQueryDecrypt',
128
+ inputs: [
129
+ { name: 'ctHash', type: 'uint256', internalType: 'uint256' },
130
+ { name: '', type: 'uint256', internalType: 'uint256' },
131
+ { name: 'issuer', type: 'address', internalType: 'address' },
132
+ ],
133
+ outputs: [
134
+ { name: 'allowed', type: 'bool', internalType: 'bool' },
135
+ { name: 'error', type: 'string', internalType: 'string' },
136
+ { name: '', type: 'uint256', internalType: 'uint256' },
137
+ ],
138
+ stateMutability: 'view',
139
+ },
140
+ {
141
+ type: 'function',
142
+ name: 'decryptForTxWithPermit',
143
+ inputs: [
144
+ { name: 'ctHash', type: 'uint256', internalType: 'uint256' },
145
+ {
146
+ name: 'permission',
147
+ type: 'tuple',
148
+ internalType: 'struct Permission',
149
+ components: [
150
+ { name: 'issuer', type: 'address', internalType: 'address' },
151
+ { name: 'expiration', type: 'uint64', internalType: 'uint64' },
152
+ { name: 'recipient', type: 'address', internalType: 'address' },
153
+ { name: 'validatorId', type: 'uint256', internalType: 'uint256' },
154
+ { name: 'validatorContract', type: 'address', internalType: 'address' },
155
+ { name: 'sealingKey', type: 'bytes32', internalType: 'bytes32' },
156
+ { name: 'issuerSignature', type: 'bytes', internalType: 'bytes' },
157
+ { name: 'recipientSignature', type: 'bytes', internalType: 'bytes' },
158
+ ],
159
+ },
160
+ ],
161
+ outputs: [
162
+ { name: 'allowed', type: 'bool', internalType: 'bool' },
163
+ { name: 'error', type: 'string', internalType: 'string' },
164
+ { name: 'decryptedValue', type: 'uint256', internalType: 'uint256' },
165
+ ],
166
+ stateMutability: 'view',
167
+ },
168
+ {
169
+ type: 'function',
170
+ name: 'decryptForTxWithoutPermit',
171
+ inputs: [{ name: 'ctHash', type: 'uint256', internalType: 'uint256' }],
172
+ outputs: [
173
+ { name: 'allowed', type: 'bool', internalType: 'bool' },
174
+ { name: 'error', type: 'string', internalType: 'string' },
175
+ { name: 'decryptedValue', type: 'uint256', internalType: 'uint256' },
176
+ ],
177
+ stateMutability: 'view',
178
+ },
179
+ ] as const;
@@ -0,0 +1,84 @@
1
+ import { type Permit, PermitUtils } from '@/permits';
2
+
3
+ import { encodePacked, keccak256, type PublicClient } from 'viem';
4
+ import { sign } from 'viem/accounts';
5
+ import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js';
6
+ import { FheTypes } from '../types.js';
7
+ import { CofheError, CofheErrorCode } from '../error.js';
8
+ import { MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY } from '../consts.js';
9
+ import { MOCKS_THRESHOLD_NETWORK_ADDRESS } from '../consts.js';
10
+
11
+ export type DecryptForTxMocksResult = {
12
+ ctHash: bigint | string;
13
+ decryptedValue: bigint;
14
+ signature: `0x${string}`;
15
+ };
16
+
17
+ export async function cofheMocksDecryptForTx(
18
+ ctHash: bigint | string,
19
+ utype: FheTypes,
20
+ permit: Permit | null,
21
+ publicClient: PublicClient
22
+ ): Promise<DecryptForTxMocksResult> {
23
+ let allowed: boolean;
24
+ let error: string;
25
+ let decryptedValue: bigint;
26
+
27
+ // With permit
28
+ if (permit !== null) {
29
+ let permission = PermitUtils.getPermission(permit, true);
30
+ const permissionWithBigInts = {
31
+ ...permission,
32
+ expiration: BigInt(permission.expiration),
33
+ validatorId: BigInt(permission.validatorId),
34
+ };
35
+
36
+ [allowed, error, decryptedValue] = await publicClient.readContract({
37
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
38
+ abi: MockThresholdNetworkAbi,
39
+ functionName: 'decryptForTxWithPermit',
40
+ args: [BigInt(ctHash), permissionWithBigInts],
41
+ });
42
+ } else {
43
+ // Without permit (global allowance)
44
+ [allowed, error, decryptedValue] = await publicClient.readContract({
45
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
46
+ abi: MockThresholdNetworkAbi,
47
+ functionName: 'decryptForTxWithoutPermit',
48
+ args: [BigInt(ctHash)],
49
+ });
50
+ }
51
+
52
+ if (error != '') {
53
+ throw new CofheError({
54
+ code: CofheErrorCode.DecryptFailed,
55
+ message: `mocks decryptForTx call failed: ${error}`,
56
+ });
57
+ }
58
+
59
+ if (allowed == false) {
60
+ throw new CofheError({
61
+ code: CofheErrorCode.DecryptFailed,
62
+ message: `mocks decryptForTx call failed: ACL Access Denied (NotAllowed)`,
63
+ });
64
+ }
65
+
66
+ // decryptForTx returns plaintext directly (no sealing/unsealing needed)
67
+ // Generate a mock threshold network signature (in production, this would be the actual signature)
68
+ // The signature must be valid for MockTaskManager verification.
69
+ const packed = encodePacked(['uint256', 'uint256'], [BigInt(ctHash), decryptedValue]);
70
+ const messageHash = keccak256(packed);
71
+
72
+ // Raw digest signature (no EIP-191 prefix). Must verify against OpenZeppelin ECDSA.recover(messageHash, signature).
73
+ const signature = await sign({
74
+ hash: messageHash,
75
+ privateKey: MOCKS_DECRYPT_RESULT_SIGNER_PRIVATE_KEY,
76
+ to: 'hex',
77
+ });
78
+
79
+ return {
80
+ ctHash,
81
+ decryptedValue,
82
+ signature,
83
+ };
84
+ }
@@ -0,0 +1,48 @@
1
+ import { type Permit, PermitUtils } from '@/permits';
2
+
3
+ import { type PublicClient } from 'viem';
4
+ import { MockThresholdNetworkAbi } from './MockThresholdNetworkAbi.js';
5
+ import { FheTypes } from '../types.js';
6
+ import { CofheError, CofheErrorCode } from '../error.js';
7
+ import { MOCKS_THRESHOLD_NETWORK_ADDRESS } from '../consts.js';
8
+
9
+ export async function cofheMocksDecryptForView(
10
+ ctHash: bigint | string,
11
+ utype: FheTypes,
12
+ permit: Permit,
13
+ publicClient: PublicClient
14
+ ): Promise<bigint> {
15
+ const permission = PermitUtils.getPermission(permit, true);
16
+ const permissionWithBigInts = {
17
+ ...permission,
18
+ expiration: BigInt(permission.expiration),
19
+ validatorId: BigInt(permission.validatorId),
20
+ };
21
+
22
+ const [allowed, error, result] = await publicClient.readContract({
23
+ address: MOCKS_THRESHOLD_NETWORK_ADDRESS,
24
+ abi: MockThresholdNetworkAbi,
25
+ functionName: 'querySealOutput',
26
+ args: [BigInt(ctHash), BigInt(utype), permissionWithBigInts],
27
+ });
28
+
29
+ if (error != '') {
30
+ throw new CofheError({
31
+ code: CofheErrorCode.SealOutputFailed,
32
+ message: `mocks querySealOutput call failed: ${error}`,
33
+ });
34
+ }
35
+
36
+ if (allowed == false) {
37
+ throw new CofheError({
38
+ code: CofheErrorCode.SealOutputFailed,
39
+ message: `mocks querySealOutput call failed: ACL Access Denied (NotAllowed)`,
40
+ });
41
+ }
42
+
43
+ const sealedBigInt = BigInt(result);
44
+ const sealingKeyBigInt = BigInt(permission.sealingKey);
45
+ const unsealed = sealedBigInt ^ sealingKeyBigInt;
46
+
47
+ return unsealed;
48
+ }