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.d.ts +277 -278
- package/dist/index.esm.js +832 -809
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +839 -809
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
4473
|
+
finalProcessedBlocks = this._process(!!'flush');
|
|
4449
4474
|
} else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
|
|
4450
4475
|
// Process final blocks
|
|
4451
|
-
finalProcessedBlocks = this._process(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
//
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
const
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
//
|
|
7649
|
-
const
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
//
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
//
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
*
|
|
7739
|
-
* @
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
CRYPTO_CONSTANTS.
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
*
|
|
7807
|
-
*
|
|
7808
|
-
*
|
|
7809
|
-
*
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
const
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
//
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
// Mix with
|
|
7851
|
-
seed ^= (
|
|
7852
|
-
//
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
*
|
|
7867
|
-
*
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
//
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
*
|
|
7960
|
-
* @
|
|
7961
|
-
* @
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
const
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
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
|
|
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
|
|
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 };
|