@zama-fhe/relayer-sdk 0.2.0-6 → 0.3.0-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.
Binary file
package/lib/node.cjs CHANGED
@@ -57,6 +57,32 @@ const bytesToBigInt = function (byteArray) {
57
57
  return BigInt(`0x${hex}`);
58
58
  };
59
59
 
60
+ function setAuth(init, auth) {
61
+ if (auth) {
62
+ switch (auth.__type) {
63
+ case 'BearerToken':
64
+ init.headers['Authorization'] =
65
+ `Bearer ${auth.token}`;
66
+ break;
67
+ case 'ApiKeyHeader':
68
+ init.headers[auth.header || 'x-api-key'] =
69
+ auth.value;
70
+ break;
71
+ case 'ApiKeyCookie':
72
+ if (typeof window !== 'undefined') {
73
+ document.cookie = `${auth.cookie || 'x-api-key'}=${auth.value}; path=/; SameSite=Lax; Secure; HttpOnly;`;
74
+ init.credentials = 'include';
75
+ }
76
+ else {
77
+ let cookie = `${auth.cookie || 'x-api-key'}=${auth.value};`;
78
+ init.headers['Cookie'] = cookie;
79
+ }
80
+ break;
81
+ }
82
+ }
83
+ return init;
84
+ }
85
+
60
86
  function getErrorCause(e) {
61
87
  if (e instanceof Error && typeof e.cause === 'object' && e.cause !== null) {
62
88
  return e.cause;
@@ -238,14 +264,13 @@ function assertIsRelayerFetchResponseJson(json) {
238
264
  }
239
265
  }
240
266
  async function fetchRelayerJsonRpcPost(relayerOperation, url, payload, options) {
241
- const init = {
267
+ const init = setAuth({
242
268
  method: 'POST',
243
269
  headers: {
244
270
  'Content-Type': 'application/json',
245
- ...(options?.apiKey && { 'x-api-key': options.apiKey }),
246
271
  },
247
272
  body: JSON.stringify(payload),
248
- };
273
+ }, options?.auth);
249
274
  let response;
250
275
  let json;
251
276
  try {
@@ -615,7 +640,7 @@ function checkDeadlineValidity(startTimestamp, durationDays) {
615
640
  throw Error('User decrypt request has expired');
616
641
  }
617
642
  }
618
- const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays) => {
643
+ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays, options) => {
619
644
  const extraData = '0x00';
620
645
  let pubKey;
621
646
  let privKey;
@@ -674,7 +699,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
674
699
  publicKey: publicKeySanitized,
675
700
  extraData,
676
701
  };
677
- const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, options);
702
+ const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, instanceOptions ?? options);
678
703
  // assume the KMS Signers have the correct order
679
704
  let indexedKmsSigners = kmsSigners.map((signer, index) => {
680
705
  return TKMS.new_server_id_addr(index + 1, signer);
@@ -956,7 +981,7 @@ function isFhevmRelayerInputProofResponse(json) {
956
981
  return (response.signatures.every((s) => typeof s === 'string') &&
957
982
  response.handles.every((h) => typeof h === 'string'));
958
983
  }
959
- const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners) => (contractAddress, userAddress) => {
984
+ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners, instanceOptions) => (contractAddress, userAddress) => {
960
985
  if (!ethers.isAddress(contractAddress)) {
961
986
  throw new Error('Contract address is not a valid address.');
962
987
  }
@@ -1019,7 +1044,7 @@ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddres
1019
1044
  contractChainId: ('0x' + chainId.toString(16)),
1020
1045
  extraData,
1021
1046
  };
1022
- const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options);
1047
+ const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options ?? instanceOptions);
1023
1048
  if (!isFhevmRelayerInputProofResponse(json)) {
1024
1049
  throwRelayerInternalError('INPUT_PROOF', json);
1025
1050
  }
@@ -1141,7 +1166,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
1141
1166
  handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
