@zama-fhe/relayer-sdk 0.3.0-3 → 0.3.0-5
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/bundle/relayer-sdk-js.js +4800 -4704
- package/bundle/relayer-sdk-js.umd.cjs +9 -9
- package/bundle.d.ts +9 -2
- package/lib/node.cjs +147 -79
- package/lib/node.d.ts +43 -15
- package/lib/node.js +147 -79
- package/lib/web.d.ts +44 -16
- package/lib/web.js +147 -79
- package/package.json +7 -7
package/lib/web.js
CHANGED
|
@@ -16282,6 +16282,9 @@ const bytesToBigInt = function (byteArray) {
|
|
|
16282
16282
|
.join('');
|
|
16283
16283
|
return BigInt(`0x${hex}`);
|
|
16284
16284
|
};
|
|
16285
|
+
function ensure0x(s) {
|
|
16286
|
+
return !s.startsWith('0x') ? `0x${s}` : s;
|
|
16287
|
+
}
|
|
16285
16288
|
|
|
16286
16289
|
function setAuth(init, auth) {
|
|
16287
16290
|
if (auth) {
|
|
@@ -16788,6 +16791,17 @@ const NumEncryptedBits = {
|
|
|
16788
16791
|
7: 160, // eaddress
|
|
16789
16792
|
8: 256, // euint256
|
|
16790
16793
|
};
|
|
16794
|
+
function getHandleType(handle) {
|
|
16795
|
+
if (handle.length !== 66) {
|
|
16796
|
+
throw new Error(`Handle ${handle} is not of valid length`);
|
|
16797
|
+
}
|
|
16798
|
+
const hexPair = handle.slice(-4, -2).toLowerCase();
|
|
16799
|
+
const typeDiscriminant = parseInt(hexPair, 16);
|
|
16800
|
+
if (!(typeDiscriminant in NumEncryptedBits)) {
|
|
16801
|
+
throw new Error(`Handle ${handle} is not of valid type`);
|
|
16802
|
+
}
|
|
16803
|
+
return typeDiscriminant;
|
|
16804
|
+
}
|
|
16791
16805
|
function checkEncryptedBits(handles) {
|
|
16792
16806
|
let total = 0;
|
|
16793
16807
|
for (const handle of handles) {
|
|
@@ -16816,37 +16830,30 @@ const aclABI$1 = [
|
|
|
16816
16830
|
];
|
|
16817
16831
|
const MAX_USER_DECRYPT_CONTRACT_ADDRESSES = 10;
|
|
16818
16832
|
const MAX_USER_DECRYPT_DURATION_DAYS = BigInt(365);
|
|
16819
|
-
function formatAccordingToType(
|
|
16833
|
+
function formatAccordingToType(clearValueAsBigInt, type) {
|
|
16820
16834
|
if (type === 0) {
|
|
16821
16835
|
// ebool
|
|
16822
|
-
return
|
|
16836
|
+
return clearValueAsBigInt === BigInt(1);
|
|
16823
16837
|
}
|
|
16824
16838
|
else if (type === 7) {
|
|
16825
16839
|
// eaddress
|
|
16826
|
-
return getAddress$1('0x' +
|
|
16827
|
-
}
|
|
16828
|
-
else if (type === 9) {
|
|
16829
|
-
// ebytes64
|
|
16830
|
-
return '0x' + decryptedBigInt.toString(16).padStart(128, '0');
|
|
16840
|
+
return getAddress$1('0x' + clearValueAsBigInt.toString(16).padStart(40, '0'));
|
|
16831
16841
|
}
|
|
16832
|
-
else if (type
|
|
16833
|
-
//
|
|
16834
|
-
|
|
16842
|
+
else if (type > 8 || type == 1) {
|
|
16843
|
+
// type == 1 : euint4 (not supported)
|
|
16844
|
+
throw new Error(`Unsupported handle type ${type}`);
|
|
16835
16845
|
}
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
return '0x' + decryptedBigInt.toString(16).padStart(512, '0');
|
|
16839
|
-
} // euintXXX
|
|
16840
|
-
return decryptedBigInt;
|
|
16846
|
+
// euintXXX
|
|
16847
|
+
return clearValueAsBigInt;
|
|
16841
16848
|
}
|
|
16842
|
-
function
|
|
16849
|
+
function buildUserDecryptResults(handles, listBigIntDecryptions) {
|
|
16843
16850
|
let typesList = [];
|
|
16844
16851
|
for (const handle of handles) {
|
|
16845
16852
|
const hexPair = handle.slice(-4, -2).toLowerCase();
|
|
16846
16853
|
const typeDiscriminant = parseInt(hexPair, 16);
|
|
16847
16854
|
typesList.push(typeDiscriminant);
|
|
16848
16855
|
}
|
|
16849
|
-
|
|
16856
|
+
const results = {};
|
|
16850
16857
|
handles.forEach((handle, idx) => (results[handle] = formatAccordingToType(listBigIntDecryptions[idx], typesList[idx])));
|
|
16851
16858
|
return results;
|
|
16852
16859
|
}
|
|
@@ -16952,7 +16959,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
|
|
|
16952
16959
|
};
|
|
16953
16960
|
const decryption = TKMS.process_user_decryption_resp_from_js(client, payloadForVerification, eip712Domain, json.response, pubKey, privKey, true);
|
|
16954
16961
|
const listBigIntDecryptions = decryption.map((d) => bytesToBigInt(d.bytes));
|
|
16955
|
-
const results =
|
|
16962
|
+
const results = buildUserDecryptResults(handles.map((h) => h.handle), listBigIntDecryptions);
|
|
16956
16963
|
return results;
|
|
16957
16964
|
}
|
|
16958
16965
|
catch (e) {
|
|
@@ -17007,7 +17014,7 @@ const createEncryptedInput = ({ aclContractAddress, chainId, tfheCompactPublicKe
|
|
|
17007
17014
|
checkEncryptedValue(Number(value), 1);
|
|
17008
17015
|
checkLimit(2);
|
|
17009
17016
|
builder.push_boolean(!!value);
|
|
17010
|
-
bits.push(
|
|
17017
|
+
bits.push(2); // ebool takes 2 encrypted bits
|
|
17011
17018
|
return this;
|
|
17012
17019
|
},
|
|
17013
17020
|
add8(value) {
|
|
@@ -17061,36 +17068,6 @@ const createEncryptedInput = ({ aclContractAddress, chainId, tfheCompactPublicKe
|
|
|
17061
17068
|
bits.push(256);
|
|
17062
17069
|
return this;
|
|
17063
17070
|
},
|
|
17064
|
-
addBytes64(value) {
|
|
17065
|
-
if (value.length !== 64)
|
|
17066
|
-
throw Error('Uncorrect length of input Uint8Array, should be 64 for an ebytes64');
|
|
17067
|
-
const bigIntValue = bytesToBigInt(value);
|
|
17068
|
-
checkEncryptedValue(bigIntValue, 512);
|
|
17069
|
-
checkLimit(512);
|
|
17070
|
-
builder.push_u512(bigIntValue);
|
|
17071
|
-
bits.push(512);
|
|
17072
|
-
return this;
|
|
17073
|
-
},
|
|
17074
|
-
addBytes128(value) {
|
|
17075
|
-
if (value.length !== 128)
|
|
17076
|
-
throw Error('Uncorrect length of input Uint8Array, should be 128 for an ebytes128');
|
|
17077
|
-
const bigIntValue = bytesToBigInt(value);
|
|
17078
|
-
checkEncryptedValue(bigIntValue, 1024);
|
|
17079
|
-
checkLimit(1024);
|
|
17080
|
-
builder.push_u1024(bigIntValue);
|
|
17081
|
-
bits.push(1024);
|
|
17082
|
-
return this;
|
|
17083
|
-
},
|
|
17084
|
-
addBytes256(value) {
|
|
17085
|
-
if (value.length !== 256)
|
|
17086
|
-
throw Error('Uncorrect length of input Uint8Array, should be 256 for an ebytes256');
|
|
17087
|
-
const bigIntValue = bytesToBigInt(value);
|
|
17088
|
-
checkEncryptedValue(bigIntValue, 2048);
|
|
17089
|
-
checkLimit(2048);
|
|
17090
|
-
builder.push_u2048(bigIntValue);
|
|
17091
|
-
bits.push(2048);
|
|
17092
|
-
return this;
|
|
17093
|
-
},
|
|
17094
17071
|
getBits() {
|
|
17095
17072
|
return bits;
|
|
17096
17073
|
},
|
|
@@ -17123,18 +17100,37 @@ const createEncryptedInput = ({ aclContractAddress, chainId, tfheCompactPublicKe
|
|
|
17123
17100
|
};
|
|
17124
17101
|
};
|
|
17125
17102
|
|
|
17103
|
+
/**
|
|
17104
|
+
* **FHE Type Mapping for Input Builders**
|
|
17105
|
+
* * Maps the **number of encrypted bits** used by a FHEVM primary type
|
|
17106
|
+
* to its corresponding **FheTypeId**. This constant is primarily used by
|
|
17107
|
+
* `EncryptedInput` and `RelayerEncryptedInput` builders to determine the correct
|
|
17108
|
+
* input type and calculate the total required bit-length.
|
|
17109
|
+
*
|
|
17110
|
+
* **Structure: \{ Encrypted Bit Length: FheTypeId \}**
|
|
17111
|
+
*
|
|
17112
|
+
* | Bits | FheTypeId | FHE Type Name | Note |
|
|
17113
|
+
* | :--- | :-------- | :------------ | :--- |
|
|
17114
|
+
* | 2 | 0 | `ebool` | The boolean type. |
|
|
17115
|
+
* | (N/A)| 1 | `euint4` | **Deprecated** and omitted from this map. |
|
|
17116
|
+
* | 8 | 2 | `euint8` | |
|
|
17117
|
+
* | 16 | 3 | `euint16` | |
|
|
17118
|
+
* | 32 | 4 | `euint32` | |
|
|
17119
|
+
* | 64 | 5 | `euint64` | |
|
|
17120
|
+
* | 128 | 6 | `euint128` | |
|
|
17121
|
+
* | 160 | 7 | `eaddress` | Used for encrypted Ethereum addresses. |
|
|
17122
|
+
* | 256 | 8 | `euint256` | The maximum supported integer size. |
|
|
17123
|
+
*/
|
|
17126
17124
|
const ENCRYPTION_TYPES = {
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
|
|
17135
|
-
|
|
17136
|
-
1024: 10,
|
|
17137
|
-
2048: 11,
|
|
17125
|
+
2: 0, // ebool (FheTypeId=0) is using 2 encrypted bits
|
|
17126
|
+
// euint4 (FheTypeId=1) is deprecated
|
|
17127
|
+
8: 2, // euint8 (FheTypeId=2) is using 8 encrypted bits
|
|
17128
|
+
16: 3, // euint16 (FheTypeId=3) is using 16 encrypted bits
|
|
17129
|
+
32: 4, // euint32 (FheTypeId=4) is using 32 encrypted bits
|
|
17130
|
+
64: 5, // euint64 (FheTypeId=5) is using 64 encrypted bits
|
|
17131
|
+
128: 6, // euint128 (FheTypeId=128) is using 128 encrypted bits
|
|
17132
|
+
160: 7, // eaddress (FheTypeId=7) is using 160 encrypted bits
|
|
17133
|
+
256: 8, // euint256 (FheTypeId=8) is using 256 encrypted bits
|
|
17138
17134
|
};
|
|
17139
17135
|
|
|
17140
17136
|
const MAX_UINT64 = BigInt('18446744073709551615'); // 2^64 - 1
|
|
@@ -17363,6 +17359,74 @@ function isThresholdReached(kmsSigners, recoveredAddresses, threshold) {
|
|
|
17363
17359
|
}
|
|
17364
17360
|
return recoveredAddresses.length >= threshold;
|
|
17365
17361
|
}
|
|
17362
|
+
function abiEncodeClearValues(clearValues) {
|
|
17363
|
+
const handlesBytes32Hex = Object.keys(clearValues);
|
|
17364
|
+
const abiTypes = [];
|
|
17365
|
+
const abiValues = [];
|
|
17366
|
+
for (let i = 0; i < handlesBytes32Hex.length; ++i) {
|
|
17367
|
+
const handle = handlesBytes32Hex[i];
|
|
17368
|
+
const handleType = getHandleType(handle);
|
|
17369
|
+
let clearTextValue = clearValues[handle];
|
|
17370
|
+
if (typeof clearTextValue === 'boolean') {
|
|
17371
|
+
clearTextValue = clearTextValue ? '0x01' : '0x00';
|
|
17372
|
+
}
|
|
17373
|
+
const clearTextValueBigInt = BigInt(clearTextValue);
|
|
17374
|
+
//abiTypes.push(fhevmTypeInfo.solidityTypeName);
|
|
17375
|
+
abiTypes.push('uint256');
|
|
17376
|
+
switch (handleType) {
|
|
17377
|
+
// eaddress
|
|
17378
|
+
case 7: {
|
|
17379
|
+
// string
|
|
17380
|
+
abiValues.push(`0x${clearTextValueBigInt.toString(16).padStart(40, '0')}`);
|
|
17381
|
+
break;
|
|
17382
|
+
}
|
|
17383
|
+
// ebool
|
|
17384
|
+
case 0: {
|
|
17385
|
+
// bigint (0 or 1)
|
|
17386
|
+
if (clearTextValueBigInt !== BigInt(0) &&
|
|
17387
|
+
clearTextValueBigInt !== BigInt(1)) {
|
|
17388
|
+
throw new Error(`Invalid ebool clear text value ${clearTextValueBigInt}. Expecting 0 or 1.`);
|
|
17389
|
+
}
|
|
17390
|
+
abiValues.push(clearTextValueBigInt);
|
|
17391
|
+
break;
|
|
17392
|
+
}
|
|
17393
|
+
case 2: //euint8
|
|
17394
|
+
case 3: //euint16
|
|
17395
|
+
case 4: //euint32
|
|
17396
|
+
case 5: //euint64
|
|
17397
|
+
case 6: //euint128
|
|
17398
|
+
case 7: {
|
|
17399
|
+
//euint256
|
|
17400
|
+
// bigint
|
|
17401
|
+
abiValues.push(clearTextValueBigInt);
|
|
17402
|
+
break;
|
|
17403
|
+
}
|
|
17404
|
+
default: {
|
|
17405
|
+
throw new Error(`Unsupported Fhevm primitive type id: ${handleType}`);
|
|
17406
|
+
}
|
|
17407
|
+
}
|
|
17408
|
+
}
|
|
17409
|
+
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
|
17410
|
+
// ABI encode the decryptedResult as done in the KMS, since all decrypted values
|
|
17411
|
+
// are native static types, thay have same abi-encoding as uint256:
|
|
17412
|
+
const abiEncodedClearValues = abiCoder.encode(abiTypes, abiValues);
|
|
17413
|
+
return {
|
|
17414
|
+
abiTypes,
|
|
17415
|
+
abiValues,
|
|
17416
|
+
abiEncodedClearValues,
|
|
17417
|
+
};
|
|
17418
|
+
}
|
|
17419
|
+
function buildDecryptionProof(kmsSignatures, extraData) {
|
|
17420
|
+
// Build the decryptionProof as numSigners + KMS signatures + extraData
|
|
17421
|
+
const packedNumSigners = ethers.solidityPacked(['uint8'], [kmsSignatures.length]);
|
|
17422
|
+
const packedSignatures = ethers.solidityPacked(Array(kmsSignatures.length).fill('bytes'), kmsSignatures);
|
|
17423
|
+
const decryptionProof = ethers.concat([
|
|
17424
|
+
packedNumSigners,
|
|
17425
|
+
packedSignatures,
|
|
17426
|
+
extraData,
|
|
17427
|
+
]);
|
|
17428
|
+
return decryptionProof;
|
|
17429
|
+
}
|
|
17366
17430
|
const CiphertextType = {
|
|
17367
17431
|
0: 'bool',
|
|
17368
17432
|
2: 'uint256',
|
|
@@ -17373,7 +17437,7 @@ const CiphertextType = {
|
|
|
17373
17437
|
7: 'address',
|
|
17374
17438
|
8: 'uint256',
|
|
17375
17439
|
};
|
|
17376
|
-
function
|
|
17440
|
+
function deserializeClearValues(handles, decryptedResult) {
|
|
17377
17441
|
let typesList = [];
|
|
17378
17442
|
for (const handle of handles) {
|
|
17379
17443
|
const hexPair = handle.slice(-4, -2).toLowerCase();
|
|
@@ -17392,7 +17456,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
|
|
|
17392
17456
|
const decoded = coder.decode(['uint256', ...abiTypes, 'bytes[]'], restoredEncoded);
|
|
17393
17457
|
// strip dummy first/last element
|
|
17394
17458
|
const rawValues = decoded.slice(1, 1 + typesList.length);
|
|
17395
|
-
|
|
17459
|
+
const results = {};
|
|
17396
17460
|
handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
|
|
17397
17461
|
return results;
|
|
17398
17462
|
}
|
|
@@ -17437,22 +17501,26 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
|
|
|
17437
17501
|
],
|
|
17438
17502
|
};
|
|
17439
17503
|
const result = json.response[0];
|
|
17440
|
-
const decryptedResult = result.decrypted_value
|
|
17441
|
-
|
|
17442
|
-
|
|
17443
|
-
const signatures = result.signatures;
|
|
17504
|
+
const decryptedResult = ensure0x(result.decrypted_value);
|
|
17505
|
+
const kmsSignatures = result.signatures.map(ensure0x);
|
|
17506
|
+
// TODO result.extra_data (RelayerPublicDecryptJsonResponse)
|
|
17444
17507
|
const signedExtraData = '0x';
|
|
17445
|
-
const recoveredAddresses =
|
|
17446
|
-
const
|
|
17447
|
-
const recoveredAddress = ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, sig);
|
|
17508
|
+
const recoveredAddresses = kmsSignatures.map((kmsSignature) => {
|
|
17509
|
+
const recoveredAddress = ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, kmsSignature);
|
|
17448
17510
|
return recoveredAddress;
|
|
17449
17511
|
});
|
|
17450
17512
|
const thresholdReached = isThresholdReached(kmsSigners, recoveredAddresses, thresholdSigners);
|
|
17451
17513
|
if (!thresholdReached) {
|
|
17452
17514
|
throw Error('KMS signers threshold is not reached');
|
|
17453
17515
|
}
|
|
17454
|
-
const
|
|
17455
|
-
|
|
17516
|
+
const clearValues = deserializeClearValues(handles, decryptedResult);
|
|
17517
|
+
const abiEnc = abiEncodeClearValues(clearValues);
|
|
17518
|
+
const decryptionProof = buildDecryptionProof(kmsSignatures, signedExtraData);
|
|
17519
|
+
return {
|
|
17520
|
+
clearValues,
|
|
17521
|
+
abiEncodedClearValues: abiEnc.abiEncodedClearValues,
|
|
17522
|
+
decryptionProof,
|
|
17523
|
+
};
|
|
17456
17524
|
};
|
|
17457
17525
|
|
|
17458
17526
|
/**
|
|
@@ -17562,23 +17630,23 @@ const generateKeypair = () => {
|
|
|
17562
17630
|
global.fetch = fetchRetry(global.fetch, { retries: 5, retryDelay: 500 });
|
|
17563
17631
|
const SepoliaConfig = {
|
|
17564
17632
|
// ACL_CONTRACT_ADDRESS (FHEVM Host chain)
|
|
17565
|
-
aclContractAddress: '
|
|
17633
|
+
aclContractAddress: '0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D',
|
|
17566
17634
|
// KMS_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
|
|
17567
|
-
kmsContractAddress: '
|
|
17635
|
+
kmsContractAddress: '0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A',
|
|
17568
17636
|
// INPUT_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
|
|
17569
|
-
inputVerifierContractAddress: '
|
|
17637
|
+
inputVerifierContractAddress: '0xBBC1fFCdc7C316aAAd72E807D9b0272BE8F84DA0',
|
|
17570
17638
|
// DECRYPTION_ADDRESS (Gateway chain)
|
|
17571
|
-
verifyingContractAddressDecryption: '
|
|
17639
|
+
verifyingContractAddressDecryption: '0x5D8BD78e2ea6bbE41f26dFe9fdaEAa349e077478',
|
|
17572
17640
|
// INPUT_VERIFICATION_ADDRESS (Gateway chain)
|
|
17573
|
-
verifyingContractAddressInputVerification: '
|
|
17641
|
+
verifyingContractAddressInputVerification: '0x483b9dE06E4E4C7D35CCf5837A1668487406D955',
|
|
17574
17642
|
// FHEVM Host chain id
|
|
17575
17643
|
chainId: 11155111,
|
|
17576
17644
|
// Gateway chain id
|
|
17577
|
-
gatewayChainId:
|
|
17645
|
+
gatewayChainId: 10901,
|
|
17578
17646
|
// Optional RPC provider to host chain
|
|
17579
|
-
network: 'https://
|
|
17647
|
+
network: 'https://ethereum-sepolia-rpc.publicnode.com',
|
|
17580
17648
|
// Relayer URL
|
|
17581
|
-
relayerUrl: 'https://relayer.testnet.zama.
|
|
17649
|
+
relayerUrl: 'https://relayer.testnet.zama.org',
|
|
17582
17650
|
};
|
|
17583
17651
|
const createInstance = async (config) => {
|
|
17584
17652
|
const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zama-fhe/relayer-sdk",
|
|
3
|
-
"version": "0.3.0-
|
|
3
|
+
"version": "0.3.0-5",
|
|
4
4
|
"description": "fhevm Relayer SDK",
|
|
5
5
|
"main": "lib/node.js",
|
|
6
6
|
"types": "lib/node.d.ts",
|
|
@@ -11,19 +11,19 @@
|
|
|
11
11
|
},
|
|
12
12
|
"exports": {
|
|
13
13
|
"./web": {
|
|
14
|
+
"types": "./lib/web.d.ts",
|
|
14
15
|
"import": "./lib/web.js",
|
|
15
|
-
"require": "./lib/web.js"
|
|
16
|
-
"types": "./lib/web.d.ts"
|
|
16
|
+
"require": "./lib/web.js"
|
|
17
17
|
},
|
|
18
18
|
"./bundle": {
|
|
19
|
+
"types": "./bundle.d.ts",
|
|
19
20
|
"import": "./bundle.js",
|
|
20
|
-
"require": "./bundle.js"
|
|
21
|
-
"types": "./bundle.d.ts"
|
|
21
|
+
"require": "./bundle.js"
|
|
22
22
|
},
|
|
23
23
|
"./node": {
|
|
24
|
+
"types": "./lib/node.d.ts",
|
|
24
25
|
"import": "./lib/node.js",
|
|
25
|
-
"require": "./lib/node.cjs"
|
|
26
|
-
"types": "./lib/node.d.ts"
|
|
26
|
+
"require": "./lib/node.cjs"
|
|
27
27
|
},
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|