@cofhe/sdk 0.1.0 → 0.2.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.
- package/CHANGELOG.md +62 -0
- package/adapters/ethers5.test.ts +174 -0
- package/adapters/ethers5.ts +36 -0
- package/adapters/ethers6.test.ts +169 -0
- package/adapters/ethers6.ts +36 -0
- package/adapters/hardhat-node.ts +167 -0
- package/adapters/hardhat.hh2.test.ts +159 -0
- package/adapters/hardhat.ts +36 -0
- package/adapters/index.test.ts +20 -0
- package/adapters/index.ts +5 -0
- package/adapters/smartWallet.ts +99 -0
- package/adapters/test-utils.ts +53 -0
- package/adapters/types.ts +6 -0
- package/adapters/wagmi.test.ts +156 -0
- package/adapters/wagmi.ts +17 -0
- package/chains/chains/arbSepolia.ts +14 -0
- package/chains/chains/baseSepolia.ts +14 -0
- package/chains/chains/hardhat.ts +15 -0
- package/chains/chains/localcofhe.ts +14 -0
- package/chains/chains/sepolia.ts +14 -0
- package/chains/chains.test.ts +50 -0
- package/chains/defineChain.ts +18 -0
- package/chains/index.ts +35 -0
- package/chains/types.ts +32 -0
- package/core/baseBuilder.ts +119 -0
- package/core/client.test.ts +315 -0
- package/core/client.ts +292 -0
- package/core/clientTypes.ts +108 -0
- package/core/config.test.ts +235 -0
- package/core/config.ts +220 -0
- package/core/decrypt/MockQueryDecrypterAbi.ts +129 -0
- package/core/decrypt/cofheMocksSealOutput.ts +57 -0
- package/core/decrypt/decryptHandleBuilder.ts +287 -0
- package/core/decrypt/decryptUtils.ts +28 -0
- package/core/decrypt/tnSealOutputV1.ts +59 -0
- package/core/decrypt/tnSealOutputV2.ts +298 -0
- package/core/encrypt/MockZkVerifierAbi.ts +106 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +284 -0
- package/core/encrypt/encryptInputsBuilder.test.ts +751 -0
- package/core/encrypt/encryptInputsBuilder.ts +560 -0
- package/core/encrypt/encryptUtils.ts +67 -0
- package/core/encrypt/zkPackProveVerify.ts +335 -0
- package/core/error.ts +168 -0
- package/core/fetchKeys.test.ts +195 -0
- package/core/fetchKeys.ts +144 -0
- package/core/index.ts +89 -0
- package/core/keyStore.test.ts +226 -0
- package/core/keyStore.ts +154 -0
- package/core/permits.test.ts +494 -0
- package/core/permits.ts +200 -0
- package/core/types.ts +398 -0
- package/core/utils.ts +130 -0
- package/dist/adapters.cjs +88 -0
- package/dist/adapters.d.cts +14576 -0
- package/dist/adapters.d.ts +14576 -0
- package/dist/adapters.js +83 -0
- package/dist/chains.cjs +114 -0
- package/dist/chains.d.cts +121 -0
- package/dist/chains.d.ts +121 -0
- package/dist/chains.js +1 -0
- package/dist/chunk-UGBVZNRT.js +818 -0
- package/dist/chunk-WEAZ25JO.js +105 -0
- package/dist/chunk-WGCRJCBR.js +2523 -0
- package/dist/clientTypes-5_1nwtUe.d.cts +914 -0
- package/dist/clientTypes-Es7fyi65.d.ts +914 -0
- package/dist/core.cjs +3414 -0
- package/dist/core.d.cts +111 -0
- package/dist/core.d.ts +111 -0
- package/dist/core.js +3 -0
- package/dist/node.cjs +3286 -0
- package/dist/node.d.cts +22 -0
- package/dist/node.d.ts +22 -0
- package/dist/node.js +91 -0
- package/dist/permit-fUSe6KKq.d.cts +349 -0
- package/dist/permit-fUSe6KKq.d.ts +349 -0
- package/dist/permits.cjs +871 -0
- package/dist/permits.d.cts +1045 -0
- package/dist/permits.d.ts +1045 -0
- package/dist/permits.js +1 -0
- package/dist/types-KImPrEIe.d.cts +48 -0
- package/dist/types-KImPrEIe.d.ts +48 -0
- package/dist/web.cjs +3478 -0
- package/dist/web.d.cts +38 -0
- package/dist/web.d.ts +38 -0
- package/dist/web.js +240 -0
- package/dist/zkProve.worker.cjs +93 -0
- package/dist/zkProve.worker.d.cts +2 -0
- package/dist/zkProve.worker.d.ts +2 -0
- package/dist/zkProve.worker.js +91 -0
- package/node/client.test.ts +147 -0
- package/node/config.test.ts +68 -0
- package/node/encryptInputs.test.ts +155 -0
- package/node/index.ts +97 -0
- package/node/storage.ts +51 -0
- package/package.json +27 -15
- package/permits/index.ts +68 -0
- package/permits/localstorage.test.ts +117 -0
- package/permits/permit.test.ts +477 -0
- package/permits/permit.ts +405 -0
- package/permits/sealing.test.ts +84 -0
- package/permits/sealing.ts +131 -0
- package/permits/signature.ts +79 -0
- package/permits/store.test.ts +128 -0
- package/permits/store.ts +166 -0
- package/permits/test-utils.ts +20 -0
- package/permits/types.ts +191 -0
- package/permits/utils.ts +62 -0
- package/permits/validation.test.ts +288 -0
- package/permits/validation.ts +369 -0
- package/web/client.web.test.ts +147 -0
- package/web/config.web.test.ts +69 -0
- package/web/encryptInputs.web.test.ts +172 -0
- package/web/index.ts +161 -0
- package/web/storage.ts +34 -0
- package/web/worker.builder.web.test.ts +148 -0
- package/web/worker.config.web.test.ts +329 -0
- package/web/worker.output.web.test.ts +84 -0
- package/web/workerManager.test.ts +80 -0
- package/web/workerManager.ts +214 -0
- package/web/workerManager.web.test.ts +114 -0
- package/web/zkProve.worker.ts +133 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getAddress } from 'viem';
|
|
2
|
+
import { FheTypes, FheUintUTypes, type UnsealedItem } from '../types.js';
|
|
3
|
+
|
|
4
|
+
export function uint160ToAddress(uint160: bigint): string {
|
|
5
|
+
// Convert bigint to hex string and pad to 20 bytes (40 hex chars)
|
|
6
|
+
const hexStr = uint160.toString(16).padStart(40, '0');
|
|
7
|
+
|
|
8
|
+
// Add 0x prefix and convert to checksum address
|
|
9
|
+
return getAddress('0x' + hexStr);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const isValidUtype = (utype: FheTypes): boolean => {
|
|
13
|
+
return (
|
|
14
|
+
utype === FheTypes.Bool || utype === FheTypes.Uint160 || utype == null || FheUintUTypes.includes(utype as number)
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const convertViaUtype = <U extends FheTypes>(utype: U, value: bigint): UnsealedItem<U> => {
|
|
19
|
+
if (utype === FheTypes.Bool) {
|
|
20
|
+
return !!value as UnsealedItem<U>;
|
|
21
|
+
} else if (utype === FheTypes.Uint160) {
|
|
22
|
+
return uint160ToAddress(value) as UnsealedItem<U>;
|
|
23
|
+
} else if (utype == null || FheUintUTypes.includes(utype as number)) {
|
|
24
|
+
return value as UnsealedItem<U>;
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error(`convertViaUtype :: invalid utype :: ${utype}`);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type Permission, type EthEncryptedData } from '@/permits';
|
|
2
|
+
|
|
3
|
+
import { CofhesdkError, CofhesdkErrorCode } from '../error.js';
|
|
4
|
+
|
|
5
|
+
export async function tnSealOutputV1(
|
|
6
|
+
ctHash: bigint,
|
|
7
|
+
chainId: number,
|
|
8
|
+
permission: Permission,
|
|
9
|
+
thresholdNetworkUrl: string
|
|
10
|
+
): Promise<EthEncryptedData> {
|
|
11
|
+
let sealed: EthEncryptedData | undefined;
|
|
12
|
+
let errorMessage: string | undefined;
|
|
13
|
+
let sealOutputResult: { sealed: EthEncryptedData; error_message: string } | undefined;
|
|
14
|
+
|
|
15
|
+
const body = {
|
|
16
|
+
ct_tempkey: ctHash.toString(16).padStart(64, '0'),
|
|
17
|
+
host_chain_id: chainId,
|
|
18
|
+
permit: permission,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const sealOutputRes = await fetch(`${thresholdNetworkUrl}/sealoutput`, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(body),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
sealOutputResult = (await sealOutputRes.json()) as { sealed: EthEncryptedData; error_message: string };
|
|
31
|
+
sealed = sealOutputResult.sealed;
|
|
32
|
+
errorMessage = sealOutputResult.error_message;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
throw new CofhesdkError({
|
|
35
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
36
|
+
message: `sealOutput request failed`,
|
|
37
|
+
hint: 'Ensure the threshold network URL is valid.',
|
|
38
|
+
cause: e instanceof Error ? e : undefined,
|
|
39
|
+
context: {
|
|
40
|
+
thresholdNetworkUrl,
|
|
41
|
+
body,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (sealed == null) {
|
|
47
|
+
throw new CofhesdkError({
|
|
48
|
+
code: CofhesdkErrorCode.SealOutputReturnedNull,
|
|
49
|
+
message: `sealOutput request returned no data | Caused by: ${errorMessage}`,
|
|
50
|
+
context: {
|
|
51
|
+
thresholdNetworkUrl,
|
|
52
|
+
body,
|
|
53
|
+
sealOutputResult,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return sealed;
|
|
59
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { type Permission, type EthEncryptedData } from '@/permits';
|
|
2
|
+
|
|
3
|
+
import { CofhesdkError, CofhesdkErrorCode } from '../error.js';
|
|
4
|
+
|
|
5
|
+
// Polling configuration
|
|
6
|
+
const POLL_INTERVAL_MS = 1000; // 1 second
|
|
7
|
+
const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
8
|
+
|
|
9
|
+
// V2 API response types
|
|
10
|
+
type SealOutputSubmitResponse = {
|
|
11
|
+
request_id: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type SealOutputStatusResponse = {
|
|
15
|
+
request_id: string;
|
|
16
|
+
status: 'PROCESSING' | 'COMPLETED';
|
|
17
|
+
submitted_at: string;
|
|
18
|
+
completed_at?: string;
|
|
19
|
+
is_succeed?: boolean;
|
|
20
|
+
sealed?: {
|
|
21
|
+
data: number[];
|
|
22
|
+
public_key: number[];
|
|
23
|
+
nonce: number[];
|
|
24
|
+
};
|
|
25
|
+
signature?: string;
|
|
26
|
+
encryption_type?: number;
|
|
27
|
+
error_message?: string | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Converts a number array to Uint8Array
|
|
32
|
+
*/
|
|
33
|
+
function numberArrayToUint8Array(arr: number[]): Uint8Array {
|
|
34
|
+
return new Uint8Array(arr);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Converts the sealed data from the API response to EthEncryptedData
|
|
39
|
+
*/
|
|
40
|
+
function convertSealedData(sealed: SealOutputStatusResponse['sealed']): EthEncryptedData {
|
|
41
|
+
if (!sealed) {
|
|
42
|
+
throw new CofhesdkError({
|
|
43
|
+
code: CofhesdkErrorCode.SealOutputReturnedNull,
|
|
44
|
+
message: 'Sealed data is missing from completed response',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
data: numberArrayToUint8Array(sealed.data),
|
|
50
|
+
public_key: numberArrayToUint8Array(sealed.public_key),
|
|
51
|
+
nonce: numberArrayToUint8Array(sealed.nonce),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Submits a sealoutput request to the v2 API and returns the request_id
|
|
57
|
+
*/
|
|
58
|
+
async function submitSealOutputRequest(
|
|
59
|
+
thresholdNetworkUrl: string,
|
|
60
|
+
ctHash: bigint,
|
|
61
|
+
chainId: number,
|
|
62
|
+
permission: Permission
|
|
63
|
+
): Promise<string> {
|
|
64
|
+
const body = {
|
|
65
|
+
ct_tempkey: ctHash.toString(16).padStart(64, '0'),
|
|
66
|
+
host_chain_id: chainId,
|
|
67
|
+
permit: permission,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
let response: Response;
|
|
71
|
+
try {
|
|
72
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify(body),
|
|
78
|
+
});
|
|
79
|
+
} catch (e) {
|
|
80
|
+
throw new CofhesdkError({
|
|
81
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
82
|
+
message: `sealOutput request failed`,
|
|
83
|
+
hint: 'Ensure the threshold network URL is valid and reachable.',
|
|
84
|
+
cause: e instanceof Error ? e : undefined,
|
|
85
|
+
context: {
|
|
86
|
+
thresholdNetworkUrl,
|
|
87
|
+
body,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle non-200 status codes
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
95
|
+
try {
|
|
96
|
+
const errorBody = await response.json();
|
|
97
|
+
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
98
|
+
} catch {
|
|
99
|
+
// Ignore JSON parse errors, use status text
|
|
100
|
+
errorMessage = response.statusText || errorMessage;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
throw new CofhesdkError({
|
|
104
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
105
|
+
message: `sealOutput request failed: ${errorMessage}`,
|
|
106
|
+
hint: 'Check the threshold network URL and request parameters.',
|
|
107
|
+
context: {
|
|
108
|
+
thresholdNetworkUrl,
|
|
109
|
+
status: response.status,
|
|
110
|
+
statusText: response.statusText,
|
|
111
|
+
body,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let submitResponse: SealOutputSubmitResponse;
|
|
117
|
+
try {
|
|
118
|
+
submitResponse = (await response.json()) as SealOutputSubmitResponse;
|
|
119
|
+
} catch (e) {
|
|
120
|
+
throw new CofhesdkError({
|
|
121
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
122
|
+
message: `Failed to parse sealOutput submit response`,
|
|
123
|
+
cause: e instanceof Error ? e : undefined,
|
|
124
|
+
context: {
|
|
125
|
+
thresholdNetworkUrl,
|
|
126
|
+
body,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!submitResponse.request_id) {
|
|
132
|
+
throw new CofhesdkError({
|
|
133
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
134
|
+
message: `sealOutput submit response missing request_id`,
|
|
135
|
+
context: {
|
|
136
|
+
thresholdNetworkUrl,
|
|
137
|
+
body,
|
|
138
|
+
submitResponse,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return submitResponse.request_id;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Polls for the sealoutput status until completed or timeout
|
|
148
|
+
*/
|
|
149
|
+
async function pollSealOutputStatus(thresholdNetworkUrl: string, requestId: string): Promise<EthEncryptedData> {
|
|
150
|
+
const startTime = Date.now();
|
|
151
|
+
let completed = false;
|
|
152
|
+
|
|
153
|
+
while (!completed) {
|
|
154
|
+
// Check timeout
|
|
155
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
156
|
+
throw new CofhesdkError({
|
|
157
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
158
|
+
message: `sealOutput polling timed out after ${POLL_TIMEOUT_MS}ms`,
|
|
159
|
+
hint: 'The request may still be processing. Try again later.',
|
|
160
|
+
context: {
|
|
161
|
+
thresholdNetworkUrl,
|
|
162
|
+
requestId,
|
|
163
|
+
timeoutMs: POLL_TIMEOUT_MS,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let response: Response;
|
|
169
|
+
try {
|
|
170
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/sealoutput/${requestId}`, {
|
|
171
|
+
method: 'GET',
|
|
172
|
+
headers: {
|
|
173
|
+
'Content-Type': 'application/json',
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
} catch (e) {
|
|
177
|
+
throw new CofhesdkError({
|
|
178
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
179
|
+
message: `sealOutput status poll failed`,
|
|
180
|
+
hint: 'Ensure the threshold network URL is valid and reachable.',
|
|
181
|
+
cause: e instanceof Error ? e : undefined,
|
|
182
|
+
context: {
|
|
183
|
+
thresholdNetworkUrl,
|
|
184
|
+
requestId,
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Handle 404 - request not found
|
|
190
|
+
if (response.status === 404) {
|
|
191
|
+
throw new CofhesdkError({
|
|
192
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
193
|
+
message: `sealOutput request not found: ${requestId}`,
|
|
194
|
+
hint: 'The request may have expired or been invalid.',
|
|
195
|
+
context: {
|
|
196
|
+
thresholdNetworkUrl,
|
|
197
|
+
requestId,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Handle other non-200 status codes
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
205
|
+
try {
|
|
206
|
+
const errorBody = await response.json();
|
|
207
|
+
errorMessage = errorBody.error_message || errorBody.message || errorMessage;
|
|
208
|
+
} catch {
|
|
209
|
+
errorMessage = response.statusText || errorMessage;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
throw new CofhesdkError({
|
|
213
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
214
|
+
message: `sealOutput status poll failed: ${errorMessage}`,
|
|
215
|
+
context: {
|
|
216
|
+
thresholdNetworkUrl,
|
|
217
|
+
requestId,
|
|
218
|
+
status: response.status,
|
|
219
|
+
statusText: response.statusText,
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let statusResponse: SealOutputStatusResponse;
|
|
225
|
+
try {
|
|
226
|
+
statusResponse = (await response.json()) as SealOutputStatusResponse;
|
|
227
|
+
} catch (e) {
|
|
228
|
+
throw new CofhesdkError({
|
|
229
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
230
|
+
message: `Failed to parse sealOutput status response`,
|
|
231
|
+
cause: e instanceof Error ? e : undefined,
|
|
232
|
+
context: {
|
|
233
|
+
thresholdNetworkUrl,
|
|
234
|
+
requestId,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Check if completed
|
|
240
|
+
if (statusResponse.status === 'COMPLETED') {
|
|
241
|
+
// Check if succeeded
|
|
242
|
+
if (statusResponse.is_succeed === false) {
|
|
243
|
+
const errorMessage = statusResponse.error_message || 'Unknown error';
|
|
244
|
+
throw new CofhesdkError({
|
|
245
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
246
|
+
message: `sealOutput request failed: ${errorMessage}`,
|
|
247
|
+
context: {
|
|
248
|
+
thresholdNetworkUrl,
|
|
249
|
+
requestId,
|
|
250
|
+
statusResponse,
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Check if sealed data exists
|
|
256
|
+
if (!statusResponse.sealed) {
|
|
257
|
+
throw new CofhesdkError({
|
|
258
|
+
code: CofhesdkErrorCode.SealOutputReturnedNull,
|
|
259
|
+
message: `sealOutput request completed but returned no sealed data`,
|
|
260
|
+
context: {
|
|
261
|
+
thresholdNetworkUrl,
|
|
262
|
+
requestId,
|
|
263
|
+
statusResponse,
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Convert and return the sealed data
|
|
269
|
+
return convertSealedData(statusResponse.sealed);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Still processing, wait before next poll
|
|
273
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// This should never be reached, but TypeScript requires it
|
|
277
|
+
throw new CofhesdkError({
|
|
278
|
+
code: CofhesdkErrorCode.SealOutputFailed,
|
|
279
|
+
message: 'Polling loop exited unexpectedly',
|
|
280
|
+
context: {
|
|
281
|
+
thresholdNetworkUrl,
|
|
282
|
+
requestId,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export async function tnSealOutputV2(
|
|
288
|
+
ctHash: bigint,
|
|
289
|
+
chainId: number,
|
|
290
|
+
permission: Permission,
|
|
291
|
+
thresholdNetworkUrl: string
|
|
292
|
+
): Promise<EthEncryptedData> {
|
|
293
|
+
// Step 1: Submit the request and get request_id
|
|
294
|
+
const requestId = await submitSealOutputRequest(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
295
|
+
|
|
296
|
+
// Step 2: Poll for status until completed
|
|
297
|
+
return await pollSealOutputStatus(thresholdNetworkUrl, requestId);
|
|
298
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export const MockZkVerifierAbi = [
|
|
2
|
+
{
|
|
3
|
+
type: 'function',
|
|
4
|
+
name: 'exists',
|
|
5
|
+
inputs: [],
|
|
6
|
+
outputs: [{ name: '', type: 'bool', internalType: 'bool' }],
|
|
7
|
+
stateMutability: 'pure',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
type: 'function',
|
|
11
|
+
name: 'insertCtHash',
|
|
12
|
+
inputs: [
|
|
13
|
+
{ name: 'ctHash', type: 'uint256', internalType: 'uint256' },
|
|
14
|
+
{ name: 'value', type: 'uint256', internalType: 'uint256' },
|
|
15
|
+
],
|
|
16
|
+
outputs: [],
|
|
17
|
+
stateMutability: 'nonpayable',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: 'function',
|
|
21
|
+
name: 'insertPackedCtHashes',
|
|
22
|
+
inputs: [
|
|
23
|
+
{ name: 'ctHashes', type: 'uint256[]', internalType: 'uint256[]' },
|
|
24
|
+
{ name: 'values', type: 'uint256[]', internalType: 'uint256[]' },
|
|
25
|
+
],
|
|
26
|
+
outputs: [],
|
|
27
|
+
stateMutability: 'nonpayable',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'function',
|
|
31
|
+
name: 'zkVerify',
|
|
32
|
+
inputs: [
|
|
33
|
+
{ name: 'value', type: 'uint256', internalType: 'uint256' },
|
|
34
|
+
{ name: 'utype', type: 'uint8', internalType: 'uint8' },
|
|
35
|
+
{ name: 'user', type: 'address', internalType: 'address' },
|
|
36
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
37
|
+
{ name: '', type: 'uint256', internalType: 'uint256' },
|
|
38
|
+
],
|
|
39
|
+
outputs: [
|
|
40
|
+
{
|
|
41
|
+
name: '',
|
|
42
|
+
type: 'tuple',
|
|
43
|
+
internalType: 'struct EncryptedInput',
|
|
44
|
+
components: [
|
|
45
|
+
{ name: 'ctHash', type: 'uint256', internalType: 'uint256' },
|
|
46
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
47
|
+
{ name: 'utype', type: 'uint8', internalType: 'uint8' },
|
|
48
|
+
{ name: 'signature', type: 'bytes', internalType: 'bytes' },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
stateMutability: 'nonpayable',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'function',
|
|
56
|
+
name: 'zkVerifyCalcCtHash',
|
|
57
|
+
inputs: [
|
|
58
|
+
{ name: 'value', type: 'uint256', internalType: 'uint256' },
|
|
59
|
+
{ name: 'utype', type: 'uint8', internalType: 'uint8' },
|
|
60
|
+
{ name: 'user', type: 'address', internalType: 'address' },
|
|
61
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
62
|
+
{ name: '', type: 'uint256', internalType: 'uint256' },
|
|
63
|
+
],
|
|
64
|
+
outputs: [{ name: 'ctHash', type: 'uint256', internalType: 'uint256' }],
|
|
65
|
+
stateMutability: 'view',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'function',
|
|
69
|
+
name: 'zkVerifyCalcCtHashesPacked',
|
|
70
|
+
inputs: [
|
|
71
|
+
{ name: 'values', type: 'uint256[]', internalType: 'uint256[]' },
|
|
72
|
+
{ name: 'utypes', type: 'uint8[]', internalType: 'uint8[]' },
|
|
73
|
+
{ name: 'user', type: 'address', internalType: 'address' },
|
|
74
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
75
|
+
{ name: 'chainId', type: 'uint256', internalType: 'uint256' },
|
|
76
|
+
],
|
|
77
|
+
outputs: [{ name: 'ctHashes', type: 'uint256[]', internalType: 'uint256[]' }],
|
|
78
|
+
stateMutability: 'view',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'function',
|
|
82
|
+
name: 'zkVerifyPacked',
|
|
83
|
+
inputs: [
|
|
84
|
+
{ name: 'values', type: 'uint256[]', internalType: 'uint256[]' },
|
|
85
|
+
{ name: 'utypes', type: 'uint8[]', internalType: 'uint8[]' },
|
|
86
|
+
{ name: 'user', type: 'address', internalType: 'address' },
|
|
87
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
88
|
+
{ name: 'chainId', type: 'uint256', internalType: 'uint256' },
|
|
89
|
+
],
|
|
90
|
+
outputs: [
|
|
91
|
+
{
|
|
92
|
+
name: 'inputs',
|
|
93
|
+
type: 'tuple[]',
|
|
94
|
+
internalType: 'struct EncryptedInput[]',
|
|
95
|
+
components: [
|
|
96
|
+
{ name: 'ctHash', type: 'uint256', internalType: 'uint256' },
|
|
97
|
+
{ name: 'securityZone', type: 'uint8', internalType: 'uint8' },
|
|
98
|
+
{ name: 'utype', type: 'uint8', internalType: 'uint8' },
|
|
99
|
+
{ name: 'signature', type: 'bytes', internalType: 'bytes' },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
stateMutability: 'nonpayable',
|
|
104
|
+
},
|
|
105
|
+
{ type: 'error', name: 'InvalidInputs', inputs: [] },
|
|
106
|
+
] as const;
|