mmn-client-js 1.0.14-node14 → 1.0.15

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.js CHANGED
@@ -1,169 +1,163 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var bs58 = require('bs58');
6
4
  var nacl = require('tweetnacl');
7
5
 
8
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
-
10
- var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
11
- var nacl__default = /*#__PURE__*/_interopDefaultLegacy(nacl);
12
-
13
- // Fetch and AbortController polyfills for Node 14 compatibility
14
- /* eslint-disable @typescript-eslint/no-require-imports */
15
- let fetchPolyfill;
16
- let AbortControllerPolyfill;
17
- if (typeof fetch === 'undefined') {
18
- try {
19
- // Use node-fetch in Node.js environments that don't have global fetch
20
- fetchPolyfill = require('node-fetch');
21
- }
22
- catch {
23
- throw new Error('node-fetch is required for Node 14 compatibility. Please install it: npm install node-fetch@2');
24
- }
25
- }
26
- else {
27
- fetchPolyfill = fetch;
28
- }
29
- if (typeof AbortController === 'undefined') {
30
- try {
31
- // Use abort-controller in environments that don't have AbortController
32
- AbortControllerPolyfill = require('abort-controller');
33
- }
34
- catch {
35
- throw new Error('abort-controller is required for Node 14 compatibility. Please install it: npm install abort-controller');
36
- }
37
- }
38
- else {
39
- AbortControllerPolyfill = AbortController;
40
- }
41
-
42
- const API_FILTER_PARAMS = {
43
- ALL: 0,
44
- SENT: 2,
45
- RECEIVED: 1,
46
- };
47
- class IndexerClient {
48
- constructor(config) {
49
- this.endpoint = config.endpoint;
50
- this.chainId = config.chainId;
51
- this.timeout = config.timeout || 30000;
52
- // Minimal headers to avoid CORS preflight issues
53
- this.headers = {
54
- Accept: 'application/json',
55
- ...(config.headers || {}),
56
- };
57
- }
58
- /**
59
- * Make HTTP request with automatic CORS handling
60
- * Works out-of-the-box without CORS configuration
61
- * @param method - HTTP method (GET or POST)
62
- * @param path - API endpoint path
63
- * @param params - URL query parameters
64
- * @param body - Request body for POST requests
65
- * @returns Promise resolving to response data
66
- */
67
- async makeRequest(method, path, params, body) {
68
- // Build full URL
69
- let url = `${this.endpoint}/${path}`;
70
- // Add query parameters
71
- if (params && Object.keys(params).length > 0) {
72
- const searchParams = new URLSearchParams();
73
- Object.entries(params).forEach(([key, value]) => {
74
- searchParams.append(key, String(value));
75
- });
76
- url += `?${searchParams.toString()}`;
77
- }
78
- // Create AbortController for timeout
79
- const controller = new AbortControllerPolyfill();
80
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
81
- try {
82
- // Simple fetch with automatic CORS handling
83
- const requestOptions = {
84
- method,
85
- mode: 'cors',
86
- credentials: 'omit',
87
- signal: controller.signal,
88
- headers: {
89
- Accept: 'application/json',
90
- ...this.headers,
91
- },
92
- };
93
- // Add body and Content-Type for POST requests
94
- if (method === 'POST' && body) {
95
- requestOptions.body = JSON.stringify(body);
96
- requestOptions.headers['Content-Type'] =
97
- 'application/json';
98
- }
99
- const response = await fetchPolyfill(url, requestOptions);
100
- clearTimeout(timeoutId);
101
- // Handle response errors
102
- if (!response.ok) {
103
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
104
- }
105
- // Parse JSON response
106
- const data = await response.json();
107
- return data;
108
- }
109
- catch (error) {
110
- clearTimeout(timeoutId);
111
- if (error instanceof Error) {
112
- if (error.name === 'AbortError') {
113
- throw new Error(`Request timeout after ${this.timeout}ms`);
114
- }
115
- throw error;
116
- }
117
- throw new Error('Request failed');
118
- }
119
- }
120
- async getTransactionByHash(hash) {
121
- const path = `${this.chainId}/tx/${hash}/detail`;
122
- const res = await this.makeRequest('GET', path);
123
- return res.data.transaction;
124
- }
125
- async getTransactionByWallet(wallet, page = 1, limit = 50, filter, sortBy = 'transaction_timestamp', sortOrder = 'desc') {
126
- if (!wallet) {
127
- throw new Error('wallet address cannot be empty');
128
- }
129
- if (page < 1)
130
- page = 1;
131
- if (limit <= 0)
132
- limit = 50;
133
- if (limit > 1000)
134
- limit = 1000;
135
- const params = {
136
- page: page - 1,
137
- limit,
138
- sort_by: sortBy,
139
- sort_order: sortOrder,
140
- };
141
- switch (filter) {
142
- case API_FILTER_PARAMS.ALL:
143
- params['wallet_address'] = wallet;
144
- break;
145
- case API_FILTER_PARAMS.SENT:
146
- params['filter_from_address'] = wallet;
147
- break;
148
- case API_FILTER_PARAMS.RECEIVED:
149
- params['filter_to_address'] = wallet;
150
- break;
151
- }
152
- const path = `${this.chainId}/transactions`;
153
- return this.makeRequest('GET', path, params);
154
- }
155
- async getWalletDetail(wallet) {
156
- if (!wallet) {
157
- throw new Error('wallet address cannot be empty');
158
- }
159
- const path = `${this.chainId}/wallets/${wallet}/detail`;
160
- const res = await this.makeRequest('GET', path);
161
- return res.data;
162
- }
6
+ const API_FILTER_PARAMS = {
7
+ ALL: 0,
8
+ SENT: 2,
9
+ RECEIVED: 1,
10
+ };
11
+ class IndexerClient {
12
+ constructor(config) {
13
+ this.endpoint = config.endpoint;
14
+ this.chainId = config.chainId;
15
+ this.timeout = config.timeout || 30000;
16
+ // Minimal headers to avoid CORS preflight issues
17
+ this.headers = {
18
+ Accept: 'application/json',
19
+ ...(config.headers || {}),
20
+ };
21
+ }
22
+ /**
23
+ * Make HTTP request with automatic CORS handling
24
+ * Works out-of-the-box without CORS configuration
25
+ * @param method - HTTP method (GET or POST)
26
+ * @param path - API endpoint path
27
+ * @param params - URL query parameters
28
+ * @param body - Request body for POST requests
29
+ * @returns Promise resolving to response data
30
+ */
31
+ async makeRequest(method, path, params, body) {
32
+ // Build full URL
33
+ let url = `${this.endpoint}/${path}`;
34
+ // Add query parameters
35
+ if (params && Object.keys(params).length > 0) {
36
+ const searchParams = new URLSearchParams();
37
+ Object.entries(params).forEach(([key, value]) => {
38
+ searchParams.append(key, String(value));
39
+ });
40
+ url += `?${searchParams.toString()}`;
41
+ }
42
+ // Create AbortController for timeout
43
+ const controller = new AbortController();
44
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
45
+ try {
46
+ // Simple fetch with automatic CORS handling
47
+ const requestOptions = {
48
+ method,
49
+ mode: 'cors',
50
+ credentials: 'omit',
51
+ signal: controller.signal,
52
+ headers: {
53
+ Accept: 'application/json',
54
+ ...this.headers,
55
+ },
56
+ };
57
+ // Add body and Content-Type for POST requests
58
+ if (method === 'POST' && body) {
59
+ requestOptions.body = JSON.stringify(body);
60
+ requestOptions.headers['Content-Type'] =
61
+ 'application/json';
62
+ }
63
+ const response = await fetch(url, requestOptions);
64
+ clearTimeout(timeoutId);
65
+ // Handle response errors
66
+ if (!response.ok) {
67
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
68
+ }
69
+ // Parse JSON response
70
+ const data = await response.json();
71
+ return data;
72
+ }
73
+ catch (error) {
74
+ clearTimeout(timeoutId);
75
+ if (error instanceof Error) {
76
+ if (error.name === 'AbortError') {
77
+ throw new Error(`Request timeout after ${this.timeout}ms`);
78
+ }
79
+ throw error;
80
+ }
81
+ throw new Error('Request failed');
82
+ }
83
+ }
84
+ async getTransactionByHash(hash) {
85
+ const path = `${this.chainId}/tx/${hash}/detail`;
86
+ const res = await this.makeRequest('GET', path);
87
+ return res.data.transaction;
88
+ }
89
+ async getTransactionsByWalletBeforeTimestamp(wallet, filter, limit, timestamp_lt, last_hash) {
90
+ if (!wallet) {
91
+ throw new Error("wallet address cannot be empty");
92
+ }
93
+ let finalLimit = limit && limit > 0 ? limit : 20;
94
+ if (finalLimit > 1000)
95
+ finalLimit = 1000;
96
+ const params = {
97
+ limit: finalLimit,
98
+ ...(timestamp_lt && { timestamp_lt }),
99
+ ...(last_hash && { last_hash }),
100
+ };
101
+ switch (filter) {
102
+ case API_FILTER_PARAMS.ALL:
103
+ params["wallet_address"] = wallet;
104
+ break;
105
+ case API_FILTER_PARAMS.SENT:
106
+ params["filter_from_address"] = wallet;
107
+ break;
108
+ case API_FILTER_PARAMS.RECEIVED:
109
+ params["filter_to_address"] = wallet;
110
+ break;
111
+ }
112
+ const path = `${this.chainId}/transactions/infinite`;
113
+ return this.makeRequest("GET", path, params);
114
+ }
115
+ async getTransactionByWallet(wallet, page = 1, limit = 50, filter, sortBy = 'transaction_timestamp', sortOrder = 'desc') {
116
+ if (!wallet) {
117
+ throw new Error('wallet address cannot be empty');
118
+ }
119
+ if (page < 1)
120
+ page = 1;
121
+ if (limit <= 0)
122
+ limit = 50;
123
+ if (limit > 1000)
124
+ limit = 1000;
125
+ const params = {
126
+ page: page - 1,
127
+ limit,
128
+ sort_by: sortBy,
129
+ sort_order: sortOrder,
130
+ };
131
+ switch (filter) {
132
+ case API_FILTER_PARAMS.ALL:
133
+ params['wallet_address'] = wallet;
134
+ break;
135
+ case API_FILTER_PARAMS.SENT:
136
+ params['filter_from_address'] = wallet;
137
+ break;
138
+ case API_FILTER_PARAMS.RECEIVED:
139
+ params['filter_to_address'] = wallet;
140
+ break;
141
+ }
142
+ const path = `${this.chainId}/transactions`;
143
+ return this.makeRequest('GET', path, params);
144
+ }
145
+ async getWalletDetail(wallet) {
146
+ if (!wallet) {
147
+ throw new Error('wallet address cannot be empty');
148
+ }
149
+ const path = `${this.chainId}/wallets/${wallet}/detail`;
150
+ const res = await this.makeRequest('GET', path);
151
+ return res.data;
152
+ }
163
153
  }
164
154
 
165
155
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
166
156
 
157
+ function getDefaultExportFromCjs (x) {
158
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
159
+ }
160
+
167
161
  var cryptoJs = {exports: {}};
168
162
 
169
163
  function commonjsRequire(path) {
@@ -976,8 +970,8 @@ function requireCore () {
976
970
 
977
971
  return CryptoJS;
978
972
 
979
- }));
980
- } (core));
973
+ }));
974
+ } (core));
981
975
  return core.exports;
