@cofhe/sdk 0.3.1 → 0.4.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 +19 -0
- package/adapters/ethers6.test.ts +1 -1
- package/core/client.ts +6 -6
- package/core/clientTypes.ts +7 -7
- package/core/decrypt/cofheMocksDecryptForTx.ts +21 -79
- package/core/decrypt/cofheMocksDecryptForView.ts +3 -10
- package/core/decrypt/decryptForTxBuilder.ts +19 -14
- package/core/decrypt/decryptForViewBuilder.ts +9 -4
- package/core/decrypt/tnDecryptUtils.ts +65 -0
- package/core/decrypt/{tnDecrypt.ts → tnDecryptV1.ts} +10 -71
- package/core/decrypt/tnDecryptV2.ts +343 -0
- package/core/decrypt/tnSealOutputV2.ts +3 -3
- package/core/encrypt/cofheMocksZkVerifySign.ts +15 -11
- package/core/permits.ts +3 -3
- package/core/types.ts +8 -0
- package/dist/{chunk-2TPSCOW3.js → chunk-MXND5SVN.js} +275 -171
- package/dist/{clientTypes-Bhq7pCSA.d.cts → clientTypes-ACVWbrXL.d.cts} +22 -14
- package/dist/{clientTypes-6aTZPQ_4.d.ts → clientTypes-kkrRdawm.d.ts} +22 -14
- package/dist/core.cjs +274 -170
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/node.cjs +274 -170
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/web.cjs +274 -170
- package/dist/web.d.cts +1 -1
- package/dist/web.d.ts +1 -1
- package/dist/web.js +1 -1
- package/node/client.test.ts +1 -1
- package/package.json +1 -1
- package/web/client.web.test.ts +1 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { type Permission } from '@/permits';
|
|
2
|
+
|
|
3
|
+
import { CofheError, CofheErrorCode } from '../error';
|
|
4
|
+
import { normalizeTnSignature, parseDecryptedBytesToBigInt } from './tnDecryptUtils';
|
|
5
|
+
|
|
6
|
+
// Polling configuration
|
|
7
|
+
const POLL_INTERVAL_MS = 1000; // 1 second
|
|
8
|
+
const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
9
|
+
|
|
10
|
+
type DecryptSubmitResponseV2 = {
|
|
11
|
+
request_id: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type DecryptStatusResponseV2 = {
|
|
15
|
+
request_id: string;
|
|
16
|
+
status: 'PROCESSING' | 'COMPLETED';
|
|
17
|
+
submitted_at: string;
|
|
18
|
+
completed_at?: string;
|
|
19
|
+
is_succeed?: boolean;
|
|
20
|
+
decrypted?: number[];
|
|
21
|
+
signature?: string;
|
|
22
|
+
encryption_type?: number;
|
|
23
|
+
error_message?: string | null;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function assertDecryptSubmitResponseV2(value: unknown): DecryptSubmitResponseV2 {
|
|
27
|
+
if (value == null || typeof value !== 'object') {
|
|
28
|
+
throw new CofheError({
|
|
29
|
+
code: CofheErrorCode.DecryptFailed,
|
|
30
|
+
message: 'decrypt submit response must be a JSON object',
|
|
31
|
+
context: {
|
|
32
|
+
value,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const v = value as Record<string, unknown>;
|
|
38
|
+
if (typeof v.request_id !== 'string' || v.request_id.trim().length === 0) {
|
|
39
|
+
throw new CofheError({
|
|
40
|
+
code: CofheErrorCode.DecryptFailed,
|
|
41
|
+
message: 'decrypt submit response missing request_id',
|
|
42
|
+
context: {
|
|
43
|
+
value,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { request_id: v.request_id };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function assertDecryptStatusResponseV2(value: unknown): DecryptStatusResponseV2 {
|
|
52
|
+
if (value == null || typeof value !== 'object') {
|
|
53
|
+
throw new CofheError({
|
|
54
|
+
code: CofheErrorCode.DecryptFailed,
|
|
55
|
+
message: 'decrypt status response must be a JSON object',
|
|
56
|
+
context: {
|
|
57
|
+
value,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const v = value as Record<string, unknown>;
|
|
63
|
+
|
|
64
|
+
const requestId = v.request_id;
|
|
65
|
+
const status = v.status;
|
|
66
|
+
const submittedAt = v.submitted_at;
|
|
67
|
+
|
|
68
|
+
if (typeof requestId !== 'string' || requestId.trim().length === 0) {
|
|
69
|
+
throw new CofheError({
|
|
70
|
+
code: CofheErrorCode.DecryptFailed,
|
|
71
|
+
message: 'decrypt status response missing request_id',
|
|
72
|
+
context: {
|
|
73
|
+
value,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (status !== 'PROCESSING' && status !== 'COMPLETED') {
|
|
79
|
+
throw new CofheError({
|
|
80
|
+
code: CofheErrorCode.DecryptFailed,
|
|
81
|
+
message: 'decrypt status response has invalid status',
|
|
82
|
+
context: {
|
|
83
|
+
value,
|
|
84
|
+
status,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (typeof submittedAt !== 'string' || submittedAt.trim().length === 0) {
|
|
90
|
+
throw new CofheError({
|
|
91
|
+
code: CofheErrorCode.DecryptFailed,
|
|
92
|
+
message: 'decrypt status response missing submitted_at',
|
|
93
|
+
context: {
|
|
94
|
+
value,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return value as DecryptStatusResponseV2;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function submitDecryptRequestV2(
|
|
103
|
+
thresholdNetworkUrl: string,
|
|
104
|
+
ctHash: bigint | string,
|
|
105
|
+
chainId: number,
|
|
106
|
+
permission: Permission | null
|
|
107
|
+
): Promise<string> {
|
|
108
|
+
const body: {
|
|
109
|
+
ct_tempkey: string;
|
|
110
|
+
host_chain_id: number;
|
|
111
|
+
permit?: Permission;
|
|
112
|
+
} = {
|
|
113
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, '0'),
|
|
114
|
+
host_chain_id: chainId,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
if (permission) {
|
|
118
|
+
body.permit = permission;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let response: Response;
|
|
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
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
145
|
+
try {
|
|
146
|
+
const errorBody = (await response.json()) as Record<string, unknown>;
|
|
147
|
+
const maybeMessage = (errorBody.error_message || errorBody.message) as unknown;
|
|
148
|
+
if (typeof maybeMessage === 'string' && maybeMessage.length > 0) errorMessage = maybeMessage;
|
|
149
|
+
} catch {
|
|
150
|
+
errorMessage = response.statusText || errorMessage;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
throw new CofheError({
|
|
154
|
+
code: CofheErrorCode.DecryptFailed,
|
|
155
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
156
|
+
hint: 'Check the threshold network URL and request parameters.',
|
|
157
|
+
context: {
|
|
158
|
+
thresholdNetworkUrl,
|
|
159
|
+
status: response.status,
|
|
160
|
+
statusText: response.statusText,
|
|
161
|
+
body,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let rawJson: unknown;
|
|
167
|
+
try {
|
|
168
|
+
rawJson = (await response.json()) as unknown;
|
|
169
|
+
} catch (e) {
|
|
170
|
+
throw new CofheError({
|
|
171
|
+
code: CofheErrorCode.DecryptFailed,
|
|
172
|
+
message: `Failed to parse decrypt submit response`,
|
|
173
|
+
cause: e instanceof Error ? e : undefined,
|
|
174
|
+
context: {
|
|
175
|
+
thresholdNetworkUrl,
|
|
176
|
+
body,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const submitResponse = assertDecryptSubmitResponseV2(rawJson);
|
|
182
|
+
return submitResponse.request_id;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function pollDecryptStatusV2(
|
|
186
|
+
thresholdNetworkUrl: string,
|
|
187
|
+
requestId: string
|
|
188
|
+
): Promise<{ decryptedValue: bigint; signature: `0x${string}` }> {
|
|
189
|
+
const startTime = Date.now();
|
|
190
|
+
let completed = false;
|
|
191
|
+
|
|
192
|
+
while (!completed) {
|
|
193
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
194
|
+
throw new CofheError({
|
|
195
|
+
code: CofheErrorCode.DecryptFailed,
|
|
196
|
+
message: `decrypt polling timed out after ${POLL_TIMEOUT_MS}ms`,
|
|
197
|
+
hint: 'The request may still be processing. Try again later.',
|
|
198
|
+
context: {
|
|
199
|
+
thresholdNetworkUrl,
|
|
200
|
+
requestId,
|
|
201
|
+
timeoutMs: POLL_TIMEOUT_MS,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let response: Response;
|
|
207
|
+
try {
|
|
208
|
+
response = await fetch(`${thresholdNetworkUrl}/v2/decrypt/${requestId}`, {
|
|
209
|
+
method: 'GET',
|
|
210
|
+
headers: {
|
|
211
|
+
'Content-Type': 'application/json',
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
} catch (e) {
|
|
215
|
+
throw new CofheError({
|
|
216
|
+
code: CofheErrorCode.DecryptFailed,
|
|
217
|
+
message: `decrypt status poll failed`,
|
|
218
|
+
hint: 'Ensure the threshold network URL is valid and reachable.',
|
|
219
|
+
cause: e instanceof Error ? e : undefined,
|
|
220
|
+
context: {
|
|
221
|
+
thresholdNetworkUrl,
|
|
222
|
+
requestId,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (response.status === 404) {
|
|
228
|
+
throw new CofheError({
|
|
229
|
+
code: CofheErrorCode.DecryptFailed,
|
|
230
|
+
message: `decrypt request not found: ${requestId}`,
|
|
231
|
+
hint: 'The request may have expired or been invalid.',
|
|
232
|
+
context: {
|
|
233
|
+
thresholdNetworkUrl,
|
|
234
|
+
requestId,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (!response.ok) {
|
|
240
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
241
|
+
try {
|
|
242
|
+
const errorBody = (await response.json()) as Record<string, unknown>;
|
|
243
|
+
const maybeMessage = (errorBody.error_message || errorBody.message) as unknown;
|
|
244
|
+
if (typeof maybeMessage === 'string' && maybeMessage.length > 0) errorMessage = maybeMessage;
|
|
245
|
+
} catch {
|
|
246
|
+
errorMessage = response.statusText || errorMessage;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
throw new CofheError({
|
|
250
|
+
code: CofheErrorCode.DecryptFailed,
|
|
251
|
+
message: `decrypt status poll failed: ${errorMessage}`,
|
|
252
|
+
context: {
|
|
253
|
+
thresholdNetworkUrl,
|
|
254
|
+
requestId,
|
|
255
|
+
status: response.status,
|
|
256
|
+
statusText: response.statusText,
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let rawJson: unknown;
|
|
262
|
+
try {
|
|
263
|
+
rawJson = (await response.json()) as unknown;
|
|
264
|
+
} catch (e) {
|
|
265
|
+
throw new CofheError({
|
|
266
|
+
code: CofheErrorCode.DecryptFailed,
|
|
267
|
+
message: `Failed to parse decrypt status response`,
|
|
268
|
+
cause: e instanceof Error ? e : undefined,
|
|
269
|
+
context: {
|
|
270
|
+
thresholdNetworkUrl,
|
|
271
|
+
requestId,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const statusResponse = assertDecryptStatusResponseV2(rawJson);
|
|
277
|
+
|
|
278
|
+
if (statusResponse.status === 'COMPLETED') {
|
|
279
|
+
if (statusResponse.is_succeed === false) {
|
|
280
|
+
const errorMessage = statusResponse.error_message || 'Unknown error';
|
|
281
|
+
throw new CofheError({
|
|
282
|
+
code: CofheErrorCode.DecryptFailed,
|
|
283
|
+
message: `decrypt request failed: ${errorMessage}`,
|
|
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 };
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// This should never be reached, but keeps TS and linters happy.
|
|
325
|
+
throw new CofheError({
|
|
326
|
+
code: CofheErrorCode.DecryptFailed,
|
|
327
|
+
message: 'Polling loop exited unexpectedly',
|
|
328
|
+
context: {
|
|
329
|
+
thresholdNetworkUrl,
|
|
330
|
+
requestId,
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export async function tnDecryptV2(
|
|
336
|
+
ctHash: bigint | string,
|
|
337
|
+
chainId: number,
|
|
338
|
+
permission: Permission | null,
|
|
339
|
+
thresholdNetworkUrl: string
|
|
340
|
+
): Promise<{ decryptedValue: bigint; signature: `0x${string}` }> {
|
|
341
|
+
const requestId = await submitDecryptRequestV2(thresholdNetworkUrl, ctHash, chainId, permission);
|
|
342
|
+
return await pollDecryptStatusV2(thresholdNetworkUrl, requestId);
|
|
343
|
+
}
|
|
@@ -57,12 +57,12 @@ function convertSealedData(sealed: SealOutputStatusResponse['sealed']): EthEncry
|
|
|
57
57
|
*/
|
|
58
58
|
async function submitSealOutputRequest(
|
|
59
59
|
thresholdNetworkUrl: string,
|
|
60
|
-
ctHash: bigint,
|
|
60
|
+
ctHash: bigint | string,
|
|
61
61
|
chainId: number,
|
|
62
62
|
permission: Permission
|
|
63
63
|
): Promise<string> {
|
|
64
64
|
const body = {
|
|
65
|
-
ct_tempkey: ctHash.toString(16).padStart(64, '0'),
|
|
65
|
+
ct_tempkey: BigInt(ctHash).toString(16).padStart(64, '0'),
|
|
66
66
|
host_chain_id: chainId,
|
|
67
67
|
permit: permission,
|
|
68
68
|
};
|
|
@@ -285,7 +285,7 @@ async function pollSealOutputStatus(thresholdNetworkUrl: string, requestId: stri
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
export async function tnSealOutputV2(
|
|
288
|
-
ctHash: bigint,
|
|
288
|
+
ctHash: bigint | string,
|
|
289
289
|
chainId: number,
|
|
290
290
|
permission: Permission,
|
|
291
291
|
thresholdNetworkUrl: string
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { MockZkVerifierAbi } from './MockZkVerifierAbi.js';
|
|
14
14
|
import { hardhat } from 'viem/chains';
|
|
15
15
|
import { CofheError, CofheErrorCode } from '../error.js';
|
|
16
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
16
|
+
import { privateKeyToAccount, sign } from 'viem/accounts';
|
|
17
17
|
import { MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY, MOCKS_ZK_VERIFIER_ADDRESS } from '../consts.js';
|
|
18
18
|
|
|
19
19
|
type EncryptableItemWithCtHash = EncryptableItem & {
|
|
@@ -181,7 +181,11 @@ async function insertCtHashes(items: EncryptableItemWithCtHash[], walletClient:
|
|
|
181
181
|
* The mocks verify the EncryptedInputs' signature against the known proof signer account.
|
|
182
182
|
* Locally, we create the proof signatures from the known proof signer account.
|
|
183
183
|
*/
|
|
184
|
-
async function createProofSignatures(
|
|
184
|
+
async function createProofSignatures(
|
|
185
|
+
items: EncryptableItemWithCtHash[],
|
|
186
|
+
securityZone: number,
|
|
187
|
+
account: string
|
|
188
|
+
): Promise<string[]> {
|
|
185
189
|
let signatures: string[] = [];
|
|
186
190
|
|
|
187
191
|
// Create wallet client for the encrypted input signer
|
|
@@ -205,16 +209,16 @@ async function createProofSignatures(items: EncryptableItemWithCtHash[], securit
|
|
|
205
209
|
try {
|
|
206
210
|
for (const item of items) {
|
|
207
211
|
// Pack the data into bytes and hash it
|
|
208
|
-
const packedData = encodePacked(
|
|
212
|
+
const packedData = encodePacked(
|
|
213
|
+
['uint256', 'uint8', 'uint8', 'address', 'uint256'],
|
|
214
|
+
[BigInt(item.ctHash), item.utype, securityZone, account as `0x${string}`, BigInt(hardhat.id)]
|
|
215
|
+
);
|
|
209
216
|
const messageHash = keccak256(packedData);
|
|
210
217
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const signature = await encInputSignerClient.signMessage({
|
|
216
|
-
message: { raw: toBytes(ethSignedHash) },
|
|
217
|
-
account: encInputSignerClient.account!,
|
|
218
|
+
const signature = await sign({
|
|
219
|
+
hash: messageHash,
|
|
220
|
+
privateKey: MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
221
|
+
to: 'hex',
|
|
218
222
|
});
|
|
219
223
|
|
|
220
224
|
signatures.push(signature);
|
|
@@ -267,7 +271,7 @@ export async function cofheMocksZkVerifySign(
|
|
|
267
271
|
await insertCtHashes(encryptableItems, _walletClient);
|
|
268
272
|
|
|
269
273
|
// Locally create the proof signatures from the known proof signer account
|
|
270
|
-
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
274
|
+
const signatures = await createProofSignatures(encryptableItems, securityZone, account);
|
|
271
275
|
|
|
272
276
|
// Return the ctHashes and signatures in the same format as CoFHE
|
|
273
277
|
return encryptableItems.map((item, index) => ({
|
package/core/permits.ts
CHANGED
|
@@ -85,15 +85,15 @@ const deserialize = (serialized: SerializedPermit) => {
|
|
|
85
85
|
|
|
86
86
|
// GET
|
|
87
87
|
|
|
88
|
-
const getPermit =
|
|
88
|
+
const getPermit = (chainId: number, account: string, hash: string): Permit | undefined => {
|
|
89
89
|
return permitStore.getPermit(chainId, account, hash);
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
const getPermits =
|
|
92
|
+
const getPermits = (chainId: number, account: string): Record<string, Permit> => {
|
|
93
93
|
return permitStore.getPermits(chainId, account);
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
const getActivePermit =
|
|
96
|
+
const getActivePermit = (chainId: number, account: string): Permit | undefined => {
|
|
97
97
|
return permitStore.getActivePermit(chainId, account);
|
|
98
98
|
};
|
|
99
99
|
|
package/core/types.ts
CHANGED
|
@@ -389,6 +389,14 @@ export type EncryptStepCallbackFunction = (state: EncryptStep, context?: Encrypt
|
|
|
389
389
|
|
|
390
390
|
// DECRYPT
|
|
391
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Decrypted plaintext value returned by view-decryption helpers.
|
|
394
|
+
*
|
|
395
|
+
* This is a scalar JS value (not a wrapper object):
|
|
396
|
+
* - `boolean` for `FheTypes.Bool`
|
|
397
|
+
* - checksummed address `string` for `FheTypes.Uint160`
|
|
398
|
+
* - `bigint` for supported integer utypes
|
|
399
|
+
*/
|
|
392
400
|
export type UnsealedItem<U extends FheTypes> = U extends FheTypes.Bool
|
|
393
401
|
? boolean
|
|
394
402
|
: U extends FheTypes.Uint160
|