mmn-client-js 1.0.13-node14 → 1.0.14-node14

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.esm.js CHANGED
@@ -1,135 +1,160 @@
1
1
  import bs58 from 'bs58';
2
2
  import nacl from 'tweetnacl';
3
3
 
4
- const API_FILTER_PARAMS = {
5
- ALL: 0,
6
- SENT: 2,
7
- RECEIVED: 1,
8
- };
9
- class IndexerClient {
10
- constructor(config) {
11
- this.endpoint = config.endpoint;
12
- this.chainId = config.chainId;
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
- };
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
- */
29
- async makeRequest(method, path, params, body) {
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
- }
81
- }
82
- async getTransactionByHash(hash) {
83
- const path = `${this.chainId}/tx/${hash}/detail`;
84
- const res = await this.makeRequest('GET', path);
85
- return res.data.transaction;
86
- }
87
- async getTransactionByWallet(wallet, page = 1, limit = 50, filter, sortBy = 'transaction_timestamp', sortOrder = 'desc') {
88
- if (!wallet) {
89
- throw new Error('wallet address cannot be empty');
90
- }
91
- if (page < 1)
92
- page = 1;
93
- if (limit <= 0)
94
- limit = 50;
95
- if (limit > 1000)
96
- limit = 1000;
97
- const params = {
98
- page: page - 1,
99
- limit,
100
- sort_by: sortBy,
101
- sort_order: sortOrder,
102
- };
103
- switch (filter) {
104
- case API_FILTER_PARAMS.ALL:
105
- params['wallet_address'] = wallet;
106
- break;
107
- case API_FILTER_PARAMS.SENT:
108
- params['filter_from_address'] = wallet;
109
- break;
110
- case API_FILTER_PARAMS.RECEIVED:
111
- params['filter_to_address'] = wallet;
112
- break;
113
- }
114
- const path = `${this.chainId}/transactions`;
115
- return this.makeRequest('GET', path, params);
116
- }
117
- async getWalletDetail(wallet) {
118
- if (!wallet) {
119
- throw new Error('wallet address cannot be empty');
120
- }
121
- const path = `${this.chainId}/wallets/${wallet}/detail`;
122
- const res = await this.makeRequest('GET', path);
123
- return res.data;
124
- }
4
+ // Fetch and AbortController polyfills for Node 14 compatibility
5
+ /* eslint-disable @typescript-eslint/no-require-imports */
6
+ let fetchPolyfill;
7
+ let AbortControllerPolyfill;
8
+ if (typeof fetch === 'undefined') {
9
+ try {
10
+ // Use node-fetch in Node.js environments that don't have global fetch
11
+ fetchPolyfill = require('node-fetch');
12
+ }
13
+ catch {
14
+ throw new Error('node-fetch is required for Node 14 compatibility. Please install it: npm install node-fetch@2');
15
+ }
16
+ }
17
+ else {
18
+ fetchPolyfill = fetch;
19
+ }
20
+ if (typeof AbortController === 'undefined') {
21
+ try {
22
+ // Use abort-controller in environments that don't have AbortController
23
+ AbortControllerPolyfill = require('abort-controller');
24
+ }
25
+ catch {
26
+ throw new Error('abort-controller is required for Node 14 compatibility. Please install it: npm install abort-controller');
27
+ }
28
+ }
29
+ else {
30
+ AbortControllerPolyfill = AbortController;
125
31
  }
126
32
 
127
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
128
-
129
- function getDefaultExportFromCjs (x) {
130
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
33
+ const API_FILTER_PARAMS = {
34
+ ALL: 0,
35
+ SENT: 2,
36
+ RECEIVED: 1,
37
+ };
38
+ class IndexerClient {
39
+ constructor(config) {
40
+ this.endpoint = config.endpoint;
41
+ this.chainId = config.chainId;
42
+ this.timeout = config.timeout || 30000;
43
+ // Minimal headers to avoid CORS preflight issues
44
+ this.headers = {
45
+ Accept: 'application/json',
46
+ ...(config.headers || {}),
47
+ };
48
+ }
49
+ /**
50
+ * Make HTTP request with automatic CORS handling
51
+ * Works out-of-the-box without CORS configuration
52
+ * @param method - HTTP method (GET or POST)
53
+ * @param path - API endpoint path
54
+ * @param params - URL query parameters
55
+ * @param body - Request body for POST requests
56
+ * @returns Promise resolving to response data
57
+ */
58
+ async makeRequest(method, path, params, body) {
59
+ // Build full URL
60
+ let url = `${this.endpoint}/${path}`;
61
+ // Add query parameters
62
+ if (params && Object.keys(params).length > 0) {
63
+ const searchParams = new URLSearchParams();
64
+ Object.entries(params).forEach(([key, value]) => {
65
+ searchParams.append(key, String(value));
66
+ });
67
+ url += `?${searchParams.toString()}`;
68
+ }
69
+ // Create AbortController for timeout
70
+ const controller = new AbortControllerPolyfill();
71
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
72
+ try {
73
+ // Simple fetch with automatic CORS handling
74
+ const requestOptions = {
75
+ method,
76
+ mode: 'cors',
77
+ credentials: 'omit',
78
+ signal: controller.signal,
79
+ headers: {
80
+ Accept: 'application/json',
81
+ ...this.headers,
82
+ },
83
+ };
84
+ // Add body and Content-Type for POST requests
85
+ if (method === 'POST' && body) {
86
+ requestOptions.body = JSON.stringify(body);
87
+ requestOptions.headers['Content-Type'] =
88
+ 'application/json';
89
+ }
90
+ const response = await fetchPolyfill(url, requestOptions);
91
+ clearTimeout(timeoutId);
92
+ // Handle response errors
93
+ if (!response.ok) {
94
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
95
+ }
96
+ // Parse JSON response
97
+ const data = await response.json();
98
+ return data;
99
+ }
100
+ catch (error) {
101
+ clearTimeout(timeoutId);
102
+ if (error instanceof Error) {
103
+ if (error.name === 'AbortError') {
104
+ throw new Error(`Request timeout after ${this.timeout}ms`);
105
+ }
106
+ throw error;
107
+ }
108
+ throw new Error('Request failed');
109
+ }
110
+ }
111
+ async getTransactionByHash(hash) {
112
+ const path = `${this.chainId}/tx/${hash}/detail`;
113
+ const res = await this.makeRequest('GET', path);
114
+ return res.data.transaction;
115
+ }
116
+ async getTransactionByWallet(wallet, page = 1, limit = 50, filter, sortBy = 'transaction_timestamp', sortOrder = 'desc') {
117
+ if (!wallet) {
118
+ throw new Error('wallet address cannot be empty');
119
+ }
120
+ if (page < 1)
121
+ page = 1;
122
+ if (limit <= 0)
123
+ limit = 50;
124
+ if (limit > 1000)
125
+ limit = 1000;
126
+ const params = {
127
+ page: page - 1,
128
+ limit,
129
+ sort_by: sortBy,
130
+ sort_order: sortOrder,
131
+ };
132
+ switch (filter) {
133
+ case API_FILTER_PARAMS.ALL:
134
+ params['wallet_address'] = wallet;
135
+ break;
136
+ case API_FILTER_PARAMS.SENT:
137
+ params['filter_from_address'] = wallet;
138
+ break;
139
+ case API_FILTER_PARAMS.RECEIVED:
140
+ params['filter_to_address'] = wallet;
141
+ break;
142
+ }
143
+ const path = `${this.chainId}/transactions`;
144
+ return this.makeRequest('GET', path, params);
145
+ }
146
+ async getWalletDetail(wallet) {
147
+ if (!wallet) {
148
+ throw new Error('wallet address cannot be empty');
149
+ }
150
+ const path = `${this.chainId}/wallets/${wallet}/detail`;
151
+ const res = await this.makeRequest('GET', path);
152
+ return res.data;
153
+ }
131
154
  }
132
155
 
156
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
157
+
133
158
  var cryptoJs = {exports: {}};
134
159
 
135
160
  function commonjsRequire(path) {
@@ -942,8 +967,8 @@ function requireCore () {
942
967
 
943
968
  return CryptoJS;
944
969
 
945
- }));
946
- } (core));
970
+ }));
971
+ } (core));
947
972
  return core.exports;
948
973
  }
949
974
 
@@ -1250,8 +1275,8 @@ function requireX64Core () {
1250
1275
 
1251
1276
  return CryptoJS;
1252
1277
 
1253
- }));
1254
- } (x64Core));
1278
+ }));
1279
+ } (x64Core));
1255
1280
  return x64Core.exports;