982
976
  }
983
977
 
@@ -1284,8 +1278,8 @@ function requireX64Core () {
1284
1278
 
1285
1279
  return CryptoJS;
1286
1280
 
1287
- }));
1288
- } (x64Core));
1281
+ }));
1282
+ } (x64Core));
1289
1283
  return x64Core.exports;
1290
1284
  }
1291
1285
 
@@ -1364,8 +1358,8 @@ function requireLibTypedarrays () {
1364
1358
 
1365
1359
  return CryptoJS.lib.WordArray;
1366
1360
 
1367
- }));
1368
- } (libTypedarrays));
1361
+ }));
1362
+ } (libTypedarrays));
1369
1363
  return libTypedarrays.exports;
1370
1364
  }
1371
1365
 
@@ -1517,8 +1511,8 @@ function requireEncUtf16 () {
1517
1511
 
1518
1512
  return CryptoJS.enc.Utf16;
1519
1513
 
1520
- }));
1521
- } (encUtf16));
1514
+ }));
1515
+ } (encUtf16));
1522
1516
  return encUtf16.exports;
1523
1517
  }
1524
1518
 
@@ -1657,8 +1651,8 @@ function requireEncBase64 () {
1657
1651
 
1658
1652
  return CryptoJS.enc.Base64;
1659
1653
 
1660
- }));
1661
- } (encBase64));
1654
+ }));
1655
+ } (encBase64));
1662
1656
  return encBase64.exports;
1663
1657
  }
1664
1658
 
@@ -1809,8 +1803,8 @@ function requireEncBase64url () {
1809
1803
 
1810
1804
  return CryptoJS.enc.Base64url;
1811
1805
 
1812
- }));
1813
- } (encBase64url));
1806
+ }));
1807
+ } (encBase64url));
1814
1808
  return encBase64url.exports;
1815
1809
  }
1816
1810
 
@@ -2081,8 +2075,8 @@ function requireMd5 () {
2081
2075
 
2082
2076
  return CryptoJS.MD5;
2083
2077
 
2084
- }));
2085
- } (md5));
2078
+ }));
2079
+ } (md5));
2086
2080
  return md5.exports;
2087
2081
  }
2088
2082
 
@@ -2235,8 +2229,8 @@ function requireSha1 () {
2235
2229
 
2236
2230
  return CryptoJS.SHA1;
2237
2231
 
2238
- }));
2239
- } (sha1));
2232
+ }));
2233
+ } (sha1));
2240
2234
  return sha1.exports;
2241
2235
  }
2242
2236
 
@@ -2438,8 +2432,8 @@ function requireSha256 () {
2438
2432
 
2439
2433
  return CryptoJS.SHA256;
2440
2434
 
2441
- }));
2442
- } (sha256));
2435
+ }));
2436
+ } (sha256));
2443
2437
  return sha256.exports;
2444
2438
  }
2445
2439
 
@@ -2522,8 +2516,8 @@ function requireSha224 () {
2522
2516
 
2523
2517
  return CryptoJS.SHA224;
2524
2518
 
2525
- }));
2526
- } (sha224));
2519
+ }));
2520
+ } (sha224));
2527
2521
  return sha224.exports;
2528
2522
  }
2529
2523
 
@@ -2852,8 +2846,8 @@ function requireSha512 () {
2852
2846
 
2853
2847
  return CryptoJS.SHA512;
2854
2848
 
2855
- }));
2856
- } (sha512));
2849
+ }));
2850
+ } (sha512));
2857
2851
  return sha512.exports;
2858
2852
  }
2859
2853
 
@@ -2939,8 +2933,8 @@ function requireSha384 () {
2939
2933
 
2940
2934
  return CryptoJS.SHA384;
2941
2935
 
2942
- }));
2943
- } (sha384));
2936
+ }));
2937
+ } (sha384));
2944
2938
  return sha384.exports;
2945
2939
  }
2946
2940
 
@@ -3269,8 +3263,8 @@ function requireSha3 () {
3269
3263
 
3270
3264
  return CryptoJS.SHA3;
3271
3265
 
3272
- }));
3273
- } (sha3));
3266
+ }));
3267
+ } (sha3));
3274
3268
  return sha3.exports;
3275
3269
  }
3276
3270
 
@@ -3540,8 +3534,8 @@ function requireRipemd160 () {
3540
3534
 
3541
3535
  return CryptoJS.RIPEMD160;
3542
3536
 
3543
- }));
3544
- } (ripemd160));
3537
+ }));
3538
+ } (ripemd160));
3545
3539
  return ripemd160.exports;
3546
3540
  }
3547
3541
 
@@ -3687,8 +3681,8 @@ function requireHmac () {
3687
3681
  }());
3688
3682
 
3689
3683
 
3690
- }));
3691
- } (hmac));
3684
+ }));
3685
+ } (hmac));
3692
3686
  return hmac.exports;
3693
3687
  }
3694
3688
 
@@ -3836,8 +3830,8 @@ function requirePbkdf2 () {
3836
3830
 
3837
3831
  return CryptoJS.PBKDF2;
3838
3832
 
3839
- }));
3840
- } (pbkdf2));
3833
+ }));
3834
+ } (pbkdf2));
3841
3835
  return pbkdf2.exports;
3842
3836
  }
3843
3837
 
@@ -3974,8 +3968,8 @@ function requireEvpkdf () {
3974
3968
 
3975
3969
  return CryptoJS.EvpKDF;
3976
3970
 
3977
- }));
3978
- } (evpkdf));
3971
+ }));
3972
+ } (evpkdf));
3979
3973
  return evpkdf.exports;
3980
3974
  }
3981
3975
 
@@ -4198,7 +4192,7 @@ function requireCipherCore () {
4198
4192
  C_lib.StreamCipher = Cipher.extend({
4199
4193
  _doFinalize: function () {
4200
4194
  // Process partial blocks
4201
- var finalProcessedBlocks = this._process(!!'flush');
4195
+ var finalProcessedBlocks = this._process(true);
4202
4196
 
4203
4197
  return finalProcessedBlocks;
4204
4198
  },
@@ -4479,10 +4473,10 @@ function requireCipherCore () {
4479
4473
  padding.pad(this._data, this.blockSize);
4480
4474
 
4481
4475
  // Process final blocks
4482
- finalProcessedBlocks = this._process(!!'flush');
4476
+ finalProcessedBlocks = this._process(true);
4483
4477
  } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
4484
4478
  // Process final blocks
4485
- finalProcessedBlocks = this._process(!!'flush');
4479
+ finalProcessedBlocks = this._process(true);
4486
4480
 
4487
4481
  // Unpad data
4488
4482
  padding.unpad(finalProcessedBlocks);
@@ -4873,8 +4867,8 @@ function requireCipherCore () {
4873
4867
  }());
4874
4868
 
4875
4869
 
4876
- }));
4877
- } (cipherCore));
4870
+ }));
4871
+ } (cipherCore));
4878
4872
  return cipherCore.exports;
4879
4873
  }
4880
4874
 
@@ -4957,8 +4951,8 @@ function requireModeCfb () {
4957
4951
 
4958
4952
  return CryptoJS.mode.CFB;
4959
4953
 
4960
- }));
4961
- } (modeCfb));
4954
+ }));
4955
+ } (modeCfb));
4962
4956
  return modeCfb.exports;
4963
4957
  }
4964
4958
 
@@ -5019,8 +5013,8 @@ function requireModeCtr () {
5019
5013
 
5020
5014
  return CryptoJS.mode.CTR;
5021
5015
 
5022
- }));
5023
- } (modeCtr));
5016
+ }));
5017
+ } (modeCtr));
5024
5018
  return modeCtr.exports;
5025
5019
  }
5026
5020
 