1142
1167
  return results;
1143
1168
  }
1144
- const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles) => {
1169
+ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, options) => {
1145
1170
  const extraData = '0x00';
1146
1171
  const acl = new ethers.ethers.Contract(aclContractAddress, aclABI, provider);
1147
1172
  let handles;
@@ -1166,7 +1191,7 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
1166
1191
  ciphertextHandles: handles,
1167
1192
  extraData,
1168
1193
  };
1169
- const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options);
1194
+ const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options ?? instanceOptions);
1170
1195
  // verify signatures on decryption:
1171
1196
  const domain = {
1172
1197
  name: 'Decryption',
@@ -1253,7 +1278,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1253
1278
  DelegatedUserDecryptRequestVerification: [
1254
1279
  { name: 'publicKey', type: 'bytes' },
1255
1280
  { name: 'contractAddresses', type: 'address[]' },
1256
- { name: 'contractsChainId', type: 'uint256' },
1257
1281
  { name: 'startTimestamp', type: 'uint256' },
1258
1282
  { name: 'durationDays', type: 'uint256' },
1259
1283
  { name: 'extraData', type: 'bytes' },
@@ -1268,7 +1292,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1268
1292
  message: {
1269
1293
  publicKey: formattedPublicKey,
1270
1294
  contractAddresses,
1271
- contractsChainId,
1272
1295
  startTimestamp: formattedStartTimestamp,
1273
1296
  durationDays: formattedDurationDays,
1274
1297
  extraData,
@@ -1282,7 +1305,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1282
1305
  UserDecryptRequestVerification: [
1283
1306
  { name: 'publicKey', type: 'bytes' },
1284
1307
  { name: 'contractAddresses', type: 'address[]' },
1285
- { name: 'contractsChainId', type: 'uint256' },
1286
1308
  { name: 'startTimestamp', type: 'uint256' },
1287
1309
  { name: 'durationDays', type: 'uint256' },
1288
1310
  { name: 'extraData', type: 'bytes' },
@@ -1293,7 +1315,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1293
1315
  message: {
1294
1316
  publicKey: formattedPublicKey,
1295
1317
  contractAddresses,
1296
- contractsChainId,
1297
1318
  startTimestamp: formattedStartTimestamp,
1298
1319
  durationDays: formattedDurationDays,
1299
1320
  extraData,
@@ -1330,7 +1351,7 @@ const SepoliaConfig = {
1330
1351
  relayerUrl: 'https://relayer.testnet.zama.cloud',
1331
1352
  };
1332
1353
  const createInstance = async (config) => {
1333
- const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, } = config;
1354
+ const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
1334
1355
  if (!kmsContractAddress || !ethers.isAddress(kmsContractAddress)) {
1335
1356
  throw new Error('KMS contract address is not valid or empty');
1336
1357
  }
@@ -1362,8 +1383,8 @@ const createInstance = async (config) => {
1362
1383
  createEncryptedInput: createRelayerEncryptedInput(aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, cleanURL(config.relayerUrl), publicKeyData.publicKey, publicParamsData, coprocessorSigners, thresholdCoprocessorSigners),
1363
1384
  generateKeypair,
1364
1385
  createEIP712: createEIP712(verifyingContractAddressDecryption, chainId),
1365
- publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
1366
- userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
1386
+ publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
1387
+ userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
1367
1388
  getPublicKey: () => publicKeyData.publicKey
1368
1389
  ? {
1369
1390
  publicKey: publicKeyData.publicKey.safe_serialize(SERIALIZED_SIZE_LIMIT_PK),
package/lib/node.d.ts CHANGED
@@ -3,6 +3,56 @@ import { Eip1193Provider } from 'ethers';
3
3
  import { TfheClientKey } from 'node-tfhe';
4
4
  import { TfheCompactPublicKey } from 'node-tfhe';
5
5
 
6
+ /**
7
+ * Custom cookie authentication
8
+ */
9
+ declare type ApiKeyCookie = {
10
+ __type: 'ApiKeyCookie';
11
+ /**
12
+ * The cookie name. The default value is `x-api-key`.
13
+ */
14
+ cookie?: string;
15
+ /**
16
+ * The API key.
17
+ */
18
+ value: string;
19
+ };
20
+
21
+ /**
22
+ * Custom header authentication
23
+ */
24
+ declare type ApiKeyHeader = {
25
+ __type: 'ApiKeyHeader';
26
+ /**
27
+ * The header name. The default value is `x-api-key`.
28
+ */
29
+ header?: string;
30
+ /**
31
+ * The API key.
32
+ */
33
+ value: string;
34
+ };
35
+
36
+ /**
37
+ * Set the authentication method for the request. The default is no authentication.
38
+ * It supports:
39
+ * - Bearer Token
40
+ * - Custom header
41
+ * - Custom cookie
42
+ */
43
+ declare type Auth = BearerToken | ApiKeyHeader | ApiKeyCookie;
44
+
45
+ /**
46
+ * Bearer Token Authentication
47
+ */
48
+ declare type BearerToken = {
49
+ __type: 'BearerToken';
50
+ /**
51
+ * The Bearer token.
52
+ */
53
+ token: string;
54
+ };
55
+
6
56
  /**
7
57
  * Creates an EIP712 structure specifically for user decrypt requests
8
58
  *
@@ -99,6 +149,7 @@ export declare type FhevmInstanceConfig = {
99
149
  data: Uint8Array | null;
100
150
  id: string | null;
101
151
  };
152
+ auth?: Auth;
102
153
  };
103
154
 
104
155
  export declare const generateKeypair: () => {
@@ -133,7 +184,7 @@ export declare type RelayerEncryptedInput = {
133
184
  addAddress: (value: string) => RelayerEncryptedInput;
134
185
  getBits: () => EncryptionTypes[];
135
186
  encrypt: (options?: {
136
- apiKey?: string;
187
+ auth?: Auth;
137
188
  }) => Promise<{
138
189
  handles: Uint8Array[];
139
190
  inputProof: Uint8Array;
package/lib/node.js CHANGED
@@ -36,6 +36,32 @@ const bytesToBigInt = function (byteArray) {
36
36
  return BigInt(`0x${hex}`);
37
37
  };
38
38
 
39
+ function setAuth(init, auth) {
40
+ if (auth) {
41
+ switch (auth.__type) {
42
+ case 'BearerToken':
43
+ init.headers['Authorization'] =
44
+ `Bearer ${auth.token}`;
45
+ break;
46
+ case 'ApiKeyHeader':
47
+ init.headers[auth.header || 'x-api-key'] =
48
+ auth.value;
49
+ break;
50
+ case 'ApiKeyCookie':
51
+ if (typeof window !== 'undefined') {
52
+ document.cookie = `${auth.cookie || 'x-api-key'}=${auth.value}; path=/; SameSite=Lax; Secure; HttpOnly;`;
53
+ init.credentials = 'include';
54
+ }
55
+ else {
56
+ let cookie = `${auth.cookie || 'x-api-key'}=${auth.value};`;
57
+ init.headers['Cookie'] = cookie;
58
+ }
59
+ break;
60
+ }
61
+ }
62
+ return init;
63
+ }
64
+
39
65
  function getErrorCause(e) {
40
66
  if (e instanceof Error && typeof e.cause === 'object' && e.cause !== null) {
41
67
  return e.cause;
@@ -217,14 +243,13 @@ function assertIsRelayerFetchResponseJson(json) {
217
243
  }
218
244
  }
219
245
  async function fetchRelayerJsonRpcPost(relayerOperation, url, payload, options) {
220
- const init = {
246
+ const init = setAuth({
221
247
  method: 'POST',
222
248
  headers: {
223
249
  'Content-Type': 'application/json',
224
- ...(options?.apiKey && { 'x-api-key': options.apiKey }),
225
250
  },
226
251
  body: JSON.stringify(payload),
227
- };
252
+ }, options?.auth);
228
253
  let response;
229
254
  let json;
230
255
  try {
@@ -594,7 +619,7 @@ function checkDeadlineValidity(startTimestamp, durationDays) {
594
619
  throw Error('User decrypt request has expired');
595
620
  }
596
621
  }
597
- const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays) => {
622
+ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays, options) => {
598
623
  const extraData = '0x00';
599
624
  let pubKey;
600
625
  let privKey;
@@ -653,7 +678,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
653
678
  publicKey: publicKeySanitized,
654
679
  extraData,
655
680
  };
656
- const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, options);
681
+ const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, instanceOptions ?? options);
657
682
  // assume the KMS Signers have the correct order
658
683
  let indexedKmsSigners = kmsSigners.map((signer, index) => {
659
684
  return TKMS.new_server_id_addr(index + 1, signer);
@@ -935,7 +960,7 @@ function isFhevmRelayerInputProofResponse(json) {
935
960
  return (response.signatures.every((s) => typeof s === 'string') &&
936
961
  response.handles.every((h) => typeof h === 'string'));
937
962
  }
938
- const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners) => (contractAddress, userAddress) => {
963
+ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners, instanceOptions) => (contractAddress, userAddress) => {
939
964
  if (!isAddress(contractAddress)) {
940
965
  throw new Error('Contract address is not a valid address.');
941
966
  }
@@ -998,7 +1023,7 @@ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddres
998
1023
  contractChainId: ('0x' + chainId.toString(16)),
999
1024
  extraData,
1000
1025
  };
1001
- const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options);
1026
+ const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options ?? instanceOptions);
1002
1027
  if (!isFhevmRelayerInputProofResponse(json)) {
1003
1028
  throwRelayerInternalError('INPUT_PROOF', json);
1004
1029
  }
@@ -1120,7 +1145,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
1120
1145
  handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
1121
1146
  return results;
1122
1147
  }
1123
- const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles) => {
1148
+ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, options) => {
1124
1149
  const extraData = '0x00';
1125
1150
  const acl = new ethers.Contract(aclContractAddress, aclABI, provider);
1126
1151
  let handles;
@@ -1145,7 +1170,7 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
1145
1170
  ciphertextHandles: handles,
1146
1171
  extraData,
1147
1172
  };
1148
- const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options);
1173
+ const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options ?? instanceOptions);
1149
1174
  // verify signatures on decryption:
1150
1175
  const domain = {
1151
1176
  name: 'Decryption',
@@ -1232,7 +1257,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1232
1257
  DelegatedUserDecryptRequestVerification: [
1233
1258
  { name: 'publicKey', type: 'bytes' },
1234
1259
  { name: 'contractAddresses', type: 'address[]' },
1235
- { name: 'contractsChainId', type: 'uint256' },
1236
1260
  { name: 'startTimestamp', type: 'uint256' },
1237
1261
  { name: 'durationDays', type: 'uint256' },
1238
1262
  { name: 'extraData', type: 'bytes' },
@@ -1247,7 +1271,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1247
1271
  message: {
1248
1272
  publicKey: formattedPublicKey,
1249
1273
  contractAddresses,
1250
- contractsChainId,
1251
1274
  startTimestamp: formattedStartTimestamp,
1252
1275
  durationDays: formattedDurationDays,
1253
1276
  extraData,
@@ -1261,7 +1284,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1261
1284
  UserDecryptRequestVerification: [
1262
1285
  { name: 'publicKey', type: 'bytes' },
1263
1286
  { name: 'contractAddresses', type: 'address[]' },
1264
- { name: 'contractsChainId', type: 'uint256' },
1265
1287
  { name: 'startTimestamp', type: 'uint256' },
1266
1288
  { name: 'durationDays', type: 'uint256' },
1267
1289
  { name: 'extraData', type: 'bytes' },
@@ -1272,7 +1294,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
1272
1294
  message: {
1273
1295
  publicKey: formattedPublicKey,
1274
1296
  contractAddresses,
1275
- contractsChainId,
1276
1297
  startTimestamp: formattedStartTimestamp,
1277
1298
  durationDays: formattedDurationDays,
1278
1299
  extraData,
@@ -1309,7 +1330,7 @@ const SepoliaConfig = {
1309
1330
  relayerUrl: 'https://relayer.testnet.zama.cloud',
1310
1331
  };
1311
1332
  const createInstance = async (config) => {
1312
- const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, } = config;
1333
+ const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
1313
1334
  if (!kmsContractAddress || !isAddress(kmsContractAddress)) {
1314
1335
  throw new Error('KMS contract address is not valid or empty');
1315
1336
  }
@@ -1341,8 +1362,8 @@ const createInstance = async (config) => {
1341
1362
  createEncryptedInput: createRelayerEncryptedInput(aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, cleanURL(config.relayerUrl), publicKeyData.publicKey, publicParamsData, coprocessorSigners, thresholdCoprocessorSigners),
1342
1363
  generateKeypair,
1343
1364
  createEIP712: createEIP712(verifyingContractAddressDecryption, chainId),
1344
- publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
1345
- userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
1365
+ publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
1366
+ userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
1346
1367
  getPublicKey: () => publicKeyData.publicKey
1347
1368
  ? {
1348
1369
  publicKey: publicKeyData.publicKey.safe_serialize(SERIALIZED_SIZE_LIMIT_PK),
package/lib/web.d.ts CHANGED
@@ -2,6 +2,56 @@ import { Eip1193Provider } from 'ethers';
2
2
  import { InitInput as KMSInput } from 'tkms';
3
3
  import { InitInput as TFHEInput } from 'tfhe';
4
4
 
5
+ /**
6
+ * Custom cookie authentication
7
+ */
8
+ declare type ApiKeyCookie = {
9
+ __type: 'ApiKeyCookie';
10
+ /**
11
+ * The cookie name. The default value is `x-api-key`.
12
+ */
13
+ cookie?: string;
14
+ /**
15
+ * The API key.
16
+ */
17
+ value: string;
18
+ };
19
+
20
+ /**
21
+ * Custom header authentication
22
+ */
23
+ declare type ApiKeyHeader = {
24
+ __type: 'ApiKeyHeader';
25
+ /**
26
+ * The header name. The default value is `x-api-key`.
27
+ */
28
+ header?: string;
29
+ /**
30
+ * The API key.
31
+ */
32
+ value: string;
33
+ };
34
+
35
+ /**
36
+ * Set the authentication method for the request. The default is no authentication.
37
+ * It supports:
38
+ * - Bearer Token
39
+ * - Custom header
40
+ * - Custom cookie
41
+ */
42
+ declare type Auth = BearerToken | ApiKeyHeader | ApiKeyCookie;
43
+
44
+ /**
45
+ * Bearer Token Authentication
46
+ */
47
+ declare type BearerToken = {
48
+ __type: 'BearerToken';
49
+ /**
50
+ * The Bearer token.
51
+ */
52
+ token: string;
53
+ };
54
+
5
55
  /**
6
56
  * Creates an EIP712 structure specifically for user decrypt requests
7
57
  *
@@ -90,6 +140,7 @@ export declare type FhevmInstanceConfig = {
90
140
  data: Uint8Array | null;
91
141
  id: string | null;
92
142
  };
143
+ auth?: Auth;
93
144
  };
94
145
 
95
146
  export declare const generateKeypair: () => {
@@ -132,7 +183,7 @@ export declare type RelayerEncryptedInput = {
132
183
  addAddress: (value: string) => RelayerEncryptedInput;
133
184
  getBits: () => EncryptionTypes[];
134
185
  encrypt: (options?: {
135
- apiKey?: string;
186
+ auth?: Auth;
136
187
  }) => Promise<{
137
188
  handles: Uint8Array[];
138
189
  inputProof: Uint8Array;
package/lib/web.js CHANGED
@@ -16167,6 +16167,32 @@ const bytesToBigInt = function (byteArray) {
16167
16167
  return BigInt(`0x${hex}`);
16168
16168
  };
16169
16169
 
16170
+ function setAuth(init, auth) {
16171
+ if (auth) {
16172
+ switch (auth.__type) {
16173
+ case 'BearerToken':
16174
+ init.headers['Authorization'] =
16175
+ `Bearer ${auth.token}`;
16176
+ break;
16177
+ case 'ApiKeyHeader':
16178
+ init.headers[auth.header || 'x-api-key'] =
16179
+ auth.value;
16180
+ break;
16181
+ case 'ApiKeyCookie':
16182
+ if (typeof window !== 'undefined') {
16183
+ document.cookie = `${auth.cookie || 'x-api-key'}=${auth.value}; path=/; SameSite=Lax; Secure; HttpOnly;`;
16184
+ init.credentials = 'include';
16185
+ }
16186
+ else {
16187
+ let cookie = `${auth.cookie || 'x-api-key'}=${auth.value};`;
16188
+ init.headers['Cookie'] = cookie;
16189
+ }
16190
+ break;
16191
+ }
16192
+ }
16193
+ return init;
16194
+ }
16195
+
16170
16196
  function getErrorCause(e) {
16171
16197
  if (e instanceof Error && typeof e.cause === 'object' && e.cause !== null) {
16172
16198
  return e.cause;
@@ -16348,14 +16374,13 @@ function assertIsRelayerFetchResponseJson(json) {
16348
16374
  }
16349
16375
  }
16350
16376
  async function fetchRelayerJsonRpcPost(relayerOperation, url, payload, options) {
16351
- const init = {
16377
+ const init = setAuth({
16352
16378
  method: 'POST',
16353
16379
  headers: {
16354
16380
  'Content-Type': 'application/json',
16355
- ...(options?.apiKey && { 'x-api-key': options.apiKey }),
16356
16381
  },
16357
16382
  body: JSON.stringify(payload),
16358
- };
16383
+ }, options?.auth);
16359
16384
  let response;
16360
16385
  let json;
16361
16386
  try {
@@ -16725,7 +16750,7 @@ function checkDeadlineValidity(startTimestamp, durationDays) {
16725
16750
  throw Error('User decrypt request has expired');
16726
16751
  }
16727
16752
  }
16728
- const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays) => {
16753
+ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, privateKey, publicKey, signature, contractAddresses, userAddress, startTimestamp, durationDays, options) => {
16729
16754
  const extraData = '0x00';
16730
16755
  let pubKey;
16731
16756
  let privKey;
@@ -16784,7 +16809,7 @@ const userDecryptRequest = (kmsSigners, gatewayChainId, chainId, verifyingContra
16784
16809
  publicKey: publicKeySanitized,
16785
16810
  extraData,
16786
16811
  };
16787
- const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, options);
16812
+ const json = await fetchRelayerJsonRpcPost('USER_DECRYPT', `${relayerUrl}/v1/user-decrypt`, payloadForRequest, instanceOptions ?? options);
16788
16813
  // assume the KMS Signers have the correct order
16789
16814
  let indexedKmsSigners = kmsSigners.map((signer, index) => {
16790
16815
  return TKMS.new_server_id_addr(index + 1, signer);
@@ -17066,7 +17091,7 @@ function isFhevmRelayerInputProofResponse(json) {
17066
17091
  return (response.signatures.every((s) => typeof s === 'string') &&
17067
17092
  response.handles.every((h) => typeof h === 'string'));
17068
17093
  }
17069
- const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners) => (contractAddress, userAddress) => {
17094
+ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, relayerUrl, tfheCompactPublicKey, publicParams, coprocessorSigners, thresholdCoprocessorSigners, instanceOptions) => (contractAddress, userAddress) => {
17070
17095
  if (!isAddress(contractAddress)) {
17071
17096
  throw new Error('Contract address is not a valid address.');
17072
17097
  }
@@ -17129,7 +17154,7 @@ const createRelayerEncryptedInput = (aclContractAddress, verifyingContractAddres
17129
17154
  contractChainId: ('0x' + chainId.toString(16)),
17130
17155
  extraData,
17131
17156
  };
17132
- const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options);
17157
+ const json = await fetchRelayerJsonRpcPost('INPUT_PROOF', `${relayerUrl}/v1/input-proof`, payload, options ?? instanceOptions);
17133
17158
  if (!isFhevmRelayerInputProofResponse(json)) {
17134
17159
  throwRelayerInternalError('INPUT_PROOF', json);
17135
17160
  }
@@ -17251,7 +17276,7 @@ function deserializeDecryptedResult(handles, decryptedResult) {
17251
17276
  handles.forEach((handle, idx) => (results[handle] = rawValues[idx]));
17252
17277
  return results;
17253
17278
  }
17254
- const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, options) => async (_handles) => {
17279
+ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, verifyingContractAddress, aclContractAddress, relayerUrl, provider, instanceOptions) => async (_handles, options) => {
17255
17280
  const extraData = '0x00';
17256
17281
  const acl = new ethers.Contract(aclContractAddress, aclABI, provider);
17257
17282
  let handles;
@@ -17276,7 +17301,7 @@ const publicDecryptRequest = (kmsSigners, thresholdSigners, gatewayChainId, veri
17276
17301
  ciphertextHandles: handles,
17277
17302
  extraData,
17278
17303
  };
17279
- const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options);
17304
+ const json = await fetchRelayerJsonRpcPost('PUBLIC_DECRYPT', `${relayerUrl}/v1/public-decrypt`, payloadForRequest, options ?? instanceOptions);
17280
17305
  // verify signatures on decryption:
17281
17306
  const domain = {
17282
17307
  name: 'Decryption',
@@ -17363,7 +17388,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
17363
17388
  DelegatedUserDecryptRequestVerification: [
17364
17389
  { name: 'publicKey', type: 'bytes' },
17365
17390
  { name: 'contractAddresses', type: 'address[]' },
17366
- { name: 'contractsChainId', type: 'uint256' },
17367
17391
  { name: 'startTimestamp', type: 'uint256' },
17368
17392
  { name: 'durationDays', type: 'uint256' },
17369
17393
  { name: 'extraData', type: 'bytes' },
@@ -17378,7 +17402,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
17378
17402
  message: {
17379
17403
  publicKey: formattedPublicKey,
17380
17404
  contractAddresses,
17381
- contractsChainId,
17382
17405
  startTimestamp: formattedStartTimestamp,
17383
17406
  durationDays: formattedDurationDays,
17384
17407
  extraData,
@@ -17392,7 +17415,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
17392
17415
  UserDecryptRequestVerification: [
17393
17416
  { name: 'publicKey', type: 'bytes' },
17394
17417
  { name: 'contractAddresses', type: 'address[]' },
17395
- { name: 'contractsChainId', type: 'uint256' },
17396
17418
  { name: 'startTimestamp', type: 'uint256' },
17397
17419
  { name: 'durationDays', type: 'uint256' },
17398
17420
  { name: 'extraData', type: 'bytes' },
@@ -17403,7 +17425,6 @@ const createEIP712 = (verifyingContract, contractsChainId) => (publicKey, contra
17403
17425
  message: {
17404
17426
  publicKey: formattedPublicKey,
17405
17427
  contractAddresses,
17406
- contractsChainId,
17407
17428
  startTimestamp: formattedStartTimestamp,
17408
17429
  durationDays: formattedDurationDays,
17409
17430
  extraData,
@@ -17440,7 +17461,7 @@ const SepoliaConfig = {
17440
17461
  relayerUrl: 'https://relayer.testnet.zama.cloud',
17441
17462
  };
17442
17463
  const createInstance = async (config) => {
17443
- const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, } = config;
17464
+ const { verifyingContractAddressDecryption, verifyingContractAddressInputVerification, publicKey, kmsContractAddress, aclContractAddress, gatewayChainId, auth, } = config;
17444
17465
  if (!kmsContractAddress || !isAddress(kmsContractAddress)) {
17445
17466
  throw new Error('KMS contract address is not valid or empty');
17446
17467
  }
@@ -17472,8 +17493,8 @@ const createInstance = async (config) => {
17472
17493
  createEncryptedInput: createRelayerEncryptedInput(aclContractAddress, verifyingContractAddressInputVerification, chainId, gatewayChainId, cleanURL(config.relayerUrl), publicKeyData.publicKey, publicParamsData, coprocessorSigners, thresholdCoprocessorSigners),
17473
17494
  generateKeypair,
17474
17495
  createEIP712: createEIP712(verifyingContractAddressDecryption, chainId),
17475
- publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
17476
- userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider),
17496
+ publicDecrypt: publicDecryptRequest(kmsSigners, thresholdKMSSigners, gatewayChainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
17497
+ userDecrypt: userDecryptRequest(kmsSigners, gatewayChainId, chainId, verifyingContractAddressDecryption, aclContractAddress, cleanURL(config.relayerUrl), provider, auth && { auth }),
17477
17498
  getPublicKey: () => publicKeyData.publicKey
17478
17499
  ? {
17479
17500
  publicKey: publicKeyData.publicKey.safe_serialize(SERIALIZED_SIZE_LIMIT_PK),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zama-fhe/relayer-sdk",
3
- "version": "0.2.0-6",
3
+ "version": "0.3.0-0",
4
4
  "description": "fhevm Relayer SDK",
5
5
  "main": "lib/node.js",
6
6
  "types": "lib/node.d.ts",
@@ -26,9 +26,6 @@
26
26
  "types": "./lib/node.d.ts"
27
27
  }
28
28
  },
29
- "engines": {
30
- "node": ">=20"
31
- },
32
29
  "scripts": {
33
30
  "lint": "eslint src/",
34
31
  "generateKeys": "./generateKeys.js",
@@ -61,15 +58,15 @@
61
58
  "ethers": "^6.15.0",
62
59
  "fetch-retry": "^6.0.0",
63
60
  "keccak": "^3.0.4",
64
- "wasm-feature-detect": "^1.8.0",
65
61
  "node-tfhe": "1.3.0",
62
+ "node-tkms": "^0.11.0",
66
63
  "tfhe": "1.3.0",
67
- "node-tkms": "0.11.0-26",
68
- "tkms": "0.11.0-26"
64
+ "tkms": "^0.11.0",
65
+ "wasm-feature-detect": "^1.8.0"
69
66
  },
70
67
  "devDependencies": {
71
- "@fetch-mock/jest": "0.2.16",
72
68
  "@fetch-mock/core": "0.7.1",
69
+ "@fetch-mock/jest": "0.2.16",
73
70
  "@jest/globals": "30.0.4",
74
71
  "@microsoft/api-extractor": "7.52.8",
75
72
  "@rollup/plugin-alias": "5.1.1",
@@ -102,6 +99,9 @@
102
99
  "typescript": "5.8.3",
103
100
  "vite": "7.0.5",
104
101
  "vite-plugin-node-polyfills": "0.24.0",
105
- "vite-plugin-static-copy": "3.1.1"
102
+ "vite-plugin-static-copy": "^3.1.2"
103
+ },
104
+ "engines": {
105
+ "node": ">=22"
106
106
  }
107
107
  }