1256
1281
  }
1257
1282
 
@@ -1330,8 +1355,8 @@ function requireLibTypedarrays () {
1330
1355
 
1331
1356
  return CryptoJS.lib.WordArray;
1332
1357
 
1333
- }));
1334
- } (libTypedarrays));
1358
+ }));
1359
+ } (libTypedarrays));
1335
1360
  return libTypedarrays.exports;
1336
1361
  }
1337
1362
 
@@ -1483,8 +1508,8 @@ function requireEncUtf16 () {
1483
1508
 
1484
1509
  return CryptoJS.enc.Utf16;
1485
1510
 
1486
- }));
1487
- } (encUtf16));
1511
+ }));
1512
+ } (encUtf16));
1488
1513
  return encUtf16.exports;
1489
1514
  }
1490
1515
 
@@ -1623,8 +1648,8 @@ function requireEncBase64 () {
1623
1648
 
1624
1649
  return CryptoJS.enc.Base64;
1625
1650
 
1626
- }));
1627
- } (encBase64));
1651
+ }));
1652
+ } (encBase64));
1628
1653
  return encBase64.exports;
1629
1654
  }
1630
1655
 
@@ -1775,8 +1800,8 @@ function requireEncBase64url () {
1775
1800
 
1776
1801
  return CryptoJS.enc.Base64url;
1777
1802
 
1778
- }));
1779
- } (encBase64url));
1803
+ }));
1804
+ } (encBase64url));
1780
1805
  return encBase64url.exports;
1781
1806
  }
1782
1807
 
@@ -2047,8 +2072,8 @@ function requireMd5 () {
2047
2072
 
2048
2073
  return CryptoJS.MD5;
2049
2074
 
2050
- }));
2051
- } (md5));
2075
+ }));
2076
+ } (md5));
2052
2077
  return md5.exports;
2053
2078
  }
2054
2079
 
@@ -2201,8 +2226,8 @@ function requireSha1 () {
2201
2226
 
2202
2227
  return CryptoJS.SHA1;
2203
2228
 
2204
- }));
2205
- } (sha1));
2229
+ }));
2230
+ } (sha1));
2206
2231
  return sha1.exports;
2207
2232
  }
2208
2233
 
@@ -2404,8 +2429,8 @@ function requireSha256 () {
2404
2429
 
2405
2430
  return CryptoJS.SHA256;
2406
2431
 
2407
- }));
2408
- } (sha256));
2432
+ }));
2433
+ } (sha256));
2409
2434
  return sha256.exports;
2410
2435
  }
2411
2436
 
@@ -2488,8 +2513,8 @@ function requireSha224 () {
2488
2513
 
2489
2514
  return CryptoJS.SHA224;
2490
2515
 
2491
- }));
2492
- } (sha224));
2516
+ }));
2517
+ } (sha224));
2493
2518
  return sha224.exports;
2494
2519
  }
2495
2520
 
@@ -2818,8 +2843,8 @@ function requireSha512 () {
2818
2843
 
2819
2844
  return CryptoJS.SHA512;
2820
2845
 
2821
- }));
2822
- } (sha512));
2846
+ }));
2847
+ } (sha512));
2823
2848
  return sha512.exports;
2824
2849
  }
2825
2850
 
@@ -2905,8 +2930,8 @@ function requireSha384 () {
2905
2930
 
2906
2931
  return CryptoJS.SHA384;
2907
2932
 
2908
- }));
2909
- } (sha384));
2933
+ }));
2934
+ } (sha384));
2910
2935
  return sha384.exports;
2911
2936
  }
2912
2937
 
@@ -3235,8 +3260,8 @@ function requireSha3 () {
3235
3260
 
3236
3261
  return CryptoJS.SHA3;
3237
3262
 
3238
- }));
3239
- } (sha3));
3263
+ }));
3264
+ } (sha3));
3240
3265
  return sha3.exports;
3241
3266
  }
3242
3267
 
@@ -3506,8 +3531,8 @@ function requireRipemd160 () {
3506
3531
 
3507
3532
  return CryptoJS.RIPEMD160;
3508
3533
 
3509
- }));
3510
- } (ripemd160));
3534
+ }));
3535
+ } (ripemd160));
3511
3536
  return ripemd160.exports;
3512
3537
  }
3513
3538
 
@@ -3653,8 +3678,8 @@ function requireHmac () {
3653
3678
  }());
3654
3679
 
3655
3680
 
3656
- }));
3657
- } (hmac));
3681
+ }));
3682
+ } (hmac));
3658
3683
  return hmac.exports;
3659
3684
  }
3660
3685
 
@@ -3802,8 +3827,8 @@ function requirePbkdf2 () {
3802
3827
 
3803
3828
  return CryptoJS.PBKDF2;
3804
3829
 
3805
- }));
3806
- } (pbkdf2));
3830
+ }));
3831
+ } (pbkdf2));
3807
3832
  return pbkdf2.exports;
3808
3833
  }
3809
3834
 
@@ -3940,8 +3965,8 @@ function requireEvpkdf () {
3940
3965
 
3941
3966
  return CryptoJS.EvpKDF;
3942
3967
 
3943
- }));
3944
- } (evpkdf));
3968
+ }));
3969
+ } (evpkdf));
3945
3970
  return evpkdf.exports;
3946
3971
  }
3947
3972
 
@@ -4164,7 +4189,7 @@ function requireCipherCore () {
4164
4189
  C_lib.StreamCipher = Cipher.extend({
4165
4190
  _doFinalize: function () {
4166
4191
  // Process partial blocks
4167
- var finalProcessedBlocks = this._process(true);
4192
+ var finalProcessedBlocks = this._process(!!'flush');
4168
4193
 
4169
4194
  return finalProcessedBlocks;
4170
4195
  },
@@ -4445,10 +4470,10 @@ function requireCipherCore () {
4445
4470
  padding.pad(this._data, this.blockSize);
4446
4471
 
4447
4472
  // Process final blocks
4448
- finalProcessedBlocks = this._process(true);
4473
+ finalProcessedBlocks = this._process(!!'flush');
4449
4474
  } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
4450
4475
  // Process final blocks
4451
- finalProcessedBlocks = this._process(true);
4476
+ finalProcessedBlocks = this._process(!!'flush');
4452
4477
 
4453
4478
  // Unpad data
4454
4479
  padding.unpad(finalProcessedBlocks);
@@ -4839,8 +4864,8 @@ function requireCipherCore () {
4839
4864
  }());
4840
4865
 
4841
4866
 
4842
- }));
4843
- } (cipherCore));
4867
+ }));
4868
+ } (cipherCore));
4844
4869
  return cipherCore.exports;
4845
4870
  }
4846
4871
 
@@ -4923,8 +4948,8 @@ function requireModeCfb () {
4923
4948
 
4924
4949
  return CryptoJS.mode.CFB;
4925
4950
 
4926
- }));
4927
- } (modeCfb));
4951
+ }));
4952
+ } (modeCfb));
4928
4953
  return modeCfb.exports;
4929
4954
  }
4930
4955
 
@@ -4985,8 +5010,8 @@ function requireModeCtr () {
4985
5010
 
4986
5011
  return CryptoJS.mode.CTR;
4987
5012
 
4988
- }));
4989
- } (modeCtr));
5013
+ }));
5014
+ } (modeCtr));
4990
5015
  return modeCtr.exports;
4991
5016
  }
4992
5017
 
@@ -5105,8 +5130,8 @@ function requireModeCtrGladman () {
5105
5130
 
5106
5131
  return CryptoJS.mode.CTRGladman;
5107
5132
 
5108
- }));
5109
- } (modeCtrGladman));
5133
+ }));
5134
+ } (modeCtrGladman));
5110
5135
  return modeCtrGladman.exports;
5111
5136
  }
5112
5137
 
@@ -5163,8 +5188,8 @@ function requireModeOfb () {
5163
5188
 
5164
5189
  return CryptoJS.mode.OFB;
5165
5190
 
5166
- }));
5167
- } (modeOfb));
5191
+ }));
5192
+ } (modeOfb));
5168
5193
  return modeOfb.exports;
5169
5194
  }
5170
5195
 
@@ -5207,8 +5232,8 @@ function requireModeEcb () {
5207
5232
 
5208
5233
  return CryptoJS.mode.ECB;
5209
5234
 
5210
- }));
5211
- } (modeEcb));
5235
+ }));
5236
+ } (modeEcb));
5212
5237
  return modeEcb.exports;
5213
5238
  }
