@zama-fhe/relayer-sdk 0.3.0-3 → 0.3.0-4

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.d.ts CHANGED
@@ -12,7 +12,10 @@ export {
12
12
  createInstance,
13
13
  EncryptionTypes,
14
14
  ENCRYPTION_TYPES,
15
- DecryptedResults,
15
+ UserDecryptResults,
16
+ PublicDecryptResults,
17
+ ClearValueType,
18
+ ClearValues,
16
19
  initSDK,
17
20
  SepoliaConfig,
18
21
  } from './lib/web';
package/lib/node.cjs CHANGED
@@ -56,6 +56,9 @@ const bytesToBigInt = function (byteArray) {
56
56
  .join('');
57
57
  return BigInt(`0x${hex}`);
58
58
  };
59
+ function ensure0x(s) {
60
+ return !s.startsWith('0x') ? `0x${s}` : s;
61
+ }
59
62
 
60
63
  function setAuth(init, auth) {
61
64
  if (auth) {
@@ -562,6 +565,17 @@ const NumEncryptedBits = {
562
565
  7: 160, // eaddress
563
566
  8: 256, // euint256
564
567
  };
568
+ function getHandleType(handle) {
569
+ if (handle.length !== 66) {
570
+ throw new Error(`Handle ${handle} is not of valid length`);
571
+ }
572
+ const hexPair = handle.slice(-4, -2).toLowerCase();
573
+ const typeDiscriminant = parseInt(hexPair, 16);
574
+ if (!(typeDiscriminant in NumEncryptedBits)) {
575
+ throw new Error(`Handle ${handle} is not of valid type`);
576
+ }
577
+ return typeDiscriminant;
578
+ }
565
579
  function checkEncryptedBits(handles) {
566
580
  let total = 0;
567
581
  for (const handle of handles) {
@@ -590,37 +604,30 @@ const aclABI$1 = [
590
604
  ];
591
605
  const MAX_USER_DECRYPT_CONTRACT_ADDRESSES = 10;
592
606
  const MAX_USER_DECRYPT_DURATION_DAYS = BigInt(365);
593
- function formatAccordingToType(decryptedBigInt, type) {
607
+ function formatAccordingToType(clearValueAsBigInt, type) {
594
608
  if (type === 0) {
595
609
  // ebool
596
- return decryptedBigInt === BigInt(1);
610
+ return clearValueAsBigInt === BigInt(1);
597
611
  }
598
612
  else if (type === 7) {
599
613
  // eaddress
600
- return getAddress$1('0x' + decryptedBigInt.toString(16).padStart(40, '0'));
614
+ return getAddress$1('0x' + clearValueAsBigInt.toString(16).padStart(40, '0'));
601
615
  }
602
- else if (type === 9) {
603
- // ebytes64
604
- return '0x' + decryptedBigInt.toString(16).padStart(128, '0');
616
+ else if (type > 8 || type == 1) {
617
+ // type == 1 : euint4 (not supported)
618
+ throw new Error(`Unsupported handle type ${type}`);
605
619
  }
606
- else if (type === 10) {
607
- // ebytes128
608
- return '0x' + decryptedBigInt.toString(16).padStart(256, '0');
609
- }
610
- else if (type === 11) {
611
- // ebytes256
612
- return '0x' + decryptedBigInt.toString(16).padStart(512, '0');
613
- } // euintXXX
614
- return decryptedBigInt;
620
+ // euintXXX
621
+ return clearValueAsBigInt;
615
622
  }
616
- function buildUserDecryptedResult(handles, listBigIntDecryptions) {
623
+ function buildUserDecryptResults(handles, listBigIntDecryptions) {
617
624
  let typesList = [];
618
625
  for (const handle of handles) {
619
626
  const hexPair = handle.slice(-4, -2).toLowerCase();
620
627
  const typeDiscriminant = parseInt(hexPair, 16);
621
628
  typesList.push(typeDiscriminant);
622
629
  }
623
- let results = {};
630
+ const results = {};
624
631
  handles.forEach((handle, idx) => (results[handle] = formatAccordingToType(listBigIntDecryptions[idx], typesList[idx])));
625
632
  return results;
626
633
  }
@@ -726,7 +733,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
726
733
  };
727
734
  const decryption = TKMS.process_user_decryption_resp_from_js(client, payloadForVerification, eip712Domain, json.response, pubKey, privKey, true);
728
735
  const listBigIntDecryptions = decryption.map((d) => bytesToBigInt(d.bytes));
729
- const results = buildUserDecryptedResult(handles.map((h) => h.handle), listBigIntDecryptions);
736
+ const results = buildUserDecryptResults(handles.map((h) => h.handle), listBigIntDecryptions);
730
737
  return results;
731
738
  }
732
739
  catch (e) {
@@ -1137,6 +1144,74 @@ function isThresholdReached(kmsSigners, recoveredAddresses, threshold) {
1137
1144
  }
1138
1145
  return recoveredAddresses.length >= threshold;
1139
1146
  }
1147
+ function abiEncodeClearValues(clearValues) {
1148
+ const handlesBytes32Hex = Object.keys(clearValues);
1149
+ const abiTypes = [];
1150
+ const abiValues = [];
1151
+ for (let i = 0; i < handlesBytes32Hex.length; ++i) {
1152
+ const handle = handlesBytes32Hex[i];
1153
+ const handleType = getHandleType(handle);
1154
+ let clearTextValue = clearValues[handle];
1155
+ if (typeof clearTextValue === 'boolean') {
1156
+ clearTextValue = clearTextValue ? '0x01' : '0x00';
1157
+ }
1158
+ const clearTextValueBigInt = BigInt(clearTextValue);
1159
+ //abiTypes.push(fhevmTypeInfo.solidityTypeName);
1160
+ abiTypes.push('uint256');
1161
+ switch (handleType) {
1162
+ // eaddress
1163
+ case 7: {
1164
+ // string
1165
+ abiValues.push(`0x${clearTextValueBigInt.toString(16).padStart(40, '0')}`);
1166
+ break;
1167
+ }
1168
+ // ebool
1169
+ case 0: {
1170
+ // bigint (0 or 1)
1171
+ if (clearTextValueBigInt !== BigInt(0) &&
1172
+ clearTextValueBigInt !== BigInt(1)) {
1173
+ throw new Error(`Invalid ebool clear text value ${clearTextValueBigInt}. Expecting 0 or 1.`);
1174
+ }
1175
+ abiValues.push(clearTextValueBigInt);
1176
+ break;
1177
+ }
1178
+ case 2: //euint8
1179
+ case 3: //euint16
1180
+ case 4: //euint32
1181
+ case 5: //euint64
1182
+ case 6: //euint128
1183
+ case 7: {
1184
+ //euint256
1185
+ // bigint
1186
+ abiValues.push(clearTextValueBigInt);
1187
+ break;
1188
+ }
1189
+ default: {
1190
+ throw new Error(`Unsupported Fhevm primitive type id: ${handleType}`);
1191
+ }
1192
+ }
1193
+ }
1194
+ const abiCoder = ethers.ethers.AbiCoder.defaultAbiCoder();
1195
+ // ABI encode the decryptedResult as done in the KMS, since all decrypted values
1196
+ // are native static types, thay have same abi-encoding as uint256:
1197
+ const abiEncodedClearValues = abiCoder.encode(abiTypes, abiValues);
1198
+ return {
1199
+ abiTypes,
1200
+ abiValues,
1201
+ abiEncodedClearValues,
1202
+ };
1203
+ }
1204
+ function buildDecryptionProof(kmsSignatures, extraData) {
1205
+ // Build the decryptionProof as numSigners + KMS signatures + extraData
1206
+ const packedNumSigners = ethers.ethers.solidityPacked(['uint8'], [kmsSignatures.length]);
1207
+ const packedSignatures = ethers.ethers.solidityPacked(Array(kmsSignatures.length).fill('bytes'), kmsSignatures);
1208
+ const decryptionProof = ethers.ethers.concat([
1209
+ packedNumSigners,
1210
+ packedSignatures,
1211
+ extraData,
1212
+ ]);
1213
+ return decryptionProof;
1214
+ }
1140
1215
  const CiphertextType = {
1141
1216
  0: 'bool',
1142
1217
  2: 'uint256',
@@ -1147,7 +1222,7 @@ const CiphertextType = {
1147
1222
  7: 'address',
1148
1223
  8: 'uint256',
1149
1224
  };
1150
- function deserializeDecryptedResult(handles, decryptedResult) {
1225
+ function deserializeClearValues(handles, decryptedResult) {
1151
1226
  let typesList = [];
1152
1227
  for (const handle of handles) {
1153
1228
  const hexPair = handle.slice(-4, -2).toLowerCase();
@@ -1166,7 +1241,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
1166
1241
  const decoded = coder.decode(['uint256', ...abiTypes, 'bytes[]'], restoredEncoded);
1167
1242
  // strip dummy first/last element
1168
1243
  const rawValues = decoded.slice(1, 1 + typesList.length);
1169
- let results = {};
1244
+ const results = {};
1170
1245
  handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
1171
1246
  return results;
1172
1247
  }
@@ -1211,22 +1286,25 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
1211
1286
  ],
1212
1287
  };
1213
1288
  const result = json.response[0];
1214
- const decryptedResult = result.decrypted_value.startsWith('0x')
1215
- ? result.decrypted_value
1216
- : `0x${result.decrypted_value}`;
1217
- const signatures = result.signatures;
1289
+ const decryptedResult = ensure0x(result.decrypted_value);
1290
+ const kmsSignatures = result.signatures.map(ensure0x);
1218
1291
  const signedExtraData = '0x';
1219
- const recoveredAddresses = signatures.map((signature) => {
1220
- const sig = signature.startsWith('0x') ? signature : `0x${signature}`;
1221
- const recoveredAddress = ethers.ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, sig);
1292
+ const recoveredAddresses = kmsSignatures.map((kmsSignature) => {
1293
+ const recoveredAddress = ethers.ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, kmsSignature);
1222
1294
  return recoveredAddress;
1223
1295
  });
1224
1296
  const thresholdReached = isThresholdReached(kmsSigners, recoveredAddresses, thresholdSigners);
1225
1297
  if (!thresholdReached) {
1226
1298
  throw Error('KMS signers threshold is not reached');
1227
1299
  }
1228
- const results = deserializeDecryptedResult(handles, decryptedResult);
1229
- return results;
1300
+ const clearValues = deserializeClearValues(handles, decryptedResult);
1301
+ const abiEnc = abiEncodeClearValues(clearValues);
1302
+ const decryptionProof = buildDecryptionProof(kmsSignatures, signedExtraData);
1303
+ return {
1304
+ clearValues,
1305
+ abiEncodedClearValues: abiEnc.abiEncodedClearValues,
1306
+ decryptionProof,
1307
+ };
1230
1308
  };
1231
1309
 
1232
1310
  /**
@@ -1336,23 +1414,23 @@ const generateKeypair = () => {
1336
1414
  global.fetch = fetchRetry(global.fetch, { retries: 5, retryDelay: 500 });
1337
1415
  const SepoliaConfig = {
1338
1416
  // ACL_CONTRACT_ADDRESS (FHEVM Host chain)
1339
- aclContractAddress: '0x687820221192C5B662b25367F70076A37bc79b6c',
1417
+ aclContractAddress: '0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D',
1340
1418
  // KMS_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
1341
- kmsContractAddress: '0x1364cBBf2cDF5032C47d8226a6f6FBD2AFCDacAC',
1419
+ kmsContractAddress: '0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A',
1342
1420
  // INPUT_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
1343
- inputVerifierContractAddress: '0xbc91f3daD1A5F19F8390c400196e58073B6a0BC4',
1421
+ inputVerifierContractAddress: '0xBBC1fFCdc7C316aAAd72E807D9b0272BE8F84DA0',
1344
1422
  // DECRYPTION_ADDRESS (Gateway chain)
1345
- verifyingContractAddressDecryption: '0xb6E160B1ff80D67Bfe90A85eE06Ce0A2613607D1',
1423
+ verifyingContractAddressDecryption: '0x5D8BD78e2ea6bbE41f26dFe9fdaEAa349e077478',
1346
1424
  // INPUT_VERIFICATION_ADDRESS (Gateway chain)
1347
- verifyingContractAddressInputVerification: '0x7048C39f048125eDa9d678AEbaDfB22F7900a29F',
1425
+ verifyingContractAddressInputVerification: '0x483b9dE06E4E4C7D35CCf5837A1668487406D955',
1348
1426
  // FHEVM Host chain id
1349
1427
  chainId: 11155111,
1350
1428
  // Gateway chain id
1351
- gatewayChainId: 55815,
1429
+ gatewayChainId: 10901,
1352
1430
  // Optional RPC provider to host chain
1353
1431
  network: 'https://eth-sepolia.public.blastapi.io',
1354
1432
  // Relayer URL
1355
- relayerUrl: 'https://relayer.testnet.zama.cloud',
1433
+ relayerUrl: 'https://relayer.testnet.zama.org',
1356
1434
  };
1357
1435
  const createInstance = async (config) => {
1358
1436
  const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
package/lib/node.d.ts CHANGED
@@ -53,6 +53,10 @@ declare type BearerToken = {
53
53
  token: string;
54
54
  };
55
55
 
56
+ export declare type ClearValues = Record<`0x${string}`, ClearValueType>;
57
+
58
+ export declare type ClearValueType = bigint | boolean | `0x${string}`;
59
+
56
60
  /**
57
61
  * Creates an EIP712 structure specifically for user decrypt requests
58
62
  *
@@ -78,8 +82,6 @@ export declare const createTfheKeypair: () => {
78
82
 
79
83
  export declare const createTfhePublicKey: () => string;
80
84
 
81
- export declare type DecryptedResults = Record<string, bigint | boolean | string>;
82
-
83
85
  export declare type EIP712 = {
84
86
  domain: {
85
87
  chainId: number;
@@ -122,8 +124,8 @@ export declare type FhevmInstance = {
122
124
  privateKey: string;
123
125
  };
124
126
  createEIP712: (publicKey: string, contractAddresses: string[], startTimestamp: string | number, durationDays: string | number) => EIP712;
125
- publicDecrypt: (handles: (string | Uint8Array)[]) => Promise<DecryptedResults>;
126
- userDecrypt: (handles: HandleContractPair[], privateKey: string, publicKey: string, signature: string, contractAddresses: string[], userAddress: string, startTimestamp: string | number, durationDays: string | number) => Promise<DecryptedResults>;
127
+ publicDecrypt: (handles: (string | Uint8Array)[]) => Promise<PublicDecryptResults>;
128
+ userDecrypt: (handles: HandleContractPair[], privateKey: string, publicKey: string, signature: string, contractAddresses: string[], userAddress: string, startTimestamp: string | number, durationDays: string | number) => Promise<UserDecryptResults>;
127
129
  getPublicKey: () => {
128
130
  publicKeyId: string;
129
131
  publicKey: Uint8Array;
@@ -166,6 +168,12 @@ export declare type HandleContractPair = {
166
168
  contractAddress: string;
167
169
  };
168
170
 
171
+ export declare type PublicDecryptResults = {
172
+ clearValues: ClearValues;
173
+ abiEncodedClearValues: `0x${string}`;
174
+ decryptionProof: `0x${string}`;
175
+ };
176
+
169
177
  export declare type PublicParams<T = TFHEType['CompactPkeCrs']> = {
170
178
  [key in EncryptionTypes]?: {
171
179
  publicParams: T;
@@ -204,4 +212,6 @@ export declare type TFHEType = {
204
212
  ZkComputeLoad: any;
205
213
  };
206
214
 
215
+ export declare type UserDecryptResults = ClearValues;
216
+
207
217
  export { }
package/lib/node.js CHANGED
@@ -35,6 +35,9 @@ const bytesToBigInt = function (byteArray) {
35
35
  .join('');
36
36
  return BigInt(`0x${hex}`);
37
37
  };
38
+ function ensure0x(s) {
39
+ return !s.startsWith('0x') ? `0x${s}` : s;
40
+ }
38
41
 
39
42
  function setAuth(init, auth) {
40
43
  if (auth) {
@@ -541,6 +544,17 @@ const NumEncryptedBits = {
541
544
  7: 160, // eaddress
542
545
  8: 256, // euint256
543
546
  };
547
+ function getHandleType(handle) {
548
+ if (handle.length !== 66) {
549
+ throw new Error(`Handle ${handle} is not of valid length`);
550
+ }
551
+ const hexPair = handle.slice(-4, -2).toLowerCase();
552
+ const typeDiscriminant = parseInt(hexPair, 16);
553
+ if (!(typeDiscriminant in NumEncryptedBits)) {
554
+ throw new Error(`Handle ${handle} is not of valid type`);
555
+ }
556
+ return typeDiscriminant;
557
+ }
544
558
  function checkEncryptedBits(handles) {
545
559
  let total = 0;
546
560
  for (const handle of handles) {
@@ -569,37 +583,30 @@ const aclABI$1 = [
569
583
  ];
570
584
  const MAX_USER_DECRYPT_CONTRACT_ADDRESSES = 10;
571
585
  const MAX_USER_DECRYPT_DURATION_DAYS = BigInt(365);
572
- function formatAccordingToType(decryptedBigInt, type) {
586
+ function formatAccordingToType(clearValueAsBigInt, type) {
573
587
  if (type === 0) {
574
588
  // ebool
575
- return decryptedBigInt === BigInt(1);
589
+ return clearValueAsBigInt === BigInt(1);
576
590
  }
577
591
  else if (type === 7) {
578
592
  // eaddress
579
- return getAddress$1('0x' + decryptedBigInt.toString(16).padStart(40, '0'));
593
+ return getAddress$1('0x' + clearValueAsBigInt.toString(16).padStart(40, '0'));
580
594
  }
581
- else if (type === 9) {
582
- // ebytes64
583
- return '0x' + decryptedBigInt.toString(16).padStart(128, '0');
595
+ else if (type > 8 || type == 1) {
596
+ // type == 1 : euint4 (not supported)
597
+ throw new Error(`Unsupported handle type ${type}`);
584
598
  }
585
- else if (type === 10) {
586
- // ebytes128
587
- return '0x' + decryptedBigInt.toString(16).padStart(256, '0');
588
- }
589
- else if (type === 11) {
590
- // ebytes256
591
- return '0x' + decryptedBigInt.toString(16).padStart(512, '0');
592
- } // euintXXX
593
- return decryptedBigInt;
599
+ // euintXXX
600
+ return clearValueAsBigInt;
594
601
  }
595
- function buildUserDecryptedResult(handles, listBigIntDecryptions) {
602
+ function buildUserDecryptResults(handles, listBigIntDecryptions) {
596
603
  let typesList = [];
597
604
  for (const handle of handles) {
598
605
  const hexPair = handle.slice(-4, -2).toLowerCase();
599
606
  const typeDiscriminant = parseInt(hexPair, 16);
600
607
  typesList.push(typeDiscriminant);
601
608
  }
602
- let results = {};
609
+ const results = {};
603
610
  handles.forEach((handle, idx) => (results[handle] = formatAccordingToType(listBigIntDecryptions[idx], typesList[idx])));
604
611
  return results;
605
612
  }
@@ -705,7 +712,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
705
712
  };
706
713
  const decryption = TKMS.process_user_decryption_resp_from_js(client, payloadForVerification, eip712Domain, json.response, pubKey, privKey, true);
707
714
  const listBigIntDecryptions = decryption.map((d) => bytesToBigInt(d.bytes));
708
- const results = buildUserDecryptedResult(handles.map((h) => h.handle), listBigIntDecryptions);
715
+ const results = buildUserDecryptResults(handles.map((h) => h.handle), listBigIntDecryptions);
709
716
  return results;
710
717
  }
711
718
  catch (e) {
@@ -1116,6 +1123,74 @@ function isThresholdReached(kmsSigners, recoveredAddresses, threshold) {
1116
1123
  }
1117
1124
  return recoveredAddresses.length >= threshold;
1118
1125
  }
1126
+ function abiEncodeClearValues(clearValues) {
1127
+ const handlesBytes32Hex = Object.keys(clearValues);
1128
+ const abiTypes = [];
1129
+ const abiValues = [];
1130
+ for (let i = 0; i < handlesBytes32Hex.length; ++i) {
1131
+ const handle = handlesBytes32Hex[i];
1132
+ const handleType = getHandleType(handle);
1133
+ let clearTextValue = clearValues[handle];
1134
+ if (typeof clearTextValue === 'boolean') {
1135
+ clearTextValue = clearTextValue ? '0x01' : '0x00';
1136
+ }
1137
+ const clearTextValueBigInt = BigInt(clearTextValue);
1138
+ //abiTypes.push(fhevmTypeInfo.solidityTypeName);
1139
+ abiTypes.push('uint256');
1140
+ switch (handleType) {
1141
+ // eaddress
1142
+ case 7: {
1143
+ // string
1144
+ abiValues.push(`0x${clearTextValueBigInt.toString(16).padStart(40, '0')}`);
1145
+ break;
1146
+ }
1147
+ // ebool
1148
+ case 0: {
1149
+ // bigint (0 or 1)
1150
+ if (clearTextValueBigInt !== BigInt(0) &&
1151
+ clearTextValueBigInt !== BigInt(1)) {
1152
+ throw new Error(`Invalid ebool clear text value ${clearTextValueBigInt}. Expecting 0 or 1.`);
1153
+ }
1154
+ abiValues.push(clearTextValueBigInt);
1155
+ break;
1156
+ }
1157
+ case 2: //euint8
1158
+ case 3: //euint16
1159
+ case 4: //euint32
1160
+ case 5: //euint64
1161
+ case 6: //euint128
1162
+ case 7: {
1163
+ //euint256
1164
+ // bigint
1165
+ abiValues.push(clearTextValueBigInt);
1166
+ break;
1167
+ }
1168
+ default: {
1169
+ throw new Error(`Unsupported Fhevm primitive type id: ${handleType}`);
1170
+ }
1171
+ }
1172
+ }
1173
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
1174
+ // ABI encode the decryptedResult as done in the KMS, since all decrypted values
1175
+ // are native static types, thay have same abi-encoding as uint256:
1176
+ const abiEncodedClearValues = abiCoder.encode(abiTypes, abiValues);
1177
+ return {
1178
+ abiTypes,
1179
+ abiValues,
1180
+ abiEncodedClearValues,
1181
+ };
1182
+ }
1183
+ function buildDecryptionProof(kmsSignatures, extraData) {
1184
+ // Build the decryptionProof as numSigners + KMS signatures + extraData
1185
+ const packedNumSigners = ethers.solidityPacked(['uint8'], [kmsSignatures.length]);
1186
+ const packedSignatures = ethers.solidityPacked(Array(kmsSignatures.length).fill('bytes'), kmsSignatures);
1187
+ const decryptionProof = ethers.concat([
1188
+ packedNumSigners,
1189
+ packedSignatures,
1190
+ extraData,
1191
+ ]);
1192
+ return decryptionProof;
1193
+ }
1119
1194
  const CiphertextType = {
1120
1195
  0: 'bool',
1121
1196
  2: 'uint256',
@@ -1126,7 +1201,7 @@ const CiphertextType = {
1126
1201
  7: 'address',
1127
1202
  8: 'uint256',
1128
1203
  };
1129
- function deserializeDecryptedResult(handles, decryptedResult) {
1204
+ function deserializeClearValues(handles, decryptedResult) {
1130
1205
  let typesList = [];
1131
1206
  for (const handle of handles) {
1132
1207
  const hexPair = handle.slice(-4, -2).toLowerCase();
@@ -1145,7 +1220,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
1145
1220
  const decoded = coder.decode(['uint256', ...abiTypes, 'bytes[]'], restoredEncoded);
1146
1221
  // strip dummy first/last element
1147
1222
  const rawValues = decoded.slice(1, 1 + typesList.length);
1148
- let results = {};
1223
+ const results = {};
1149
1224
  handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
1150
1225
  return results;
1151
1226
  }
@@ -1190,22 +1265,25 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
1190
1265
  ],
1191
1266
  };
1192
1267
  const result = json.response[0];
1193
- const decryptedResult = result.decrypted_value.startsWith('0x')
1194
- ? result.decrypted_value
1195
- : `0x${result.decrypted_value}`;
1196
- const signatures = result.signatures;
1268
+ const decryptedResult = ensure0x(result.decrypted_value);
1269
+ const kmsSignatures = result.signatures.map(ensure0x);
1197
1270
  const signedExtraData = '0x';
1198
- const recoveredAddresses = signatures.map((signature) => {
1199
- const sig = signature.startsWith('0x') ? signature : `0x${signature}`;
1200
- const recoveredAddress = ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, sig);
1271
+ const recoveredAddresses = kmsSignatures.map((kmsSignature) => {
1272
+ const recoveredAddress = ethers.verifyTypedData(domain, types, { ctHandles: handles, decryptedResult, extraData: signedExtraData }, kmsSignature);
1201
1273
  return recoveredAddress;
1202
1274
  });
1203
1275
  const thresholdReached = isThresholdReached(kmsSigners, recoveredAddresses, thresholdSigners);
1204
1276
  if (!thresholdReached) {
1205
1277
  throw Error('KMS signers threshold is not reached');
1206
1278
  }
1207
- const results = deserializeDecryptedResult(handles, decryptedResult);
1208
- return results;
1279
+ const clearValues = deserializeClearValues(handles, decryptedResult);
1280
+ const abiEnc = abiEncodeClearValues(clearValues);
1281
+ const decryptionProof = buildDecryptionProof(kmsSignatures, signedExtraData);
1282
+ return {
1283
+ clearValues,
1284
+ abiEncodedClearValues: abiEnc.abiEncodedClearValues,
1285
+ decryptionProof,
1286
+ };
1209
1287
  };
1210
1288
 
1211
1289
  /**
@@ -1315,23 +1393,23 @@ const generateKeypair = () => {
1315
1393
  global.fetch = fetchRetry(global.fetch, { retries: 5, retryDelay: 500 });
1316
1394
  const SepoliaConfig = {
1317
1395
  // ACL_CONTRACT_ADDRESS (FHEVM Host chain)
1318
- aclContractAddress: '0x687820221192C5B662b25367F70076A37bc79b6c',
1396
+ aclContractAddress: '0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D',
1319
1397
  // KMS_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
1320
- kmsContractAddress: '0x1364cBBf2cDF5032C47d8226a6f6FBD2AFCDacAC',
1398
+ kmsContractAddress: '0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A',
1321
1399
  // INPUT_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain)
1322
- inputVerifierContractAddress: '0xbc91f3daD1A5F19F8390c400196e58073B6a0BC4',
1400
+ inputVerifierContractAddress: '0xBBC1fFCdc7C316aAAd72E807D9b0272BE8F84DA0',
1323
1401
  // DECRYPTION_ADDRESS (Gateway chain)
1324
- verifyingContractAddressDecryption: '0xb6E160B1ff80D67Bfe90A85eE06Ce0A2613607D1',
1402
+ verifyingContractAddressDecryption: '0x5D8BD78e2ea6bbE41f26dFe9fdaEAa349e077478',
1325
1403
  // INPUT_VERIFICATION_ADDRESS (Gateway chain)
1326
- verifyingContractAddressInputVerification: '0x7048C39f048125eDa9d678AEbaDfB22F7900a29F',
1404
+ verifyingContractAddressInputVerification: '0x483b9dE06E4E4C7D35CCf5837A1668487406D955',
1327
1405
  // FHEVM Host chain id
1328
1406
  chainId: 11155111,
1329
1407
  // Gateway chain id
1330
- gatewayChainId: 55815,
1408
+ gatewayChainId: 10901,
1331
1409
  // Optional RPC provider to host chain
1332
1410
  network: 'https://eth-sepolia.public.blastapi.io',
1333
1411
  // Relayer URL
1334
- relayerUrl: 'https://relayer.testnet.zama.cloud',
1412
+ relayerUrl: 'https://relayer.testnet.zama.org',
1335
1413
  };
1336
1414
  const createInstance = async (config) => {
1337
1415
  const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
package/lib/web.d.ts CHANGED
@@ -52,6 +52,10 @@ declare type BearerToken = {
52
52
  token: string;
53
53
  };
54
54
 
55
+ export declare type ClearValues = Record<`0x${string}`, ClearValueType>;
56
+
57
+ export declare type ClearValueType = bigint | boolean | `0x${string}`;
58
+
55
59
  /**
56
60
  * Creates an EIP712 structure specifically for user decrypt requests
57
61
  *
@@ -69,8 +73,6 @@ export declare const createEIP712: (verifyingContract: string, contractsChainId:
69
73
 
70
74
  export declare const createInstance: (config: FhevmInstanceConfig) => Promise<FhevmInstance>;
71
75
 
72
- export declare type DecryptedResults = Record<string, bigint | boolean | string>;
73
-
74
76
  export declare type EIP712 = {
75
77
  domain: {
76
78
  chainId: number;
@@ -113,8 +115,8 @@ export declare type FhevmInstance = {
113
115
  privateKey: string;
114
116
  };
115
117
  createEIP712: (publicKey: string, contractAddresses: string[], startTimestamp: string | number, durationDays: string | number) => EIP712;
116
- publicDecrypt: (handles: (string | Uint8Array)[]) => Promise<DecryptedResults>;
117
- userDecrypt: (handles: HandleContractPair[], privateKey: string, publicKey: string, signature: string, contractAddresses: string[], userAddress: string, startTimestamp: string | number, durationDays: string | number) => Promise<DecryptedResults>;
118
+ publicDecrypt: (handles: (string | Uint8Array)[]) => Promise<PublicDecryptResults>;
119
+ userDecrypt: (handles: HandleContractPair[], privateKey: string, publicKey: string, signature: string, contractAddresses: string[], userAddress: string, startTimestamp: string | number, durationDays: string | number) => Promise<UserDecryptResults>;
118
120
  getPublicKey: () => {
119
121
  publicKeyId: string;
120
122
  publicKey: Uint8Array;
@@ -165,6 +167,12 @@ export declare const initSDK: ({ tfheParams, kmsParams, thread, }?: {
165
167
 
166
168
  export { KMSInput }
167
169
 
170
+ export declare type PublicDecryptResults = {
171
+ clearValues: ClearValues;
172
+ abiEncodedClearValues: `0x${string}`;
173
+ decryptionProof: `0x${string}`;
174
+ };
175
+
168
176
  export declare type PublicParams<T = TFHEType['CompactPkeCrs']> = {
169
177
  [key in EncryptionTypes]?: {
170
178
  publicParams: T;
@@ -205,4 +213,6 @@ declare type TFHEType = {
205
213
  ZkComputeLoad: any;
206
214
  };
207
215
 
216
+ export declare type UserDecryptResults = ClearValues;
217
+
208
218
  export { }