mmn-client-js 1.0.6 → 1.0.7
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 +202 -75
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +202 -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,36 @@ 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
|
+
console.log('🚀 ~ MmnClient ~ makeRequest ~ response:', response);
|
|
7717
|
+
clearTimeout(timeoutId);
|
|
7718
|
+
if (!response.ok) {
|
|
7719
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
7720
|
+
}
|
|
7721
|
+
const result = await response.json();
|
|
7643
7722
|
if (result.error) {
|
|
7644
7723
|
throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
|
|
7645
7724
|
}
|
|
7646
7725
|
return result.result;
|
|
7647
7726
|
}
|
|
7648
7727
|
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
|
-
}
|
|
7728
|
+
clearTimeout(timeoutId);
|
|
7663
7729
|
if (error instanceof Error) {
|
|
7730
|
+
if (error.name === 'AbortError') {
|
|
7731
|
+
throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
|
|
7732
|
+
}
|
|
7664
7733
|
throw error;
|
|
7665
7734
|
}
|
|
7666
7735
|
throw new Error('Unknown error occurred');
|
|
@@ -7681,22 +7750,31 @@ class MmnClient {
|
|
|
7681
7750
|
throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
|
|
7682
7751
|
}
|
|
7683
7752
|
try {
|
|
7684
|
-
// Ed25519 OID: 1.3.101.112 (
|
|
7685
|
-
const ED25519_OID = BufferCompat.from(
|
|
7753
|
+
// Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
|
|
7754
|
+
const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
|
|
7686
7755
|
const VERSION_BYTES = BufferCompat.from([
|
|
7687
7756
|
CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
|
|
7688
|
-
0x01,
|
|
7757
|
+
0x01, // Length of integer (1 byte)
|
|
7689
7758
|
CRYPTO_CONSTANTS.PKCS8_VERSION,
|
|
7690
|
-
]);
|
|
7691
|
-
// Create algorithm identifier sequence
|
|
7759
|
+
]);
|
|
7760
|
+
// Create algorithm identifier sequence (AlgorithmIdentifier)
|
|
7692
7761
|
const algorithmId = BufferCompat.concat([
|
|
7693
|
-
BufferCompat.from([
|
|
7762
|
+
BufferCompat.from([
|
|
7763
|
+
CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
|
|
7764
|
+
CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
|
|
7765
|
+
]),
|
|
7694
7766
|
ED25519_OID,
|
|
7695
7767
|
]);
|
|
7696
|
-
// Create private key octet string
|
|
7768
|
+
// Create private key octet string (wrapped Ed25519 private key)
|
|
7697
7769
|
const privateKeyOctetString = BufferCompat.concat([
|
|
7698
|
-
BufferCompat.from([
|
|
7699
|
-
|
|
7770
|
+
BufferCompat.from([
|
|
7771
|
+
CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
|
|
7772
|
+
CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH,
|
|
7773
|
+
]), // OCTET STRING, length 34
|
|
7774
|
+
BufferCompat.from([
|
|
7775
|
+
CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
|
|
7776
|
+
CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH,
|
|
7777
|
+
]), // inner OCTET STRING, length 32
|
|
7700
7778
|
raw,
|
|
7701
7779
|
]);
|
|
7702
7780
|
// Create PKCS#8 body
|
|
@@ -7725,17 +7803,28 @@ class MmnClient {
|
|
|
7725
7803
|
throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
7726
7804
|
}
|
|
7727
7805
|
}
|
|
7806
|
+
/**
|
|
7807
|
+
* Encode length in ASN.1 DER format
|
|
7808
|
+
* ASN.1 length encoding rules:
|
|
7809
|
+
* - Short form (0-127): single byte with the length value
|
|
7810
|
+
* - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
|
|
7811
|
+
* @param length - The length value to encode
|
|
7812
|
+
* @returns ASN.1 DER encoded length bytes
|
|
7813
|
+
*/
|
|
7728
7814
|
encodeLength(length) {
|
|
7729
|
-
if (length <
|
|
7815
|
+
if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
|
|
7730
7816
|
return BufferCompat.from([length]);
|
|
7731
7817
|
}
|
|
7732
7818
|
const bytes = [];
|
|
7733
7819
|
let len = length;
|
|
7734
7820
|
while (len > 0) {
|
|
7735
|
-
bytes.unshift(len &
|
|
7821
|
+
bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
|
|
7736
7822
|
len >>= 8;
|
|
7737
7823
|
}
|
|
7738
|
-
return BufferCompat.from([
|
|
7824
|
+
return BufferCompat.from([
|
|
7825
|
+
CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
|
|
7826
|
+
...bytes,
|
|
7827
|
+
]);
|
|
7739
7828
|
}
|
|
7740
7829
|
/**
|
|
7741
7830
|
* Generate secure entropy using multiple sources for maximum compatibility
|
|
@@ -7752,19 +7841,25 @@ class MmnClient {
|
|
|
7752
7841
|
const random = Math.random();
|
|
7753
7842
|
// Create initial seed from timestamp and random
|
|
7754
7843
|
let seed = now + performance + random;
|
|
7755
|
-
// Generate bytes using
|
|
7844
|
+
// Generate bytes using Linear Congruential Generator (LCG) with multiple entropy sources
|
|
7845
|
+
// This provides a fallback Pseudorandom Number Generator (PRNG) when crypto.getRandomValues is not available
|
|
7756
7846
|
for (let i = 0; i < targetLength; i++) {
|
|
7757
|
-
//
|
|
7758
|
-
seed =
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
//
|
|
7847
|
+
// Xₙ₊₁ = (a * Xₙ + c) mod m
|
|
7848
|
+
seed =
|
|
7849
|
+
(seed * PRNG_CONSTANTS.LCG_MULTIPLIER + PRNG_CONSTANTS.LCG_INCREMENT) %
|
|
7850
|
+
PRNG_CONSTANTS.LCG_MODULUS;
|
|
7851
|
+
// Mix with timestamp to add time-based entropy
|
|
7852
|
+
seed ^= (now + i) * PRNG_CONSTANTS.TIMESTAMP_MULTIPLIER;
|
|
7853
|
+
// Mix with Math.random() for additional browser-provided randomness
|
|
7854
|
+
seed ^= Math.floor(Math.random() * PRNG_CONSTANTS.LCG_MODULUS);
|
|
7855
|
+
// Additional cryptographic mixing using SHA256 if CryptoJS is available
|
|
7762
7856
|
if (typeof CryptoJS !== 'undefined') {
|
|
7763
7857
|
const hashInput = seed.toString() + i.toString() + now.toString();
|
|
7764
7858
|
const hash = CryptoJS.SHA256(hashInput).toString();
|
|
7765
|
-
|
|
7859
|
+
// Extract first 8 hex characters (32 bits) from hash for mixing
|
|
7860
|
+
seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
|
|
7766
7861
|
}
|
|
7767
|
-
entropy.push((seed >>>
|
|
7862
|
+
entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
|
|
7768
7863
|
}
|
|
7769
7864
|
return entropy;
|
|
7770
7865
|
}
|
|
@@ -7969,24 +8064,56 @@ var ETransferType;
|
|
|
7969
8064
|
class ZkClient {
|
|
7970
8065
|
constructor(config) {
|
|
7971
8066
|
this.endpoint = config.endpoint;
|
|
7972
|
-
this.
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
...(config.headers || {}),
|
|
7979
|
-
},
|
|
7980
|
-
});
|
|
8067
|
+
this.timeout = config.timeout || 30000;
|
|
8068
|
+
this.headers = {
|
|
8069
|
+
Accept: 'application/json',
|
|
8070
|
+
'Content-Type': 'application/json',
|
|
8071
|
+
...(config.headers || {}),
|
|
8072
|
+
};
|
|
7981
8073
|
}
|
|
7982
8074
|
async makeRequest(method, path, params, body) {
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
8075
|
+
let url = `${this.endpoint}/${path}`;
|
|
8076
|
+
// Add query parameters for GET requests
|
|
8077
|
+
if (params && Object.keys(params).length > 0) {
|
|
8078
|
+
const searchParams = new URLSearchParams();
|
|
8079
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
8080
|
+
searchParams.append(key, String(value));
|
|
8081
|
+
});
|
|
8082
|
+
url += `?${searchParams.toString()}`;
|
|
8083
|
+
}
|
|
8084
|
+
// Create AbortController for timeout
|
|
8085
|
+
const controller = new AbortController();
|
|
8086
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
8087
|
+
try {
|
|
8088
|
+
const requestOptions = {
|
|
8089
|
+
method,
|
|
8090
|
+
mode: 'cors',
|
|
8091
|
+
credentials: 'omit',
|
|
8092
|
+
signal: controller.signal,
|
|
8093
|
+
headers: this.headers,
|
|
8094
|
+
};
|
|
8095
|
+
// Add body for POST requests
|
|
8096
|
+
if (method === 'POST' && body) {
|
|
8097
|
+
requestOptions.body = JSON.stringify(body);
|
|
8098
|
+
}
|
|
8099
|
+
const response = await fetch(url, requestOptions);
|
|
8100
|
+
clearTimeout(timeoutId);
|
|
8101
|
+
if (!response.ok) {
|
|
8102
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
8103
|
+
}
|
|
8104
|
+
const data = await response.json();
|
|
8105
|
+
return data;
|
|
8106
|
+
}
|
|
8107
|
+
catch (error) {
|
|
8108
|
+
clearTimeout(timeoutId);
|
|
8109
|
+
if (error instanceof Error) {
|
|
8110
|
+
if (error.name === 'AbortError') {
|
|
8111
|
+
throw new Error(`Request timeout after ${this.timeout}ms`);
|
|
8112
|
+
}
|
|
8113
|
+
throw error;
|
|
8114
|
+
}
|
|
8115
|
+
throw new Error('Request failed');
|
|
8116
|
+
}
|
|
7990
8117
|
}
|
|
7991
8118
|
async getZkProofs({ userId, ephemeralPublicKey, jwt, address, }) {
|
|
7992
8119
|
const path = `prove`;
|