@cofhe/sdk 0.4.0 → 0.5.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 +32 -0
- package/adapters/{ethers5.test.ts → test/ethers5.test.ts} +2 -2
- package/adapters/{ethers6.test.ts → test/ethers6.test.ts} +2 -2
- package/adapters/{hardhat.hh2.test.ts → test/hardhat.hh2.test.ts} +2 -2
- package/adapters/{index.test.ts → test/index.test.ts} +1 -1
- package/adapters/{wagmi.test.ts → test/wagmi.test.ts} +1 -1
- package/chains/{chains.test.ts → test/chains.test.ts} +1 -1
- package/core/client.ts +11 -1
- package/core/clientTypes.ts +3 -1
- package/core/consts.ts +9 -0
- package/core/decrypt/cofheMocksDecryptForTx.ts +14 -3
- package/core/decrypt/decryptForTxBuilder.ts +16 -2
- package/core/decrypt/decryptForViewBuilder.ts +14 -7
- package/core/decrypt/polling.ts +14 -0
- package/core/decrypt/tnDecryptV2.ts +250 -110
- package/core/decrypt/tnSealOutputV2.ts +245 -104
- package/core/decrypt/verifyDecryptResult.ts +65 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +6 -6
- package/core/encrypt/zkPackProveVerify.ts +10 -19
- package/core/fetchKeys.ts +0 -2
- package/core/index.ts +9 -1
- package/core/keyStore.ts +5 -2
- package/core/permits.ts +5 -0
- package/core/{client.test.ts → test/client.test.ts} +7 -7
- package/core/{config.test.ts → test/config.test.ts} +1 -1
- package/core/test/decrypt.test.ts +252 -0
- package/core/test/decryptBuilders.test.ts +390 -0
- package/core/{encrypt → test}/encryptInputsBuilder.test.ts +61 -6
- package/core/{fetchKeys.test.ts → test/fetchKeys.test.ts} +3 -3
- package/core/{keyStore.test.ts → test/keyStore.test.ts} +5 -3
- package/core/{permits.test.ts → test/permits.test.ts} +42 -1
- package/core/test/pollCallbacks.test.ts +563 -0
- package/core/types.ts +13 -0
- package/dist/chains.d.cts +2 -2
- package/dist/chains.d.ts +2 -2
- package/dist/chunk-4FP4V35O.js +13 -0
- package/dist/{chunk-NWDKXBIP.js → chunk-MRCKUMOS.js} +62 -22
- package/dist/{chunk-MXND5SVN.js → chunk-S7OKGLFD.js} +485 -207
- package/dist/{clientTypes-kkrRdawm.d.ts → clientTypes-BSbwairE.d.cts} +23 -6
- package/dist/{clientTypes-ACVWbrXL.d.cts → clientTypes-DDmcgZ0a.d.ts} +23 -6
- package/dist/core.cjs +561 -244
- package/dist/core.d.cts +24 -6
- package/dist/core.d.ts +24 -6
- package/dist/core.js +3 -2
- package/dist/node.cjs +566 -246
- package/dist/node.d.cts +3 -3
- package/dist/node.d.ts +3 -3
- package/dist/node.js +14 -7
- package/dist/{permit-MZ502UBl.d.cts → permit-DnVMDT5h.d.cts} +34 -4
- package/dist/{permit-MZ502UBl.d.ts → permit-DnVMDT5h.d.ts} +34 -4
- package/dist/permits.cjs +66 -29
- package/dist/permits.d.cts +18 -13
- package/dist/permits.d.ts +18 -13
- package/dist/permits.js +2 -1
- package/dist/web.cjs +588 -251
- package/dist/web.d.cts +8 -4
- package/dist/web.d.ts +8 -4
- package/dist/web.js +34 -11
- package/dist/zkProve.worker.cjs +6 -3
- package/dist/zkProve.worker.js +5 -3
- package/node/index.ts +13 -4
- package/node/test/client.test.ts +25 -0
- package/node/test/config.test.ts +16 -0
- package/node/test/inherited.test.ts +244 -0
- package/node/test/tfheinit.test.ts +56 -0
- package/package.json +24 -22
- package/permits/permit.ts +31 -5
- package/permits/sealing.ts +1 -1
- package/permits/{localstorage.test.ts → test/localstorage.test.ts} +2 -2
- package/permits/{permit.test.ts → test/permit.test.ts} +35 -1
- package/permits/{sealing.test.ts → test/sealing.test.ts} +1 -1
- package/permits/{store.test.ts → test/store.test.ts} +2 -2
- package/permits/{validation.test.ts → test/validation.test.ts} +82 -6
- package/permits/types.ts +1 -1
- package/permits/validation.ts +42 -2
- package/web/const.ts +2 -0
- package/web/index.ts +20 -6
- package/web/storage.ts +18 -3
- package/web/{client.web.test.ts → test/client.web.test.ts} +13 -1
- package/web/test/config.web.test.ts +16 -0
- package/web/test/inherited.web.test.ts +245 -0
- package/web/test/tfheinit.web.test.ts +62 -0
- package/web/{worker.config.web.test.ts → test/worker.config.web.test.ts} +1 -1
- package/web/{worker.output.web.test.ts → test/worker.output.web.test.ts} +1 -1
- package/web/{workerManager.test.ts → test/workerManager.test.ts} +1 -1
- package/web/{workerManager.web.test.ts → test/workerManager.web.test.ts} +1 -1
- package/web/zkProve.worker.ts +4 -3
- package/node/client.test.ts +0 -147
- package/node/config.test.ts +0 -68
- package/node/encryptInputs.test.ts +0 -155
- package/web/config.web.test.ts +0 -69
- package/web/encryptInputs.web.test.ts +0 -172
- package/web/worker.builder.web.test.ts +0 -148
- /package/dist/{types-YiAC4gig.d.cts → types-C07FK-cL.d.cts} +0 -0
- /package/dist/{types-YiAC4gig.d.ts → types-C07FK-cL.d.ts} +0 -0
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
import { type Permission } from '@/permits';
|
|
2
2
|
|
|
3
3
|
import { CofheError, CofheErrorCode } from '../error';
|
|
4
|
+
import { type DecryptPollCallbackFunction } from '../types';
|
|
4
5
|
import { normalizeTnSignature, parseDecryptedBytesToBigInt } from './tnDecryptUtils';
|
|
6
|
+
import { computeMinuteRampPollIntervalMs } from './polling.js';
|
|
5
7
|
|
|
6
8
|
// Polling configuration
|
|
7
9
|
const POLL_INTERVAL_MS = 1000; // 1 second
|
|
8
|
-
const
|
|
10
|
+
const POLL_MAX_INTERVAL_MS = 10_000; // 10 seconds
|
|
11
|
+
const DECRYPT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes total across submit + poll
|
|
12
|
+
const SUBMIT_RETRY_INTERVAL_MS = 1000; // 1 second
|
|
9
13
|
|
|
10
14
|
type DecryptSubmitResponseV2 = {
|
|
11
|
-
request_id: string;
|
|
15
|
+
request_id: string | null;
|
|
16
|
+
status?: string;
|
|
17
|
+
is_succeed?: boolean;
|
|
18
|
+
decrypted?: number[];
|
|
19
|
+
signature?: string;
|
|
20
|
+
encryption_type?: number;
|
|
21
|
+
error_message?: string | null;
|
|
22
|
+
message?: string;
|
|
12
23
|
};
|
|
13
24
|
|
|
25
|
+
type DecryptSubmitResultV2 =
|
|
26
|
+
| { kind: 'request_id'; requestId: string }
|
|
27
|
+
| { kind: 'completed'; decryptedValue: bigint; signature: `0x${string}` };
|
|
28
|
+
|
|
14
29
|
type DecryptStatusResponseV2 = {
|
|
15
30
|
request_id: string;
|
|
16
31
|
status: 'PROCESSING' | 'COMPLETED';
|
|
@@ -35,17 +50,75 @@ function assertDecryptSubmitResponseV2(value: unknown): DecryptSubmitResponseV2
|
|
|
35
50
|
}
|
|
36
51
|
|
|
37
52
|
const v = value as Record<string, unknown>;
|
|
38
|
-
if (
|
|
53
|
+
if (v.request_id !== null && typeof v.request_id !== 'string') {
|
|
39
54
|
throw new CofheError({
|
|
40
55
|
code: CofheErrorCode.DecryptFailed,
|
|
41
|
-
message: 'decrypt submit response
|
|
56
|
+
message: 'decrypt submit response has invalid request_id',
|
|
42
57
|
context: {
|
|
43
58
|
value,
|
|
44
59
|
},
|
|
45
60
|
});
|
|
46
61
|
}
|
|
47
62
|
|
|
48
|
-
return {
|
|
63
|
+
return {
|
|
64
|
+
request_id: v.request_id ?? null,
|
|
65
|
+
status: typeof v.status === 'string' ? v.status : undefined,
|
|
66
|
+
is_succeed: typeof v.is_succeed === 'boolean' ? v.is_succeed : undefined,
|
|
67
|
+
decrypted: Array.isArray(v.decrypted) ? (v.decrypted as number[]) : undefined,
|
|
68
|
+
signature: typeof v.signature === 'string' ? v.signature : undefined,
|
|
69
|
+
encryption_type: typeof v.encryption_type === 'number' ? v.encryption_type : undefined,
|
|
70
|
+
error_message: typeof v.error_message === 'string' || v.error_message === null ? v.error_message : undefined,
|
|
71
|
+
message: typeof v.message === 'string' ? v.message : undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function parseCompletedDecryptResponseV2(params: {
|
|
76
|
+
value: Pick<DecryptStatusResponseV2, 'decrypted' | 'signature' | 'error_message' | 'is_succeed'>;
|
|
77
|
+
thresholdNetworkUrl: string;
|
|
78
|
+
requestId?: string | null;
|
|
79
|
+
}): { decryptedValue: bigint; signature: `0x${string}` } {
|
|
80
|
+
const { value, thresholdNetworkUrl, requestId } = params;
|
|
81
|
+
|
|
82
|
+
if (value.is_succeed === false) {
|
|
83
|
+
const errorMessage = value.error_message || 'Unknown error';
|
|
84
|
+
throw new CofheError({
|
|
85
|
+
code: CofheErrorCode.DecryptFailed,
|
|
86
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
87
|
+
context: {
|
|
88
|
+
thresholdNetworkUrl,
|
|
89
|
+
requestId,
|
|
90
|
+
response: value,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (value.error_message) {
|
|
96
|
+
throw new CofheError({
|
|
97
|
+
code: CofheErrorCode.DecryptFailed,
|
|
98
|
+
message: `decrypt request failed: ${value.error_message}`,
|
|
99
|
+
context: {
|
|
100
|
+
thresholdNetworkUrl,
|
|
101
|
+
requestId,
|
|
102
|
+
response: value,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!Array.isArray(value.decrypted)) {
|
|
108
|
+
throw new CofheError({
|
|
109
|
+
code: CofheErrorCode.DecryptReturnedNull,
|
|
110
|
+
message: 'decrypt completed but response missing <decrypted> byte array',
|
|
111
|
+
context: {
|
|
112
|
+
thresholdNetworkUrl,
|
|
113
|
+
requestId,
|
|
114
|
+
response: value,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const decryptedValue = parseDecryptedBytesToBigInt(value.decrypted);
|
|
120
|
+
const signature = normalizeTnSignature(value.signature);
|
|
121
|
+
return { decryptedValue, signature };
|
|
49
122
|
}
|
|
50
123
|
|
|
51
124
|
function assertDecryptStatusResponseV2(value: unknown): DecryptStatusResponseV2 {
|
|
@@ -103,8 +176,10 @@ async function submitDecryptRequestV2(
|
|
|
103
176
|
thresholdNetworkUrl: string,
|
|
104
177
|
ctHash: bigint | string,
|
|
105
178
|
chainId: number,
|
|
106
|
-
permission: Permission | null
|
|
107
|
-
|
|
179
|
+
permission: Permission | null,
|
|
180
|
+
overallStartTime: number,
|
|
181
|
+
onPoll?: DecryptPollCallbackFunction
|
|
182
|
+
): Promise<DecryptSubmitResultV2> {
|
|
108
183
|
const body: {
|
|
109
184
|
ct_tempkey: string;
|
|
110
185
|
host_chain_id: number;
|
|
@@ -118,87 +193,171 @@ async function submitDecryptRequestV2(
|
|
|
118
193
|
body.permit = permission;
|
|
119
194
|
}
|
|
120
195
|
|
|
121
|
-
let
|
|
122
|
-
try {
|
|
123
|
-
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
|
|
124
|
-
method: 'POST',
|
|
125
|
-
headers: {
|
|
126
|
-
'Content-Type': 'application/json',
|
|
127
|
-
},
|
|
128
|
-
body: JSON.stringify(body),
|
|
129
|
-
});
|
|
130
|
-
} catch (e) {
|
|
131
|
-
throw new CofheError({
|
|
132
|
-
code: CofheErrorCode.DecryptFailed,
|
|
133
|
-
message: `decrypt request failed`,
|
|
134
|
-
hint: 'Ensure the threshold network URL is valid and reachable.',
|
|
135
|
-
cause: e instanceof Error ? e : undefined,
|
|
136
|
-
context: {
|
|
137
|
-
thresholdNetworkUrl,
|
|
138
|
-
body,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
}
|
|
196
|
+
let attemptIndex = 0;
|
|
142
197
|
|
|
143
|
-
|
|
144
|
-
let
|
|
198
|
+
for (;;) {
|
|
199
|
+
let response: Response;
|
|
145
200
|
try {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
201
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt`, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
headers: {
|
|
204
|
+
'Content-Type': 'application/json',
|
|
205
|
+
},
|
|
206
|
+
body: JSON.stringify(body),
|
|
207
|
+
});
|
|
208
|
+
} catch (e) {
|
|
209
|
+
throw new CofheError({
|
|
210
|
+
code: CofheErrorCode.DecryptFailed,
|
|
211
|
+
message: `decrypt request failed`,
|
|
212
|
+
hint: 'Ensure the threshold network URL is valid and reachable.',
|
|
213
|
+
cause: e instanceof Error ? e : undefined,
|
|
214
|
+
context: {
|
|
215
|
+
thresholdNetworkUrl,
|
|
216
|
+
body,
|
|
217
|
+
attemptIndex,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
151
220
|
}
|
|
152
221
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
222
|
+
if (!response.ok) {
|
|
223
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
224
|
+
try {
|
|
225
|
+
const errorBody = (await response.json()) as Record<string, unknown>;
|
|
226
|
+
const maybeMessage = (errorBody.error_message || errorBody.message) as unknown;
|
|
227
|
+
if (typeof maybeMessage === 'string' && maybeMessage.length > 0) errorMessage = maybeMessage;
|
|
228
|
+
} catch {
|
|
229
|
+
errorMessage = response.statusText || errorMessage;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
throw new CofheError({
|
|
233
|
+
code: CofheErrorCode.DecryptFailed,
|
|
234
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
235
|
+
hint: 'Check the threshold network URL and request parameters.',
|
|
236
|
+
context: {
|
|
237
|
+
thresholdNetworkUrl,
|
|
238
|
+
status: response.status,
|
|
239
|
+
statusText: response.statusText,
|
|
240
|
+
body,
|
|
241
|
+
attemptIndex,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
let submitResponse: DecryptSubmitResponseV2 | undefined;
|
|
247
|
+
if (response.status !== 204) {
|
|
248
|
+
let rawJson: unknown;
|
|
249
|
+
try {
|
|
250
|
+
rawJson = (await response.json()) as unknown;
|
|
251
|
+
} catch (e) {
|
|
252
|
+
throw new CofheError({
|
|
253
|
+
code: CofheErrorCode.DecryptFailed,
|
|
254
|
+
message: `Failed to parse decrypt submit response`,
|
|
255
|
+
cause: e instanceof Error ? e : undefined,
|
|
256
|
+
context: {
|
|
257
|
+
thresholdNetworkUrl,
|
|
258
|
+
body,
|
|
259
|
+
attemptIndex,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
submitResponse = assertDecryptSubmitResponseV2(rawJson);
|
|
265
|
+
|
|
266
|
+
if (Array.isArray(submitResponse.decrypted) && typeof submitResponse.signature === 'string') {
|
|
267
|
+
return {
|
|
268
|
+
kind: 'completed',
|
|
269
|
+
...parseCompletedDecryptResponseV2({
|
|
270
|
+
value: submitResponse,
|
|
271
|
+
thresholdNetworkUrl,
|
|
272
|
+
requestId: submitResponse.request_id,
|
|
273
|
+
}),
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (submitResponse.request_id) {
|
|
278
|
+
return { kind: 'request_id', requestId: submitResponse.request_id };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// 204 means backend is aware of ct hash but didn't calculate it yet
|
|
283
|
+
if (response.status === 204) {
|
|
284
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
285
|
+
if (elapsedMs > DECRYPT_TIMEOUT_MS) {
|
|
286
|
+
throw new CofheError({
|
|
287
|
+
code: CofheErrorCode.DecryptFailed,
|
|
288
|
+
message: `decrypt submit retried without receiving request_id for ${DECRYPT_TIMEOUT_MS}ms`,
|
|
289
|
+
hint: 'The ciphertext may still be propagating. Try again later.',
|
|
290
|
+
context: {
|
|
291
|
+
thresholdNetworkUrl,
|
|
292
|
+
body,
|
|
293
|
+
attemptIndex,
|
|
294
|
+
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
295
|
+
submitResponse,
|
|
296
|
+
status: response.status,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
onPoll?.({
|
|
302
|
+
operation: 'decrypt',
|
|
303
|
+
requestId: '',
|
|
304
|
+
attemptIndex,
|
|
305
|
+
elapsedMs,
|
|
306
|
+
intervalMs: SUBMIT_RETRY_INTERVAL_MS,
|
|
307
|
+
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
await new Promise((resolve) => setTimeout(resolve, SUBMIT_RETRY_INTERVAL_MS));
|
|
311
|
+
attemptIndex += 1;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
165
314
|
|
|
166
|
-
let rawJson: unknown;
|
|
167
|
-
try {
|
|
168
|
-
rawJson = (await response.json()) as unknown;
|
|
169
|
-
} catch (e) {
|
|
170
315
|
throw new CofheError({
|
|
171
316
|
code: CofheErrorCode.DecryptFailed,
|
|
172
|
-
message: `
|
|
173
|
-
cause: e instanceof Error ? e : undefined,
|
|
317
|
+
message: `decrypt submit response missing request_id`,
|
|
174
318
|
context: {
|
|
175
319
|
thresholdNetworkUrl,
|
|
176
320
|
body,
|
|
321
|
+
submitResponse,
|
|
322
|
+
attemptIndex,
|
|
177
323
|
},
|
|
178
324
|
});
|
|
179
325
|
}
|
|
180
|
-
|
|
181
|
-
const submitResponse = assertDecryptSubmitResponseV2(rawJson);
|
|
182
|
-
return submitResponse.request_id;
|
|
183
326
|
}
|
|
184
327
|
|
|
185
328
|
async function pollDecryptStatusV2(
|
|
186
329
|
thresholdNetworkUrl: string,
|
|
187
|
-
requestId: string
|
|
330
|
+
requestId: string,
|
|
331
|
+
overallStartTime: number,
|
|
332
|
+
onPoll?: DecryptPollCallbackFunction
|
|
188
333
|
): Promise<{ decryptedValue: bigint; signature: `0x${string}` }> {
|
|
189
|
-
|
|
334
|
+
let attemptIndex = 0;
|
|
190
335
|
let completed = false;
|
|
191
336
|
|
|
192
337
|
while (!completed) {
|
|
193
|
-
|
|
338
|
+
const elapsedMs = Date.now() - overallStartTime;
|
|
339
|
+
const intervalMs = computeMinuteRampPollIntervalMs(elapsedMs, {
|
|
340
|
+
minIntervalMs: POLL_INTERVAL_MS,
|
|
341
|
+
maxIntervalMs: POLL_MAX_INTERVAL_MS,
|
|
342
|
+
});
|
|
343
|
+
onPoll?.({
|
|
344
|
+
operation: 'decrypt',
|
|
345
|
+
requestId,
|
|
346
|
+
attemptIndex,
|
|
347
|
+
elapsedMs,
|
|
348
|
+
intervalMs,
|
|
349
|
+
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
if (elapsedMs > DECRYPT_TIMEOUT_MS) {
|
|
194
353
|
throw new CofheError({
|
|
195
354
|
code: CofheErrorCode.DecryptFailed,
|
|
196
|
-
message: `decrypt polling timed out after ${
|
|
355
|
+
message: `decrypt polling timed out after ${DECRYPT_TIMEOUT_MS}ms`,
|
|
197
356
|
hint: 'The request may still be processing. Try again later.',
|
|
198
357
|
context: {
|
|
199
358
|
thresholdNetworkUrl,
|
|
200
359
|
requestId,
|
|
201
|
-
timeoutMs:
|
|
360
|
+
timeoutMs: DECRYPT_TIMEOUT_MS,
|
|
202
361
|
},
|
|
203
362
|
});
|
|
204
363
|
}
|
|
@@ -276,49 +435,15 @@ async function pollDecryptStatusV2(
|
|
|
276
435
|
const statusResponse = assertDecryptStatusResponseV2(rawJson);
|
|
277
436
|
|
|
278
437
|
if (statusResponse.status === 'COMPLETED') {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
context: {
|
|
285
|
-
thresholdNetworkUrl,
|
|
286
|
-
requestId,
|
|
287
|
-
statusResponse,
|
|
288
|
-
},
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (statusResponse.error_message) {
|
|
293
|
-
throw new CofheError({
|
|
294
|
-
code: CofheErrorCode.DecryptFailed,
|
|
295
|
-
message: `decrypt request failed: ${statusResponse.error_message}`,
|
|
296
|
-
context: {
|
|
297
|
-
thresholdNetworkUrl,
|
|
298
|
-
requestId,
|
|
299
|
-
statusResponse,
|
|
300
|
-
},
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (!Array.isArray(statusResponse.decrypted)) {
|
|
305
|
-
throw new CofheError({
|
|
306
|
-
code: CofheErrorCode.DecryptReturnedNull,
|
|
307
|
-
message: 'decrypt completed but response missing <decrypted> byte array',
|
|
308
|
-
context: {
|
|
309
|
-
thresholdNetworkUrl,
|
|
310
|
-
requestId,
|
|
311
|
-
statusResponse,
|
|
312
|
-
},
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const decryptedValue = parseDecryptedBytesToBigInt(statusResponse.decrypted);
|
|
317
|
-
const signature = normalizeTnSignature(statusResponse.signature);
|
|
318
|
-
return { decryptedValue, signature };
|
|
438
|
+
return parseCompletedDecryptResponseV2({
|
|
439
|
+
value: statusResponse,
|
|
440
|
+
thresholdNetworkUrl,
|
|
441
|
+
requestId,
|
|
442
|
+
});
|
|
319
443
|
}
|
|
320
444
|
|
|
321
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
445
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
446
|
+
attemptIndex += 1;
|
|
322
447
|
}
|
|
323
448
|
|
|
324
449
|
// This should never be reached, but keeps TS and linters happy.
|
|
@@ -332,12 +457,27 @@ async function pollDecryptStatusV2(
|
|
|
332
457
|
});
|
|
333
458
|
}
|
|
334
459
|
|
|
335
|
-
export async function tnDecryptV2(
|
|
336
|
-
ctHash: bigint | string
|
|
337
|
-
chainId: number
|
|
338
|
-
permission: Permission | null
|
|
339
|
-
thresholdNetworkUrl: string
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
460
|
+
export async function tnDecryptV2(params: {
|
|
461
|
+
ctHash: bigint | string;
|
|
462
|
+
chainId: number;
|
|
463
|
+
permission: Permission | null;
|
|
464
|
+
thresholdNetworkUrl: string;
|
|
465
|
+
onPoll?: DecryptPollCallbackFunction;
|
|
466
|
+
}): Promise<{ decryptedValue: bigint; signature: `0x${string}` }> {
|
|
467
|
+
const { thresholdNetworkUrl, ctHash, chainId, permission, onPoll } = params;
|
|
468
|
+
const overallStartTime = Date.now();
|
|
469
|
+
const submitResult = await submitDecryptRequestV2(
|
|
470
|
+
thresholdNetworkUrl,
|
|
471
|
+
ctHash,
|
|
472
|
+
chainId,
|
|
473
|
+
permission,
|
|
474
|
+
overallStartTime,
|
|
475
|
+
onPoll
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
if (submitResult.kind === 'completed') {
|
|
479
|
+
return submitResult;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return await pollDecryptStatusV2(thresholdNetworkUrl, submitResult.requestId, overallStartTime, onPoll);
|
|
343
483
|
}
|