5214
5239
 
@@ -5260,8 +5285,8 @@ function requirePadAnsix923 () {
5260
5285
 
5261
5286
  return CryptoJS.pad.Ansix923;
5262
5287
 
5263
- }));
5264
- } (padAnsix923));
5288
+ }));
5289
+ } (padAnsix923));
5265
5290
  return padAnsix923.exports;
5266
5291
  }
5267
5292
 
@@ -5308,8 +5333,8 @@ function requirePadIso10126 () {
5308
5333
 
5309
5334
  return CryptoJS.pad.Iso10126;
5310
5335
 
5311
- }));
5312
- } (padIso10126));
5336
+ }));
5337
+ } (padIso10126));
5313
5338
  return padIso10126.exports;
5314
5339
  }
5315
5340
 
@@ -5352,8 +5377,8 @@ function requirePadIso97971 () {
5352
5377
 
5353
5378
  return CryptoJS.pad.Iso97971;
5354
5379
 
5355
- }));
5356
- } (padIso97971));
5380
+ }));
5381
+ } (padIso97971));
5357
5382
  return padIso97971.exports;
5358
5383
  }
5359
5384
 
@@ -5403,8 +5428,8 @@ function requirePadZeropadding () {
5403
5428
 
5404
5429
  return CryptoJS.pad.ZeroPadding;
5405
5430
 
5406
- }));
5407
- } (padZeropadding));
5431
+ }));
5432
+ } (padZeropadding));
5408
5433
  return padZeropadding.exports;
5409
5434
  }
5410
5435
 
@@ -5437,8 +5462,8 @@ function requirePadNopadding () {
5437
5462
 
5438
5463
  return CryptoJS.pad.NoPadding;
5439
5464
 
5440
- }));
5441
- } (padNopadding));
5465
+ }));
5466
+ } (padNopadding));
5442
5467
  return padNopadding.exports;
5443
5468
  }
5444
5469
 
@@ -5507,8 +5532,8 @@ function requireFormatHex () {
5507
5532
 
5508
5533
  return CryptoJS.format.Hex;
5509
5534
 
5510
- }));
5511
- } (formatHex));
5535
+ }));
5536
+ } (formatHex));
5512
5537
  return formatHex.exports;
5513
5538
  }
5514
5539
 
@@ -5745,8 +5770,8 @@ function requireAes () {
5745
5770
 
5746
5771
  return CryptoJS.AES;
5747
5772
 
5748
- }));
5749
- } (aes));
5773
+ }));
5774
+ } (aes));
5750
5775
  return aes.exports;
5751
5776
  }
5752
5777
 
@@ -6528,8 +6553,8 @@ function requireTripledes () {
6528
6553
 
6529
6554
  return CryptoJS.TripleDES;
6530
6555
 
6531
- }));
6532
- } (tripledes));
6556
+ }));
6557
+ } (tripledes));
6533
6558
  return tripledes.exports;
6534
6559
  }
6535
6560
 
@@ -6671,8 +6696,8 @@ function requireRc4 () {
6671
6696
 
6672
6697
  return CryptoJS.RC4;
6673
6698
 
6674
- }));
6675
- } (rc4));
6699
+ }));
6700
+ } (rc4));
6676
6701
  return rc4.exports;
6677
6702
  }
6678
6703
 
@@ -6867,8 +6892,8 @@ function requireRabbit () {
6867
6892
 
6868
6893
  return CryptoJS.Rabbit;
6869
6894
 
6870
- }));
6871
- } (rabbit));
6895
+ }));
6896
+ } (rabbit));
6872
6897
  return rabbit.exports;
6873
6898
  }
6874
6899
 
@@ -7061,8 +7086,8 @@ function requireRabbitLegacy () {
7061
7086
 
7062
7087
  return CryptoJS.RabbitLegacy;
7063
7088
 
7064
- }));
7065
- } (rabbitLegacy));
7089
+ }));
7090
+ } (rabbitLegacy));
7066
7091
  return rabbitLegacy.exports;
7067
7092
  }
7068
7093
 
@@ -7536,8 +7561,8 @@ function requireBlowfish () {
7536
7561
 
7537
7562
  return CryptoJS.Blowfish;
7538
7563
 
7539
- }));
7540
- } (blowfish));
7564
+ }));
7565
+ } (blowfish));
7541
7566
  return blowfish.exports;
7542
7567
  }
7543
7568
 
@@ -7551,623 +7576,621 @@ function requireBlowfish () {
7551
7576
 
7552
7577
  return CryptoJS;
7553
7578
 
7554
- }));
7579
+ }));
7555
7580
  } (cryptoJs));
7556
7581
 