@@ -5139,8 +5133,8 @@ function requireModeCtrGladman () {
5139
5133
 
5140
5134
  return CryptoJS.mode.CTRGladman;
5141
5135
 
5142
- }));
5143
- } (modeCtrGladman));
5136
+ }));
5137
+ } (modeCtrGladman));
5144
5138
  return modeCtrGladman.exports;
5145
5139
  }
5146
5140
 
@@ -5197,8 +5191,8 @@ function requireModeOfb () {
5197
5191
 
5198
5192
  return CryptoJS.mode.OFB;
5199
5193
 
5200
- }));
5201
- } (modeOfb));
5194
+ }));
5195
+ } (modeOfb));
5202
5196
  return modeOfb.exports;
5203
5197
  }
5204
5198
 
@@ -5241,8 +5235,8 @@ function requireModeEcb () {
5241
5235
 
5242
5236
  return CryptoJS.mode.ECB;
5243
5237
 
5244
- }));
5245
- } (modeEcb));
5238
+ }));
5239
+ } (modeEcb));
5246
5240
  return modeEcb.exports;
5247
5241
  }
5248
5242
 
@@ -5294,8 +5288,8 @@ function requirePadAnsix923 () {
5294
5288
 
5295
5289
  return CryptoJS.pad.Ansix923;
5296
5290
 
5297
- }));
5298
- } (padAnsix923));
5291
+ }));
5292
+ } (padAnsix923));
5299
5293
  return padAnsix923.exports;
5300
5294
  }
5301
5295
 
@@ -5342,8 +5336,8 @@ function requirePadIso10126 () {
5342
5336
 
5343
5337
  return CryptoJS.pad.Iso10126;
5344
5338
 
5345
- }));
5346
- } (padIso10126));
5339
+ }));
5340
+ } (padIso10126));
5347
5341
  return padIso10126.exports;
5348
5342
  }
5349
5343
 
@@ -5386,8 +5380,8 @@ function requirePadIso97971 () {
5386
5380
 
5387
5381
  return CryptoJS.pad.Iso97971;
5388
5382
 
5389
- }));
5390
- } (padIso97971));
5383
+ }));
5384
+ } (padIso97971));
5391
5385
  return padIso97971.exports;
5392
5386
  }
5393
5387
 
@@ -5437,8 +5431,8 @@ function requirePadZeropadding () {
5437
5431
 
5438
5432
  return CryptoJS.pad.ZeroPadding;
5439
5433
 
5440
- }));
5441
- } (padZeropadding));
5434
+ }));
5435
+ } (padZeropadding));
5442
5436
  return padZeropadding.exports;
5443
5437
  }
5444
5438
 
@@ -5471,8 +5465,8 @@ function requirePadNopadding () {
5471
5465
 
5472
5466
  return CryptoJS.pad.NoPadding;
5473
5467
 
5474
- }));
5475
- } (padNopadding));
5468
+ }));
5469
+ } (padNopadding));
5476
5470
  return padNopadding.exports;
5477
5471
  }
5478
5472
 
@@ -5541,8 +5535,8 @@ function requireFormatHex () {
5541
5535
 
5542
5536
  return CryptoJS.format.Hex;
5543
5537
 
5544
- }));
5545
- } (formatHex));
5538
+ }));
5539
+ } (formatHex));
5546
5540
  return formatHex.exports;
5547
5541
  }
5548
5542
 
@@ -5779,8 +5773,8 @@ function requireAes () {
5779
5773
 
5780
5774
  return CryptoJS.AES;
5781
5775
 
5782
- }));
5783
- } (aes));
5776
+ }));
5777
+ } (aes));
5784
5778
  return aes.exports;
5785
5779
  }
5786
5780
 
@@ -6562,8 +6556,8 @@ function requireTripledes () {
6562
6556
 
6563
6557
  return CryptoJS.TripleDES;
6564
6558
 
6565
- }));
6566
- } (tripledes));
6559
+ }));
6560
+ } (tripledes));
6567
6561
  return tripledes.exports;
6568
6562
  }
6569
6563
 
@@ -6705,8 +6699,8 @@ function requireRc4 () {
6705
6699
 
6706
6700
  return CryptoJS.RC4;
6707
6701
 
6708
- }));
6709
- } (rc4));
6702
+ }));
6703
+ } (rc4));
6710
6704
  return rc4.exports;
6711
6705
  }
6712
6706
 
@@ -6901,8 +6895,8 @@ function requireRabbit () {
6901
6895
 
6902
6896
  return CryptoJS.Rabbit;
6903
6897
 
6904
- }));
6905
- } (rabbit));
6898
+ }));
6899
+ } (rabbit));
6906
6900
  return rabbit.exports;
6907
6901
  }
6908
6902
 
@@ -7095,8 +7089,8 @@ function requireRabbitLegacy () {
7095
7089
 
7096
7090
  return CryptoJS.RabbitLegacy;
7097
7091
 
7098
- }));
7099
- } (rabbitLegacy));
7092
+ }));
7093
+ } (rabbitLegacy));
7100
7094
  return rabbitLegacy.exports;
7101
7095
  }
7102
7096
 
@@ -7570,8 +7564,8 @@ function requireBlowfish () {
7570
7564
 
7571
7565
  return CryptoJS.Blowfish;
7572
7566
 
7573
- }));
7574
- } (blowfish));
7567
+ }));
7568
+ } (blowfish));
7575
7569
  return blowfish.exports;
7576
7570
  }
7577
7571
 
@@ -7585,621 +7579,634 @@ function requireBlowfish () {
7585
7579
 
7586
7580
  return CryptoJS;
7587
7581
 
7588
- }));
7582
+ }));
7589
7583
  } (cryptoJs));
7590
7584
 
