mmn-client-js 1.0.6 → 1.0.8
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/dist/index.d.ts +21 -6
- package/dist/index.esm.js +201 -75
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +201 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { AxiosRequestConfig } from 'axios';
|
|
2
|
-
|
|
3
1
|
interface JsonRpcRequest {
|
|
4
2
|
jsonrpc: '2.0';
|
|
5
3
|
method: string;
|
|
@@ -91,7 +89,6 @@ interface MmnClientConfig {
|
|
|
91
89
|
baseUrl: string;
|
|
92
90
|
timeout?: number;
|
|
93
91
|
headers?: Record<string, string>;
|
|
94
|
-
axiosConfig?: AxiosRequestConfig;
|
|
95
92
|
}
|
|
96
93
|
interface Transaction {
|
|
97
94
|
chain_id: string;
|
|
@@ -170,10 +167,20 @@ interface ZkClientConfig {
|
|
|
170
167
|
}
|
|
171
168
|
|
|
172
169
|
declare class IndexerClient {
|
|
173
|
-
private axiosInstance;
|
|
174
170
|
private endpoint;
|
|
175
171
|
private chainId;
|
|
172
|
+
private timeout;
|
|
173
|
+
private headers;
|
|
176
174
|
constructor(config: IndexerClientConfig);
|
|
175
|
+
/**
|
|
176
|
+
* Make HTTP request with automatic CORS handling
|
|
177
|
+
* Works out-of-the-box without CORS configuration
|
|
178
|
+
* @param method - HTTP method (GET or POST)
|
|
179
|
+
* @param path - API endpoint path
|
|
180
|
+
* @param params - URL query parameters
|
|
181
|
+
* @param body - Request body for POST requests
|
|
182
|
+
* @returns Promise resolving to response data
|
|
183
|
+
*/
|
|
177
184
|
private makeRequest;
|
|
178
185
|
getTransactionByHash(hash: string): Promise<Transaction>;
|
|
179
186
|
getTransactionByWallet(wallet: string, page: number | undefined, limit: number | undefined, filter: number, sortBy?: string, sortOrder?: 'asc' | 'desc'): Promise<ListTransactionResponse>;
|
|
@@ -182,7 +189,6 @@ declare class IndexerClient {
|
|
|
182
189
|
|
|
183
190
|
declare class MmnClient {
|
|
184
191
|
private config;
|
|
185
|
-
private axiosInstance;
|
|
186
192
|
private requestId;
|
|
187
193
|
constructor(config: MmnClientConfig);
|
|
188
194
|
private makeRequest;
|
|
@@ -193,6 +199,14 @@ declare class MmnClient {
|
|
|
193
199
|
* @throws Error if input validation fails
|
|
194
200
|
*/
|
|
195
201
|
private rawEd25519ToPkcs8Hex;
|
|
202
|
+
/**
|
|
203
|
+
* Encode length in ASN.1 DER format
|
|
204
|
+
* ASN.1 length encoding rules:
|
|
205
|
+
* - Short form (0-127): single byte with the length value
|
|
206
|
+
* - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
|
|
207
|
+
* @param length - The length value to encode
|
|
208
|
+
* @returns ASN.1 DER encoded length bytes
|
|
209
|
+
*/
|
|
196
210
|
private encodeLength;
|
|
197
211
|
/**
|
|
198
212
|
* Generate secure entropy using multiple sources for maximum compatibility
|
|
@@ -241,8 +255,9 @@ declare class MmnClient {
|
|
|
241
255
|
declare function createMmnClient(config: MmnClientConfig): MmnClient;
|
|
242
256
|
|
|
243
257
|
declare class ZkClient {
|
|
244
|
-
private axiosInstance;
|
|
245
258
|
private endpoint;
|
|
259
|
+
private timeout;
|
|
260
|
+
private headers;
|
|
246
261
|
constructor(config: ZkClientConfig);
|
|
247
262
|
private makeRequest;
|
|
248
263
|
getZkProofs({ userId, ephemeralPublicKey, jwt, address, }: {
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
1
|
import bs58 from 'bs58';
|
|
3
2
|
import nacl from 'tweetnacl';
|
|
4
3
|
|
|
@@ -11,24 +10,74 @@ class IndexerClient {
|
|
|
11
10
|
constructor(config) {
|
|
12
11
|
this.endpoint = config.endpoint;
|
|
13
12
|
this.chainId = config.chainId;
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
...(config.headers || {}),
|
|
21
|
-
},
|
|
22
|
-
});
|
|
13
|
+
this.timeout = config.timeout || 30000;
|
|
14
|
+
// Minimal headers to avoid CORS preflight issues
|
|
15
|
+
this.headers = {
|
|
16
|
+
Accept: 'application/json',
|
|
17
|
+
...(config.headers || {}),
|
|
18
|
+
};
|
|
23
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Make HTTP request with automatic CORS handling
|
|
22
|
+
* Works out-of-the-box without CORS configuration
|
|
23
|
+
* @param method - HTTP method (GET or POST)
|
|
24
|
+
* @param path - API endpoint path
|
|
25
|
+
* @param params - URL query parameters
|
|
26
|
+
* @param body - Request body for POST requests
|
|
27
|
+
* @returns Promise resolving to response data
|
|
28
|
+
*/
|
|
24
29
|
async makeRequest(method, path, params, body) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// Build full URL
|
|
31
|
+
let url = `${this.endpoint}/${path}`;
|
|
32
|
+
// Add query parameters
|
|
33
|
+
if (params && Object.keys(params).length > 0) {
|
|
34
|
+
const searchParams = new URLSearchParams();
|
|
35
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
36
|
+
searchParams.append(key, String(value));
|
|
37
|
+
});
|
|
38
|
+
url += `?${searchParams.toString()}`;
|
|
39
|
+
}
|
|
40
|
+
// Create AbortController for timeout
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
43
|
+
try {
|
|
44
|
+
// Simple fetch with automatic CORS handling
|
|
45
|
+
const requestOptions = {
|
|
46
|
+
method,
|
|
47
|
+
mode: 'cors',
|
|
48
|
+
credentials: 'omit',
|
|
49
|
+
signal: controller.signal,
|
|
50
|
+
headers: {
|
|
51
|
+
Accept: 'application/json',
|
|
52
|
+
...this.headers,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
// Add body and Content-Type for POST requests
|
|
56
|
+
if (method === 'POST' && body) {
|
|
57
|
+
requestOptions.body = JSON.stringify(body);
|
|
58
|
+
requestOptions.headers['Content-Type'] =
|
|
59
|
+
'application/json';
|
|
60
|
+
}
|
|
61
|
+
const response = await fetch(url, requestOptions);
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
// Handle response errors
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
66
|
+
}
|
|
67
|
+
// Parse JSON response
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
return data;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
clearTimeout(timeoutId);
|
|
73
|
+
if (error instanceof Error) {
|
|
74
|
+
if (error.name === 'AbortError') {
|
|
75
|
+
throw new Error(`Request timeout after ${this.timeout}ms`);
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
throw new Error('Request failed');
|
|
80
|
+
}
|
|
32
81
|
}
|
|
33
82
|
async getTransactionByHash(hash) {
|
|
34
83
|
const path = `${this.chainId}/tx/${hash}/detail`;
|
|
@@ -7604,9 +7653,28 @@ const CRYPTO_CONSTANTS = {
|
|
|
7604
7653
|
ED25519_PUBLIC_KEY_LENGTH: 32,
|
|
7605
7654
|
MNEMONIC_ENTROPY_BITS: 128,
|
|
7606
7655
|
PKCS8_VERSION: 0,
|
|
7656
|
+
// ASN.1 DER encoding
|
|
7607
7657
|
ASN1_SEQUENCE_TAG: 0x30,
|
|
7608
7658
|
ASN1_OCTET_STRING_TAG: 0x04,
|
|
7609
7659
|
ASN1_INTEGER_TAG: 0x02,
|
|
7660
|
+
ASN1_LENGTH: 0x80,
|
|
7661
|
+
// Ed25519 OID bytes: 1.3.101.112 (RFC 8410)
|
|
7662
|
+
ED25519_OID_BYTES: [0x06, 0x03, 0x2b, 0x65, 0x70],
|
|
7663
|
+
// PKCS#8 structure length constants
|
|
7664
|
+
PKCS8_ALGORITHM_ID_LENGTH: 0x0b, // SEQUENCE length for algorithm identifier
|
|
7665
|
+
PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH: 0x22, // Outer OCTET STRING length (34 bytes)
|
|
7666
|
+
PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH: 0x20, // Inner OCTET STRING length (32 bytes)
|
|
7667
|
+
};
|
|
7668
|
+
// PRNG (Pseudo-Random Number Generator) constants
|
|
7669
|
+
const PRNG_CONSTANTS = {
|
|
7670
|
+
// Numerical Recipes LCG
|
|
7671
|
+
LCG_MULTIPLIER: 1664525, // LCG multiplier (from Numerical Recipes)
|
|
7672
|
+
LCG_INCREMENT: 1013904223, // LCG increment
|
|
7673
|
+
LCG_MODULUS: 4294967296, // 2^32 modulus for LCG
|
|
7674
|
+
TIMESTAMP_MULTIPLIER: 2654435761, // Golden Ratio constant
|
|
7675
|
+
HASH_SUBSTRING_LENGTH: 8,
|
|
7676
|
+
BYTE_SHIFT: 24,
|
|
7677
|
+
BYTE_MASK: 0xff,
|
|
7610
7678
|
};
|
|
7611
7679
|
const TX_TYPE = {
|
|
7612
7680
|
TRANSFER: 0,
|
|
@@ -7620,15 +7688,10 @@ class MmnClient {
|
|
|
7620
7688
|
timeout: 30000,
|
|
7621
7689
|
headers: {
|
|
7622
7690
|
'Content-Type': 'application/json',
|
|
7691
|
+
Accept: 'application/json',
|
|
7623
7692
|
},
|
|
7624
7693
|
...config,
|
|
7625
7694
|
};
|
|
7626
|
-
this.axiosInstance = axios.create({
|
|
7627
|
-
baseURL: this.config.baseUrl,
|
|
7628
|
-
timeout: this.config.timeout || 30000,
|
|
7629
|
-
headers: this.config.headers || {},
|
|
7630
|
-
...(this.config.axiosConfig || {}),
|
|
7631
|
-
});
|
|
7632
7695
|
}
|
|
7633
7696
|
async makeRequest(method, params) {
|
|
7634
7697
|
const request = {
|
|
@@ -7637,30 +7700,35 @@ class MmnClient {
|
|
|
7637
7700
|
params,
|
|
7638
7701
|
id: ++this.requestId,
|
|
7639
7702
|
};
|
|
7703
|
+
// Create AbortController for timeout
|
|
7704
|
+
const controller = new AbortController();
|
|
7705
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
|
|
7640
7706
|
try {
|
|
7641
|
-
const
|
|
7642
|
-
|
|
7707
|
+
const requestOptions = {
|
|
7708
|
+
method: 'POST',
|
|
7709
|
+
mode: 'cors',
|
|
7710
|
+
credentials: 'omit',
|
|
7711
|
+
signal: controller.signal,
|
|
7712
|
+
headers: this.config.headers || {},
|
|
7713
|
+
body: JSON.stringify(request),
|
|
7714
|
+
};
|
|
7715
|
+
const response = await fetch(this.config.baseUrl, requestOptions);
|
|
7716
|
+
clearTimeout(timeoutId);
|
|
7717
|
+
if (!response.ok) {
|
|
7718
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
7719
|
+
}
|
|
7720
|
+
const result = await response.json();
|
|
7643
7721
|
if (result.error) {
|
|
7644
7722
|
throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
|
|
7645
7723
|
}
|
|
7646
7724
|
return result.result;
|
|
7647
7725
|
}
|
|
7648
7726
|
catch (error) {
|
|
7649
|
-
|
|
7650
|
-
if (error.response) {
|
|
7651
|
-
// Server responded with error status
|
|
7652
|
-
throw new Error(`HTTP ${error.response.status}: ${error.response.statusText}`);
|
|
7653
|
-
}
|
|
7654
|
-
else if (error.request) {
|
|
7655
|
-
// Request was made but no response received
|
|
7656
|
-
throw new Error('Network error: No response received');
|
|
7657
|
-
}
|
|
7658
|
-
else {
|
|
7659
|
-
// Something else happened
|
|
7660
|
-
throw new Error(`Request error: ${error.message}`);
|
|
7661
|
-
}
|
|
7662
|
-
}
|
|
7727
|
+
clearTimeout(timeoutId);
|
|
7663
7728
|
if (error instanceof Error) {
|
|
7729
|
+
if (error.name === 'AbortError') {
|
|
7730
|
+
throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
|
|
7731
|
+
}
|
|
7664
7732
|
throw error;
|
|
7665
7733
|
}
|
|
7666
7734
|
throw new Error('Unknown error occurred');
|
|
@@ -7681,22 +7749,31 @@ class MmnClient {
|
|
|
7681
7749
|
throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
|
|
7682
7750
|
}
|
|
7683
7751
|
try {
|
|
7684
|
-
// Ed25519 OID: 1.3.101.112 (
|
|
7685
|
-
const ED25519_OID = BufferCompat.from(
|
|
7752
|
+
// Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
|
|
7753
|
+
const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
|
|
7686
7754
|
const VERSION_BYTES = BufferCompat.from([
|
|
7687
7755
|
CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
|
|
7688
|
-
0x01,
|
|
7756
|
+
0x01, // Length of integer (1 byte)
|
|
7689
7757
|
CRYPTO_CONSTANTS.PKCS8_VERSION,
|
|
7690
|
-
]);
|
|
7691
|
-
// Create algorithm identifier sequence
|
|
7758
|
+
]);
|
|
7759
|
+
// Create algorithm identifier sequence (AlgorithmIdentifier)
|
|
7692
7760
|
const algorithmId = BufferCompat.concat([
|
|
7693
|
-
BufferCompat.from([
|
|
7761
|
+
BufferCompat.from([
|
|
7762
|
+
CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
|
|
7763
|
+
CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
|
|
7764
|
+
]),
|
|
7694
7765
|
ED25519_OID,
|
|
7695
7766
|
]);
|
|
7696
|
-
// Create private key octet string
|
|
7767
|
+
// Create private key octet string (wrapped Ed25519 private key)
|
|
7697
7768
|
const privateKeyOctetString = BufferCompat.concat([
|
|
7698
|
-
BufferCompat.from([
|
|
7699
|
-
|
|
7769
|
+
BufferCompat.from([
|
|
7770
|
+
CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
|
|
7771
|
+
CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH,
|
|
7772
|
+
]), // OCTET STRING, length 34
|
|
7773
|
+
BufferCompat.from([
|
|
7774
|
+
CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
|
|
7775
|
+
CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH,
|
|
7776
|
+
]), // inner OCTET STRING, length 32
|
|
7700
7777
|
raw,
|
|
7701
7778
|
]);
|
|
7702
7779
|
// Create PKCS#8 body
|
|
@@ -7725,17 +7802,28 @@ class MmnClient {
|
|
|
7725
7802
|
throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
7726
7803
|
}
|
|
7727
7804
|
}
|
|
7805
|
+
/**
|
|
7806
|
+
* Encode length in ASN.1 DER format
|
|
7807
|
+
* ASN.1 length encoding rules:
|
|
7808
|
+
* - Short form (0-127): single byte with the length value
|
|
7809
|
+
* - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
|
|
7810
|
+
* @param length - The length value to encode
|
|
7811
|
+
* @returns ASN.1 DER encoded length bytes
|
|
7812
|
+
*/
|
|
7728
7813
|
encodeLength(length) {
|
|
7729
|
-
if (length <
|
|
7814
|
+
if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
|
|
7730
7815
|
return BufferCompat.from([length]);
|
|
7731
7816
|
}
|
|
7732
7817
|
const bytes = [];
|
|
7733
7818
|
let len = length;
|
|
7734
7819
|
while (len > 0) {
|
|
7735
|
-
bytes.unshift(len &
|
|
7820
|
+
bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
|
|
7736
7821
|
len >>= 8;
|
|
7737
7822
|
}
|
|
7738
|
-
return BufferCompat.from([
|
|
7823
|
+
return BufferCompat.from([
|
|
7824
|
+
CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
|
|
7825
|
+
...bytes,
|
|
7826
|
+
]);
|
|
7739
7827
|
}
|
|
7740
7828
|
/**
|
|
7741
7829
|
* Generate secure entropy using multiple sources for maximum compatibility
|
|
@@ -7752,19 +7840,25 @@ class MmnClient {
|
|
|
7752
7840
|
const random = Math.random();
|
|
7753
7841
|
// Create initial seed from timestamp and random
|
|
7754
7842
|
let seed = now + performance + random;
|
|
7755
|
-
// Generate bytes using
|
|
7843
|
+
// Generate bytes using Linear Congruential Generator (LCG) with multiple entropy sources
|
|
7844
|
+
// This provides a fallback Pseudorandom Number Generator (PRNG) when crypto.getRandomValues is not available
|
|
7756
7845
|
for (let i = 0; i < targetLength; i++) {
|
|
7757
|
-
//
|
|
7758
|
-
seed =
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
//
|
|
7846
|
+
// Xₙ₊₁ = (a * Xₙ + c) mod m
|
|
7847
|
+
seed =
|
|
7848
|
+
(seed * PRNG_CONSTANTS.LCG_MULTIPLIER + PRNG_CONSTANTS.LCG_INCREMENT) %
|
|
7849
|
+
PRNG_CONSTANTS.LCG_MODULUS;
|
|
7850
|
+
// Mix with timestamp to add time-based entropy
|
|
7851
|
+
seed ^= (now + i) * PRNG_CONSTANTS.TIMESTAMP_MULTIPLIER;
|
|
7852
|
+
// Mix with Math.random() for additional browser-provided randomness
|
|
7853
|
+
seed ^= Math.floor(Math.random() * PRNG_CONSTANTS.LCG_MODULUS);
|
|
7854
|
+
// Additional cryptographic mixing using SHA256 if CryptoJS is available
|
|
7762
7855
|
if (typeof CryptoJS !== 'undefined') {
|
|
7763
7856
|
const hashInput = seed.toString() + i.toString() + now.toString();
|
|
7764
7857
|
const hash = CryptoJS.SHA256(hashInput).toString();
|
|
7765
|
-
|
|
7858
|
+
// Extract first 8 hex characters (32 bits) from hash for mixing
|
|
7859
|
+
seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
|
|
7766
7860
|
}
|
|
7767
|
-
entropy.push((seed >>>
|
|
7861
|
+
entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
|
|
7768
7862
|
}
|
|
7769
7863
|
return entropy;
|
|
7770
7864
|
}
|
|
@@ -7969,24 +8063,56 @@ var ETransferType;
|
|
|
7969
8063
|
class ZkClient {
|
|
7970
8064
|
constructor(config) {
|
|
7971
8065
|
this.endpoint = config.endpoint;
|
|
7972
|
-
this.
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
...(config.headers || {}),
|
|
7979
|
-
},
|
|
7980
|
-
});
|
|
8066
|
+
this.timeout = config.timeout || 30000;
|
|
8067
|
+
this.headers = {
|
|
8068
|
+
Accept: 'application/json',
|
|
8069
|
+
'Content-Type': 'application/json',
|
|
8070
|
+
...(config.headers || {}),
|
|
8071
|
+
};
|
|
7981
8072
|
}
|
|
7982
8073
|
async makeRequest(method, path, params, body) {
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
8074
|
+
let url = `${this.endpoint}/${path}`;
|
|
8075
|
+
// Add query parameters for GET requests
|
|
8076
|
+
if (params && Object.keys(params).length > 0) {
|
|
8077
|
+
const searchParams = new URLSearchParams();
|
|
8078
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
8079
|
+
searchParams.append(key, String(value));
|
|
8080
|
+
});
|
|
8081
|
+
url += `?${searchParams.toString()}`;
|
|
8082
|
+
}
|
|
8083
|
+
// Create AbortController for timeout
|
|
8084
|
+
const controller = new AbortController();
|
|
8085
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
8086
|
+
try {
|
|
8087
|
+
const requestOptions = {
|
|
8088
|
+
method,
|
|
8089
|
+
mode: 'cors',
|
|
8090
|
+
credentials: 'omit',
|
|
8091
|
+
signal: controller.signal,
|
|
8092
|
+
headers: this.headers,
|
|
8093
|
+
};
|
|
8094
|
+
// Add body for POST requests
|
|
8095
|
+
if (method === 'POST' && body) {
|
|
8096
|
+
requestOptions.body = JSON.stringify(body);
|
|
8097
|
+
}
|
|
8098
|
+
const response = await fetch(url, requestOptions);
|
|
8099
|
+
clearTimeout(timeoutId);
|
|
8100
|
+
if (!response.ok) {
|
|
8101
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
8102
|
+
}
|
|
8103
|
+
const data = await response.json();
|
|
8104
|
+
return data;
|
|
8105
|
+
}
|
|
8106
|
+
catch (error) {
|
|
8107
|
+
clearTimeout(timeoutId);
|
|
8108
|
+
if (error instanceof Error) {
|
|
8109
|
+
if (error.name === 'AbortError') {
|
|
8110
|
+
throw new Error(`Request timeout after ${this.timeout}ms`);
|
|
8111
|
+
}
|
|
8112
|
+
throw error;
|
|
8113
|
+
}
|
|
8114
|
+
throw new Error('Request failed');
|
|
8115
|
+
}
|
|
7990
8116
|
}
|
|
7991
8117
|
async getZkProofs({ userId, ephemeralPublicKey, jwt, address, }) {
|
|
7992
8118
|
const path = `prove`;
|