7557
- var cryptoJsExports = cryptoJs.exports;
7558
- var CryptoJS = /*@__PURE__*/getDefaultExportFromCjs(cryptoJsExports);
7559
-
7560
- // MMN Client
7561
- // This client provides a complete interface for interacting with MMN blockchain
7562
- // Buffer polyfill for mobile environments
7563
- class BufferPolyfill {
7564
- static isBuffer(obj) {
7565
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer) {
7566
- return Buffer.isBuffer(obj);
7567
- }
7568
- return obj instanceof Uint8Array;
7569
- }
7570
- static from(data, encoding) {
7571
- if (typeof Buffer !== 'undefined' && Buffer.from) {
7572
- return Buffer.from(data, encoding);
7573
- }
7574
- let result;
7575
- if (Array.isArray(data)) {
7576
- result = new Uint8Array(data);
7577
- }
7578
- else if (typeof data === 'string') {
7579
- if (encoding === 'hex') {
7580
- const bytes = [];
7581
- for (let i = 0; i < data.length; i += 2) {
7582
- bytes.push(parseInt(data.substr(i, 2), 16));
7583
- }
7584
- result = new Uint8Array(bytes);
7585
- }
7586
- else {
7587
- // UTF-8 encoding
7588
- const encoder = new TextEncoder();
7589
- result = encoder.encode(data);
7590
- }
7591
- }
7592
- else if (data instanceof Uint8Array) {
7593
- result = data;
7594
- }
7595
- else {
7596
- result = new Uint8Array(data);
7597
- }
7598
- // Add toString method
7599
- result.toString = function (encoding) {
7600
- if (encoding === 'hex') {
7601
- return Array.from(this)
7602
- .map((b) => b.toString(16).padStart(2, '0'))
7603
- .join('');
7604
- }
7605
- else if (encoding === 'base64') {
7606
- // Simple base64 encoding
7607
- const bytes = this;
7608
- let binary = '';
7609
- for (let i = 0; i < bytes.length; i++) {
7610
- binary += String.fromCharCode(bytes[i]);
7611
- }
7612
- return btoa(binary);
7613
- }
7614
- else {
7615
- // UTF-8 decoding
7616
- const decoder = new TextDecoder();
7617
- return decoder.decode(this);
7618
- }
7619
- };
7620
- return result;
7621
- }
7622
- static concat(arrays) {
7623
- if (typeof Buffer !== 'undefined' && Buffer.concat) {
7624
- return Buffer.concat(arrays);
7625
- }
7626
- const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
7627
- const result = new Uint8Array(totalLength);
7628
- let offset = 0;
7629
- for (const arr of arrays) {
7630
- result.set(arr, offset);
7631
- offset += arr.length;
7632
- }
7633
- // Add toString method
7634
- result.toString = function (encoding) {
7635
- if (encoding === 'hex') {
7636
- return Array.from(this)
7637
- .map((b) => b.toString(16).padStart(2, '0'))
7638
- .join('');
7639
- }
7640
- else {
7641
- const decoder = new TextDecoder();
7642
- return decoder.decode(this);
7643
- }
7644
- };
7645
- return result;
7646
- }
7647
- }
7648
- // Use polyfill if Buffer is not available
7649
- const BufferCompat = typeof Buffer !== 'undefined' ? Buffer : BufferPolyfill;
7650
- // Cryptographic constants
7651
- const CRYPTO_CONSTANTS = {
7652
- ED25519_PRIVATE_KEY_LENGTH: 32,
7653
- ED25519_PUBLIC_KEY_LENGTH: 32,
7654
- MNEMONIC_ENTROPY_BITS: 128,
7655
- PKCS8_VERSION: 0,
7656
- // ASN.1 DER encoding
7657
- ASN1_SEQUENCE_TAG: 0x30,
7658
- ASN1_OCTET_STRING_TAG: 0x04,
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,
7678
- };
7679
- const TX_TYPE = {
7680
- TRANSFER: 0,
7681
- PRIVATE_KEY: 1,
7682
- };
7683
- const DECIMALS = 6;
7684
- class MmnClient {
7685
- constructor(config) {
7686
- this.requestId = 0;
7687
- this.config = {
7688
- timeout: 30000,
7689
- headers: {
7690
- 'Content-Type': 'application/json',
7691
- Accept: 'application/json',
7692
- },
7693
- ...config,
7694
- };
7695
- }
7696
- async makeRequest(method, params) {
7697
- const request = {
7698
- jsonrpc: '2.0',
7699
- method,
7700
- params,
7701
- id: ++this.requestId,
7702
- };
7703
- // Create AbortController for timeout
7704
- const controller = new AbortController();
7705
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
7706
- try {
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();
7721
- if (result.error) {
7722
- throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
7723
- }
7724
- return result.result;
7725
- }
7726
- catch (error) {
7727
- clearTimeout(timeoutId);
7728
- if (error instanceof Error) {
7729
- if (error.name === 'AbortError') {
7730
- throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
7731
- }
7732
- throw error;
7733
- }
7734
- throw new Error('Unknown error occurred');
7735
- }
7736
- }
7737
- /**
7738
- * Securely convert raw Ed25519 private key to PKCS#8 format
7739
- * @param raw - Raw 32-byte Ed25519 private key
7740
- * @returns PKCS#8 formatted private key in hex
7741
- * @throws Error if input validation fails
7742
- */
7743
- rawEd25519ToPkcs8Hex(raw) {
7744
- // Input validation
7745
- if (!BufferCompat.isBuffer(raw)) {
7746
- throw new Error('Private key must be a Buffer');
7747
- }
7748
- if (raw.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7749
- throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
7750
- }
7751
- try {
7752
- // Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
7753
- const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
7754
- const VERSION_BYTES = BufferCompat.from([
7755
- CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
7756
- 0x01, // Length of integer (1 byte)
7757
- CRYPTO_CONSTANTS.PKCS8_VERSION,
7758
- ]);
7759
- // Create algorithm identifier sequence (AlgorithmIdentifier)
7760
- const algorithmId = BufferCompat.concat([
7761
- BufferCompat.from([
7762
- CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
7763
- CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
7764
- ]),
7765
- ED25519_OID,
7766
- ]);
7767
- // Create private key octet string (wrapped Ed25519 private key)
7768
- const privateKeyOctetString = BufferCompat.concat([
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
7777
- raw,
7778
- ]);
7779
- // Create PKCS#8 body
7780
- const pkcs8Body = BufferCompat.concat([
7781
- VERSION_BYTES,
7782
- algorithmId,
7783
- privateKeyOctetString,
7784
- ]);
7785
- // Create final PKCS#8 structure
7786
- const pkcs8 = BufferCompat.concat([
7787
- BufferCompat.from([CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG]), // SEQUENCE
7788
- this.encodeLength(pkcs8Body.length),
7789
- pkcs8Body,
7790
- ]);
7791
- const result = pkcs8.toString('hex');
7792
- // Clear sensitive data from memory
7793
- raw.fill(0);
7794
- privateKeyOctetString.fill(0);
7795
- pkcs8Body.fill(0);
7796
- pkcs8.fill(0);
7797
- return result;
7798
- }
7799
- catch (error) {
7800
- // Clear sensitive data on error
7801
- raw.fill(0);
7802
- throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
7803
- }
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
- */
7813
- encodeLength(length) {
7814
- if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
7815
- return BufferCompat.from([length]);
7816
- }
7817
- const bytes = [];
7818
- let len = length;
7819
- while (len > 0) {
7820
- bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
7821
- len >>= 8;
7822
- }
7823
- return BufferCompat.from([
7824
- CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
7825
- ...bytes,
7826
- ]);
7827
- }
7828
- /**
7829
- * Generate secure entropy using multiple sources for maximum compatibility
7830
- * @returns Array of 32 random bytes
7831
- */
7832
- generateSecureEntropy() {
7833
- const entropy = [];
7834
- const targetLength = CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH;
7835
- // Use multiple entropy sources
7836
- const now = Date.now();
7837
- const performance = typeof window !== 'undefined' && window.performance
7838
- ? window.performance.now()
7839
- : now;
7840
- const random = Math.random();
7841
- // Create initial seed from timestamp and random
7842
- let seed = now + performance + random;
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
7845
- for (let i = 0; i < targetLength; i++) {
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
7855
- if (typeof CryptoJS !== 'undefined') {
7856
- const hashInput = seed.toString() + i.toString() + now.toString();
7857
- const hash = CryptoJS.SHA256(hashInput).toString();
7858
- // Extract first 8 hex characters (32 bits) from hash for mixing
7859
- seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
7860
- }
7861
- entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
7862
- }
7863
- return entropy;
7864
- }
7865
- /**
7866
- * Securely generate ephemeral key pair with proper entropy
7867
- * React Native compatible version with multiple fallbacks
7868
- * @returns Ephemeral key pair with private and public keys
7869
- * @throws Error if key generation fails
7870
- */
7871
- generateEphemeralKeyPair() {
7872
- try {
7873
- let seed;
7874
- // Try multiple approaches for mobile compatibility
7875
- try {
7876
- // Method 1: Try nacl.randomBytes first
7877
- seed = nacl.randomBytes(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7878
- }
7879
- catch (naclError) {
7880
- try {
7881
- // Method 2: Use crypto.getRandomValues if available (browsers/React Native)
7882
- if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
7883
- seed = new Uint8Array(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7884
- crypto.getRandomValues(seed);
7885
- }
7886
- else {
7887
- throw new Error('crypto.getRandomValues not available');
7888
- }
7889
- }
7890
- catch (cryptoError) {
7891
- // Method 3: Fallback to secure pseudo-random generation
7892
- const entropy = this.generateSecureEntropy();
7893
- seed = new Uint8Array(entropy);
7894
- }
7895
- }
7896
- // Validate seed length
7897
- if (seed.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7898
- throw new Error(`Invalid seed length: expected ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH}, got ${seed.length}`);
7899
- }
7900
- // Generate key pair from seed
7901
- const keyPair = nacl.sign.keyPair.fromSeed(seed);
7902
- const publicKeyBytes = keyPair.publicKey;
7903
- // Validate public key
7904
- if (publicKeyBytes.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
7905
- throw new Error(`Invalid public key length: expected ${CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH}, got ${publicKeyBytes.length}`);
7906
- }
7907
- // Convert private key to PKCS#8 format
7908
- const privateKeyHex = this.rawEd25519ToPkcs8Hex(BufferCompat.from(seed));
7909
- // Clear sensitive data
7910
- seed.fill(0);
7911
- keyPair.secretKey.fill(0);
7912
- return {
7913
- privateKey: privateKeyHex,
7914
- publicKey: bs58.encode(publicKeyBytes),
7915
- };
7916
- }
7917
- catch (error) {
7918
- throw new Error(`Failed to generate ephemeral key pair: ${error instanceof Error ? error.message : 'Unknown error'}`);
7919
- }
7920
- }
7921
- getAddressFromUserId(userId) {
7922
- // Use crypto-js for SHA-256 in React Native
7923
- const hash = CryptoJS.SHA256(userId).toString(CryptoJS.enc.Hex);
7924
- const hashBuffer = BufferCompat.from(hash, 'hex');
7925
- return bs58.encode(hashBuffer);
7926
- }
7927
- /**
7928
- * Create and sign a transaction message
7929
- */
7930
- createAndSignTx(params) {
7931
- if (!this.validateAddress(params.sender)) {
7932
- throw new Error('Invalid sender address');
7933
- }
7934
- if (!this.validateAddress(params.recipient)) {
7935
- throw new Error('Invalid recipient address');
7936
- }
7937
- if (params.sender === params.recipient) {
7938
- throw new Error('Sender and recipient addresses cannot be the same');
7939
- }
7940
- const txMsg = {
7941
- type: params.type,
7942
- sender: params.sender,
7943
- recipient: params.recipient,
7944
- amount: params.amount,
7945
- timestamp: params.timestamp || Date.now(),
7946
- text_data: params.textData || '',
7947
- nonce: params.nonce,
7948
- extra_info: JSON.stringify(params.extraInfo) || '',
7949
- zk_proof: params.zkProof || '',
7950
- zk_pub: params.zkPub || '',
7951
- };
7952
- const signature = this.signTransaction(txMsg, params.privateKey);
7953
- return {
7954
- tx_msg: txMsg,
7955
- signature,
7956
- };
7957
- }
7958
- /**
7959
- * Securely sign a transaction with Ed25519
7960
- * @param tx - Transaction message to sign
7961
- * @param privateKeyHex - Private key in PKCS#8 hex format
7962
- * @returns Base58 encoded signature
7963
- * @throws Error if signing fails
7964
- */
7965
- signTransaction(tx, privateKeyHex) {
7966
- try {
7967
- // Validate inputs
7968
- if (!tx || typeof tx !== 'object') {
7969
- throw new Error('Invalid transaction object');
7970
- }
7971
- if (!privateKeyHex || typeof privateKeyHex !== 'string') {
7972
- throw new Error('Invalid private key format');
7973
- }
7974
- // Serialize transaction data
7975
- const serializedData = this.serializeTransaction(tx);
7976
- if (!serializedData || serializedData.length === 0) {
7977
- throw new Error('Failed to serialize transaction');
7978
- }
7979
- // Extract the Ed25519 seed from the private key for nacl signing
7980
- const privateKeyDer = BufferCompat.from(privateKeyHex, 'hex');
7981
- if (privateKeyDer.length < CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7982
- throw new Error(`Invalid private key length: expected at least ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes, got ${privateKeyDer.length}`);
7983
- }
7984
- const seed = privateKeyDer.subarray(-CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH); // Last 32 bytes
7985
- const keyPair = nacl.sign.keyPair.fromSeed(seed);
7986
- // Validate key pair
7987
- if (!keyPair.publicKey || !keyPair.secretKey) {
7988
- throw new Error('Failed to create key pair from seed');
7989
- }
7990
- // Sign using Ed25519 (nacl) - constant time operation
7991
- const signature = nacl.sign.detached(serializedData, keyPair.secretKey);
7992
- if (!signature || signature.length === 0) {
7993
- throw new Error('Failed to generate signature');
7994
- }
7995
- // Clear sensitive data
7996
- privateKeyDer.fill(0);
7997
- seed.fill(0);
7998
- keyPair.secretKey.fill(0);
7999
- // Return signature based on transaction type
8000
- if (tx.type === TX_TYPE.PRIVATE_KEY) {
8001
- return bs58.encode(BufferCompat.from(signature));
8002
- }
8003
- // For regular transactions, wrap signature with public key
8004
- const userSig = {
8005
- PubKey: BufferCompat.from(keyPair.publicKey).toString('base64'),
8006
- Sig: BufferCompat.from(signature).toString('base64'),
8007
- };
8008
- return bs58.encode(BufferCompat.from(JSON.stringify(userSig)));
8009
- }
8010
- catch (error) {
8011
- throw new Error(`Transaction signing failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
8012
- }
8013
- }
8014
- /**
8015
- * Serialize transaction for signing
8016
- */
8017
- serializeTransaction(tx) {
8018
- const data = `${tx.type}|${tx.sender}|${tx.recipient}|${tx.amount}|${tx.text_data}|${tx.nonce}|${tx.extra_info}`;
8019
- return BufferCompat.from(data, 'utf8');
8020
- }
8021
- /**
8022
- * Add a signed transaction to the blockchain
8023
- */
8024
- async addTx(signedTx) {
8025
- return this.makeRequest('tx.addtx', signedTx);
8026
- }
8027
- /**
8028
- * Send a transaction (create, sign, and submit)
8029
- */
8030
- async sendTransaction(params) {
8031
- const fromAddress = this.getAddressFromUserId(params.sender);
8032
- const toAddress = this.getAddressFromUserId(params.recipient);
8033
- const signedTx = this.createAndSignTx({
8034
- ...params,
8035
- type: TX_TYPE.TRANSFER,
8036
- sender: fromAddress,
8037
- recipient: toAddress,
8038
- });
8039
- return this.addTx(signedTx);
8040
- }
8041
- async sendTransactionByAddress(params) {
8042
- const signedTx = this.createAndSignTx({
8043
- ...params,
8044
- type: TX_TYPE.TRANSFER,
8045
- });
8046
- return this.addTx(signedTx);
8047
- }
8048
- async sendTransactionByPrivateKey(params) {
8049
- const signedTx = this.createAndSignTx({
8050
- ...params,
8051
- type: TX_TYPE.PRIVATE_KEY,
8052
- });
8053
- return this.addTx(signedTx);
8054
- }
8055
- /**
8056
- * Get current nonce for an account
8057
- */
8058
- async getCurrentNonce(userId, tag = 'latest') {
8059
- const address = this.getAddressFromUserId(userId);
8060
- return this.makeRequest('account.getcurrentnonce', { address, tag });
8061
- }
8062
- async getAccountByUserId(userId) {
8063
- const address = this.getAddressFromUserId(userId);
8064
- return this.makeRequest('account.getaccount', {
8065
- address,
8066
- });
8067
- }
8068
- scaleAmountToDecimals(originalAmount, decimals = DECIMALS) {
8069
- let scaledAmount = BigInt(originalAmount);
8070
- for (let i = 0; i < decimals; i++) {
8071
- scaledAmount = scaledAmount * BigInt(10);
8072
- }
8073
- return scaledAmount.toString();
8074
- }
8075
- validateAddress(addr) {
8076
- const decoded = bs58.decode(addr);
8077
- if (!decoded ||
8078
- decoded.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
8079
- return false;
8080
- }
8081
- return true;
8082
- }
8083
- validateAmount(balance, amount) {
8084
- const bigBalance = BigInt(balance);
8085
- const bigAmount = BigInt(typeof amount === 'number' ? this.scaleAmountToDecimals(amount) : amount);
8086
- return bigAmount <= bigBalance;
8087
- }
8088
- }
8089
- function createMmnClient(config) {
8090
- return new MmnClient(config);
7582
+ var CryptoJS = cryptoJs.exports;
7583
+
7584
+ // MMN Client
7585
+ // Buffer polyfill for mobile environments
7586
+ class BufferPolyfill {
7587
+ static isBuffer(obj) {
7588
+ if (typeof Buffer !== 'undefined' && Buffer.isBuffer) {
7589
+ return Buffer.isBuffer(obj);
7590
+ }
7591
+ return obj instanceof Uint8Array;
7592
+ }
7593
+ static from(data, encoding) {
7594
+ if (typeof Buffer !== 'undefined' && Buffer.from) {
7595
+ return Buffer.from(data, encoding);
7596
+ }
7597
+ let result;
7598
+ if (Array.isArray(data)) {
7599
+ result = new Uint8Array(data);
7600
+ }
7601
+ else if (typeof data === 'string') {
7602
+ if (encoding === 'hex') {
7603
+ const bytes = [];
7604
+ for (let i = 0; i < data.length; i += 2) {
7605
+ bytes.push(parseInt(data.substr(i, 2), 16));
7606
+ }
7607
+ result = new Uint8Array(bytes);
7608
+ }
7609
+ else {
7610
+ // UTF-8 encoding
7611
+ const encoder = new TextEncoder();
7612
+ result = encoder.encode(data);
7613
+ }
7614
+ }
7615
+ else if (data instanceof Uint8Array) {
7616
+ result = data;
7617
+ }
7618
+ else {
7619
+ result = new Uint8Array(data);
7620
+ }
7621
+ // Add toString method
7622
+ result.toString = function (encoding) {
7623
+ if (encoding === 'hex') {
7624
+ return Array.from(this)
7625
+ .map((b) => b.toString(16).padStart(2, '0'))
7626
+ .join('');
7627
+ }
7628
+ else if (encoding === 'base64') {
7629
+ // Simple base64 encoding
7630
+ const bytes = this;
7631
+ let binary = '';
7632
+ for (let i = 0; i < bytes.length; i++) {
7633
+ binary += String.fromCharCode(bytes[i]);
7634
+ }
7635
+ return btoa(binary);
7636
+ }
7637
+ else {
7638
+ // UTF-8 decoding
7639
+ const decoder = new TextDecoder();
7640
+ return decoder.decode(this);
7641
+ }
7642
+ };
7643
+ return result;
7644
+ }
7645
+ static concat(arrays) {
7646
+ if (typeof Buffer !== 'undefined' && Buffer.concat) {
7647
+ return Buffer.concat(arrays);
7648
+ }
7649
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
7650
+ const result = new Uint8Array(totalLength);
7651
+ let offset = 0;
7652
+ for (const arr of arrays) {
7653
+ result.set(arr, offset);
7654
+ offset += arr.length;
7655
+ }
7656
+ // Add toString method
7657
+ result.toString = function (encoding) {
7658
+ if (encoding === 'hex') {
7659
+ return Array.from(this)
7660
+ .map((b) => b.toString(16).padStart(2, '0'))
7661
+ .join('');
7662
+ }
7663
+ else {
7664
+ const decoder = new TextDecoder();
7665
+ return decoder.decode(this);
7666
+ }
7667
+ };
7668
+ return result;
7669
+ }
7670
+ }
7671
+ // Use polyfill if Buffer is not available
7672
+ const BufferCompat = typeof Buffer !== 'undefined' ? Buffer : BufferPolyfill;
7673
+ // Cryptographic constants
7674
+ const CRYPTO_CONSTANTS = {
7675
+ ED25519_PRIVATE_KEY_LENGTH: 32,
7676
+ ED25519_PUBLIC_KEY_LENGTH: 32,
7677
+ MNEMONIC_ENTROPY_BITS: 128,
7678
+ PKCS8_VERSION: 0,
7679
+ // ASN.1 DER encoding
7680
+ ASN1_SEQUENCE_TAG: 0x30,
7681
+ ASN1_OCTET_STRING_TAG: 0x04,
7682
+ ASN1_INTEGER_TAG: 0x02,
7683
+ ASN1_LENGTH: 0x80,
7684
+ // Ed25519 OID bytes: 1.3.101.112 (RFC 8410)
7685
+ ED25519_OID_BYTES: [0x06, 0x03, 0x2b, 0x65, 0x70],
7686
+ // PKCS#8 structure length constants
7687
+ PKCS8_ALGORITHM_ID_LENGTH: 0x0b,
7688
+ PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH: 0x22,
7689
+ PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH: 0x20, // Inner OCTET STRING length (32 bytes)
7690
+ };
7691
+ // PRNG (Pseudo-Random Number Generator) constants
7692
+ const PRNG_CONSTANTS = {
7693
+ // Numerical Recipes LCG
7694
+ LCG_MULTIPLIER: 1664525,
7695
+ LCG_INCREMENT: 1013904223,
7696
+ LCG_MODULUS: 4294967296,
7697
+ TIMESTAMP_MULTIPLIER: 2654435761,
7698
+ HASH_SUBSTRING_LENGTH: 8,
7699
+ BYTE_SHIFT: 24,
7700
+ BYTE_MASK: 0xff,
7701
+ };
7702
+ const TX_TYPE = {
7703
+ TRANSFER: 0,
7704
+ PRIVATE_KEY: 1,
7705
+ };
7706
+ const DECIMALS = 6;
7707
+ class MmnClient {
7708
+ constructor(config) {
7709
+ this.requestId = 0;
7710
+ this.config = {
7711
+ timeout: 30000,
7712
+ headers: {
7713
+ 'Content-Type': 'application/json',
7714
+ Accept: 'application/json',
7715
+ },
7716
+ ...config,
7717
+ };
7718
+ }
7719
+ async makeRequest(method, params) {
7720
+ const request = {
7721
+ jsonrpc: '2.0',
7722
+ method,
7723
+ params,
7724
+ id: ++this.requestId,
7725
+ };
7726
+ // Create AbortController for timeout
7727
+ const controller = new AbortControllerPolyfill();
7728
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
7729
+ try {
7730
+ const requestOptions = {
7731
+ method: 'POST',
7732
+ mode: 'cors',
7733
+ credentials: 'omit',
7734
+ signal: controller.signal,
7735
+ headers: this.config.headers || {},
7736
+ body: JSON.stringify(request),
7737
+ };
7738
+ const response = await fetchPolyfill(this.config.baseUrl, requestOptions);
7739
+ clearTimeout(timeoutId);
7740
+ if (!response.ok) {
7741
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
7742
+ }
7743
+ const result = await response.json();
7744
+ if (result.error) {
7745
+ throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
7746
+ }
7747
+ return result.result;
7748
+ }
7749
+ catch (error) {
7750
+ clearTimeout(timeoutId);
7751
+ if (error instanceof Error) {
7752
+ if (error.name === 'AbortError') {
7753
+ throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
7754
+ }
7755
+ throw error;
7756
+ }
7757
+ throw new Error('Unknown error occurred');
7758
+ }
7759
+ }
7760
+ /**
7761
+ * Securely convert raw Ed25519 private key to PKCS#8 format
7762
+ * @param raw - Raw 32-byte Ed25519 private key
7763
+ * @returns PKCS#8 formatted private key in hex
7764
+ * @throws Error if input validation fails
7765
+ */
7766
+ rawEd25519ToPkcs8Hex(raw) {
7767
+ // Input validation
7768
+ if (!BufferCompat.isBuffer(raw)) {
7769
+ throw new Error('Private key must be a Buffer');
7770
+ }
7771
+ if (raw.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7772
+ throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
7773
+ }
7774
+ try {
7775
+ // Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
7776
+ const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
7777
+ const VERSION_BYTES = BufferCompat.from([
7778
+ CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
7779
+ 0x01,
7780
+ CRYPTO_CONSTANTS.PKCS8_VERSION,
7781
+ ]);
7782
+ // Create algorithm identifier sequence (AlgorithmIdentifier)
7783
+ const algorithmId = BufferCompat.concat([
7784
+ BufferCompat.from([
7785
+ CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
7786
+ CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
7787
+ ]),
7788
+ ED25519_OID,
7789
+ ]);
7790
+ // Create private key octet string (wrapped Ed25519 private key)
7791
+ const privateKeyOctetString = BufferCompat.concat([
7792
+ BufferCompat.from([
7793
+ CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7794
+ CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH,
7795
+ ]),
7796
+ BufferCompat.from([
7797
+ CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7798
+ CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH,
7799
+ ]),
7800
+ raw,
7801
+ ]);
7802
+ // Create PKCS#8 body
7803
+ const pkcs8Body = BufferCompat.concat([
7804
+ VERSION_BYTES,
7805
+ algorithmId,
7806
+ privateKeyOctetString,
7807
+ ]);
7808
+ // Create final PKCS#8 structure
7809
+ const pkcs8 = BufferCompat.concat([
7810
+ BufferCompat.from([CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG]),
7811
+ this.encodeLength(pkcs8Body.length),
7812
+ pkcs8Body,
7813
+ ]);
7814
+ const result = pkcs8.toString('hex');
7815
+ // Clear sensitive data from memory
7816
+ raw.fill(0);
7817
+ privateKeyOctetString.fill(0);
7818
+ pkcs8Body.fill(0);
7819
+ pkcs8.fill(0);
7820
+ return result;
7821
+ }
7822
+ catch (error) {
7823
+ // Clear sensitive data on error
7824
+ raw.fill(0);
7825
+ throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
7826
+ }
7827
+ }
7828
+ /**
7829
+ * Encode length in ASN.1 DER format
7830
+ * ASN.1 length encoding rules:
7831
+ * - Short form (0-127): single byte with the length value
7832
+ * - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
7833
+ * @param length - The length value to encode
7834
+ * @returns ASN.1 DER encoded length bytes
7835
+ */
7836
+ encodeLength(length) {
7837
+ if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
7838
+ return BufferCompat.from([length]);
7839
+ }
7840
+ const bytes = [];
7841
+ let len = length;
7842
+ while (len > 0) {
7843
+ bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
7844
+ len >>= 8;
7845
+ }
7846
+ return BufferCompat.from([
7847
+ CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
7848
+ ...bytes,
7849
+ ]);
7850
+ }
7851
+ /**
7852
+ * Generate secure entropy using multiple sources for maximum compatibility
7853
+ * @returns Array of 32 random bytes
7854
+ */
7855
+ generateSecureEntropy() {
7856
+ const entropy = [];
7857
+ const targetLength = CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH;
7858
+ // Use multiple entropy sources
7859
+ const now = Date.now();
7860
+ const performance = typeof window !== 'undefined' && window.performance
7861
+ ? window.performance.now()
7862
+ : now;
7863
+ const random = Math.random();
7864
+ // Create initial seed from timestamp and random
7865
+ let seed = now + performance + random;
7866
+ // Generate bytes using Linear Congruential Generator (LCG) with multiple entropy sources
7867
+ // This provides a fallback Pseudorandom Number Generator (PRNG) when crypto.getRandomValues is not available
7868
+ for (let i = 0; i < targetLength; i++) {
7869
+ // Xₙ₊₁ = (a * Xₙ + c) mod m
7870
+ seed =
7871
+ (seed * PRNG_CONSTANTS.LCG_MULTIPLIER + PRNG_CONSTANTS.LCG_INCREMENT) %
7872
+ PRNG_CONSTANTS.LCG_MODULUS;
7873
+ // Mix with timestamp to add time-based entropy
7874
+ seed ^= (now + i) * PRNG_CONSTANTS.TIMESTAMP_MULTIPLIER;
7875
+ // Mix with Math.random() for additional browser-provided randomness
7876
+ seed ^= Math.floor(Math.random() * PRNG_CONSTANTS.LCG_MODULUS);
7877
+ // Additional cryptographic mixing using SHA256 if CryptoJS is available
7878
+ if (typeof CryptoJS !== 'undefined') {
7879
+ const hashInput = seed.toString() + i.toString() + now.toString();
7880
+ const hash = CryptoJS.SHA256(hashInput).toString();
7881
+ // Extract first 8 hex characters (32 bits) from hash for mixing
7882
+ seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
7883
+ }
7884
+ entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
7885
+ }
7886
+ return entropy;
7887
+ }
7888
+ /**
7889
+ * Securely generate ephemeral key pair with proper entropy
7890
+ * React Native compatible version with multiple fallbacks
7891
+ * @returns Ephemeral key pair with private and public keys
7892
+ * @throws Error if key generation fails
7893
+ */
7894
+ generateEphemeralKeyPair() {
7895
+ try {
7896
+ let seed;
7897
+ // Try multiple approaches for mobile compatibility
7898
+ try {
7899
+ // Method 1: Try nacl.randomBytes first
7900
+ seed = nacl.randomBytes(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7901
+ }
7902
+ catch (naclError) {
7903
+ try {
7904
+ // Method 2: Use crypto.getRandomValues if available (browsers/React Native)
7905
+ if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
7906
+ seed = new Uint8Array(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7907
+ crypto.getRandomValues(seed);
7908
+ }
7909
+ else {
7910
+ throw new Error('crypto.getRandomValues not available');
7911
+ }
7912
+ }
7913
+ catch (cryptoError) {
7914
+ // Method 3: Fallback to secure pseudo-random generation
7915
+ const entropy = this.generateSecureEntropy();
7916
+ seed = new Uint8Array(entropy);
7917
+ }
7918
+ }
7919
+ // Validate seed length
7920
+ if (seed.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7921
+ throw new Error(`Invalid seed length: expected ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH}, got ${seed.length}`);
7922
+ }
7923
+ // Generate key pair from seed
7924
+ const keyPair = nacl.sign.keyPair.fromSeed(seed);
7925
+ const publicKeyBytes = keyPair.publicKey;
7926
+ // Validate public key
7927
+ if (publicKeyBytes.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
7928
+ throw new Error(`Invalid public key length: expected ${CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH}, got ${publicKeyBytes.length}`);
7929
+ }
7930
+ // Convert private key to PKCS#8 format
7931
+ const privateKeyHex = this.rawEd25519ToPkcs8Hex(BufferCompat.from(seed));
7932
+ // Clear sensitive data
7933
+ seed.fill(0);
7934
+ keyPair.secretKey.fill(0);
7935
+ return {
7936
+ privateKey: privateKeyHex,
7937
+ publicKey: bs58.encode(publicKeyBytes),
7938
+ };
7939
+ }
7940
+ catch (error) {
7941
+ throw new Error(`Failed to generate ephemeral key pair: ${error instanceof Error ? error.message : 'Unknown error'}`);
7942
+ }
7943
+ }
7944
+ getAddressFromUserId(userId) {
7945
+ // Use crypto-js for SHA-256 in React Native
7946
+ const hash = CryptoJS.SHA256(userId).toString(CryptoJS.enc.Hex);
7947
+ const hashBuffer = BufferCompat.from(hash, 'hex');
7948
+ return bs58.encode(hashBuffer);
7949
+ }
7950
+ /**
7951
+ * Create and sign a transaction message
7952
+ */
7953
+ createAndSignTx(params) {
7954
+ if (!this.validateAddress(params.sender)) {
7955
+ throw new Error('Invalid sender address');
7956
+ }
7957
+ if (!this.validateAddress(params.recipient)) {
7958
+ throw new Error('Invalid recipient address');
7959
+ }
7960
+ if (params.sender === params.recipient) {
7961
+ throw new Error('Sender and recipient addresses cannot be the same');
7962
+ }
7963
+ const txMsg = {
7964
+ type: params.type,
7965
+ sender: params.sender,
7966
+ recipient: params.recipient,
7967
+ amount: params.amount,
7968
+ timestamp: params.timestamp || Date.now(),
7969
+ text_data: params.textData || '',
7970
+ nonce: params.nonce,
7971
+ extra_info: JSON.stringify(params.extraInfo) || '',
7972
+ zk_proof: params.zkProof || '',
7973
+ zk_pub: params.zkPub || '',
7974
+ };
7975
+ const signature = this.signTransaction(txMsg, params.privateKey);
7976
+ return {
7977
+ tx_msg: txMsg,
7978
+ signature,
7979
+ };
7980
+ }
7981
+ /**
7982
+ * Securely sign a transaction with Ed25519
7983
+ * @param tx - Transaction message to sign
7984
+ * @param privateKeyHex - Private key in PKCS#8 hex format
7985
+ * @returns Base58 encoded signature
7986
+ * @throws Error if signing fails
7987
+ */
7988
+ signTransaction(tx, privateKeyHex) {
7989
+ try {
7990
+ // Validate inputs
7991
+ if (!tx || typeof tx !== 'object') {
7992
+ throw new Error('Invalid transaction object');
7993
+ }
7994
+ if (!privateKeyHex || typeof privateKeyHex !== 'string') {
7995
+ throw new Error('Invalid private key format');
7996
+ }
7997
+ // Serialize transaction data
7998
+ const serializedData = this.serializeTransaction(tx);
7999
+ if (!serializedData || serializedData.length === 0) {
8000
+ throw new Error('Failed to serialize transaction');
8001
+ }
8002
+ // Extract the Ed25519 seed from the private key for nacl signing
8003
+ const privateKeyDer = BufferCompat.from(privateKeyHex, 'hex');
8004
+ if (privateKeyDer.length < CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
8005
+ throw new Error(`Invalid private key length: expected at least ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes, got ${privateKeyDer.length}`);
8006
+ }
8007
+ const seed = privateKeyDer.subarray(-CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH); // Last 32 bytes
8008
+ const keyPair = nacl.sign.keyPair.fromSeed(seed);
8009
+ // Validate key pair
8010
+ if (!keyPair.publicKey || !keyPair.secretKey) {
8011
+ throw new Error('Failed to create key pair from seed');
8012
+ }
8013
+ // Sign using Ed25519 (nacl) - constant time operation
8014
+ const signature = nacl.sign.detached(serializedData, keyPair.secretKey);
8015
+ if (!signature || signature.length === 0) {
8016
+ throw new Error('Failed to generate signature');
8017
+ }
8018
+ // Clear sensitive data
8019
+ privateKeyDer.fill(0);
8020
+ seed.fill(0);
8021
+ keyPair.secretKey.fill(0);
8022
+ // Return signature based on transaction type
8023
+ if (tx.type === TX_TYPE.PRIVATE_KEY) {
8024
+ return bs58.encode(BufferCompat.from(signature));
8025
+ }
8026
+ // For regular transactions, wrap signature with public key
8027
+ const userSig = {
8028
+ PubKey: BufferCompat.from(keyPair.publicKey).toString('base64'),
8029
+ Sig: BufferCompat.from(signature).toString('base64'),
8030
+ };
8031
+ return bs58.encode(BufferCompat.from(JSON.stringify(userSig)));
8032
+ }
8033
+ catch (error) {
8034
+ throw new Error(`Transaction signing failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
8035
+ }
8036
+ }
8037
+ /**
8038
+ * Serialize transaction for signing
8039
+ */
8040
+ serializeTransaction(tx) {
8041
+ const data = `${tx.type}|${tx.sender}|${tx.recipient}|${tx.amount}|${tx.text_data}|${tx.nonce}|${tx.extra_info}`;
8042
+ return BufferCompat.from(data, 'utf8');
8043
+ }
8044
+ /**
8045
+ * Add a signed transaction to the blockchain
8046
+ */
8047
+ async addTx(signedTx) {
8048
+ return this.makeRequest('tx.addtx', signedTx);
8049
+ }
8050
+ /**
8051
+ * Send a transaction (create, sign, and submit)
8052
+ */
8053
+ async sendTransaction(params) {
8054
+ const fromAddress = this.getAddressFromUserId(params.sender);
8055
+ const toAddress = this.getAddressFromUserId(params.recipient);
8056
+ const signedTx = this.createAndSignTx({
8057
+ ...params,
8058
+ type: TX_TYPE.TRANSFER,
8059
+ sender: fromAddress,
8060
+ recipient: toAddress,
8061
+ });
8062
+ return this.addTx(signedTx);
8063
+ }
8064
+ async sendTransactionByAddress(params) {
8065
+ const signedTx = this.createAndSignTx({
8066
+ ...params,
8067
+ type: TX_TYPE.TRANSFER,
8068
+ });
8069
+ return this.addTx(signedTx);
8070
+ }
8071
+ async sendTransactionByPrivateKey(params) {
8072
+ const signedTx = this.createAndSignTx({
8073
+ ...params,
8074
+ type: TX_TYPE.PRIVATE_KEY,
8075
+ });
8076
+ return this.addTx(signedTx);
8077
+ }
8078
+ /**
8079
+ * Get current nonce for an account
8080
+ */
8081
+ async getCurrentNonce(userId, tag = 'latest') {
8082
+ const address = this.getAddressFromUserId(userId);
8083
+ return this.makeRequest('account.getcurrentnonce', { address, tag });
8084
+ }
8085
+ async getAccountByUserId(userId) {
8086
+ const address = this.getAddressFromUserId(userId);
8087
+ return this.makeRequest('account.getaccount', {
8088
+ address,
8089
+ });
8090
+ }
8091
+ scaleAmountToDecimals(originalAmount, decimals = DECIMALS) {
8092
+ let scaledAmount = BigInt(originalAmount);
8093
+ for (let i = 0; i < decimals; i++) {
8094
+ scaledAmount = scaledAmount * BigInt(10);
8095
+ }
8096
+ return scaledAmount.toString();
8097
+ }
8098
+ validateAddress(addr) {
8099
+ const decoded = bs58.decode(addr);
8100
+ if (!decoded ||
8101
+ decoded.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
8102
+ return false;
8103
+ }
8104
+ return true;
8105
+ }
8106
+ validateAmount(balance, amount) {
8107
+ const bigBalance = BigInt(balance);
8108
+ const bigAmount = BigInt(typeof amount === 'number' ? this.scaleAmountToDecimals(amount) : amount);
8109
+ return bigAmount <= bigBalance;
8110
+ }
8111
+ }
8112
+ function createMmnClient(config) {
8113
+ return new MmnClient(config);
8091
8114
  }
8092
8115
 
8093
- // --- JSON-RPC Types ---
8094
- var ETransferType;
8095
- (function (ETransferType) {
8096
- ETransferType["GiveCoffee"] = "give_coffee";
8097
- ETransferType["TransferToken"] = "transfer_token";
8098
- ETransferType["UnlockItem"] = "unlock_item";
8099
- })(ETransferType || (ETransferType = {}));
8100
- var EZkClientType;
8101
- (function (EZkClientType) {
8102
- EZkClientType["MEZON"] = "mezon";
8103
- EZkClientType["OAUTH"] = "oauth";
8116
+ // --- JSON-RPC Types ---
8117
+ var ETransferType;
8118
+ (function (ETransferType) {
8119
+ ETransferType["GiveCoffee"] = "give_coffee";
8120
+ ETransferType["TransferToken"] = "transfer_token";
8121
+ ETransferType["UnlockItem"] = "unlock_item";
8122
+ })(ETransferType || (ETransferType = {}));
8123
+ var EZkClientType;
8124
+ (function (EZkClientType) {
8125
+ EZkClientType["MEZON"] = "mezon";
8126
+ EZkClientType["OAUTH"] = "oauth";
8104
8127
  })(EZkClientType || (EZkClientType = {}));
8105
8128
 
8106
- class ZkClient {
8107
- constructor(config) {
8108
- this.endpoint = config.endpoint;
8109
- this.timeout = config.timeout || 30000;
8110
- this.headers = {
8111
- Accept: 'application/json',
8112
- 'Content-Type': 'application/json',
8113
- ...(config.headers || {}),
8114
- };
8115
- }
8116
- async makeRequest(method, path, params, body) {
8117
- let url = `${this.endpoint}/${path}`;
8118
- // Add query parameters for GET requests
8119
- if (params && Object.keys(params).length > 0) {
8120
- const searchParams = new URLSearchParams();
8121
- Object.entries(params).forEach(([key, value]) => {
8122
- searchParams.append(key, String(value));
8123
- });
8124
- url += `?${searchParams.toString()}`;
8125
- }
8126
- // Create AbortController for timeout
8127
- const controller = new AbortController();
8128
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8129
- try {
8130
- const requestOptions = {
8131
- method,
8132
- mode: 'cors',
8133
- credentials: 'omit',
8134
- signal: controller.signal,
8135
- headers: this.headers,
8136
- };
8137
- // Add body for POST requests
8138
- if (method === 'POST' && body) {
8139
- requestOptions.body = JSON.stringify(body);
8140
- }
8141
- const response = await fetch(url, requestOptions);
8142
- clearTimeout(timeoutId);
8143
- if (!response.ok) {
8144
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
8145
- }
8146
- const data = await response.json();
8147
- return data;
8148
- }
8149
- catch (error) {
8150
- clearTimeout(timeoutId);
8151
- if (error instanceof Error) {
8152
- if (error.name === 'AbortError') {
8153
- throw new Error(`Request timeout after ${this.timeout}ms`);
8154
- }
8155
- throw error;
8156
- }
8157
- throw new Error('Request failed');
8158
- }
8159
- }
8160
- async getZkProofs({ userId, ephemeralPublicKey, jwt, address, clientType = EZkClientType.MEZON, }) {
8161
- const path = `prove`;
8162
- const res = await this.makeRequest('POST', path, undefined, {
8163
- user_id: userId,
8164
- ephemeral_pk: ephemeralPublicKey,
8165
- jwt,
8166
- address,
8167
- client_type: clientType,
8168
- });
8169
- return res.data;
8170
- }
8129
+ class ZkClient {
8130
+ constructor(config) {
8131
+ this.endpoint = config.endpoint;
8132
+ this.timeout = config.timeout || 30000;
8133
+ this.headers = {
8134
+ Accept: 'application/json',
8135
+ 'Content-Type': 'application/json',
8136
+ ...(config.headers || {}),
8137
+ };
8138
+ }
8139
+ async makeRequest(method, path, params, body) {
8140
+ let url = `${this.endpoint}/${path}`;
8141
+ // Add query parameters for GET requests
8142
+ if (params && Object.keys(params).length > 0) {
8143
+ const searchParams = new URLSearchParams();
8144
+ Object.entries(params).forEach(([key, value]) => {
8145
+ searchParams.append(key, String(value));
8146
+ });
8147
+ url += `?${searchParams.toString()}`;
8148
+ }
8149
+ // Create AbortController for timeout
8150
+ const controller = new AbortControllerPolyfill();
8151
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8152
+ try {
8153
+ const requestOptions = {
8154
+ method,
8155
+ mode: 'cors',
8156
+ credentials: 'omit',
8157
+ signal: controller.signal,
8158
+ headers: this.headers,
8159
+ };
8160
+ // Add body for POST requests
8161
+ if (method === 'POST' && body) {
8162
+ requestOptions.body = JSON.stringify(body);
8163
+ }
8164
+ const response = await fetchPolyfill(url, requestOptions);
8165
+ clearTimeout(timeoutId);
8166
+ if (!response.ok) {
8167
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
8168
+ }
8169
+ const data = await response.json();
8170
+ return data;
8171
+ }
8172
+ catch (error) {
8173
+ clearTimeout(timeoutId);
8174
+ if (error instanceof Error) {
8175
+ if (error.name === 'AbortError') {
8176
+ throw new Error(`Request timeout after ${this.timeout}ms`);
8177
+ }
8178
+ throw error;
8179
+ }
8180
+ throw new Error('Request failed');
8181
+ }
8182
+ }
8183
+ async getZkProofs({ userId, ephemeralPublicKey, jwt, address, clientType = EZkClientType.MEZON, }) {
8184
+ const path = `prove`;
8185
+ const res = await this.makeRequest('POST', path, undefined, {
8186
+ user_id: userId,
8187
+ ephemeral_pk: ephemeralPublicKey,
8188
+ jwt,
8189
+ address,
8190
+ client_type: clientType,
8191
+ });
8192
+ return res.data;
8193
+ }
8171
8194
  }
8172
8195
 
8173
8196
  export { ETransferType, EZkClientType, IndexerClient, MmnClient, ZkClient, createMmnClient };