7591
- var CryptoJS = cryptoJs.exports;
7592
-
7593
- // MMN Client
7594
- // Buffer polyfill for mobile environments
7595
- class BufferPolyfill {
7596
- static isBuffer(obj) {
7597
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer) {
7598
- return Buffer.isBuffer(obj);
7599
- }
7600
- return obj instanceof Uint8Array;
7601
- }
7602
- static from(data, encoding) {
7603
- if (typeof Buffer !== 'undefined' && Buffer.from) {
7604
- return Buffer.from(data, encoding);
7605
- }
7606
- let result;
7607
- if (Array.isArray(data)) {
7608
- result = new Uint8Array(data);
7609
- }
7610
- else if (typeof data === 'string') {
7611
- if (encoding === 'hex') {
7612
- const bytes = [];
7613
- for (let i = 0; i < data.length; i += 2) {
7614
- bytes.push(parseInt(data.substr(i, 2), 16));
7615
- }
7616
- result = new Uint8Array(bytes);
7617
- }
7618
- else {
7619
- // UTF-8 encoding
7620
- const encoder = new TextEncoder();
7621
- result = encoder.encode(data);
7622
- }
7623
- }
7624
- else if (data instanceof Uint8Array) {
7625
- result = data;
7626
- }
7627
- else {
7628
- result = new Uint8Array(data);
7629
- }
7630
- // Add toString method
7631
- result.toString = function (encoding) {
7632
- if (encoding === 'hex') {
7633
- return Array.from(this)
7634
- .map((b) => b.toString(16).padStart(2, '0'))
7635
- .join('');
7636
- }
7637
- else if (encoding === 'base64') {
7638
- // Simple base64 encoding
7639
- const bytes = this;
7640
- let binary = '';
7641
- for (let i = 0; i < bytes.length; i++) {
7642
- binary += String.fromCharCode(bytes[i]);
7643
- }
7644
- return btoa(binary);
7645
- }
7646
- else {
7647
- // UTF-8 decoding
7648
- const decoder = new TextDecoder();
7649
- return decoder.decode(this);
7650
- }
7651
- };
7652
- return result;
7653
- }
7654
- static concat(arrays) {
7655
- if (typeof Buffer !== 'undefined' && Buffer.concat) {
7656
- return Buffer.concat(arrays);
7657
- }
7658
- const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
7659
- const result = new Uint8Array(totalLength);
7660
- let offset = 0;
7661
- for (const arr of arrays) {
7662
- result.set(arr, offset);
7663
- offset += arr.length;
7664
- }
7665
- // Add toString method
7666
- result.toString = function (encoding) {
7667
- if (encoding === 'hex') {
7668
- return Array.from(this)
7669
- .map((b) => b.toString(16).padStart(2, '0'))
7670
- .join('');
7671
- }
7672
- else {
7673
- const decoder = new TextDecoder();
7674
- return decoder.decode(this);
7675
- }
7676
- };
7677
- return result;
7678
- }
7679
- }
7680
- // Use polyfill if Buffer is not available
7681
- const BufferCompat = typeof Buffer !== 'undefined' ? Buffer : BufferPolyfill;
7682
- // Cryptographic constants
7683
- const CRYPTO_CONSTANTS = {
7684
- ED25519_PRIVATE_KEY_LENGTH: 32,
7685
- ED25519_PUBLIC_KEY_LENGTH: 32,
7686
- MNEMONIC_ENTROPY_BITS: 128,
7687
- PKCS8_VERSION: 0,
7688
- // ASN.1 DER encoding
7689
- ASN1_SEQUENCE_TAG: 0x30,
7690
- ASN1_OCTET_STRING_TAG: 0x04,
7691
- ASN1_INTEGER_TAG: 0x02,
7692
- ASN1_LENGTH: 0x80,
7693
- // Ed25519 OID bytes: 1.3.101.112 (RFC 8410)
7694
- ED25519_OID_BYTES: [0x06, 0x03, 0x2b, 0x65, 0x70],
7695
- // PKCS#8 structure length constants
7696
- PKCS8_ALGORITHM_ID_LENGTH: 0x0b,
7697
- PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH: 0x22,
7698
- PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH: 0x20, // Inner OCTET STRING length (32 bytes)
7699
- };
7700
- // PRNG (Pseudo-Random Number Generator) constants
7701
- const PRNG_CONSTANTS = {
7702
- // Numerical Recipes LCG
7703
- LCG_MULTIPLIER: 1664525,
7704
- LCG_INCREMENT: 1013904223,
7705
- LCG_MODULUS: 4294967296,
7706
- TIMESTAMP_MULTIPLIER: 2654435761,
7707
- HASH_SUBSTRING_LENGTH: 8,
7708
- BYTE_SHIFT: 24,
7709
- BYTE_MASK: 0xff,
7710
- };
7711
- const TX_TYPE = {
7712
- TRANSFER: 0,
7713
- PRIVATE_KEY: 1,
7714
- };
7715
- const DECIMALS = 6;
7716
- class MmnClient {
7717
- constructor(config) {
7718
- this.requestId = 0;
7719
- this.config = {
7720
- timeout: 30000,
7721
- headers: {
7722
- 'Content-Type': 'application/json',
7723
- Accept: 'application/json',
7724
- },
7725
- ...config,
7726
- };
7727
- }
7728
- async makeRequest(method, params) {
7729
- const request = {
7730
- jsonrpc: '2.0',
7731
- method,
7732
- params,
7733
- id: ++this.requestId,
7734
- };
7735
- // Create AbortController for timeout
7736
- const controller = new AbortControllerPolyfill();
7737
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
7738
- try {
7739
- const requestOptions = {
7740
- method: 'POST',
7741
- mode: 'cors',
7742
- credentials: 'omit',
7743
- signal: controller.signal,
7744
- headers: this.config.headers || {},
7745
- body: JSON.stringify(request),
7746
- };
7747
- const response = await fetchPolyfill(this.config.baseUrl, requestOptions);
7748
- clearTimeout(timeoutId);
7749
- if (!response.ok) {
7750
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
7751
- }
7752
- const result = await response.json();
7753
- if (result.error) {
7754
- throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
7755
- }
7756
- return result.result;
7757
- }
7758
- catch (error) {
7759
- clearTimeout(timeoutId);
7760
- if (error instanceof Error) {
7761
- if (error.name === 'AbortError') {
7762
- throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
7763
- }
7764
- throw error;
7765
- }
7766
- throw new Error('Unknown error occurred');
7767
- }
7768
- }
7769
- /**
7770
- * Securely convert raw Ed25519 private key to PKCS#8 format
7771
- * @param raw - Raw 32-byte Ed25519 private key
7772
- * @returns PKCS#8 formatted private key in hex
7773
- * @throws Error if input validation fails
7774
- */
7775
- rawEd25519ToPkcs8Hex(raw) {
7776
- // Input validation
7777
- if (!BufferCompat.isBuffer(raw)) {
7778
- throw new Error('Private key must be a Buffer');
7779
- }
7780
- if (raw.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7781
- throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
7782
- }
7783
- try {
7784
- // Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
7785
- const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
7786
- const VERSION_BYTES = BufferCompat.from([
7787
- CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
7788
- 0x01,
7789
- CRYPTO_CONSTANTS.PKCS8_VERSION,
7790
- ]);
7791
- // Create algorithm identifier sequence (AlgorithmIdentifier)
7792
- const algorithmId = BufferCompat.concat([
7793
- BufferCompat.from([
7794
- CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
7795
- CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
7796
- ]),
7797
- ED25519_OID,
7798
- ]);
7799
- // Create private key octet string (wrapped Ed25519 private key)
7800
- const privateKeyOctetString = BufferCompat.concat([
7801
- BufferCompat.from([
7802
- CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7803
- CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH,
7804
- ]),
7805
- BufferCompat.from([
7806
- CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7807
- CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH,
7808
- ]),
7809
- raw,
7810
- ]);
7811
- // Create PKCS#8 body
7812
- const pkcs8Body = BufferCompat.concat([
7813
- VERSION_BYTES,
7814
- algorithmId,
7815
- privateKeyOctetString,
7816
- ]);
7817
- // Create final PKCS#8 structure
7818
- const pkcs8 = BufferCompat.concat([
7819
- BufferCompat.from([CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG]),
7820
- this.encodeLength(pkcs8Body.length),
7821
- pkcs8Body,
7822
- ]);
7823
- const result = pkcs8.toString('hex');
7824
- // Clear sensitive data from memory
7825
- raw.fill(0);
7826
- privateKeyOctetString.fill(0);
7827
- pkcs8Body.fill(0);
7828
- pkcs8.fill(0);
7829
- return result;
7830
- }
7831
- catch (error) {
7832
- // Clear sensitive data on error
7833
- raw.fill(0);
7834
- throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
7835
- }
7836
- }
7837
- /**
7838
- * Encode length in ASN.1 DER format
7839
- * ASN.1 length encoding rules:
7840
- * - Short form (0-127): single byte with the length value
7841
- * - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
7842
- * @param length - The length value to encode
7843
- * @returns ASN.1 DER encoded length bytes
7844
- */
7845
- encodeLength(length) {
7846
- if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
7847
- return BufferCompat.from([length]);
7848
- }
7849
- const bytes = [];
7850
- let len = length;
7851
- while (len > 0) {
7852
- bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
7853
- len >>= 8;
7854
- }
7855
- return BufferCompat.from([
7856
- CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
7857
- ...bytes,
7858
- ]);
7859
- }
7860
- /**
7861
- * Generate secure entropy using multiple sources for maximum compatibility
7862
- * @returns Array of 32 random bytes
7863
- */
7864
- generateSecureEntropy() {
7865
- const entropy = [];
7866
- const targetLength = CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH;
7867
- // Use multiple entropy sources
7868
- const now = Date.now();
7869
- const performance = typeof window !== 'undefined' && window.performance
7870
- ? window.performance.now()
7871
- : now;
7872
- const random = Math.random();
7873
- // Create initial seed from timestamp and random
7874
- let seed = now + performance + random;
7875
- // Generate bytes using Linear Congruential Generator (LCG) with multiple entropy sources
7876
- // This provides a fallback Pseudorandom Number Generator (PRNG) when crypto.getRandomValues is not available
7877
- for (let i = 0; i < targetLength; i++) {
7878
- // Xₙ₊₁ = (a * Xₙ + c) mod m
7879
- seed =
7880
- (seed * PRNG_CONSTANTS.LCG_MULTIPLIER + PRNG_CONSTANTS.LCG_INCREMENT) %
7881
- PRNG_CONSTANTS.LCG_MODULUS;
7882
- // Mix with timestamp to add time-based entropy
7883
- seed ^= (now + i) * PRNG_CONSTANTS.TIMESTAMP_MULTIPLIER;
7884
- // Mix with Math.random() for additional browser-provided randomness
7885
- seed ^= Math.floor(Math.random() * PRNG_CONSTANTS.LCG_MODULUS);
7886
- // Additional cryptographic mixing using SHA256 if CryptoJS is available
7887
- if (typeof CryptoJS !== 'undefined') {
7888
- const hashInput = seed.toString() + i.toString() + now.toString();
7889
- const hash = CryptoJS.SHA256(hashInput).toString();
7890
- // Extract first 8 hex characters (32 bits) from hash for mixing
7891
- seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
7892
- }
7893
- entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
7894
- }
7895
- return entropy;
7896
- }
7897
- /**
7898
- * Securely generate ephemeral key pair with proper entropy
7899
- * React Native compatible version with multiple fallbacks
7900
- * @returns Ephemeral key pair with private and public keys
7901
- * @throws Error if key generation fails
7902
- */
7903
- generateEphemeralKeyPair() {
7904
- try {
7905
- let seed;
7906
- // Try multiple approaches for mobile compatibility
7907
- try {
7908
- // Method 1: Try nacl.randomBytes first
7909
- seed = nacl__default["default"].randomBytes(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7910
- }
7911
- catch (naclError) {
7912
- try {
7913
- // Method 2: Use crypto.getRandomValues if available (browsers/React Native)
7914
- if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
7915
- seed = new Uint8Array(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7916
- crypto.getRandomValues(seed);
7917
- }
7918
- else {
7919
- throw new Error('crypto.getRandomValues not available');
7920
- }
7921
- }
7922
- catch (cryptoError) {
7923
- // Method 3: Fallback to secure pseudo-random generation
7924
- const entropy = this.generateSecureEntropy();
7925
- seed = new Uint8Array(entropy);
7926
- }
7927
- }
7928
- // Validate seed length
7929
- if (seed.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7930
- throw new Error(`Invalid seed length: expected ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH}, got ${seed.length}`);
7931
- }
7932
- // Generate key pair from seed
7933
- const keyPair = nacl__default["default"].sign.keyPair.fromSeed(seed);
7934
- const publicKeyBytes = keyPair.publicKey;
7935
- // Validate public key
7936
- if (publicKeyBytes.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
7937
- throw new Error(`Invalid public key length: expected ${CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH}, got ${publicKeyBytes.length}`);
7938
- }
7939
- // Convert private key to PKCS#8 format
7940
- const privateKeyHex = this.rawEd25519ToPkcs8Hex(BufferCompat.from(seed));
7941
- // Clear sensitive data
7942
- seed.fill(0);
7943
- keyPair.secretKey.fill(0);
7944
- return {
7945
- privateKey: privateKeyHex,
7946
- publicKey: bs58__default["default"].encode(publicKeyBytes),
7947
- };
7948
- }
7949
- catch (error) {
7950
- throw new Error(`Failed to generate ephemeral key pair: ${error instanceof Error ? error.message : 'Unknown error'}`);
7951
- }
7952
- }
7953
- getAddressFromUserId(userId) {
7954
- // Use crypto-js for SHA-256 in React Native
7955
- const hash = CryptoJS.SHA256(userId).toString(CryptoJS.enc.Hex);
7956
- const hashBuffer = BufferCompat.from(hash, 'hex');
7957
- return bs58__default["default"].encode(hashBuffer);
7958
- }
7959
- /**
7960
- * Create and sign a transaction message
7961
- */
7962
- createAndSignTx(params) {
7963
- if (!this.validateAddress(params.sender)) {
7964
- throw new Error('Invalid sender address');
7965
- }
7966
- if (!this.validateAddress(params.recipient)) {
7967
- throw new Error('Invalid recipient address');
7968
- }
7969
- if (params.sender === params.recipient) {
7970
- throw new Error('Sender and recipient addresses cannot be the same');
7971
- }
7972
- const txMsg = {
7973
- type: params.type,
7974
- sender: params.sender,
7975
- recipient: params.recipient,
7976
- amount: params.amount,
7977
- timestamp: params.timestamp || Date.now(),
7978
- text_data: params.textData || '',
7979
- nonce: params.nonce,
7980
- extra_info: JSON.stringify(params.extraInfo) || '',
7981
- zk_proof: params.zkProof || '',
7982
- zk_pub: params.zkPub || '',
7983
- };
7984
- const signature = this.signTransaction(txMsg, params.privateKey);
7985
- return {
7986
- tx_msg: txMsg,
7987
- signature,
7988
- };
7989
- }
7990
- /**
7991
- * Securely sign a transaction with Ed25519
7992
- * @param tx - Transaction message to sign
7993
- * @param privateKeyHex - Private key in PKCS#8 hex format
7994
- * @returns Base58 encoded signature
7995
- * @throws Error if signing fails
7996
- */
7997
- signTransaction(tx, privateKeyHex) {
7998
- try {
7999
- // Validate inputs
8000
- if (!tx || typeof tx !== 'object') {
8001
- throw new Error('Invalid transaction object');
8002
- }
8003
- if (!privateKeyHex || typeof privateKeyHex !== 'string') {
8004
- throw new Error('Invalid private key format');
8005
- }
8006
- // Serialize transaction data
8007
- const serializedData = this.serializeTransaction(tx);
8008
- if (!serializedData || serializedData.length === 0) {
8009
- throw new Error('Failed to serialize transaction');
8010
- }
8011
- // Extract the Ed25519 seed from the private key for nacl signing
8012
- const privateKeyDer = BufferCompat.from(privateKeyHex, 'hex');
8013
- if (privateKeyDer.length < CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
8014
- throw new Error(`Invalid private key length: expected at least ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes, got ${privateKeyDer.length}`);
8015
- }
8016
- const seed = privateKeyDer.subarray(-CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH); // Last 32 bytes
8017
- const keyPair = nacl__default["default"].sign.keyPair.fromSeed(seed);
8018
- // Validate key pair
8019
- if (!keyPair.publicKey || !keyPair.secretKey) {
8020
- throw new Error('Failed to create key pair from seed');
8021
- }
8022
- // Sign using Ed25519 (nacl) - constant time operation
8023
- const signature = nacl__default["default"].sign.detached(serializedData, keyPair.secretKey);
8024
- if (!signature || signature.length === 0) {
8025
- throw new Error('Failed to generate signature');
8026
- }
8027
- // Clear sensitive data
8028
- privateKeyDer.fill(0);
8029
- seed.fill(0);
8030
- keyPair.secretKey.fill(0);
8031
- // Return signature based on transaction type
8032
- if (tx.type === TX_TYPE.PRIVATE_KEY) {
8033
- return bs58__default["default"].encode(BufferCompat.from(signature));
8034
- }
8035
- // For regular transactions, wrap signature with public key
8036
- const userSig = {
8037
- PubKey: BufferCompat.from(keyPair.publicKey).toString('base64'),
8038
- Sig: BufferCompat.from(signature).toString('base64'),
8039
- };
8040
- return bs58__default["default"].encode(BufferCompat.from(JSON.stringify(userSig)));
8041
- }
8042
- catch (error) {
8043
- throw new Error(`Transaction signing failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
8044
- }
8045
- }
8046
- /**
8047
- * Serialize transaction for signing
8048
- */
8049
- serializeTransaction(tx) {
8050
- const data = `${tx.type}|${tx.sender}|${tx.recipient}|${tx.amount}|${tx.text_data}|${tx.nonce}|${tx.extra_info}`;
8051
- return BufferCompat.from(data, 'utf8');
8052
- }
8053
- /**
8054
- * Add a signed transaction to the blockchain
8055
- */
8056
- async addTx(signedTx) {
8057
- return this.makeRequest('tx.addtx', signedTx);
8058
- }
8059
- /**
8060
- * Send a transaction (create, sign, and submit)
8061
- */
8062
- async sendTransaction(params) {
8063
- const fromAddress = this.getAddressFromUserId(params.sender);
8064
- const toAddress = this.getAddressFromUserId(params.recipient);
8065
- const signedTx = this.createAndSignTx({
8066
- ...params,
8067
- type: TX_TYPE.TRANSFER,
8068
- sender: fromAddress,
8069
- recipient: toAddress,
8070
- });
8071
- return this.addTx(signedTx);
8072
- }
8073
- async sendTransactionByAddress(params) {
8074
- const signedTx = this.createAndSignTx({
8075
- ...params,
8076
- type: TX_TYPE.TRANSFER,
8077
- });
8078
- return this.addTx(signedTx);
8079
- }
8080
- async sendTransactionByPrivateKey(params) {
8081
- const signedTx = this.createAndSignTx({
8082
- ...params,
8083
- type: TX_TYPE.PRIVATE_KEY,
8084
- });
8085
- return this.addTx(signedTx);
8086
- }
8087
- /**
8088
- * Get current nonce for an account
8089
- */
8090
- async getCurrentNonce(userId, tag = 'latest') {
8091
- const address = this.getAddressFromUserId(userId);
8092
- return this.makeRequest('account.getcurrentnonce', { address, tag });
8093
- }
8094
- async getAccountByUserId(userId) {
8095
- const address = this.getAddressFromUserId(userId);
8096
- return this.makeRequest('account.getaccount', {
8097
- address,
8098
- });
8099
- }
8100
- scaleAmountToDecimals(originalAmount, decimals = DECIMALS) {
8101
- let scaledAmount = BigInt(originalAmount);
8102
- for (let i = 0; i < decimals; i++) {
8103
- scaledAmount = scaledAmount * BigInt(10);
8104
- }
8105
- return scaledAmount.toString();
8106
- }
8107
- validateAddress(addr) {
8108
- const decoded = bs58__default["default"].decode(addr);
8109
- if (!decoded ||
8110
- decoded.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
8111
- return false;
8112
- }
8113
- return true;
8114
- }
8115
- validateAmount(balance, amount) {
8116
- const bigBalance = BigInt(balance);
8117
- const bigAmount = BigInt(typeof amount === 'number' ? this.scaleAmountToDecimals(amount) : amount);
8118
- return bigAmount <= bigBalance;
8119
- }
8120
- }
8121
- function createMmnClient(config) {
8122
- return new MmnClient(config);
7585
+ var cryptoJsExports = cryptoJs.exports;
7586
+ var CryptoJS = /*@__PURE__*/getDefaultExportFromCjs(cryptoJsExports);
7587
+
7588
+ // MMN Client
7589
+ // This client provides a complete interface for interacting with MMN blockchain
7590
+ // Buffer polyfill for mobile environments
7591
+ class BufferPolyfill {
7592
+ static isBuffer(obj) {
7593
+ if (typeof Buffer !== 'undefined' && Buffer.isBuffer) {
7594
+ return Buffer.isBuffer(obj);
7595
+ }
7596
+ return obj instanceof Uint8Array;
7597
+ }
7598
+ static from(data, encoding) {
7599
+ if (typeof Buffer !== 'undefined' && Buffer.from) {
7600
+ return Buffer.from(data, encoding);
7601
+ }
7602
+ let result;
7603
+ if (Array.isArray(data)) {
7604
+ result = new Uint8Array(data);
7605
+ }
7606
+ else if (typeof data === 'string') {
7607
+ if (encoding === 'hex') {
7608
+ const bytes = [];
7609
+ for (let i = 0; i < data.length; i += 2) {
7610
+ bytes.push(parseInt(data.substr(i, 2), 16));
7611
+ }
7612
+ result = new Uint8Array(bytes);
7613
+ }
7614
+ else {
7615
+ // UTF-8 encoding
7616
+ const encoder = new TextEncoder();
7617
+ result = encoder.encode(data);
7618
+ }
7619
+ }
7620
+ else if (data instanceof Uint8Array) {
7621
+ result = data;
7622
+ }
7623
+ else {
7624
+ result = new Uint8Array(data);
7625
+ }
7626
+ // Add toString method
7627
+ result.toString = function (encoding) {
7628
+ if (encoding === 'hex') {
7629
+ return Array.from(this)
7630
+ .map((b) => b.toString(16).padStart(2, '0'))
7631
+ .join('');
7632
+ }
7633
+ else if (encoding === 'base64') {
7634
+ // Simple base64 encoding
7635
+ const bytes = this;
7636
+ let binary = '';
7637
+ for (let i = 0; i < bytes.length; i++) {
7638
+ binary += String.fromCharCode(bytes[i]);
7639
+ }
7640
+ return btoa(binary);
7641
+ }
7642
+ else {
7643
+ // UTF-8 decoding
7644
+ const decoder = new TextDecoder();
7645
+ return decoder.decode(this);
7646
+ }
7647
+ };
7648
+ return result;
7649
+ }
7650
+ static concat(arrays) {
7651
+ if (typeof Buffer !== 'undefined' && Buffer.concat) {
7652
+ return Buffer.concat(arrays);
7653
+ }
7654
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
7655
+ const result = new Uint8Array(totalLength);
7656
+ let offset = 0;
7657
+ for (const arr of arrays) {
7658
+ result.set(arr, offset);
7659
+ offset += arr.length;
7660
+ }
7661
+ // Add toString method
7662
+ result.toString = function (encoding) {
7663
+ if (encoding === 'hex') {
7664
+ return Array.from(this)
7665
+ .map((b) => b.toString(16).padStart(2, '0'))
7666
+ .join('');
7667
+ }
7668
+ else {
7669
+ const decoder = new TextDecoder();
7670
+ return decoder.decode(this);
7671
+ }
7672
+ };
7673
+ return result;
7674
+ }
7675
+ }
7676
+ // Use polyfill if Buffer is not available
7677
+ const BufferCompat = typeof Buffer !== 'undefined' ? Buffer : BufferPolyfill;
7678
+ // Cryptographic constants
7679
+ const CRYPTO_CONSTANTS = {
7680
+ ED25519_PRIVATE_KEY_LENGTH: 32,
7681
+ ED25519_PUBLIC_KEY_LENGTH: 32,
7682
+ MNEMONIC_ENTROPY_BITS: 128,
7683
+ PKCS8_VERSION: 0,
7684
+ // ASN.1 DER encoding
7685
+ ASN1_SEQUENCE_TAG: 0x30,
7686
+ ASN1_OCTET_STRING_TAG: 0x04,
7687
+ ASN1_INTEGER_TAG: 0x02,
7688
+ ASN1_LENGTH: 0x80,
7689
+ // Ed25519 OID bytes: 1.3.101.112 (RFC 8410)
7690
+ ED25519_OID_BYTES: [0x06, 0x03, 0x2b, 0x65, 0x70],
7691
+ // PKCS#8 structure length constants
7692
+ PKCS8_ALGORITHM_ID_LENGTH: 0x0b, // SEQUENCE length for algorithm identifier
7693
+ PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH: 0x22, // Outer OCTET STRING length (34 bytes)
7694
+ PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH: 0x20, // Inner OCTET STRING length (32 bytes)
7695
+ };
7696
+ // PRNG (Pseudo-Random Number Generator) constants
7697
+ const PRNG_CONSTANTS = {
7698
+ // Numerical Recipes LCG
7699
+ LCG_MULTIPLIER: 1664525, // LCG multiplier (from Numerical Recipes)
7700
+ LCG_INCREMENT: 1013904223, // LCG increment
7701
+ LCG_MODULUS: 4294967296, // 2^32 modulus for LCG
7702
+ TIMESTAMP_MULTIPLIER: 2654435761, // Golden Ratio constant
7703
+ HASH_SUBSTRING_LENGTH: 8,
7704
+ BYTE_SHIFT: 24,
7705
+ BYTE_MASK: 0xff,
7706
+ };
7707
+ const TX_TYPE = {
7708
+ TRANSFER_BY_ZK: 0,
7709
+ TRANSFER_BY_KEY: 1,
7710
+ USER_CONTENT: 2,
7711
+ };
7712
+ const DECIMALS = 6;
7713
+ class MmnClient {
7714
+ constructor(config) {
7715
+ this.requestId = 0;
7716
+ this.config = {
7717
+ timeout: 30000,
7718
+ headers: {
7719
+ 'Content-Type': 'application/json',
7720
+ Accept: 'application/json',
7721
+ },
7722
+ ...config,
7723
+ };
7724
+ }
7725
+ async makeRequest(method, params) {
7726
+ const request = {
7727
+ jsonrpc: '2.0',
7728
+ method,
7729
+ params,
7730
+ id: ++this.requestId,
7731
+ };
7732
+ // Create AbortController for timeout
7733
+ const controller = new AbortController();
7734
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
7735
+ try {
7736
+ const requestOptions = {
7737
+ method: 'POST',
7738
+ mode: 'cors',
7739
+ credentials: 'omit',
7740
+ signal: controller.signal,
7741
+ headers: this.config.headers || {},
7742
+ body: JSON.stringify(request),
7743
+ };
7744
+ const response = await fetch(this.config.baseUrl, requestOptions);
7745
+ clearTimeout(timeoutId);
7746
+ if (!response.ok) {
7747
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
7748
+ }
7749
+ const result = await response.json();
7750
+ if (result.error) {
7751
+ throw new Error(`JSON-RPC Error ${result.error.code}: ${result.error.message}`);
7752
+ }
7753
+ return result.result;
7754
+ }
7755
+ catch (error) {
7756
+ clearTimeout(timeoutId);
7757
+ if (error instanceof Error) {
7758
+ if (error.name === 'AbortError') {
7759
+ throw new Error(`Request timeout after ${this.config.timeout || 30000}ms`);
7760
+ }
7761
+ throw error;
7762
+ }
7763
+ throw new Error('Unknown error occurred');
7764
+ }
7765
+ }
7766
+ /**
7767
+ * Securely convert raw Ed25519 private key to PKCS#8 format
7768
+ * @param raw - Raw 32-byte Ed25519 private key
7769
+ * @returns PKCS#8 formatted private key in hex
7770
+ * @throws Error if input validation fails
7771
+ */
7772
+ rawEd25519ToPkcs8Hex(raw) {
7773
+ // Input validation
7774
+ if (!BufferCompat.isBuffer(raw)) {
7775
+ throw new Error('Private key must be a Buffer');
7776
+ }
7777
+ if (raw.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7778
+ throw new Error(`Ed25519 private key must be exactly ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes`);
7779
+ }
7780
+ try {
7781
+ // Ed25519 OID: 1.3.101.112 (RFC 8410 - Algorithm Identifiers for Ed25519)
7782
+ const ED25519_OID = BufferCompat.from(CRYPTO_CONSTANTS.ED25519_OID_BYTES);
7783
+ const VERSION_BYTES = BufferCompat.from([
7784
+ CRYPTO_CONSTANTS.ASN1_INTEGER_TAG,
7785
+ 0x01, // Length of integer (1 byte)
7786
+ CRYPTO_CONSTANTS.PKCS8_VERSION,
7787
+ ]);
7788
+ // Create algorithm identifier sequence (AlgorithmIdentifier)
7789
+ const algorithmId = BufferCompat.concat([
7790
+ BufferCompat.from([
7791
+ CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG,
7792
+ CRYPTO_CONSTANTS.PKCS8_ALGORITHM_ID_LENGTH,
7793
+ ]),
7794
+ ED25519_OID,
7795
+ ]);
7796
+ // Create private key octet string (wrapped Ed25519 private key)
7797
+ const privateKeyOctetString = BufferCompat.concat([
7798
+ BufferCompat.from([
7799
+ CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7800
+ CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_OUTER_LENGTH,
7801
+ ]), // OCTET STRING, length 34
7802
+ BufferCompat.from([
7803
+ CRYPTO_CONSTANTS.ASN1_OCTET_STRING_TAG,
7804
+ CRYPTO_CONSTANTS.PKCS8_PRIVATE_KEY_OCTET_INNER_LENGTH,
7805
+ ]), // inner OCTET STRING, length 32
7806
+ raw,
7807
+ ]);
7808
+ // Create PKCS#8 body
7809
+ const pkcs8Body = BufferCompat.concat([
7810
+ VERSION_BYTES,
7811
+ algorithmId,
7812
+ privateKeyOctetString,
7813
+ ]);
7814
+ // Create final PKCS#8 structure
7815
+ const pkcs8 = BufferCompat.concat([
7816
+ BufferCompat.from([CRYPTO_CONSTANTS.ASN1_SEQUENCE_TAG]), // SEQUENCE
7817
+ this.encodeLength(pkcs8Body.length),
7818
+ pkcs8Body,
7819
+ ]);
7820
+ const result = pkcs8.toString('hex');
7821
+ // Clear sensitive data from memory
7822
+ raw.fill(0);
7823
+ privateKeyOctetString.fill(0);
7824
+ pkcs8Body.fill(0);
7825
+ pkcs8.fill(0);
7826
+ return result;
7827
+ }
7828
+ catch (error) {
7829
+ // Clear sensitive data on error
7830
+ raw.fill(0);
7831
+ throw new Error(`Failed to convert private key to PKCS#8: ${error instanceof Error ? error.message : 'Unknown error'}`);
7832
+ }
7833
+ }
7834
+ /**
7835
+ * Encode length in ASN.1 DER format
7836
+ * ASN.1 length encoding rules:
7837
+ * - Short form (0-127): single byte with the length value
7838
+ * - Long form (128+): first byte is 0x80 + number of length bytes, followed by length bytes
7839
+ * @param length - The length value to encode
7840
+ * @returns ASN.1 DER encoded length bytes
7841
+ */
7842
+ encodeLength(length) {
7843
+ if (length < CRYPTO_CONSTANTS.ASN1_LENGTH) {
7844
+ return BufferCompat.from([length]);
7845
+ }
7846
+ const bytes = [];
7847
+ let len = length;
7848
+ while (len > 0) {
7849
+ bytes.unshift(len & PRNG_CONSTANTS.BYTE_MASK);
7850
+ len >>= 8;
7851
+ }
7852
+ return BufferCompat.from([
7853
+ CRYPTO_CONSTANTS.ASN1_LENGTH | bytes.length,
7854
+ ...bytes,
7855
+ ]);
7856
+ }
7857
+ /**
7858
+ * Generate secure entropy using multiple sources for maximum compatibility
7859
+ * @returns Array of 32 random bytes
7860
+ */
7861
+ generateSecureEntropy() {
7862
+ const entropy = [];
7863
+ const targetLength = CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH;
7864
+ // Use multiple entropy sources
7865
+ const now = Date.now();
7866
+ const performance = typeof window !== 'undefined' && window.performance
7867
+ ? window.performance.now()
7868
+ : now;
7869
+ const random = Math.random();
7870
+ // Create initial seed from timestamp and random
7871
+ let seed = now + performance + random;
7872
+ // Generate bytes using Linear Congruential Generator (LCG) with multiple entropy sources
7873
+ // This provides a fallback Pseudorandom Number Generator (PRNG) when crypto.getRandomValues is not available
7874
+ for (let i = 0; i < targetLength; i++) {
7875
+ // Xₙ₊₁ = (a * Xₙ + c) mod m
7876
+ seed =
7877
+ (seed * PRNG_CONSTANTS.LCG_MULTIPLIER + PRNG_CONSTANTS.LCG_INCREMENT) %
7878
+ PRNG_CONSTANTS.LCG_MODULUS;
7879
+ // Mix with timestamp to add time-based entropy
7880
+ seed ^= (now + i) * PRNG_CONSTANTS.TIMESTAMP_MULTIPLIER;
7881
+ // Mix with Math.random() for additional browser-provided randomness
7882
+ seed ^= Math.floor(Math.random() * PRNG_CONSTANTS.LCG_MODULUS);
7883
+ // Additional cryptographic mixing using SHA256 if CryptoJS is available
7884
+ if (typeof CryptoJS !== 'undefined') {
7885
+ const hashInput = seed.toString() + i.toString() + now.toString();
7886
+ const hash = CryptoJS.SHA256(hashInput).toString();
7887
+ // Extract first 8 hex characters (32 bits) from hash for mixing
7888
+ seed ^= parseInt(hash.substring(0, PRNG_CONSTANTS.HASH_SUBSTRING_LENGTH), 16);
7889
+ }
7890
+ entropy.push((seed >>> PRNG_CONSTANTS.BYTE_SHIFT) & PRNG_CONSTANTS.BYTE_MASK);
7891
+ }
7892
+ return entropy;
7893
+ }
7894
+ /**
7895
+ * Securely generate ephemeral key pair with proper entropy
7896
+ * React Native compatible version with multiple fallbacks
7897
+ * @returns Ephemeral key pair with private and public keys
7898
+ * @throws Error if key generation fails
7899
+ */
7900
+ generateEphemeralKeyPair() {
7901
+ try {
7902
+ let seed;
7903
+ // Try multiple approaches for mobile compatibility
7904
+ try {
7905
+ // Method 1: Try nacl.randomBytes first
7906
+ seed = nacl.randomBytes(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7907
+ }
7908
+ catch (naclError) {
7909
+ try {
7910
+ // Method 2: Use crypto.getRandomValues if available (browsers/React Native)
7911
+ if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
7912
+ seed = new Uint8Array(CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH);
7913
+ crypto.getRandomValues(seed);
7914
+ }
7915
+ else {
7916
+ throw new Error('crypto.getRandomValues not available');
7917
+ }
7918
+ }
7919
+ catch (cryptoError) {
7920
+ // Method 3: Fallback to secure pseudo-random generation
7921
+ const entropy = this.generateSecureEntropy();
7922
+ seed = new Uint8Array(entropy);
7923
+ }
7924
+ }
7925
+ // Validate seed length
7926
+ if (seed.length !== CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
7927
+ throw new Error(`Invalid seed length: expected ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH}, got ${seed.length}`);
7928
+ }
7929
+ // Generate key pair from seed
7930
+ const keyPair = nacl.sign.keyPair.fromSeed(seed);
7931
+ const publicKeyBytes = keyPair.publicKey;
7932
+ // Validate public key
7933
+ if (publicKeyBytes.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
7934
+ throw new Error(`Invalid public key length: expected ${CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH}, got ${publicKeyBytes.length}`);
7935
+ }
7936
+ // Convert private key to PKCS#8 format
7937
+ const privateKeyHex = this.rawEd25519ToPkcs8Hex(BufferCompat.from(seed));
7938
+ // Clear sensitive data
7939
+ seed.fill(0);
7940
+ keyPair.secretKey.fill(0);
7941
+ return {
7942
+ privateKey: privateKeyHex,
7943
+ publicKey: bs58.encode(publicKeyBytes),
7944
+ };
7945
+ }
7946
+ catch (error) {
7947
+ throw new Error(`Failed to generate ephemeral key pair: ${error instanceof Error ? error.message : 'Unknown error'}`);
7948
+ }
7949
+ }
7950
+ getAddressFromUserId(userId) {
7951
+ // Use crypto-js for SHA-256 in React Native
7952
+ const hash = CryptoJS.SHA256(userId).toString(CryptoJS.enc.Hex);
7953
+ const hashBuffer = BufferCompat.from(hash, 'hex');
7954
+ return bs58.encode(hashBuffer);
7955
+ }
7956
+ /**
7957
+ * Create and sign a transaction message
7958
+ */
7959
+ createAndSignTx(params) {
7960
+ if (!this.validateAddress(params.sender)) {
7961
+ throw new Error('Invalid sender address');
7962
+ }
7963
+ if (!this.validateAddress(params.recipient)) {
7964
+ throw new Error('Invalid recipient address');
7965
+ }
7966
+ if (params.sender === params.recipient) {
7967
+ throw new Error('Sender and recipient addresses cannot be the same');
7968
+ }
7969
+ const txMsg = {
7970
+ type: params.type,
7971
+ sender: params.sender,
7972
+ recipient: params.recipient,
7973
+ amount: params.amount,
7974
+ timestamp: params.timestamp || Date.now(),
7975
+ text_data: params.textData || '',
7976
+ nonce: params.nonce,
7977
+ extra_info: JSON.stringify(params.extraInfo) || '',
7978
+ zk_proof: params.zkProof || '',
7979
+ zk_pub: params.zkPub || '',
7980
+ };
7981
+ const signature = this.signTransaction(txMsg, params.privateKey);
7982
+ return {
7983
+ tx_msg: txMsg,
7984
+ signature,
7985
+ };
7986
+ }
7987
+ /**
7988
+ * Securely sign a transaction with Ed25519
7989
+ * @param tx - Transaction message to sign
7990
+ * @param privateKeyHex - Private key in PKCS#8 hex format
7991
+ * @returns Base58 encoded signature
7992
+ * @throws Error if signing fails
7993
+ */
7994
+ signTransaction(tx, privateKeyHex) {
7995
+ try {
7996
+ // Validate inputs
7997
+ if (!tx || typeof tx !== 'object') {
7998
+ throw new Error('Invalid transaction object');
7999
+ }
8000
+ if (!privateKeyHex || typeof privateKeyHex !== 'string') {
8001
+ throw new Error('Invalid private key format');
8002
+ }
8003
+ // Serialize transaction data
8004
+ const serializedData = this.serializeTransaction(tx);
8005
+ if (!serializedData || serializedData.length === 0) {
8006
+ throw new Error('Failed to serialize transaction');
8007
+ }
8008
+ // Extract the Ed25519 seed from the private key for nacl signing
8009
+ const privateKeyDer = BufferCompat.from(privateKeyHex, 'hex');
8010
+ if (privateKeyDer.length < CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH) {
8011
+ throw new Error(`Invalid private key length: expected at least ${CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH} bytes, got ${privateKeyDer.length}`);
8012
+ }
8013
+ const seed = privateKeyDer.subarray(-CRYPTO_CONSTANTS.ED25519_PRIVATE_KEY_LENGTH); // Last 32 bytes
8014
+ const keyPair = nacl.sign.keyPair.fromSeed(seed);
8015
+ // Validate key pair
8016
+ if (!keyPair.publicKey || !keyPair.secretKey) {
8017
+ throw new Error('Failed to create key pair from seed');
8018
+ }
8019
+ // Sign using Ed25519 (nacl) - constant time operation
8020
+ const signature = nacl.sign.detached(serializedData, keyPair.secretKey);
8021
+ if (!signature || signature.length === 0) {
8022
+ throw new Error('Failed to generate signature');
8023
+ }
8024
+ // Clear sensitive data
8025
+ privateKeyDer.fill(0);
8026
+ seed.fill(0);
8027
+ keyPair.secretKey.fill(0);
8028
+ // Return signature based on transaction type
8029
+ if (tx.type === TX_TYPE.TRANSFER_BY_KEY) {
8030
+ return bs58.encode(BufferCompat.from(signature));
8031
+ }
8032
+ // For regular transactions, wrap signature with public key
8033
+ const userSig = {
8034
+ PubKey: BufferCompat.from(keyPair.publicKey).toString('base64'),
8035
+ Sig: BufferCompat.from(signature).toString('base64'),
8036
+ };
8037
+ return bs58.encode(BufferCompat.from(JSON.stringify(userSig)));
8038
+ }
8039
+ catch (error) {
8040
+ throw new Error(`Transaction signing failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
8041
+ }
8042
+ }
8043
+ /**
8044
+ * Serialize transaction for signing
8045
+ */
8046
+ serializeTransaction(tx) {
8047
+ const data = `${tx.type}|${tx.sender}|${tx.recipient}|${tx.amount}|${tx.text_data}|${tx.nonce}|${tx.extra_info}`;
8048
+ return BufferCompat.from(data, 'utf8');
8049
+ }
8050
+ /**
8051
+ * Add a signed transaction to the blockchain
8052
+ */
8053
+ async addTx(signedTx) {
8054
+ return this.makeRequest('tx.addtx', signedTx);
8055
+ }
8056
+ /**
8057
+ * Send a transaction (create, sign, and submit)
8058
+ */
8059
+ async sendTransaction(params) {
8060
+ const fromAddress = this.getAddressFromUserId(params.sender);
8061
+ const toAddress = this.getAddressFromUserId(params.recipient);
8062
+ const signedTx = this.createAndSignTx({
8063
+ ...params,
8064
+ type: TX_TYPE.TRANSFER_BY_ZK,
8065
+ sender: fromAddress,
8066
+ recipient: toAddress,
8067
+ });
8068
+ return this.addTx(signedTx);
8069
+ }
8070
+ async sendTransactionByAddress(params) {
8071
+ const signedTx = this.createAndSignTx({
8072
+ ...params,
8073
+ type: TX_TYPE.TRANSFER_BY_ZK,
8074
+ });
8075
+ return this.addTx(signedTx);
8076
+ }
8077
+ async sendTransactionByPrivateKey(params) {
8078
+ const signedTx = this.createAndSignTx({
8079
+ ...params,
8080
+ type: TX_TYPE.TRANSFER_BY_KEY,
8081
+ });
8082
+ return this.addTx(signedTx);
8083
+ }
8084
+ async postDonationCampaignFeed(params) {
8085
+ const signedTx = this.createAndSignTx({
8086
+ ...params,
8087
+ type: TX_TYPE.USER_CONTENT,
8088
+ });
8089
+ return this.addTx(signedTx);
8090
+ }
8091
+ /**
8092
+ * Get current nonce for an account
8093
+ */
8094
+ async getCurrentNonce(userId, tag = 'latest') {
8095
+ const address = this.getAddressFromUserId(userId);
8096
+ return this.makeRequest('account.getcurrentnonce', { address, tag });
8097
+ }
8098
+ async getCurrentNonceByAddress(address, tag = 'latest') {
8099
+ return this.makeRequest('account.getcurrentnonce', { address, tag });
8100
+ }
8101
+ async getAccountByUserId(userId) {
8102
+ const address = this.getAddressFromUserId(userId);
8103
+ return this.makeRequest('account.getaccount', {
8104
+ address,
8105
+ });
8106
+ }
8107
+ scaleAmountToDecimals(originalAmount, decimals = DECIMALS) {
8108
+ let scaledAmount = BigInt(originalAmount);
8109
+ for (let i = 0; i < decimals; i++) {
8110
+ scaledAmount = scaledAmount * BigInt(10);
8111
+ }
8112
+ return scaledAmount.toString();
8113
+ }
8114
+ validateAddress(addr) {
8115
+ const decoded = bs58.decode(addr);
8116
+ if (!decoded ||
8117
+ decoded.length !== CRYPTO_CONSTANTS.ED25519_PUBLIC_KEY_LENGTH) {
8118
+ return false;
8119
+ }
8120
+ return true;
8121
+ }
8122
+ validateAmount(balance, amount) {
8123
+ const bigBalance = BigInt(balance);
8124
+ const bigAmount = BigInt(typeof amount === 'number' ? this.scaleAmountToDecimals(amount) : amount);
8125
+ return bigAmount <= bigBalance;
8126
+ }
8127
+ }
8128
+ function createMmnClient(config) {
8129
+ return new MmnClient(config);
8123
8130
  }
8124
8131
 
8125
- // --- JSON-RPC Types ---
8126
- exports.ETransferType = void 0;
8127
- (function (ETransferType) {
8128
- ETransferType["GiveCoffee"] = "give_coffee";
8129
- ETransferType["TransferToken"] = "transfer_token";
8130
- ETransferType["UnlockItem"] = "unlock_item";
8131
- })(exports.ETransferType || (exports.ETransferType = {}));
8132
- exports.EZkClientType = void 0;
8133
- (function (EZkClientType) {
8134
- EZkClientType["MEZON"] = "mezon";
8135
- EZkClientType["OAUTH"] = "oauth";
8132
+ // --- JSON-RPC Types ---
8133
+ exports.ETransferType = void 0;
8134
+ (function (ETransferType) {
8135
+ ETransferType["GiveCoffee"] = "give_coffee";
8136
+ ETransferType["TransferToken"] = "transfer_token";
8137
+ ETransferType["UnlockItem"] = "unlock_item";
8138
+ })(exports.ETransferType || (exports.ETransferType = {}));
8139
+ exports.EZkClientType = void 0;
8140
+ (function (EZkClientType) {
8141
+ EZkClientType["MEZON"] = "mezon";
8142
+ EZkClientType["OAUTH"] = "oauth";
8136
8143
  })(exports.EZkClientType || (exports.EZkClientType = {}));
8137
8144
 
8138
- class ZkClient {
8139
- constructor(config) {
8140
- this.endpoint = config.endpoint;
8141
- this.timeout = config.timeout || 30000;
8142
- this.headers = {
8143
- Accept: 'application/json',
8144
- 'Content-Type': 'application/json',
8145
- ...(config.headers || {}),
8146
- };
8147
- }
8148
- async makeRequest(method, path, params, body) {
8149
- let url = `${this.endpoint}/${path}`;
8150
- // Add query parameters for GET requests
8151
- if (params && Object.keys(params).length > 0) {
8152
- const searchParams = new URLSearchParams();
8153
- Object.entries(params).forEach(([key, value]) => {
8154
- searchParams.append(key, String(value));
8155
- });
8156
- url += `?${searchParams.toString()}`;
8157
- }
8158
- // Create AbortController for timeout
8159
- const controller = new AbortControllerPolyfill();
8160
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8161
- try {
8162
- const requestOptions = {
8163
- method,
8164
- mode: 'cors',
8165
- credentials: 'omit',
8166
- signal: controller.signal,
8167
- headers: this.headers,
8168
- };
8169
- // Add body for POST requests
8170
- if (method === 'POST' && body) {
8171
- requestOptions.body = JSON.stringify(body);
8172
- }
8173
- const response = await fetchPolyfill(url, requestOptions);
8174
- clearTimeout(timeoutId);
8175
- if (!response.ok) {
8176
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
8177
- }
8178
- const data = await response.json();
8179
- return data;
8180
- }
8181
- catch (error) {
8182
- clearTimeout(timeoutId);
8183
- if (error instanceof Error) {
8184
- if (error.name === 'AbortError') {
8185
- throw new Error(`Request timeout after ${this.timeout}ms`);
8186
- }
8187
- throw error;
8188
- }
8189
- throw new Error('Request failed');
8190
- }
8191
- }
8192
- async getZkProofs({ userId, ephemeralPublicKey, jwt, address, clientType = exports.EZkClientType.MEZON, }) {
8193
- const path = `prove`;
8194
- const res = await this.makeRequest('POST', path, undefined, {
8195
- user_id: userId,
8196
- ephemeral_pk: ephemeralPublicKey,
8197
- jwt,
8198
- address,
8199
- client_type: clientType,
8200
- });
8201
- return res.data;
8202
- }
8145
+ class ZkClient {
8146
+ constructor(config) {
8147
+ this.endpoint = config.endpoint;
8148
+ this.timeout = config.timeout || 30000;
8149
+ this.headers = {
8150
+ Accept: 'application/json',
8151
+ 'Content-Type': 'application/json',
8152
+ ...(config.headers || {}),
8153
+ };
8154
+ }
8155
+ async makeRequest(method, path, params, body) {
8156
+ let url = `${this.endpoint}/${path}`;
8157
+ // Add query parameters for GET requests
8158
+ if (params && Object.keys(params).length > 0) {
8159
+ const searchParams = new URLSearchParams();
8160
+ Object.entries(params).forEach(([key, value]) => {
8161
+ searchParams.append(key, String(value));
8162
+ });
8163
+ url += `?${searchParams.toString()}`;
8164
+ }
8165
+ // Create AbortController for timeout
8166
+ const controller = new AbortController();
8167
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8168
+ try {
8169
+ const requestOptions = {
8170
+ method,
8171
+ mode: 'cors',
8172
+ credentials: 'omit',
8173
+ signal: controller.signal,
8174
+ headers: this.headers,
8175
+ };
8176
+ // Add body for POST requests
8177
+ if (method === 'POST' && body) {
8178
+ requestOptions.body = JSON.stringify(body);
8179
+ }
8180
+ const response = await fetch(url, requestOptions);
8181
+ clearTimeout(timeoutId);
8182
+ if (!response.ok) {
8183
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
8184
+ }
8185
+ const data = await response.json();
8186
+ return data;
8187
+ }
8188
+ catch (error) {
8189
+ clearTimeout(timeoutId);
8190
+ if (error instanceof Error) {
8191
+ if (error.name === 'AbortError') {
8192
+ throw new Error(`Request timeout after ${this.timeout}ms`);
8193
+ }
8194
+ throw error;
8195
+ }
8196
+ throw new Error('Request failed');
8197
+ }
8198
+ }
8199
+ async getZkProofs({ userId, ephemeralPublicKey, jwt, address, clientType = exports.EZkClientType.MEZON, }) {
8200
+ const path = `prove`;
8201
+ const res = await this.makeRequest('POST', path, undefined, {
8202
+ user_id: userId,
8203
+ ephemeral_pk: ephemeralPublicKey,
8204
+ jwt,
8205
+ address,
8206
+ client_type: clientType,
8207
+ });
8208
+ return res.data;
8209
+ }
8203
8210
  }
8204
8211
 
8205
8212
  exports.IndexerClient = IndexerClient;