@zama-fhe/relayer-sdk 0.1.0 → 0.1.1
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/README.md +6 -1
- package/bundle/relayer-sdk-js.js +10811 -10645
- package/bundle/relayer-sdk-js.umd.cjs +14 -14
- package/lib/node.cjs +399 -214
- package/lib/node.d.ts +19 -5
- package/lib/node.js +397 -214
- package/lib/web.d.ts +20 -6
- package/lib/web.js +397 -214
- package/package.json +1 -5
package/lib/web.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JsonRpcProvider, BrowserProvider, Contract, ethers, getAddress, isAddress, AbiCoder } from 'ethers';
|
|
1
|
+
import { JsonRpcProvider, BrowserProvider, Contract, ethers, getAddress as getAddress$2, isAddress, AbiCoder } from 'ethers';
|
|
2
2
|
import createHash from 'keccak';
|
|
3
3
|
import fetchRetry from 'fetch-retry';
|
|
4
4
|
import { threads } from 'wasm-feature-detect';
|
|
@@ -26235,7 +26235,9 @@ const fromHexString = (hexString) => {
|
|
|
26235
26235
|
return new Uint8Array();
|
|
26236
26236
|
return Uint8Array.from(arr.map((byte) => parseInt(byte, 16)));
|
|
26237
26237
|
};
|
|
26238
|
-
|
|
26238
|
+
function toHexString(bytes, with0x = false) {
|
|
26239
|
+
return `${with0x ? '0x' : ''}${bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '')}`;
|
|
26240
|
+
}
|
|
26239
26241
|
const bytesToBigInt = function (byteArray) {
|
|
26240
26242
|
if (!byteArray || byteArray?.length === 0) {
|
|
26241
26243
|
return BigInt(0);
|
|
@@ -26246,95 +26248,370 @@ const bytesToBigInt = function (byteArray) {
|
|
|
26246
26248
|
return BigInt(`0x${hex}`);
|
|
26247
26249
|
};
|
|
26248
26250
|
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26252
|
-
return keyurlCache[url];
|
|
26251
|
+
function getErrorCause(e) {
|
|
26252
|
+
if (e instanceof Error && typeof e.cause === 'object' && e.cause !== null) {
|
|
26253
|
+
return e.cause;
|
|
26253
26254
|
}
|
|
26254
|
-
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26259
|
-
|
|
26260
|
-
|
|
26261
|
-
|
|
26262
|
-
|
|
26263
|
-
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
|
|
26267
|
-
|
|
26268
|
-
|
|
26269
|
-
|
|
26270
|
-
|
|
26271
|
-
|
|
26272
|
-
|
|
26273
|
-
|
|
26274
|
-
|
|
26275
|
-
|
|
26276
|
-
|
|
26277
|
-
|
|
26278
|
-
|
|
26279
|
-
|
|
26280
|
-
|
|
26281
|
-
|
|
26282
|
-
|
|
26283
|
-
|
|
26284
|
-
|
|
26285
|
-
|
|
26286
|
-
|
|
26287
|
-
else {
|
|
26288
|
-
publicKey = new Uint8Array(await publicKeyResponse.arrayBuffer());
|
|
26255
|
+
return undefined;
|
|
26256
|
+
}
|
|
26257
|
+
function getErrorCauseCode(e) {
|
|
26258
|
+
const cause = getErrorCause(e);
|
|
26259
|
+
if (!cause || !('code' in cause) || !cause.code) {
|
|
26260
|
+
return undefined;
|
|
26261
|
+
}
|
|
26262
|
+
if (typeof cause.code !== 'string') {
|
|
26263
|
+
return undefined;
|
|
26264
|
+
}
|
|
26265
|
+
return cause.code;
|
|
26266
|
+
}
|
|
26267
|
+
function getErrorCauseStatus(e) {
|
|
26268
|
+
const cause = getErrorCause(e);
|
|
26269
|
+
if (!cause || !('status' in cause) || cause.status === undefined) {
|
|
26270
|
+
return undefined;
|
|
26271
|
+
}
|
|
26272
|
+
if (typeof cause.status !== 'number') {
|
|
26273
|
+
return undefined;
|
|
26274
|
+
}
|
|
26275
|
+
return cause.status;
|
|
26276
|
+
}
|
|
26277
|
+
async function throwRelayerResponseError(operation, response) {
|
|
26278
|
+
let message;
|
|
26279
|
+
// Special case for 429
|
|
26280
|
+
if (response.status === 429) {
|
|
26281
|
+
message = `Relayer rate limit exceeded: Please wait and try again later.`;
|
|
26282
|
+
}
|
|
26283
|
+
else {
|
|
26284
|
+
switch (operation) {
|
|
26285
|
+
case 'PUBLIC_DECRYPT': {
|
|
26286
|
+
message = `Public decrypt failed: relayer respond with HTTP code ${response.status}`;
|
|
26287
|
+
break;
|
|
26289
26288
|
}
|
|
26290
|
-
|
|
26291
|
-
|
|
26292
|
-
|
|
26293
|
-
if (!publicParams2048Response.ok) {
|
|
26294
|
-
throw new Error(`HTTP error! status: ${publicParams2048Response.status} on ${publicParams2048Response.url}`);
|
|
26289
|
+
case 'USER_DECRYPT': {
|
|
26290
|
+
message = `User decrypt failed: relayer respond with HTTP code ${response.status}`;
|
|
26291
|
+
break;
|
|
26295
26292
|
}
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26299
|
-
publicParams2048 = await publicParams2048Response.bytes();
|
|
26293
|
+
case 'KEY_URL': {
|
|
26294
|
+
message = `HTTP error! status: ${response.status}`;
|
|
26295
|
+
break;
|
|
26300
26296
|
}
|
|
26301
|
-
|
|
26302
|
-
|
|
26297
|
+
default: {
|
|
26298
|
+
const responseText = await response.text();
|
|
26299
|
+
message = `Relayer didn't response correctly. Bad status ${response.statusText}. Content: ${responseText}`;
|
|
26300
|
+
break;
|
|
26303
26301
|
}
|
|
26304
|
-
|
|
26305
|
-
|
|
26306
|
-
|
|
26302
|
+
}
|
|
26303
|
+
}
|
|
26304
|
+
const cause = {
|
|
26305
|
+
code: 'RELAYER_FETCH_ERROR',
|
|
26306
|
+
operation,
|
|
26307
|
+
status: response.status,
|
|
26308
|
+
statusText: response.statusText,
|
|
26309
|
+
url: response.url,
|
|
26310
|
+
};
|
|
26311
|
+
throw new Error(message, {
|
|
26312
|
+
cause,
|
|
26313
|
+
});
|
|
26314
|
+
}
|
|
26315
|
+
function throwRelayerJSONError(operation, error) {
|
|
26316
|
+
let message;
|
|
26317
|
+
switch (operation) {
|
|
26318
|
+
case 'PUBLIC_DECRYPT': {
|
|
26319
|
+
message = "Public decrypt failed: Relayer didn't return a JSON";
|
|
26320
|
+
break;
|
|
26321
|
+
}
|
|
26322
|
+
case 'USER_DECRYPT': {
|
|
26323
|
+
message = "User decrypt failed: Relayer didn't return a JSON";
|
|
26324
|
+
break;
|
|
26325
|
+
}
|
|
26326
|
+
default: {
|
|
26327
|
+
message = "Relayer didn't return a JSON";
|
|
26328
|
+
break;
|
|
26329
|
+
}
|
|
26330
|
+
}
|
|
26331
|
+
const cause = {
|
|
26332
|
+
code: 'RELAYER_NO_JSON_ERROR',
|
|
26333
|
+
operation,
|
|
26334
|
+
error,
|
|
26335
|
+
};
|
|
26336
|
+
throw new Error(message, {
|
|
26337
|
+
cause,
|
|
26338
|
+
});
|
|
26339
|
+
}
|
|
26340
|
+
function throwRelayerUnexpectedJSONError(operation, error) {
|
|
26341
|
+
let message;
|
|
26342
|
+
switch (operation) {
|
|
26343
|
+
case 'PUBLIC_DECRYPT': {
|
|
26344
|
+
message =
|
|
26345
|
+
'Public decrypt failed: Relayer returned an unexpected JSON response';
|
|
26346
|
+
break;
|
|
26347
|
+
}
|
|
26348
|
+
case 'USER_DECRYPT': {
|
|
26349
|
+
message =
|
|
26350
|
+
'User decrypt failed: Relayer returned an unexpected JSON response';
|
|
26351
|
+
break;
|
|
26352
|
+
}
|
|
26353
|
+
default: {
|
|
26354
|
+
message = 'Relayer returned an unexpected JSON response';
|
|
26355
|
+
break;
|
|
26356
|
+
}
|
|
26357
|
+
}
|
|
26358
|
+
const cause = {
|
|
26359
|
+
code: 'RELAYER_UNEXPECTED_JSON_ERROR',
|
|
26360
|
+
operation,
|
|
26361
|
+
error,
|
|
26362
|
+
};
|
|
26363
|
+
throw new Error(message, {
|
|
26364
|
+
cause,
|
|
26365
|
+
});
|
|
26366
|
+
}
|
|
26367
|
+
function throwRelayerInternalError(operation, json) {
|
|
26368
|
+
let message;
|
|
26369
|
+
switch (operation) {
|
|
26370
|
+
case 'PUBLIC_DECRYPT': {
|
|
26371
|
+
message =
|
|
26372
|
+
"Pulbic decrypt failed: the public decryption didn't succeed for an unknown reason";
|
|
26373
|
+
break;
|
|
26374
|
+
}
|
|
26375
|
+
case 'USER_DECRYPT': {
|
|
26376
|
+
message =
|
|
26377
|
+
"User decrypt failed: the user decryption didn't succeed for an unknown reason";
|
|
26378
|
+
break;
|
|
26379
|
+
}
|
|
26380
|
+
default: {
|
|
26381
|
+
message = "Relayer didn't response correctly.";
|
|
26382
|
+
break;
|
|
26383
|
+
}
|
|
26384
|
+
}
|
|
26385
|
+
const cause = {
|
|
26386
|
+
code: 'RELAYER_INTERNAL_ERROR',
|
|
26387
|
+
operation,
|
|
26388
|
+
error: json,
|
|
26389
|
+
};
|
|
26390
|
+
throw new Error(message, {
|
|
26391
|
+
cause,
|
|
26392
|
+
});
|
|
26393
|
+
}
|
|
26394
|
+
function throwRelayerUnknownError(operation, error, message) {
|
|
26395
|
+
if (!message) {
|
|
26396
|
+
switch (operation) {
|
|
26397
|
+
case 'PUBLIC_DECRYPT': {
|
|
26398
|
+
message = "Public decrypt failed: Relayer didn't respond";
|
|
26399
|
+
break;
|
|
26307
26400
|
}
|
|
26308
|
-
|
|
26309
|
-
|
|
26310
|
-
|
|
26311
|
-
});
|
|
26401
|
+
case 'USER_DECRYPT': {
|
|
26402
|
+
message = "User decrypt failed: Relayer didn't respond";
|
|
26403
|
+
break;
|
|
26312
26404
|
}
|
|
26313
|
-
|
|
26314
|
-
|
|
26315
|
-
|
|
26405
|
+
default: {
|
|
26406
|
+
message = "Relayer didn't response correctly. Bad JSON.";
|
|
26407
|
+
break;
|
|
26316
26408
|
}
|
|
26317
|
-
|
|
26318
|
-
|
|
26319
|
-
|
|
26320
|
-
|
|
26409
|
+
}
|
|
26410
|
+
}
|
|
26411
|
+
const cause = {
|
|
26412
|
+
code: 'RELAYER_UNKNOWN_ERROR',
|
|
26413
|
+
operation,
|
|
26414
|
+
error,
|
|
26415
|
+
};
|
|
26416
|
+
throw new Error(message ?? "Relayer didn't response correctly.", {
|
|
26417
|
+
cause,
|
|
26418
|
+
});
|
|
26419
|
+
}
|
|
26420
|
+
|
|
26421
|
+
function assertIsRelayerFetchResponseJson(json) {
|
|
26422
|
+
if (!json || typeof json !== 'object') {
|
|
26423
|
+
throw new Error('Unexpected response JSON.');
|
|
26424
|
+
}
|
|
26425
|
+
if (!('response' in json &&
|
|
26426
|
+
json.response !== null &&
|
|
26427
|
+
json.response !== undefined)) {
|
|
26428
|
+
throw new Error("Unexpected response JSON format: missing 'response' property.");
|
|
26429
|
+
}
|
|
26430
|
+
}
|
|
26431
|
+
async function fetchRelayerJsonRpcPost(relayerOperation, url, payload, options) {
|
|
26432
|
+
const init = {
|
|
26433
|
+
method: 'POST',
|
|
26434
|
+
headers: {
|
|
26435
|
+
'Content-Type': 'application/json',
|
|
26436
|
+
...(options?.apiKey && { 'x-api-key': options.apiKey }),
|
|
26437
|
+
},
|
|
26438
|
+
body: JSON.stringify(payload),
|
|
26439
|
+
};
|
|
26440
|
+
let response;
|
|
26441
|
+
let json;
|
|
26442
|
+
try {
|
|
26443
|
+
response = await fetch(url, init);
|
|
26444
|
+
}
|
|
26445
|
+
catch (e) {
|
|
26446
|
+
throwRelayerUnknownError(relayerOperation, e);
|
|
26447
|
+
}
|
|
26448
|
+
if (!response.ok) {
|
|
26449
|
+
await throwRelayerResponseError(relayerOperation, response);
|
|
26450
|
+
}
|
|
26451
|
+
let parsed;
|
|
26452
|
+
try {
|
|
26453
|
+
parsed = await response.json();
|
|
26454
|
+
}
|
|
26455
|
+
catch (e) {
|
|
26456
|
+
throwRelayerJSONError(relayerOperation, e);
|
|
26457
|
+
}
|
|
26458
|
+
try {
|
|
26459
|
+
assertIsRelayerFetchResponseJson(parsed);
|
|
26460
|
+
json = parsed;
|
|
26461
|
+
}
|
|
26462
|
+
catch (e) {
|
|
26463
|
+
throwRelayerUnexpectedJSONError(relayerOperation, e);
|
|
26464
|
+
}
|
|
26465
|
+
return json;
|
|
26466
|
+
}
|
|
26467
|
+
async function fetchRelayerGet(relayerOperation, url) {
|
|
26468
|
+
let response;
|
|
26469
|
+
let json;
|
|
26470
|
+
try {
|
|
26471
|
+
response = await fetch(url);
|
|
26472
|
+
}
|
|
26473
|
+
catch (e) {
|
|
26474
|
+
throwRelayerUnknownError(relayerOperation, e);
|
|
26475
|
+
}
|
|
26476
|
+
if (!response.ok) {
|
|
26477
|
+
await throwRelayerResponseError(relayerOperation, response);
|
|
26478
|
+
}
|
|
26479
|
+
let parsed;
|
|
26480
|
+
try {
|
|
26481
|
+
parsed = await response.json();
|
|
26482
|
+
}
|
|
26483
|
+
catch (e) {
|
|
26484
|
+
throwRelayerJSONError(relayerOperation, e);
|
|
26485
|
+
}
|
|
26486
|
+
try {
|
|
26487
|
+
assertIsRelayerFetchResponseJson(parsed);
|
|
26488
|
+
json = parsed;
|
|
26489
|
+
}
|
|
26490
|
+
catch (e) {
|
|
26491
|
+
throwRelayerUnexpectedJSONError(relayerOperation, e);
|
|
26492
|
+
}
|
|
26493
|
+
return json;
|
|
26494
|
+
}
|
|
26495
|
+
|
|
26496
|
+
// export type RelayerKeysItem = {
|
|
26497
|
+
// data_id: string;
|
|
26498
|
+
// param_choice: number;
|
|
26499
|
+
// urls: string[];
|
|
26500
|
+
// signatures: string[];
|
|
26501
|
+
// };
|
|
26502
|
+
// export type RelayerKey = {
|
|
26503
|
+
// data_id: string;
|
|
26504
|
+
// param_choice: number;
|
|
26505
|
+
// signatures: string[];
|
|
26506
|
+
// urls: string[];
|
|
26507
|
+
// };
|
|
26508
|
+
// export type RelayerKeys = {
|
|
26509
|
+
// response: {
|
|
26510
|
+
// fhe_key_info: {
|
|
26511
|
+
// fhe_public_key: RelayerKey;
|
|
26512
|
+
// fhe_server_key: RelayerKey;
|
|
26513
|
+
// }[];
|
|
26514
|
+
// verf_public_key: {
|
|
26515
|
+
// key_id: string;
|
|
26516
|
+
// server_id: number;
|
|
26517
|
+
// verf_public_key_address: string;
|
|
26518
|
+
// verf_public_key_url: string;
|
|
26519
|
+
// }[];
|
|
26520
|
+
// crs: {
|
|
26521
|
+
// [key: string]: RelayerKeysItem;
|
|
26522
|
+
// };
|
|
26523
|
+
// };
|
|
26524
|
+
// status: string;
|
|
26525
|
+
// };
|
|
26526
|
+
const keyurlCache = {};
|
|
26527
|
+
const getKeysFromRelayer = async (url, publicKeyId) => {
|
|
26528
|
+
if (keyurlCache[url]) {
|
|
26529
|
+
return keyurlCache[url];
|
|
26530
|
+
}
|
|
26531
|
+
const data = await fetchRelayerGet('KEY_URL', `${url}/v1/keyurl`);
|
|
26532
|
+
try {
|
|
26533
|
+
// const response = await fetch(`${url}/v1/keyurl`);
|
|
26534
|
+
// if (!response.ok) {
|
|
26535
|
+
// await throwRelayerResponseError("KEY_URL", response);
|
|
26536
|
+
// }
|
|
26537
|
+
//const data: RelayerKeys = await response.json();
|
|
26538
|
+
//if (data) {
|
|
26539
|
+
let pubKeyUrl;
|
|
26540
|
+
// If no publicKeyId is provided, use the first one
|
|
26541
|
+
// Warning: if there are multiple keys available, the first one will most likely never be the
|
|
26542
|
+
// same between several calls (fetching the infos is non-deterministic)
|
|
26543
|
+
if (!publicKeyId) {
|
|
26544
|
+
pubKeyUrl = data.response.fhe_key_info[0].fhe_public_key.urls[0];
|
|
26545
|
+
publicKeyId = data.response.fhe_key_info[0].fhe_public_key.data_id;
|
|
26546
|
+
}
|
|
26547
|
+
else {
|
|
26548
|
+
// If a publicKeyId is provided, get the corresponding info
|
|
26549
|
+
const keyInfo = data.response.fhe_key_info.find((info) => info.fhe_public_key.data_id === publicKeyId);
|
|
26550
|
+
if (!keyInfo) {
|
|
26551
|
+
throw new Error(`Could not find FHE key info with data_id ${publicKeyId}`);
|
|
26321
26552
|
}
|
|
26322
|
-
|
|
26323
|
-
|
|
26324
|
-
|
|
26325
|
-
|
|
26326
|
-
|
|
26327
|
-
|
|
26328
|
-
|
|
26329
|
-
|
|
26330
|
-
|
|
26331
|
-
|
|
26332
|
-
|
|
26333
|
-
return result;
|
|
26553
|
+
// TODO: Get a given party's public key url instead of the first one
|
|
26554
|
+
pubKeyUrl = keyInfo.fhe_public_key.urls[0];
|
|
26555
|
+
}
|
|
26556
|
+
const publicKeyResponse = await fetch(pubKeyUrl);
|
|
26557
|
+
if (!publicKeyResponse.ok) {
|
|
26558
|
+
throw new Error(`HTTP error! status: ${publicKeyResponse.status} on ${publicKeyResponse.url}`);
|
|
26559
|
+
}
|
|
26560
|
+
let publicKey;
|
|
26561
|
+
if (typeof publicKeyResponse.bytes === 'function') {
|
|
26562
|
+
// bytes is not widely supported yet
|
|
26563
|
+
publicKey = await publicKeyResponse.bytes();
|
|
26334
26564
|
}
|
|
26335
26565
|
else {
|
|
26336
|
-
|
|
26566
|
+
publicKey = new Uint8Array(await publicKeyResponse.arrayBuffer());
|
|
26567
|
+
}
|
|
26568
|
+
const publicParamsUrl = data.response.crs['2048'].urls[0];
|
|
26569
|
+
const publicParamsId = data.response.crs['2048'].data_id;
|
|
26570
|
+
const publicParams2048Response = await fetch(publicParamsUrl);
|
|
26571
|
+
if (!publicParams2048Response.ok) {
|
|
26572
|
+
throw new Error(`HTTP error! status: ${publicParams2048Response.status} on ${publicParams2048Response.url}`);
|
|
26337
26573
|
}
|
|
26574
|
+
let publicParams2048;
|
|
26575
|
+
if (typeof publicParams2048Response.bytes === 'function') {
|
|
26576
|
+
// bytes is not widely supported yet
|
|
26577
|
+
publicParams2048 = await publicParams2048Response.bytes();
|
|
26578
|
+
}
|
|
26579
|
+
else {
|
|
26580
|
+
publicParams2048 = new Uint8Array(await publicParams2048Response.arrayBuffer());
|
|
26581
|
+
}
|
|
26582
|
+
let pub_key;
|
|
26583
|
+
try {
|
|
26584
|
+
pub_key = TFHE.TfheCompactPublicKey.safe_deserialize(publicKey, SERIALIZED_SIZE_LIMIT_PK);
|
|
26585
|
+
}
|
|
26586
|
+
catch (e) {
|
|
26587
|
+
throw new Error('Invalid public key (deserialization failed)', {
|
|
26588
|
+
cause: e,
|
|
26589
|
+
});
|
|
26590
|
+
}
|
|
26591
|
+
let crs;
|
|
26592
|
+
try {
|
|
26593
|
+
crs = TFHE.CompactPkeCrs.safe_deserialize(new Uint8Array(publicParams2048), SERIALIZED_SIZE_LIMIT_CRS);
|
|
26594
|
+
}
|
|
26595
|
+
catch (e) {
|
|
26596
|
+
throw new Error('Invalid crs (deserialization failed)', {
|
|
26597
|
+
cause: e,
|
|
26598
|
+
});
|
|
26599
|
+
}
|
|
26600
|
+
const result = {
|
|
26601
|
+
publicKey: pub_key,
|
|
26602
|
+
publicKeyId,
|
|
26603
|
+
publicParams: {
|
|
26604
|
+
2048: {
|
|
26605
|
+
publicParams: crs,
|
|
26606
|
+
publicParamsId,
|
|
26607
|
+
},
|
|
26608
|
+
},
|
|
26609
|
+
};
|
|
26610
|
+
keyurlCache[url] = result;
|
|
26611
|
+
return result;
|
|
26612
|
+
// } else {
|
|
26613
|
+
// throw new Error('No public key available');
|
|
26614
|
+
// }
|
|
26338
26615
|
}
|
|
26339
26616
|
catch (e) {
|
|
26340
26617
|
throw new Error('Impossible to fetch public key: wrong relayer url.', {
|
|
@@ -26450,9 +26727,6 @@ const NumEncryptedBits = {
|
|
|
26450
26727
|
6: 128, // euint128
|
|
26451
26728
|
7: 160, // eaddress
|
|
26452
26729
|
8: 256, // euint256
|
|
26453
|
-
9: 512, // ebytes64
|
|
26454
|
-
10: 1024, // ebytes128
|
|
26455
|
-
11: 2048, // ebytes256
|
|
26456
26730
|
};
|
|
26457
26731
|
function checkEncryptedBits(handles) {
|
|
26458
26732
|
let total = 0;
|
|
@@ -26475,6 +26749,8 @@ function checkEncryptedBits(handles) {
|
|
|
26475
26749
|
return total;
|
|
26476
26750
|
}
|
|
26477
26751
|
|
|
26752
|
+
// Add type checking
|
|
26753
|
+
const getAddress$1 = (value) => getAddress$2(value);
|
|
26478
26754
|
const aclABI$1 = [
|
|
26479
26755
|
'function persistAllowed(bytes32 handle, address account) view returns (bool)',
|
|
26480
26756
|
];
|
|
@@ -26487,7 +26763,7 @@ function formatAccordingToType(decryptedBigInt, type) {
|
|
|
26487
26763
|
}
|
|
26488
26764
|
else if (type === 7) {
|
|
26489
26765
|
// eaddress
|
|
26490
|
-
return getAddress('0x' + decryptedBigInt.toString(16).padStart(40, '0'));
|
|
26766
|
+
return getAddress$1('0x' + decryptedBigInt.toString(16).padStart(40, '0'));
|
|
26491
26767
|
}
|
|
26492
26768
|
else if (type === 9) {
|
|
26493
26769
|
// ebytes64
|
|
@@ -26530,7 +26806,16 @@ function checkDeadlineValidity(startTimestamp, durationDays) {
|
|
|
26530
26806
|
throw Error('User decrypt request has expired');
|
|
26531
26807
|
}
|
|
26532
26808
|
}
|
|
26533
|
-
const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays) => {
|
|
26809
|
+
const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays) => {
|
|
26810
|
+
let pubKey;
|
|
26811
|
+
let privKey;
|
|
26812
|
+
try {
|
|
26813
|
+
pubKey = TKMS.u8vec_to_ml_kem_pke_pk(fromHexString(publicKey));
|
|
26814
|
+
privKey = TKMS.u8vec_to_ml_kem_pke_sk(fromHexString(privateKey));
|
|
26815
|
+
}
|
|
26816
|
+
catch (e) {
|
|
26817
|
+
throw new Error('Invalid public or private key', { cause: e });
|
|
26818
|
+
}
|
|
26534
26819
|
// Casting handles if string
|
|
26535
26820
|
const signatureSanitized = signature.replace(/^(0x)/, '');
|
|
26536
26821
|
const publicKeySanitized = publicKey.replace(/^(0x)/, '');
|
|
@@ -26538,7 +26823,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
|
|
|
26538
26823
|
handle: typeof h.handle === 'string'
|
|
26539
26824
|
? toHexString(fromHexString(h.handle), true)
|
|
26540
26825
|
: toHexString(h.handle, true),
|
|
26541
|
-
contractAddress: h.contractAddress,
|
|
26826
|
+
contractAddress: getAddress$1(h.contractAddress),
|
|
26542
26827
|
}));
|
|
26543
26828
|
checkEncryptedBits(handles.map((h) => h.handle));
|
|
26544
26829
|
checkDeadlineValidity(BigInt(startTimestamp), BigInt(durationDays));
|
|
@@ -26573,51 +26858,12 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
|
|
|
26573
26858
|
durationDays: durationDays.toString(), // Convert to string
|
|
26574
26859
|
},
|
|
26575
26860
|
contractsChainId: chainId.toString(), // Convert to string
|
|
26576
|
-
contractAddresses: contractAddresses.map((c) => getAddress(c)),
|
|
26577
|
-
userAddress: getAddress(userAddress),
|
|
26861
|
+
contractAddresses: contractAddresses.map((c) => getAddress$1(c)),
|
|
26862
|
+
userAddress: getAddress$1(userAddress),
|
|
26578
26863
|
signature: signatureSanitized,
|
|
26579
26864
|
publicKey: publicKeySanitized,
|
|
26580
26865
|
};
|
|
26581
|
-
const
|
|
26582
|
-
method: 'POST',
|
|
26583
|
-
headers: {
|
|
26584
|
-
'Content-Type': 'application/json',
|
|
26585
|
-
},
|
|
26586
|
-
body: JSON.stringify(payloadForRequest),
|
|
26587
|
-
};
|
|
26588
|
-
let pubKey;
|
|
26589
|
-
let privKey;
|
|
26590
|
-
try {
|
|
26591
|
-
pubKey = TKMS.u8vec_to_ml_kem_pke_pk(fromHexString(publicKey));
|
|
26592
|
-
privKey = TKMS.u8vec_to_ml_kem_pke_sk(fromHexString(privateKey));
|
|
26593
|
-
}
|
|
26594
|
-
catch (e) {
|
|
26595
|
-
throw new Error('Invalid public or private key', { cause: e });
|
|
26596
|
-
}
|
|
26597
|
-
let response;
|
|
26598
|
-
let json;
|
|
26599
|
-
try {
|
|
26600
|
-
response = await fetch(`${relayerUrl}/v1/user-decrypt`, options);
|
|
26601
|
-
if (!response.ok) {
|
|
26602
|
-
throw new Error(`User decrypt failed: relayer respond with HTTP code ${response.status}`);
|
|
26603
|
-
}
|
|
26604
|
-
}
|
|
26605
|
-
catch (e) {
|
|
26606
|
-
throw new Error("User decrypt failed: Relayer didn't respond", {
|
|
26607
|
-
cause: e,
|
|
26608
|
-
});
|
|
26609
|
-
}
|
|
26610
|
-
try {
|
|
26611
|
-
json = await response.json();
|
|
26612
|
-
}
|
|
26613
|
-
catch (e) {
|
|
26614
|
-
throw new Error("User decrypt failed: Relayer didn't return a JSON", {
|
|
26615
|
-
cause: e,
|
|
26616
|
-
});
|
|
26617
|
-
}
|
|
26618
|
-
if (json.status === 'failure') {
|
|
26619
|
-
throw new Error("User decrypt failed: the user decryption didn't succeed for an unknown reason", { cause: json });
|
|
26620
|
-
}
|
|
26866
|
+
const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, options);
|
|
26621
26867
|
// assume the KMS Signers have the correct order
|
|
26622
26868
|
let indexedKmsSigners = kmsSigners.map((signer, index) => {
|
|
26623
26869
|
return TKMS.new_server_id_addr(index + 1, signer);
|
|
@@ -26864,6 +27110,8 @@ const computeHandles = (ciphertextWithZKProof, bitwidths, aclContractAddress, ch
|
|
|
26864
27110
|
return handles;
|
|
26865
27111
|
};
|
|
26866
27112
|
|
|
27113
|
+
// Add type checking
|
|
27114
|
+
const getAddress = (value) => getAddress$2(value);
|
|
26867
27115
|
const currentCiphertextVersion = () => {
|
|
26868
27116
|
return 0;
|
|
26869
27117
|
};
|
|
@@ -26883,6 +27131,20 @@ function isThresholdReached$1(coprocessorSigners, recoveredAddresses, threshold)
|
|
|
26883
27131
|
}
|
|
26884
27132
|
return recoveredAddresses.length >= threshold;
|
|
26885
27133
|
}
|
|
27134
|
+
function isFhevmRelayerInputProofResponse(json) {
|
|
27135
|
+
const response = json.response;
|
|
27136
|
+
if (typeof response !== 'object' || response === null) {
|
|
27137
|
+
return false;
|
|
27138
|
+
}
|
|
27139
|
+
if (!('handles' in response && Array.isArray(response.handles))) {
|
|
27140
|
+
return false;
|
|
27141
|
+
}
|
|
27142
|
+
if (!('signatures' in response && Array.isArray(response.signatures))) {
|
|
27143
|
+
return false;
|
|
27144
|
+
}
|
|
27145
|
+
return (response.signatures.every((s) => typeof s === 'string') &&
|
|
27146
|
+
response.handles.every((h) => typeof h === 'string'));
|
|
27147
|
+
}
|
|
26886
27148
|
const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners) => (contractAddress, userAddress) => {
|
|
26887
27149
|
if (!isAddress(contractAddress)) {
|
|
26888
27150
|
throw new Error('Contract address is not a valid address.');
|
|
@@ -26928,18 +27190,6 @@ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddres
|
|
|
26928
27190
|
input.add256(value);
|
|
26929
27191
|
return this;
|
|
26930
27192
|
},
|
|
26931
|
-
addBytes64(value) {
|
|
26932
|
-
input.addBytes64(value);
|
|
26933
|
-
return this;
|
|
26934
|
-
},
|
|
26935
|
-
addBytes128(value) {
|
|
26936
|
-
input.addBytes128(value);
|
|
26937
|
-
return this;
|
|
26938
|
-
},
|
|
26939
|
-
addBytes256(value) {
|
|
26940
|
-
input.addBytes256(value);
|
|
26941
|
-
return this;
|
|
26942
|
-
},
|
|
26943
27193
|
addAddress(value) {
|
|
26944
27194
|
input.addAddress(value);
|
|
26945
27195
|
return this;
|
|
@@ -26947,43 +27197,18 @@ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddres
|
|
|
26947
27197
|
getBits() {
|
|
26948
27198
|
return input.getBits();
|
|
26949
27199
|
},
|
|
26950
|
-
encrypt: async () => {
|
|
27200
|
+
encrypt: async (options) => {
|
|
26951
27201
|
const bits = input.getBits();
|
|
26952
27202
|
const ciphertext = input.encrypt();
|
|
26953
|
-
// https://github.com/zama-ai/fhevm-relayer/blob/978b08f62de060a9b50d2c6cc19fd71b5fb8d873/src/input_http_listener.rs#L13C1-L22C1
|
|
26954
27203
|
const payload = {
|
|
26955
27204
|
contractAddress: getAddress(contractAddress),
|
|
26956
27205
|
userAddress: getAddress(userAddress),
|
|
26957
27206
|
ciphertextWithInputVerification: toHexString(ciphertext),
|
|
26958
|
-
contractChainId: '0x' + chainId.toString(16),
|
|
27207
|
+
contractChainId: ('0x' + chainId.toString(16)),
|
|
26959
27208
|
};
|
|
26960
|
-
const
|
|
26961
|
-
|
|
26962
|
-
|
|
26963
|
-
'Content-Type': 'application/json',
|
|
26964
|
-
},
|
|
26965
|
-
body: JSON.stringify(payload),
|
|
26966
|
-
};
|
|
26967
|
-
const url = `${relayerUrl}/v1/input-proof`;
|
|
26968
|
-
let json;
|
|
26969
|
-
try {
|
|
26970
|
-
const response = await fetch(url, options);
|
|
26971
|
-
if (!response.ok) {
|
|
26972
|
-
throw new Error(`Relayer didn't response correctly. Bad status ${response.statusText}. Content: ${await response.text()}`);
|
|
26973
|
-
}
|
|
26974
|
-
try {
|
|
26975
|
-
json = await response.json();
|
|
26976
|
-
}
|
|
26977
|
-
catch (e) {
|
|
26978
|
-
throw new Error("Relayer didn't response correctly. Bad JSON.", {
|
|
26979
|
-
cause: e,
|
|
26980
|
-
});
|
|
26981
|
-
}
|
|
26982
|
-
}
|
|
26983
|
-
catch (e) {
|
|
26984
|
-
throw new Error("Relayer didn't response correctly.", {
|
|
26985
|
-
cause: e,
|
|
26986
|
-
});
|
|
27209
|
+
const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options);
|
|
27210
|
+
if (!isFhevmRelayerInputProofResponse(json)) {
|
|
27211
|
+
throwRelayerInternalError('INPUT_PROOF', json);
|
|
26987
27212
|
}
|
|
26988
27213
|
const handles = computeHandles(ciphertext, bits, aclContractAddress, chainId, currentCiphertextVersion());
|
|
26989
27214
|
// Note that the hex strings returned by the relayer do have have the 0x prefix
|
|
@@ -27075,9 +27300,6 @@ const CiphertextType = {
|
|
|
27075
27300
|
6: 'uint256',
|
|
27076
27301
|
7: 'address',
|
|
27077
27302
|
8: 'uint256',
|
|
27078
|
-
9: 'bytes',
|
|
27079
|
-
10: 'bytes',
|
|
27080
|
-
11: 'bytes',
|
|
27081
27303
|
};
|
|
27082
27304
|
function deserializeDecryptedResult(handles, decryptedResult) {
|
|
27083
27305
|
let typesList = [];
|
|
@@ -27102,7 +27324,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
|
|
|
27102
27324
|
handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
|
|
27103
27325
|
return results;
|
|
27104
27326
|
}
|
|
27105
|
-
const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider) => async (_handles) => {
|
|
27327
|
+
const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles) => {
|
|
27106
27328
|
const acl = new ethers.Contract(aclContractAddress, aclABI, provider);
|
|
27107
27329
|
let handles;
|
|
27108
27330
|
try {
|
|
@@ -27120,51 +27342,12 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
|
|
|
27120
27342
|
catch (e) {
|
|
27121
27343
|
throw e;
|
|
27122
27344
|
}
|
|
27123
|
-
const verifications = handles.map(async (ctHandle) => {
|
|
27124
|
-
const isAllowedForDecryption = await acl.isAllowedForDecryption(ctHandle);
|
|
27125
|
-
if (!isAllowedForDecryption) {
|
|
27126
|
-
throw new Error(`Handle ${ctHandle} is not allowed for public decryption!`);
|
|
27127
|
-
}
|
|
27128
|
-
});
|
|
27129
|
-
await Promise.all(verifications).catch((e) => {
|
|
27130
|
-
throw e;
|
|
27131
|
-
});
|
|
27132
27345
|
// check 2048 bits limit
|
|
27133
27346
|
checkEncryptedBits(handles);
|
|
27134
27347
|
const payloadForRequest = {
|
|
27135
27348
|
ciphertextHandles: handles,
|
|
27136
27349
|
};
|
|
27137
|
-
const
|
|
27138
|
-
method: 'POST',
|
|
27139
|
-
headers: {
|
|
27140
|
-
'Content-Type': 'application/json',
|
|
27141
|
-
},
|
|
27142
|
-
body: JSON.stringify(payloadForRequest),
|
|
27143
|
-
};
|
|
27144
|
-
let response;
|
|
27145
|
-
let json;
|
|
27146
|
-
try {
|
|
27147
|
-
response = await fetch(`${relayerUrl}/v1/public-decrypt`, options);
|
|
27148
|
-
if (!response.ok) {
|
|
27149
|
-
throw new Error(`Public decrypt failed: relayer respond with HTTP code ${response.status}`);
|
|
27150
|
-
}
|
|
27151
|
-
}
|
|
27152
|
-
catch (e) {
|
|
27153
|
-
throw new Error("Public decrypt failed: Relayer didn't respond", {
|
|
27154
|
-
cause: e,
|
|
27155
|
-
});
|
|
27156
|
-
}
|
|
27157
|
-
try {
|
|
27158
|
-
json = await response.json();
|
|
27159
|
-
}
|
|
27160
|
-
catch (e) {
|
|
27161
|
-
throw new Error("Public decrypt failed: Relayer didn't return a JSON", {
|
|
27162
|
-
cause: e,
|
|
27163
|
-
});
|
|
27164
|
-
}
|
|
27165
|
-
if (json.status === 'failure') {
|
|
27166
|
-
throw new Error("Public decrypt failed: the public decrypt didn't succeed for an unknown reason", { cause: json });
|
|
27167
|
-
}
|
|
27350
|
+
const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options);
|
|
27168
27351
|
// verify signatures on decryption:
|
|
27169
27352
|
const domain = {
|
|
27170
27353
|
name: 'Decryption',
|
|
@@ -27418,4 +27601,4 @@ window.TKMS = {
|
|
|
27418
27601
|
ml_kem_pke_get_pk,
|
|
27419
27602
|
};
|
|
27420
27603
|
|
|
27421
|
-
export { ENCRYPTION_TYPES, SepoliaConfig, createEIP712, createInstance, generateKeypair, initSDK };
|
|
27604
|
+
export { ENCRYPTION_TYPES, SepoliaConfig, createEIP712, createInstance, generateKeypair, getErrorCauseCode, getErrorCauseStatus, initSDK };
|