@zubari/sdk 0.5.1 → 0.5.2
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 +800 -230
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +798 -228
- package/dist/index.mjs.map +1 -1
- package/dist/protocols/index.js.map +1 -1
- package/dist/protocols/index.mjs.map +1 -1
- package/dist/react/index.js +744 -174
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +742 -172
- package/dist/react/index.mjs.map +1 -1
- package/dist/services/index.js +708 -114
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +706 -112
- package/dist/services/index.mjs.map +1 -1
- package/dist/wallet/index.js +745 -175
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +743 -173
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs
CHANGED
|
@@ -2,9 +2,12 @@ import { useMemo, useState, useCallback, useEffect } from 'react';
|
|
|
2
2
|
import { Wallet, HDNodeWallet } from 'ethers';
|
|
3
3
|
import { generateMnemonic, validateMnemonic, mnemonicToSeedSync } from '@scure/bip39';
|
|
4
4
|
import { wordlist } from '@scure/bip39/wordlists/english';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
6
|
+
import { hmac } from '@noble/hashes/hmac.js';
|
|
7
|
+
import { ripemd160 as ripemd160$1 } from '@noble/hashes/legacy.js';
|
|
8
|
+
import { sha256, sha512 } from '@noble/hashes/sha2.js';
|
|
9
|
+
import { createView, concatBytes, abytes } from '@noble/hashes/utils.js';
|
|
10
|
+
import { sha256 as sha256$1 } from '@noble/hashes/sha256';
|
|
8
11
|
import { ripemd160 } from '@noble/hashes/ripemd160';
|
|
9
12
|
import { createPublicClient, http, formatEther, getAddress } from 'viem';
|
|
10
13
|
import { mainnet, sepolia } from 'viem/chains';
|
|
@@ -132,8 +135,8 @@ var TESTNET_NETWORKS = {
|
|
|
132
135
|
var USDT_ADDRESSES = {
|
|
133
136
|
ethereum: {
|
|
134
137
|
mainnet: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
135
|
-
testnet: "
|
|
136
|
-
// Sepolia
|
|
138
|
+
testnet: "0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0"
|
|
139
|
+
// Sepolia
|
|
137
140
|
},
|
|
138
141
|
tron: {
|
|
139
142
|
mainnet: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
|
@@ -214,14 +217,14 @@ var WdkApiClient = class {
|
|
|
214
217
|
/**
|
|
215
218
|
* Derive address for a specific chain using Tether WDK
|
|
216
219
|
*/
|
|
217
|
-
async deriveAddress(seed,
|
|
220
|
+
async deriveAddress(seed, chain2, network = "mainnet") {
|
|
218
221
|
try {
|
|
219
222
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-address`, {
|
|
220
223
|
method: "POST",
|
|
221
224
|
headers: {
|
|
222
225
|
"Content-Type": "application/json"
|
|
223
226
|
},
|
|
224
|
-
body: JSON.stringify({ seed, chain, network })
|
|
227
|
+
body: JSON.stringify({ seed, chain: chain2, network })
|
|
225
228
|
});
|
|
226
229
|
return await response.json();
|
|
227
230
|
} catch (error) {
|
|
@@ -254,14 +257,14 @@ var WdkApiClient = class {
|
|
|
254
257
|
/**
|
|
255
258
|
* Send a transaction on a specific chain using Tether WDK
|
|
256
259
|
*/
|
|
257
|
-
async sendTransaction(seed,
|
|
260
|
+
async sendTransaction(seed, chain2, to, amount, network = "mainnet") {
|
|
258
261
|
try {
|
|
259
262
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/send`, {
|
|
260
263
|
method: "POST",
|
|
261
264
|
headers: {
|
|
262
265
|
"Content-Type": "application/json"
|
|
263
266
|
},
|
|
264
|
-
body: JSON.stringify({ seed, chain, to, amount, network })
|
|
267
|
+
body: JSON.stringify({ seed, chain: chain2, to, amount, network })
|
|
265
268
|
});
|
|
266
269
|
return await response.json();
|
|
267
270
|
} catch (error) {
|
|
@@ -275,14 +278,14 @@ var WdkApiClient = class {
|
|
|
275
278
|
* Get transaction history for an address on a specific chain
|
|
276
279
|
* Fetches from blockchain explorers (Etherscan, mempool.space, etc.)
|
|
277
280
|
*/
|
|
278
|
-
async getTransactionHistory(seed,
|
|
281
|
+
async getTransactionHistory(seed, chain2, network = "mainnet", limit = 10) {
|
|
279
282
|
try {
|
|
280
283
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/history`, {
|
|
281
284
|
method: "POST",
|
|
282
285
|
headers: {
|
|
283
286
|
"Content-Type": "application/json"
|
|
284
287
|
},
|
|
285
|
-
body: JSON.stringify({ seed, chain, network, limit })
|
|
288
|
+
body: JSON.stringify({ seed, chain: chain2, network, limit })
|
|
286
289
|
});
|
|
287
290
|
return await response.json();
|
|
288
291
|
} catch (error) {
|
|
@@ -296,14 +299,14 @@ var WdkApiClient = class {
|
|
|
296
299
|
* Get transaction status by hash
|
|
297
300
|
* Fetches from blockchain explorers to check confirmation status
|
|
298
301
|
*/
|
|
299
|
-
async getTransactionStatus(txHash,
|
|
302
|
+
async getTransactionStatus(txHash, chain2, network = "mainnet") {
|
|
300
303
|
try {
|
|
301
304
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/tx-status`, {
|
|
302
305
|
method: "POST",
|
|
303
306
|
headers: {
|
|
304
307
|
"Content-Type": "application/json"
|
|
305
308
|
},
|
|
306
|
-
body: JSON.stringify({ txHash, chain, network })
|
|
309
|
+
body: JSON.stringify({ txHash, chain: chain2, network })
|
|
307
310
|
});
|
|
308
311
|
return await response.json();
|
|
309
312
|
} catch (error) {
|
|
@@ -324,6 +327,589 @@ function getWdkApiClient(baseUrl) {
|
|
|
324
327
|
}
|
|
325
328
|
return wdkApiClient;
|
|
326
329
|
}
|
|
330
|
+
|
|
331
|
+
// node_modules/@scure/base/index.js
|
|
332
|
+
function isBytes(a) {
|
|
333
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
334
|
+
}
|
|
335
|
+
function isArrayOf(isString, arr) {
|
|
336
|
+
if (!Array.isArray(arr))
|
|
337
|
+
return false;
|
|
338
|
+
if (arr.length === 0)
|
|
339
|
+
return true;
|
|
340
|
+
if (isString) {
|
|
341
|
+
return arr.every((item) => typeof item === "string");
|
|
342
|
+
} else {
|
|
343
|
+
return arr.every((item) => Number.isSafeInteger(item));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function afn(input) {
|
|
347
|
+
if (typeof input !== "function")
|
|
348
|
+
throw new Error("function expected");
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
function astr(label, input) {
|
|
352
|
+
if (typeof input !== "string")
|
|
353
|
+
throw new Error(`${label}: string expected`);
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
function anumber(n) {
|
|
357
|
+
if (!Number.isSafeInteger(n))
|
|
358
|
+
throw new Error(`invalid integer: ${n}`);
|
|
359
|
+
}
|
|
360
|
+
function aArr(input) {
|
|
361
|
+
if (!Array.isArray(input))
|
|
362
|
+
throw new Error("array expected");
|
|
363
|
+
}
|
|
364
|
+
function astrArr(label, input) {
|
|
365
|
+
if (!isArrayOf(true, input))
|
|
366
|
+
throw new Error(`${label}: array of strings expected`);
|
|
367
|
+
}
|
|
368
|
+
function anumArr(label, input) {
|
|
369
|
+
if (!isArrayOf(false, input))
|
|
370
|
+
throw new Error(`${label}: array of numbers expected`);
|
|
371
|
+
}
|
|
372
|
+
// @__NO_SIDE_EFFECTS__
|
|
373
|
+
function chain(...args) {
|
|
374
|
+
const id = (a) => a;
|
|
375
|
+
const wrap = (a, b) => (c) => a(b(c));
|
|
376
|
+
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
|
|
377
|
+
const decode = args.map((x) => x.decode).reduce(wrap, id);
|
|
378
|
+
return { encode, decode };
|
|
379
|
+
}
|
|
380
|
+
// @__NO_SIDE_EFFECTS__
|
|
381
|
+
function alphabet(letters) {
|
|
382
|
+
const lettersA = typeof letters === "string" ? letters.split("") : letters;
|
|
383
|
+
const len = lettersA.length;
|
|
384
|
+
astrArr("alphabet", lettersA);
|
|
385
|
+
const indexes = new Map(lettersA.map((l, i) => [l, i]));
|
|
386
|
+
return {
|
|
387
|
+
encode: (digits) => {
|
|
388
|
+
aArr(digits);
|
|
389
|
+
return digits.map((i) => {
|
|
390
|
+
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
|
|
391
|
+
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
|
|
392
|
+
return lettersA[i];
|
|
393
|
+
});
|
|
394
|
+
},
|
|
395
|
+
decode: (input) => {
|
|
396
|
+
aArr(input);
|
|
397
|
+
return input.map((letter) => {
|
|
398
|
+
astr("alphabet.decode", letter);
|
|
399
|
+
const i = indexes.get(letter);
|
|
400
|
+
if (i === void 0)
|
|
401
|
+
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
|
|
402
|
+
return i;
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
// @__NO_SIDE_EFFECTS__
|
|
408
|
+
function join(separator = "") {
|
|
409
|
+
astr("join", separator);
|
|
410
|
+
return {
|
|
411
|
+
encode: (from) => {
|
|
412
|
+
astrArr("join.decode", from);
|
|
413
|
+
return from.join(separator);
|
|
414
|
+
},
|
|
415
|
+
decode: (to) => {
|
|
416
|
+
astr("join.decode", to);
|
|
417
|
+
return to.split(separator);
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function convertRadix(data, from, to) {
|
|
422
|
+
if (from < 2)
|
|
423
|
+
throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
|
|
424
|
+
if (to < 2)
|
|
425
|
+
throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
|
|
426
|
+
aArr(data);
|
|
427
|
+
if (!data.length)
|
|
428
|
+
return [];
|
|
429
|
+
let pos = 0;
|
|
430
|
+
const res = [];
|
|
431
|
+
const digits = Array.from(data, (d) => {
|
|
432
|
+
anumber(d);
|
|
433
|
+
if (d < 0 || d >= from)
|
|
434
|
+
throw new Error(`invalid integer: ${d}`);
|
|
435
|
+
return d;
|
|
436
|
+
});
|
|
437
|
+
const dlen = digits.length;
|
|
438
|
+
while (true) {
|
|
439
|
+
let carry = 0;
|
|
440
|
+
let done = true;
|
|
441
|
+
for (let i = pos; i < dlen; i++) {
|
|
442
|
+
const digit = digits[i];
|
|
443
|
+
const fromCarry = from * carry;
|
|
444
|
+
const digitBase = fromCarry + digit;
|
|
445
|
+
if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) {
|
|
446
|
+
throw new Error("convertRadix: carry overflow");
|
|
447
|
+
}
|
|
448
|
+
const div = digitBase / to;
|
|
449
|
+
carry = digitBase % to;
|
|
450
|
+
const rounded = Math.floor(div);
|
|
451
|
+
digits[i] = rounded;
|
|
452
|
+
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
|
|
453
|
+
throw new Error("convertRadix: carry overflow");
|
|
454
|
+
if (!done)
|
|
455
|
+
continue;
|
|
456
|
+
else if (!rounded)
|
|
457
|
+
pos = i;
|
|
458
|
+
else
|
|
459
|
+
done = false;
|
|
460
|
+
}
|
|
461
|
+
res.push(carry);
|
|
462
|
+
if (done)
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
|
466
|
+
res.push(0);
|
|
467
|
+
return res.reverse();
|
|
468
|
+
}
|
|
469
|
+
var gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
|
|
470
|
+
var radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
|
|
471
|
+
var powers = /* @__PURE__ */ (() => {
|
|
472
|
+
let res = [];
|
|
473
|
+
for (let i = 0; i < 40; i++)
|
|
474
|
+
res.push(2 ** i);
|
|
475
|
+
return res;
|
|
476
|
+
})();
|
|
477
|
+
function convertRadix2(data, from, to, padding) {
|
|
478
|
+
aArr(data);
|
|
479
|
+
if (from <= 0 || from > 32)
|
|
480
|
+
throw new Error(`convertRadix2: wrong from=${from}`);
|
|
481
|
+
if (to <= 0 || to > 32)
|
|
482
|
+
throw new Error(`convertRadix2: wrong to=${to}`);
|
|
483
|
+
if (/* @__PURE__ */ radix2carry(from, to) > 32) {
|
|
484
|
+
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${/* @__PURE__ */ radix2carry(from, to)}`);
|
|
485
|
+
}
|
|
486
|
+
let carry = 0;
|
|
487
|
+
let pos = 0;
|
|
488
|
+
const max = powers[from];
|
|
489
|
+
const mask = powers[to] - 1;
|
|
490
|
+
const res = [];
|
|
491
|
+
for (const n of data) {
|
|
492
|
+
anumber(n);
|
|
493
|
+
if (n >= max)
|
|
494
|
+
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
|
495
|
+
carry = carry << from | n;
|
|
496
|
+
if (pos + from > 32)
|
|
497
|
+
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
|
498
|
+
pos += from;
|
|
499
|
+
for (; pos >= to; pos -= to)
|
|
500
|
+
res.push((carry >> pos - to & mask) >>> 0);
|
|
501
|
+
const pow = powers[pos];
|
|
502
|
+
if (pow === void 0)
|
|
503
|
+
throw new Error("invalid carry");
|
|
504
|
+
carry &= pow - 1;
|
|
505
|
+
}
|
|
506
|
+
carry = carry << to - pos & mask;
|
|
507
|
+
if (!padding && pos >= from)
|
|
508
|
+
throw new Error("Excess padding");
|
|
509
|
+
if (!padding && carry > 0)
|
|
510
|
+
throw new Error(`Non-zero padding: ${carry}`);
|
|
511
|
+
if (padding && pos > 0)
|
|
512
|
+
res.push(carry >>> 0);
|
|
513
|
+
return res;
|
|
514
|
+
}
|
|
515
|
+
// @__NO_SIDE_EFFECTS__
|
|
516
|
+
function radix(num) {
|
|
517
|
+
anumber(num);
|
|
518
|
+
const _256 = 2 ** 8;
|
|
519
|
+
return {
|
|
520
|
+
encode: (bytes) => {
|
|
521
|
+
if (!isBytes(bytes))
|
|
522
|
+
throw new Error("radix.encode input should be Uint8Array");
|
|
523
|
+
return convertRadix(Array.from(bytes), _256, num);
|
|
524
|
+
},
|
|
525
|
+
decode: (digits) => {
|
|
526
|
+
anumArr("radix.decode", digits);
|
|
527
|
+
return Uint8Array.from(convertRadix(digits, num, _256));
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
// @__NO_SIDE_EFFECTS__
|
|
532
|
+
function radix2(bits, revPadding = false) {
|
|
533
|
+
anumber(bits);
|
|
534
|
+
if (/* @__PURE__ */ radix2carry(8, bits) > 32 || /* @__PURE__ */ radix2carry(bits, 8) > 32)
|
|
535
|
+
throw new Error("radix2: carry overflow");
|
|
536
|
+
return {
|
|
537
|
+
encode: (bytes) => {
|
|
538
|
+
if (!isBytes(bytes))
|
|
539
|
+
throw new Error("radix2.encode input should be Uint8Array");
|
|
540
|
+
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
|
541
|
+
},
|
|
542
|
+
decode: (digits) => {
|
|
543
|
+
anumArr("radix2.decode", digits);
|
|
544
|
+
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function unsafeWrapper(fn) {
|
|
549
|
+
afn(fn);
|
|
550
|
+
return function(...args) {
|
|
551
|
+
try {
|
|
552
|
+
return fn.apply(null, args);
|
|
553
|
+
} catch (e) {
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function checksum(len, fn) {
|
|
558
|
+
anumber(len);
|
|
559
|
+
afn(fn);
|
|
560
|
+
return {
|
|
561
|
+
encode(data) {
|
|
562
|
+
if (!isBytes(data))
|
|
563
|
+
throw new Error("checksum.encode: input should be Uint8Array");
|
|
564
|
+
const sum = fn(data).slice(0, len);
|
|
565
|
+
const res = new Uint8Array(data.length + len);
|
|
566
|
+
res.set(data);
|
|
567
|
+
res.set(sum, data.length);
|
|
568
|
+
return res;
|
|
569
|
+
},
|
|
570
|
+
decode(data) {
|
|
571
|
+
if (!isBytes(data))
|
|
572
|
+
throw new Error("checksum.decode: input should be Uint8Array");
|
|
573
|
+
const payload = data.slice(0, -len);
|
|
574
|
+
const oldChecksum = data.slice(-len);
|
|
575
|
+
const newChecksum = fn(payload).slice(0, len);
|
|
576
|
+
for (let i = 0; i < len; i++)
|
|
577
|
+
if (newChecksum[i] !== oldChecksum[i])
|
|
578
|
+
throw new Error("Invalid checksum");
|
|
579
|
+
return payload;
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
|
|
584
|
+
var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
585
|
+
var createBase58check = (sha2563) => /* @__PURE__ */ chain(checksum(4, (data) => sha2563(sha2563(data))), base58);
|
|
586
|
+
var base58check = createBase58check;
|
|
587
|
+
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join(""));
|
|
588
|
+
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
589
|
+
function bech32Polymod(pre) {
|
|
590
|
+
const b = pre >> 25;
|
|
591
|
+
let chk = (pre & 33554431) << 5;
|
|
592
|
+
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
|
593
|
+
if ((b >> i & 1) === 1)
|
|
594
|
+
chk ^= POLYMOD_GENERATORS[i];
|
|
595
|
+
}
|
|
596
|
+
return chk;
|
|
597
|
+
}
|
|
598
|
+
function bechChecksum(prefix, words, encodingConst = 1) {
|
|
599
|
+
const len = prefix.length;
|
|
600
|
+
let chk = 1;
|
|
601
|
+
for (let i = 0; i < len; i++) {
|
|
602
|
+
const c = prefix.charCodeAt(i);
|
|
603
|
+
if (c < 33 || c > 126)
|
|
604
|
+
throw new Error(`Invalid prefix (${prefix})`);
|
|
605
|
+
chk = bech32Polymod(chk) ^ c >> 5;
|
|
606
|
+
}
|
|
607
|
+
chk = bech32Polymod(chk);
|
|
608
|
+
for (let i = 0; i < len; i++)
|
|
609
|
+
chk = bech32Polymod(chk) ^ prefix.charCodeAt(i) & 31;
|
|
610
|
+
for (let v of words)
|
|
611
|
+
chk = bech32Polymod(chk) ^ v;
|
|
612
|
+
for (let i = 0; i < 6; i++)
|
|
613
|
+
chk = bech32Polymod(chk);
|
|
614
|
+
chk ^= encodingConst;
|
|
615
|
+
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
|
|
616
|
+
}
|
|
617
|
+
// @__NO_SIDE_EFFECTS__
|
|
618
|
+
function genBech32(encoding) {
|
|
619
|
+
const ENCODING_CONST = 1 ;
|
|
620
|
+
const _words = /* @__PURE__ */ radix2(5);
|
|
621
|
+
const fromWords = _words.decode;
|
|
622
|
+
const toWords = _words.encode;
|
|
623
|
+
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
|
624
|
+
function encode(prefix, words, limit = 90) {
|
|
625
|
+
astr("bech32.encode prefix", prefix);
|
|
626
|
+
if (isBytes(words))
|
|
627
|
+
words = Array.from(words);
|
|
628
|
+
anumArr("bech32.encode", words);
|
|
629
|
+
const plen = prefix.length;
|
|
630
|
+
if (plen === 0)
|
|
631
|
+
throw new TypeError(`Invalid prefix length ${plen}`);
|
|
632
|
+
const actualLength = plen + 7 + words.length;
|
|
633
|
+
if (limit !== false && actualLength > limit)
|
|
634
|
+
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
|
635
|
+
const lowered = prefix.toLowerCase();
|
|
636
|
+
const sum = bechChecksum(lowered, words, ENCODING_CONST);
|
|
637
|
+
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
|
|
638
|
+
}
|
|
639
|
+
function decode(str, limit = 90) {
|
|
640
|
+
astr("bech32.decode input", str);
|
|
641
|
+
const slen = str.length;
|
|
642
|
+
if (slen < 8 || limit !== false && slen > limit)
|
|
643
|
+
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
|
|
644
|
+
const lowered = str.toLowerCase();
|
|
645
|
+
if (str !== lowered && str !== str.toUpperCase())
|
|
646
|
+
throw new Error(`String must be lowercase or uppercase`);
|
|
647
|
+
const sepIndex = lowered.lastIndexOf("1");
|
|
648
|
+
if (sepIndex === 0 || sepIndex === -1)
|
|
649
|
+
throw new Error(`Letter "1" must be present between prefix and data only`);
|
|
650
|
+
const prefix = lowered.slice(0, sepIndex);
|
|
651
|
+
const data = lowered.slice(sepIndex + 1);
|
|
652
|
+
if (data.length < 6)
|
|
653
|
+
throw new Error("Data must be at least 6 characters long");
|
|
654
|
+
const words = BECH_ALPHABET.decode(data).slice(0, -6);
|
|
655
|
+
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
|
656
|
+
if (!data.endsWith(sum))
|
|
657
|
+
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
|
658
|
+
return { prefix, words };
|
|
659
|
+
}
|
|
660
|
+
const decodeUnsafe = unsafeWrapper(decode);
|
|
661
|
+
function decodeToBytes(str) {
|
|
662
|
+
const { prefix, words } = decode(str, false);
|
|
663
|
+
return { prefix, words, bytes: fromWords(words) };
|
|
664
|
+
}
|
|
665
|
+
function encodeFromBytes(prefix, bytes) {
|
|
666
|
+
return encode(prefix, toWords(bytes));
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
encode,
|
|
670
|
+
decode,
|
|
671
|
+
encodeFromBytes,
|
|
672
|
+
decodeToBytes,
|
|
673
|
+
decodeUnsafe,
|
|
674
|
+
fromWords,
|
|
675
|
+
fromWordsUnsafe,
|
|
676
|
+
toWords
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
var bech32 = /* @__PURE__ */ genBech32();
|
|
680
|
+
|
|
681
|
+
// node_modules/@scure/bip32/index.js
|
|
682
|
+
var Point = secp256k1.Point;
|
|
683
|
+
var { Fn } = Point;
|
|
684
|
+
var base58check2 = createBase58check(sha256);
|
|
685
|
+
var MASTER_SECRET = Uint8Array.from("Bitcoin seed".split(""), (char) => char.charCodeAt(0));
|
|
686
|
+
var BITCOIN_VERSIONS = { private: 76066276, public: 76067358 };
|
|
687
|
+
var HARDENED_OFFSET = 2147483648;
|
|
688
|
+
var hash160 = (data) => ripemd160$1(sha256(data));
|
|
689
|
+
var fromU32 = (data) => createView(data).getUint32(0, false);
|
|
690
|
+
var toU32 = (n) => {
|
|
691
|
+
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
|
692
|
+
throw new Error("invalid number, should be from 0 to 2**32-1, got " + n);
|
|
693
|
+
}
|
|
694
|
+
const buf = new Uint8Array(4);
|
|
695
|
+
createView(buf).setUint32(0, n, false);
|
|
696
|
+
return buf;
|
|
697
|
+
};
|
|
698
|
+
var HDKey = class _HDKey {
|
|
699
|
+
get fingerprint() {
|
|
700
|
+
if (!this.pubHash) {
|
|
701
|
+
throw new Error("No publicKey set!");
|
|
702
|
+
}
|
|
703
|
+
return fromU32(this.pubHash);
|
|
704
|
+
}
|
|
705
|
+
get identifier() {
|
|
706
|
+
return this.pubHash;
|
|
707
|
+
}
|
|
708
|
+
get pubKeyHash() {
|
|
709
|
+
return this.pubHash;
|
|
710
|
+
}
|
|
711
|
+
get privateKey() {
|
|
712
|
+
return this._privateKey || null;
|
|
713
|
+
}
|
|
714
|
+
get publicKey() {
|
|
715
|
+
return this._publicKey || null;
|
|
716
|
+
}
|
|
717
|
+
get privateExtendedKey() {
|
|
718
|
+
const priv = this._privateKey;
|
|
719
|
+
if (!priv) {
|
|
720
|
+
throw new Error("No private key");
|
|
721
|
+
}
|
|
722
|
+
return base58check2.encode(this.serialize(this.versions.private, concatBytes(Uint8Array.of(0), priv)));
|
|
723
|
+
}
|
|
724
|
+
get publicExtendedKey() {
|
|
725
|
+
if (!this._publicKey) {
|
|
726
|
+
throw new Error("No public key");
|
|
727
|
+
}
|
|
728
|
+
return base58check2.encode(this.serialize(this.versions.public, this._publicKey));
|
|
729
|
+
}
|
|
730
|
+
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
|
|
731
|
+
abytes(seed);
|
|
732
|
+
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
|
733
|
+
throw new Error("HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got " + seed.length);
|
|
734
|
+
}
|
|
735
|
+
const I = hmac(sha512, MASTER_SECRET, seed);
|
|
736
|
+
const privateKey = I.slice(0, 32);
|
|
737
|
+
const chainCode = I.slice(32);
|
|
738
|
+
return new _HDKey({ versions, chainCode, privateKey });
|
|
739
|
+
}
|
|
740
|
+
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
|
|
741
|
+
const keyBuffer = base58check2.decode(base58key);
|
|
742
|
+
const keyView = createView(keyBuffer);
|
|
743
|
+
const version = keyView.getUint32(0, false);
|
|
744
|
+
const opt = {
|
|
745
|
+
versions,
|
|
746
|
+
depth: keyBuffer[4],
|
|
747
|
+
parentFingerprint: keyView.getUint32(5, false),
|
|
748
|
+
index: keyView.getUint32(9, false),
|
|
749
|
+
chainCode: keyBuffer.slice(13, 45)
|
|
750
|
+
};
|
|
751
|
+
const key = keyBuffer.slice(45);
|
|
752
|
+
const isPriv = key[0] === 0;
|
|
753
|
+
if (version !== versions[isPriv ? "private" : "public"]) {
|
|
754
|
+
throw new Error("Version mismatch");
|
|
755
|
+
}
|
|
756
|
+
if (isPriv) {
|
|
757
|
+
return new _HDKey({ ...opt, privateKey: key.slice(1) });
|
|
758
|
+
} else {
|
|
759
|
+
return new _HDKey({ ...opt, publicKey: key });
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
static fromJSON(json) {
|
|
763
|
+
return _HDKey.fromExtendedKey(json.xpriv);
|
|
764
|
+
}
|
|
765
|
+
versions;
|
|
766
|
+
depth = 0;
|
|
767
|
+
index = 0;
|
|
768
|
+
chainCode = null;
|
|
769
|
+
parentFingerprint = 0;
|
|
770
|
+
_privateKey;
|
|
771
|
+
_publicKey;
|
|
772
|
+
pubHash;
|
|
773
|
+
constructor(opt) {
|
|
774
|
+
if (!opt || typeof opt !== "object") {
|
|
775
|
+
throw new Error("HDKey.constructor must not be called directly");
|
|
776
|
+
}
|
|
777
|
+
this.versions = opt.versions || BITCOIN_VERSIONS;
|
|
778
|
+
this.depth = opt.depth || 0;
|
|
779
|
+
this.chainCode = opt.chainCode || null;
|
|
780
|
+
this.index = opt.index || 0;
|
|
781
|
+
this.parentFingerprint = opt.parentFingerprint || 0;
|
|
782
|
+
if (!this.depth) {
|
|
783
|
+
if (this.parentFingerprint || this.index) {
|
|
784
|
+
throw new Error("HDKey: zero depth with non-zero index/parent fingerprint");
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (this.depth > 255) {
|
|
788
|
+
throw new Error("HDKey: depth exceeds the serializable value 255");
|
|
789
|
+
}
|
|
790
|
+
if (opt.publicKey && opt.privateKey) {
|
|
791
|
+
throw new Error("HDKey: publicKey and privateKey at same time.");
|
|
792
|
+
}
|
|
793
|
+
if (opt.privateKey) {
|
|
794
|
+
if (!secp256k1.utils.isValidSecretKey(opt.privateKey))
|
|
795
|
+
throw new Error("Invalid private key");
|
|
796
|
+
this._privateKey = opt.privateKey;
|
|
797
|
+
this._publicKey = secp256k1.getPublicKey(opt.privateKey, true);
|
|
798
|
+
} else if (opt.publicKey) {
|
|
799
|
+
this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true);
|
|
800
|
+
} else {
|
|
801
|
+
throw new Error("HDKey: no public or private key provided");
|
|
802
|
+
}
|
|
803
|
+
this.pubHash = hash160(this._publicKey);
|
|
804
|
+
}
|
|
805
|
+
derive(path) {
|
|
806
|
+
if (!/^[mM]'?/.test(path)) {
|
|
807
|
+
throw new Error('Path must start with "m" or "M"');
|
|
808
|
+
}
|
|
809
|
+
if (/^[mM]'?$/.test(path)) {
|
|
810
|
+
return this;
|
|
811
|
+
}
|
|
812
|
+
const parts = path.replace(/^[mM]'?\//, "").split("/");
|
|
813
|
+
let child = this;
|
|
814
|
+
for (const c of parts) {
|
|
815
|
+
const m = /^(\d+)('?)$/.exec(c);
|
|
816
|
+
const m1 = m && m[1];
|
|
817
|
+
if (!m || m.length !== 3 || typeof m1 !== "string")
|
|
818
|
+
throw new Error("invalid child index: " + c);
|
|
819
|
+
let idx = +m1;
|
|
820
|
+
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
|
|
821
|
+
throw new Error("Invalid index");
|
|
822
|
+
}
|
|
823
|
+
if (m[2] === "'") {
|
|
824
|
+
idx += HARDENED_OFFSET;
|
|
825
|
+
}
|
|
826
|
+
child = child.deriveChild(idx);
|
|
827
|
+
}
|
|
828
|
+
return child;
|
|
829
|
+
}
|
|
830
|
+
deriveChild(index) {
|
|
831
|
+
if (!this._publicKey || !this.chainCode) {
|
|
832
|
+
throw new Error("No publicKey or chainCode set");
|
|
833
|
+
}
|
|
834
|
+
let data = toU32(index);
|
|
835
|
+
if (index >= HARDENED_OFFSET) {
|
|
836
|
+
const priv = this._privateKey;
|
|
837
|
+
if (!priv) {
|
|
838
|
+
throw new Error("Could not derive hardened child key");
|
|
839
|
+
}
|
|
840
|
+
data = concatBytes(Uint8Array.of(0), priv, data);
|
|
841
|
+
} else {
|
|
842
|
+
data = concatBytes(this._publicKey, data);
|
|
843
|
+
}
|
|
844
|
+
const I = hmac(sha512, this.chainCode, data);
|
|
845
|
+
const childTweak = I.slice(0, 32);
|
|
846
|
+
const chainCode = I.slice(32);
|
|
847
|
+
if (!secp256k1.utils.isValidSecretKey(childTweak)) {
|
|
848
|
+
throw new Error("Tweak bigger than curve order");
|
|
849
|
+
}
|
|
850
|
+
const opt = {
|
|
851
|
+
versions: this.versions,
|
|
852
|
+
chainCode,
|
|
853
|
+
depth: this.depth + 1,
|
|
854
|
+
parentFingerprint: this.fingerprint,
|
|
855
|
+
index
|
|
856
|
+
};
|
|
857
|
+
const ctweak = Fn.fromBytes(childTweak);
|
|
858
|
+
try {
|
|
859
|
+
if (this._privateKey) {
|
|
860
|
+
const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak);
|
|
861
|
+
if (!Fn.isValidNot0(added)) {
|
|
862
|
+
throw new Error("The tweak was out of range or the resulted private key is invalid");
|
|
863
|
+
}
|
|
864
|
+
opt.privateKey = Fn.toBytes(added);
|
|
865
|
+
} else {
|
|
866
|
+
const added = Point.fromBytes(this._publicKey).add(Point.BASE.multiply(ctweak));
|
|
867
|
+
if (added.equals(Point.ZERO)) {
|
|
868
|
+
throw new Error("The tweak was equal to negative P, which made the result key invalid");
|
|
869
|
+
}
|
|
870
|
+
opt.publicKey = added.toBytes(true);
|
|
871
|
+
}
|
|
872
|
+
return new _HDKey(opt);
|
|
873
|
+
} catch (err) {
|
|
874
|
+
return this.deriveChild(index + 1);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
sign(hash) {
|
|
878
|
+
if (!this._privateKey) {
|
|
879
|
+
throw new Error("No privateKey set!");
|
|
880
|
+
}
|
|
881
|
+
abytes(hash, 32);
|
|
882
|
+
return secp256k1.sign(hash, this._privateKey, { prehash: false });
|
|
883
|
+
}
|
|
884
|
+
verify(hash, signature) {
|
|
885
|
+
abytes(hash, 32);
|
|
886
|
+
abytes(signature, 64);
|
|
887
|
+
if (!this._publicKey) {
|
|
888
|
+
throw new Error("No publicKey set!");
|
|
889
|
+
}
|
|
890
|
+
return secp256k1.verify(signature, hash, this._publicKey, { prehash: false });
|
|
891
|
+
}
|
|
892
|
+
wipePrivateData() {
|
|
893
|
+
if (this._privateKey) {
|
|
894
|
+
this._privateKey.fill(0);
|
|
895
|
+
this._privateKey = void 0;
|
|
896
|
+
}
|
|
897
|
+
return this;
|
|
898
|
+
}
|
|
899
|
+
toJSON() {
|
|
900
|
+
return {
|
|
901
|
+
xpriv: this.privateExtendedKey,
|
|
902
|
+
xpub: this.publicExtendedKey
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
serialize(version, key) {
|
|
906
|
+
if (!this.chainCode) {
|
|
907
|
+
throw new Error("No chainCode set");
|
|
908
|
+
}
|
|
909
|
+
abytes(key, 33);
|
|
910
|
+
return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
|
|
911
|
+
}
|
|
912
|
+
};
|
|
327
913
|
var DERIVATION_PATHS2 = {
|
|
328
914
|
ethereum: "m/44'/60'/0'/0/0",
|
|
329
915
|
bitcoin_mainnet: "m/84'/0'/0'/0/0",
|
|
@@ -346,7 +932,7 @@ function deriveBitcoinAddress(seed, network = "mainnet") {
|
|
|
346
932
|
if (!child.publicKey) {
|
|
347
933
|
throw new Error("Failed to derive public key");
|
|
348
934
|
}
|
|
349
|
-
const pubKeyHash = ripemd160(sha256(child.publicKey));
|
|
935
|
+
const pubKeyHash = ripemd160(sha256$1(child.publicKey));
|
|
350
936
|
const witnessVersion = 0;
|
|
351
937
|
const words = bech32.toWords(pubKeyHash);
|
|
352
938
|
words.unshift(witnessVersion);
|
|
@@ -387,7 +973,7 @@ async function deriveTonAddress(seed) {
|
|
|
387
973
|
const publicKey = keypair.publicKey;
|
|
388
974
|
const workchain = 0;
|
|
389
975
|
const flags = 17;
|
|
390
|
-
const hash = sha256(publicKey);
|
|
976
|
+
const hash = sha256$1(publicKey);
|
|
391
977
|
const addressData = new Uint8Array(34);
|
|
392
978
|
addressData[0] = flags;
|
|
393
979
|
addressData[1] = workchain;
|
|
@@ -424,7 +1010,7 @@ function deriveTronAddress(seed) {
|
|
|
424
1010
|
for (let i = 0; i < 20; i++) {
|
|
425
1011
|
addressBytes[i + 1] = parseInt(ethAddressHex.slice(i * 2, i * 2 + 2), 16);
|
|
426
1012
|
}
|
|
427
|
-
const tronBase58check = base58check(sha256);
|
|
1013
|
+
const tronBase58check = base58check(sha256$1);
|
|
428
1014
|
return tronBase58check.encode(addressBytes);
|
|
429
1015
|
} catch (error) {
|
|
430
1016
|
console.error("TRON address derivation failed:", error);
|
|
@@ -439,7 +1025,7 @@ function deriveSparkAddress(seed, network = "mainnet") {
|
|
|
439
1025
|
if (!child.publicKey) {
|
|
440
1026
|
throw new Error("Failed to derive public key");
|
|
441
1027
|
}
|
|
442
|
-
const pubKeyHash = ripemd160(sha256(child.publicKey));
|
|
1028
|
+
const pubKeyHash = ripemd160(sha256$1(child.publicKey));
|
|
443
1029
|
const witnessVersion = 0;
|
|
444
1030
|
const words = bech32.toWords(pubKeyHash);
|
|
445
1031
|
words.unshift(witnessVersion);
|
|
@@ -540,9 +1126,9 @@ var CHAIN_ERROR_MESSAGES = {
|
|
|
540
1126
|
"no route": "NETWORK_ERROR"
|
|
541
1127
|
}
|
|
542
1128
|
};
|
|
543
|
-
function parseChainError(
|
|
1129
|
+
function parseChainError(chain2, errorMessage) {
|
|
544
1130
|
const errorLower = errorMessage.toLowerCase();
|
|
545
|
-
const chainErrors = CHAIN_ERROR_MESSAGES[
|
|
1131
|
+
const chainErrors = CHAIN_ERROR_MESSAGES[chain2];
|
|
546
1132
|
for (const [pattern, code] of Object.entries(chainErrors)) {
|
|
547
1133
|
if (errorLower.includes(pattern)) {
|
|
548
1134
|
return code;
|
|
@@ -680,38 +1266,38 @@ var ZubariWdkService = class {
|
|
|
680
1266
|
* For Ethereum, falls back to local derivation if API fails.
|
|
681
1267
|
* For other chains, WDK API is required - no placeholder fallback.
|
|
682
1268
|
*/
|
|
683
|
-
async deriveAddress(seed,
|
|
1269
|
+
async deriveAddress(seed, chain2) {
|
|
684
1270
|
await this.initialize();
|
|
685
|
-
const path = this.getDerivationPath(
|
|
1271
|
+
const path = this.getDerivationPath(chain2);
|
|
686
1272
|
try {
|
|
687
|
-
const response = await this.apiClient.deriveAddress(seed,
|
|
1273
|
+
const response = await this.apiClient.deriveAddress(seed, chain2, this.config.network);
|
|
688
1274
|
if (response.success && response.address) {
|
|
689
1275
|
return {
|
|
690
|
-
chain,
|
|
1276
|
+
chain: chain2,
|
|
691
1277
|
address: response.address,
|
|
692
1278
|
path: response.path || path
|
|
693
1279
|
};
|
|
694
1280
|
}
|
|
695
1281
|
} catch (error) {
|
|
696
|
-
console.warn(`API address derivation failed for ${
|
|
697
|
-
if (
|
|
698
|
-
return this.deriveBrowserAddress(seed,
|
|
1282
|
+
console.warn(`API address derivation failed for ${chain2}:`, error);
|
|
1283
|
+
if (chain2 === "ethereum") {
|
|
1284
|
+
return this.deriveBrowserAddress(seed, chain2);
|
|
699
1285
|
}
|
|
700
1286
|
}
|
|
701
1287
|
if (this.useNativeWdk && this.nativeWdkService) {
|
|
702
1288
|
try {
|
|
703
1289
|
const wdk = this.nativeWdkService;
|
|
704
1290
|
await wdk.initialize(seed);
|
|
705
|
-
return await wdk.deriveAddress(
|
|
1291
|
+
return await wdk.deriveAddress(chain2);
|
|
706
1292
|
} catch (error) {
|
|
707
|
-
console.warn(`Native WDK address derivation failed for ${
|
|
1293
|
+
console.warn(`Native WDK address derivation failed for ${chain2}:`, error);
|
|
708
1294
|
}
|
|
709
1295
|
}
|
|
710
|
-
if (
|
|
711
|
-
return this.deriveBrowserAddress(seed,
|
|
1296
|
+
if (chain2 === "ethereum") {
|
|
1297
|
+
return this.deriveBrowserAddress(seed, chain2);
|
|
712
1298
|
}
|
|
713
1299
|
throw new Error(
|
|
714
|
-
`WDK API required for ${
|
|
1300
|
+
`WDK API required for ${chain2} address derivation. Ensure the backend is running.`
|
|
715
1301
|
);
|
|
716
1302
|
}
|
|
717
1303
|
/**
|
|
@@ -791,13 +1377,13 @@ var ZubariWdkService = class {
|
|
|
791
1377
|
/**
|
|
792
1378
|
* Get fee rates for a chain
|
|
793
1379
|
*/
|
|
794
|
-
async getFeeRates(seed,
|
|
1380
|
+
async getFeeRates(seed, chain2) {
|
|
795
1381
|
await this.initialize();
|
|
796
1382
|
try {
|
|
797
1383
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/fee-rates`, {
|
|
798
1384
|
method: "POST",
|
|
799
1385
|
headers: { "Content-Type": "application/json" },
|
|
800
|
-
body: JSON.stringify({ seed, chain, network: this.config.network })
|
|
1386
|
+
body: JSON.stringify({ seed, chain: chain2, network: this.config.network })
|
|
801
1387
|
});
|
|
802
1388
|
if (response.ok) {
|
|
803
1389
|
const data = await response.json();
|
|
@@ -806,20 +1392,20 @@ var ZubariWdkService = class {
|
|
|
806
1392
|
}
|
|
807
1393
|
}
|
|
808
1394
|
} catch (error) {
|
|
809
|
-
console.warn(`Failed to fetch fee rates for ${
|
|
1395
|
+
console.warn(`Failed to fetch fee rates for ${chain2}:`, error);
|
|
810
1396
|
}
|
|
811
1397
|
return { slow: "0", normal: "0", fast: "0" };
|
|
812
1398
|
}
|
|
813
1399
|
/**
|
|
814
1400
|
* Estimate transaction fee
|
|
815
1401
|
*/
|
|
816
|
-
async estimateFee(seed,
|
|
1402
|
+
async estimateFee(seed, chain2, to, amount) {
|
|
817
1403
|
await this.initialize();
|
|
818
1404
|
try {
|
|
819
1405
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/estimate-fee`, {
|
|
820
1406
|
method: "POST",
|
|
821
1407
|
headers: { "Content-Type": "application/json" },
|
|
822
|
-
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1408
|
+
body: JSON.stringify({ seed, chain: chain2, to, amount, network: this.config.network })
|
|
823
1409
|
});
|
|
824
1410
|
if (response.ok) {
|
|
825
1411
|
const data = await response.json();
|
|
@@ -828,9 +1414,9 @@ var ZubariWdkService = class {
|
|
|
828
1414
|
}
|
|
829
1415
|
}
|
|
830
1416
|
} catch (error) {
|
|
831
|
-
console.warn(`Failed to estimate fee for ${
|
|
1417
|
+
console.warn(`Failed to estimate fee for ${chain2}:`, error);
|
|
832
1418
|
}
|
|
833
|
-
return { fee: "0", symbol: this.getChainSymbol(
|
|
1419
|
+
return { fee: "0", symbol: this.getChainSymbol(chain2) };
|
|
834
1420
|
}
|
|
835
1421
|
/**
|
|
836
1422
|
* Send a transaction on any supported chain
|
|
@@ -841,10 +1427,10 @@ var ZubariWdkService = class {
|
|
|
841
1427
|
* @param amount - Amount to send (in native units: ETH, BTC, SOL, etc.)
|
|
842
1428
|
* @returns Transaction result with hash on success, or error details on failure
|
|
843
1429
|
*/
|
|
844
|
-
async sendTransaction(seed,
|
|
1430
|
+
async sendTransaction(seed, chain2, to, amount) {
|
|
845
1431
|
await this.initialize();
|
|
846
1432
|
const startTime = Date.now();
|
|
847
|
-
console.log(`[ZubariWdkService] Sending ${
|
|
1433
|
+
console.log(`[ZubariWdkService] Sending ${chain2} transaction`, {
|
|
848
1434
|
to: `${to.slice(0, 10)}...${to.slice(-6)}`,
|
|
849
1435
|
amount,
|
|
850
1436
|
network: this.config.network
|
|
@@ -853,7 +1439,7 @@ var ZubariWdkService = class {
|
|
|
853
1439
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/send`, {
|
|
854
1440
|
method: "POST",
|
|
855
1441
|
headers: { "Content-Type": "application/json" },
|
|
856
|
-
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1442
|
+
body: JSON.stringify({ seed, chain: chain2, to, amount, network: this.config.network })
|
|
857
1443
|
});
|
|
858
1444
|
const elapsed = Date.now() - startTime;
|
|
859
1445
|
if (response.ok) {
|
|
@@ -863,22 +1449,22 @@ var ZubariWdkService = class {
|
|
|
863
1449
|
txHash = txHash.hash;
|
|
864
1450
|
}
|
|
865
1451
|
if (txHash) {
|
|
866
|
-
const isValid = this.validateTxHash(
|
|
1452
|
+
const isValid = this.validateTxHash(chain2, txHash);
|
|
867
1453
|
if (!isValid) {
|
|
868
|
-
console.warn(`[ZubariWdkService] Invalid ${
|
|
1454
|
+
console.warn(`[ZubariWdkService] Invalid ${chain2} tx hash format:`, txHash);
|
|
869
1455
|
}
|
|
870
1456
|
}
|
|
871
|
-
console.log(`[ZubariWdkService] ${
|
|
1457
|
+
console.log(`[ZubariWdkService] ${chain2} transaction ${data.success ? "SUCCESS" : "FAILED"}`, {
|
|
872
1458
|
txHash: txHash ? `${txHash.slice(0, 16)}...` : "N/A",
|
|
873
1459
|
elapsed: `${elapsed}ms`
|
|
874
1460
|
});
|
|
875
1461
|
if (!data.success) {
|
|
876
|
-
const errorCode2 = parseChainError(
|
|
1462
|
+
const errorCode2 = parseChainError(chain2, data.error || "");
|
|
877
1463
|
return {
|
|
878
1464
|
success: false,
|
|
879
1465
|
error: data.error,
|
|
880
1466
|
errorCode: errorCode2,
|
|
881
|
-
chain
|
|
1467
|
+
chain: chain2
|
|
882
1468
|
};
|
|
883
1469
|
}
|
|
884
1470
|
return {
|
|
@@ -887,14 +1473,14 @@ var ZubariWdkService = class {
|
|
|
887
1473
|
from: data.from,
|
|
888
1474
|
to: data.to,
|
|
889
1475
|
amount: data.amount,
|
|
890
|
-
chain: data.chain ||
|
|
1476
|
+
chain: data.chain || chain2,
|
|
891
1477
|
network: data.network || this.config.network
|
|
892
1478
|
};
|
|
893
1479
|
}
|
|
894
1480
|
const errorData = await response.json().catch(() => ({}));
|
|
895
1481
|
const errorMessage = errorData.error || `HTTP ${response.status}`;
|
|
896
|
-
const errorCode = parseChainError(
|
|
897
|
-
console.error(`[ZubariWdkService] ${
|
|
1482
|
+
const errorCode = parseChainError(chain2, errorMessage);
|
|
1483
|
+
console.error(`[ZubariWdkService] ${chain2} transaction FAILED`, {
|
|
898
1484
|
status: response.status,
|
|
899
1485
|
error: errorMessage,
|
|
900
1486
|
errorCode,
|
|
@@ -904,13 +1490,13 @@ var ZubariWdkService = class {
|
|
|
904
1490
|
success: false,
|
|
905
1491
|
error: errorMessage,
|
|
906
1492
|
errorCode,
|
|
907
|
-
chain
|
|
1493
|
+
chain: chain2
|
|
908
1494
|
};
|
|
909
1495
|
} catch (error) {
|
|
910
1496
|
const elapsed = Date.now() - startTime;
|
|
911
1497
|
const errorMessage = error instanceof Error ? error.message : "Transaction failed";
|
|
912
|
-
const errorCode = parseChainError(
|
|
913
|
-
console.error(`[ZubariWdkService] ${
|
|
1498
|
+
const errorCode = parseChainError(chain2, errorMessage);
|
|
1499
|
+
console.error(`[ZubariWdkService] ${chain2} transaction ERROR`, {
|
|
914
1500
|
error: errorMessage,
|
|
915
1501
|
errorCode,
|
|
916
1502
|
elapsed: `${elapsed}ms`
|
|
@@ -919,15 +1505,15 @@ var ZubariWdkService = class {
|
|
|
919
1505
|
success: false,
|
|
920
1506
|
error: errorMessage,
|
|
921
1507
|
errorCode,
|
|
922
|
-
chain
|
|
1508
|
+
chain: chain2
|
|
923
1509
|
};
|
|
924
1510
|
}
|
|
925
1511
|
}
|
|
926
1512
|
/**
|
|
927
1513
|
* Validate transaction hash format for a specific chain
|
|
928
1514
|
*/
|
|
929
|
-
validateTxHash(
|
|
930
|
-
switch (
|
|
1515
|
+
validateTxHash(chain2, txHash) {
|
|
1516
|
+
switch (chain2) {
|
|
931
1517
|
case "ethereum":
|
|
932
1518
|
return /^0x[a-fA-F0-9]{64}$/.test(txHash);
|
|
933
1519
|
case "bitcoin":
|
|
@@ -959,7 +1545,7 @@ var ZubariWdkService = class {
|
|
|
959
1545
|
// ==========================================
|
|
960
1546
|
// Private Helper Methods
|
|
961
1547
|
// ==========================================
|
|
962
|
-
getDerivationPath(
|
|
1548
|
+
getDerivationPath(chain2) {
|
|
963
1549
|
const paths = {
|
|
964
1550
|
bitcoin: this.config.network === "testnet" ? "m/84'/1'/0'/0/0" : "m/84'/0'/0'/0/0",
|
|
965
1551
|
ethereum: "m/44'/60'/0'/0/0",
|
|
@@ -968,9 +1554,9 @@ var ZubariWdkService = class {
|
|
|
968
1554
|
solana: "m/44'/501'/0'/0'",
|
|
969
1555
|
spark: "m/44'/998'/0'/0/0"
|
|
970
1556
|
};
|
|
971
|
-
return paths[
|
|
1557
|
+
return paths[chain2];
|
|
972
1558
|
}
|
|
973
|
-
getChainSymbol(
|
|
1559
|
+
getChainSymbol(chain2) {
|
|
974
1560
|
const symbols = {
|
|
975
1561
|
ethereum: "ETH",
|
|
976
1562
|
bitcoin: "BTC",
|
|
@@ -979,16 +1565,16 @@ var ZubariWdkService = class {
|
|
|
979
1565
|
solana: "SOL",
|
|
980
1566
|
spark: "SAT"
|
|
981
1567
|
};
|
|
982
|
-
return symbols[
|
|
1568
|
+
return symbols[chain2];
|
|
983
1569
|
}
|
|
984
1570
|
/**
|
|
985
1571
|
* Derive address using browser-compatible libraries
|
|
986
1572
|
*/
|
|
987
|
-
async deriveBrowserAddress(seed,
|
|
988
|
-
const path = this.getDerivationPath(
|
|
1573
|
+
async deriveBrowserAddress(seed, chain2) {
|
|
1574
|
+
const path = this.getDerivationPath(chain2);
|
|
989
1575
|
try {
|
|
990
1576
|
let address;
|
|
991
|
-
switch (
|
|
1577
|
+
switch (chain2) {
|
|
992
1578
|
case "ethereum":
|
|
993
1579
|
address = deriveEthereumAddress(seed);
|
|
994
1580
|
break;
|
|
@@ -1008,11 +1594,11 @@ var ZubariWdkService = class {
|
|
|
1008
1594
|
address = await deriveTonAddress(seed);
|
|
1009
1595
|
break;
|
|
1010
1596
|
default:
|
|
1011
|
-
throw new Error(`Unsupported chain: ${
|
|
1597
|
+
throw new Error(`Unsupported chain: ${chain2}`);
|
|
1012
1598
|
}
|
|
1013
|
-
return { chain, address, path };
|
|
1599
|
+
return { chain: chain2, address, path };
|
|
1014
1600
|
} catch (error) {
|
|
1015
|
-
console.error(`Browser derivation failed for ${
|
|
1601
|
+
console.error(`Browser derivation failed for ${chain2}:`, error);
|
|
1016
1602
|
throw error;
|
|
1017
1603
|
}
|
|
1018
1604
|
}
|
|
@@ -1414,8 +2000,8 @@ async function fetchPrices() {
|
|
|
1414
2000
|
if (response.ok) {
|
|
1415
2001
|
const data = await response.json();
|
|
1416
2002
|
const prices = {};
|
|
1417
|
-
for (const [
|
|
1418
|
-
prices[
|
|
2003
|
+
for (const [chain2, geckoId] of Object.entries(COINGECKO_IDS)) {
|
|
2004
|
+
prices[chain2] = data[geckoId]?.usd || 0;
|
|
1419
2005
|
}
|
|
1420
2006
|
priceCache = { prices, timestamp: Date.now() };
|
|
1421
2007
|
return prices;
|
|
@@ -1425,22 +2011,9 @@ async function fetchPrices() {
|
|
|
1425
2011
|
}
|
|
1426
2012
|
return priceCache?.prices || {};
|
|
1427
2013
|
}
|
|
1428
|
-
async function getPriceForChain(
|
|
2014
|
+
async function getPriceForChain(chain2) {
|
|
1429
2015
|
const prices = await fetchPrices();
|
|
1430
|
-
return prices[
|
|
1431
|
-
}
|
|
1432
|
-
function tonFriendlyToRaw(addr) {
|
|
1433
|
-
if (addr.includes(":")) return addr;
|
|
1434
|
-
try {
|
|
1435
|
-
const b64 = addr.replace(/-/g, "+").replace(/_/g, "/");
|
|
1436
|
-
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
1437
|
-
if (bytes.length !== 36) return addr;
|
|
1438
|
-
const workchain = bytes[1] === 255 ? -1 : bytes[1];
|
|
1439
|
-
const hash = Array.from(bytes.slice(2, 34)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1440
|
-
return `${workchain}:${hash}`;
|
|
1441
|
-
} catch {
|
|
1442
|
-
return addr;
|
|
1443
|
-
}
|
|
2016
|
+
return prices[chain2] || 0;
|
|
1444
2017
|
}
|
|
1445
2018
|
var STORAGE_KEYS = {
|
|
1446
2019
|
ENCRYPTED_SEED: "encrypted_seed",
|
|
@@ -1646,9 +2219,9 @@ var WalletManager = class _WalletManager {
|
|
|
1646
2219
|
if (!this.derivedAddress) {
|
|
1647
2220
|
throw new Error("Wallet not initialized");
|
|
1648
2221
|
}
|
|
1649
|
-
const
|
|
2222
|
+
const chain2 = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
1650
2223
|
const client = createPublicClient({
|
|
1651
|
-
chain,
|
|
2224
|
+
chain: chain2,
|
|
1652
2225
|
transport: http(this.config.rpcUrl, {
|
|
1653
2226
|
timeout: 15e3,
|
|
1654
2227
|
// 15 second timeout
|
|
@@ -1670,9 +2243,9 @@ var WalletManager = class _WalletManager {
|
|
|
1670
2243
|
* Create viem public client for the current network
|
|
1671
2244
|
*/
|
|
1672
2245
|
getPublicClient() {
|
|
1673
|
-
const
|
|
2246
|
+
const chain2 = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
1674
2247
|
return createPublicClient({
|
|
1675
|
-
chain,
|
|
2248
|
+
chain: chain2,
|
|
1676
2249
|
transport: http(this.config.rpcUrl, {
|
|
1677
2250
|
timeout: 15e3,
|
|
1678
2251
|
// 15 second timeout
|
|
@@ -1726,11 +2299,11 @@ var WalletManager = class _WalletManager {
|
|
|
1726
2299
|
*
|
|
1727
2300
|
* No fallback to placeholder addresses - WDK API is required for real addresses.
|
|
1728
2301
|
*/
|
|
1729
|
-
static async deriveAddressForChainAsync(seed,
|
|
1730
|
-
if (
|
|
2302
|
+
static async deriveAddressForChainAsync(seed, chain2, network = "mainnet", apiUrl) {
|
|
2303
|
+
if (chain2 === "ethereum") {
|
|
1731
2304
|
try {
|
|
1732
2305
|
const wdkService2 = getZubariWdkService({ network, apiUrl });
|
|
1733
|
-
const result2 = await wdkService2.deriveAddress(seed,
|
|
2306
|
+
const result2 = await wdkService2.deriveAddress(seed, chain2);
|
|
1734
2307
|
return result2.address;
|
|
1735
2308
|
} catch (error) {
|
|
1736
2309
|
console.warn("WDK service failed for Ethereum, using local derivation:", error);
|
|
@@ -1738,7 +2311,7 @@ var WalletManager = class _WalletManager {
|
|
|
1738
2311
|
}
|
|
1739
2312
|
}
|
|
1740
2313
|
const wdkService = getZubariWdkService({ network, apiUrl });
|
|
1741
|
-
const result = await wdkService.deriveAddress(seed,
|
|
2314
|
+
const result = await wdkService.deriveAddress(seed, chain2);
|
|
1742
2315
|
return result.address;
|
|
1743
2316
|
}
|
|
1744
2317
|
/**
|
|
@@ -1747,14 +2320,14 @@ var WalletManager = class _WalletManager {
|
|
|
1747
2320
|
*
|
|
1748
2321
|
* @throws Error for non-Ethereum chains - use WDK API instead
|
|
1749
2322
|
*/
|
|
1750
|
-
static deriveAddressForChain(seed,
|
|
1751
|
-
if (
|
|
2323
|
+
static deriveAddressForChain(seed, chain2) {
|
|
2324
|
+
if (chain2 === "ethereum") {
|
|
1752
2325
|
const ethPath = DERIVATION_PATHS["ethereum"];
|
|
1753
2326
|
const ethNode = HDNodeWallet.fromPhrase(seed, void 0, `${ethPath}/0`);
|
|
1754
2327
|
return ethNode.address;
|
|
1755
2328
|
}
|
|
1756
2329
|
throw new Error(
|
|
1757
|
-
`Sync derivation not supported for ${
|
|
2330
|
+
`Sync derivation not supported for ${chain2}. Use deriveAddressForChainAsync() with WDK API.`
|
|
1758
2331
|
);
|
|
1759
2332
|
}
|
|
1760
2333
|
/**
|
|
@@ -1786,9 +2359,9 @@ var WalletManager = class _WalletManager {
|
|
|
1786
2359
|
const wdkAddresses = await this.wdkService.deriveAllAddresses(this.currentSeed);
|
|
1787
2360
|
const enabledChainsSet = new Set(this.config.enabledChains);
|
|
1788
2361
|
const addresses = {};
|
|
1789
|
-
for (const [
|
|
1790
|
-
if (enabledChainsSet.has(
|
|
1791
|
-
addresses[
|
|
2362
|
+
for (const [chain2, address] of Object.entries(wdkAddresses)) {
|
|
2363
|
+
if (enabledChainsSet.has(chain2) && address) {
|
|
2364
|
+
addresses[chain2] = address;
|
|
1792
2365
|
}
|
|
1793
2366
|
}
|
|
1794
2367
|
this.derivedAddresses = addresses;
|
|
@@ -1829,10 +2402,10 @@ var WalletManager = class _WalletManager {
|
|
|
1829
2402
|
*/
|
|
1830
2403
|
normalizeAddresses(addresses) {
|
|
1831
2404
|
const normalized = {};
|
|
1832
|
-
for (const [
|
|
2405
|
+
for (const [chain2, value] of Object.entries(addresses)) {
|
|
1833
2406
|
const addr = this.normalizeAddress(value);
|
|
1834
2407
|
if (addr) {
|
|
1835
|
-
normalized[
|
|
2408
|
+
normalized[chain2] = addr;
|
|
1836
2409
|
}
|
|
1837
2410
|
}
|
|
1838
2411
|
return normalized;
|
|
@@ -1885,20 +2458,20 @@ var WalletManager = class _WalletManager {
|
|
|
1885
2458
|
* Get address for a specific chain
|
|
1886
2459
|
* Returns cached address or null - use deriveAllAddressesAsync to derive addresses
|
|
1887
2460
|
*/
|
|
1888
|
-
getAddressForChain(
|
|
1889
|
-
const cachedValue = this.derivedAddresses[
|
|
2461
|
+
getAddressForChain(chain2) {
|
|
2462
|
+
const cachedValue = this.derivedAddresses[chain2];
|
|
1890
2463
|
if (cachedValue) {
|
|
1891
|
-
console.log(`[WalletManager] getAddressForChain(${
|
|
2464
|
+
console.log(`[WalletManager] getAddressForChain(${chain2}) cached value:`, cachedValue, "type:", typeof cachedValue);
|
|
1892
2465
|
const addr = this.normalizeAddress(cachedValue);
|
|
1893
|
-
console.log(`[WalletManager] getAddressForChain(${
|
|
2466
|
+
console.log(`[WalletManager] getAddressForChain(${chain2}) normalized:`, addr);
|
|
1894
2467
|
if (addr) {
|
|
1895
|
-
this.derivedAddresses[
|
|
2468
|
+
this.derivedAddresses[chain2] = addr;
|
|
1896
2469
|
return addr;
|
|
1897
2470
|
}
|
|
1898
2471
|
}
|
|
1899
|
-
if (
|
|
1900
|
-
this.derivedAddresses[
|
|
1901
|
-
return this.derivedAddresses[
|
|
2472
|
+
if (chain2 === "ethereum" && this.currentSeed) {
|
|
2473
|
+
this.derivedAddresses[chain2] = _WalletManager.deriveAddressForChain(this.currentSeed, chain2);
|
|
2474
|
+
return this.derivedAddresses[chain2];
|
|
1902
2475
|
}
|
|
1903
2476
|
return null;
|
|
1904
2477
|
}
|
|
@@ -1911,11 +2484,11 @@ var WalletManager = class _WalletManager {
|
|
|
1911
2484
|
/**
|
|
1912
2485
|
* Set the selected chain
|
|
1913
2486
|
*/
|
|
1914
|
-
setSelectedChain(
|
|
1915
|
-
if (!this.config.enabledChains.includes(
|
|
1916
|
-
throw new Error(`Chain ${
|
|
2487
|
+
setSelectedChain(chain2) {
|
|
2488
|
+
if (!this.config.enabledChains.includes(chain2)) {
|
|
2489
|
+
throw new Error(`Chain ${chain2} is not enabled`);
|
|
1917
2490
|
}
|
|
1918
|
-
this.selectedChain =
|
|
2491
|
+
this.selectedChain = chain2;
|
|
1919
2492
|
}
|
|
1920
2493
|
/**
|
|
1921
2494
|
* Get the currently selected chain
|
|
@@ -1932,22 +2505,22 @@ var WalletManager = class _WalletManager {
|
|
|
1932
2505
|
/**
|
|
1933
2506
|
* Get chain configuration
|
|
1934
2507
|
*/
|
|
1935
|
-
getChainConfig(
|
|
1936
|
-
return getNetworkConfig(
|
|
2508
|
+
getChainConfig(chain2) {
|
|
2509
|
+
return getNetworkConfig(chain2, this.config.network === "testnet");
|
|
1937
2510
|
}
|
|
1938
2511
|
/**
|
|
1939
2512
|
* Fetch balance for a specific chain
|
|
1940
2513
|
* Note: Currently only Ethereum is implemented
|
|
1941
2514
|
*/
|
|
1942
|
-
async fetchBalanceForChain(
|
|
1943
|
-
const address = this.getAddressForChain(
|
|
2515
|
+
async fetchBalanceForChain(chain2) {
|
|
2516
|
+
const address = this.getAddressForChain(chain2);
|
|
1944
2517
|
if (!address) {
|
|
1945
|
-
throw new Error(`No address for chain ${
|
|
2518
|
+
throw new Error(`No address for chain ${chain2}`);
|
|
1946
2519
|
}
|
|
1947
|
-
const networkConfig = this.getChainConfig(
|
|
2520
|
+
const networkConfig = this.getChainConfig(chain2);
|
|
1948
2521
|
let balance = "0";
|
|
1949
2522
|
const tokenBalances = {};
|
|
1950
|
-
if (
|
|
2523
|
+
if (chain2 === "ethereum") {
|
|
1951
2524
|
const viemChain = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
1952
2525
|
const isTestnet = this.config.network !== "mainnet";
|
|
1953
2526
|
const client = createPublicClient({
|
|
@@ -1994,7 +2567,7 @@ var WalletManager = class _WalletManager {
|
|
|
1994
2567
|
} else if (usdtResult.status === "rejected") {
|
|
1995
2568
|
console.warn("[WalletManager] Failed to fetch ETH USDT balance:", usdtResult.reason);
|
|
1996
2569
|
}
|
|
1997
|
-
} else if (
|
|
2570
|
+
} else if (chain2 === "bitcoin") {
|
|
1998
2571
|
const isMainnet = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
|
|
1999
2572
|
const apisToTry = isMainnet ? ["https://mempool.space/api"] : [
|
|
2000
2573
|
"https://mempool.space/testnet/api",
|
|
@@ -2026,7 +2599,7 @@ var WalletManager = class _WalletManager {
|
|
|
2026
2599
|
console.warn(`Failed to fetch from ${apiUrl}:`, error);
|
|
2027
2600
|
}
|
|
2028
2601
|
}
|
|
2029
|
-
} else if (
|
|
2602
|
+
} else if (chain2 === "solana") {
|
|
2030
2603
|
const rpcUrl = this.config.network === "mainnet" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
|
|
2031
2604
|
try {
|
|
2032
2605
|
const response = await fetch(rpcUrl, {
|
|
@@ -2046,7 +2619,7 @@ var WalletManager = class _WalletManager {
|
|
|
2046
2619
|
}
|
|
2047
2620
|
}
|
|
2048
2621
|
} catch (error) {
|
|
2049
|
-
console.warn(`Failed to fetch ${
|
|
2622
|
+
console.warn(`Failed to fetch ${chain2} balance:`, error);
|
|
2050
2623
|
}
|
|
2051
2624
|
const isTestnet = this.config.network !== "mainnet";
|
|
2052
2625
|
const usdtMint = USDT_ADDRESSES.solana?.[isTestnet ? "testnet" : "mainnet"];
|
|
@@ -2080,7 +2653,7 @@ var WalletManager = class _WalletManager {
|
|
|
2080
2653
|
console.warn("Failed to fetch Solana USDT balance:", error);
|
|
2081
2654
|
}
|
|
2082
2655
|
}
|
|
2083
|
-
} else if (
|
|
2656
|
+
} else if (chain2 === "tron") {
|
|
2084
2657
|
const tronConfig = getNetworkConfig("tron", this.config.network !== "mainnet");
|
|
2085
2658
|
const baseUrl = tronConfig.rpcUrl;
|
|
2086
2659
|
try {
|
|
@@ -2109,9 +2682,9 @@ var WalletManager = class _WalletManager {
|
|
|
2109
2682
|
}
|
|
2110
2683
|
}
|
|
2111
2684
|
} catch (error) {
|
|
2112
|
-
console.warn(`Failed to fetch ${
|
|
2685
|
+
console.warn(`Failed to fetch ${chain2} balance:`, error);
|
|
2113
2686
|
}
|
|
2114
|
-
} else if (
|
|
2687
|
+
} else if (chain2 === "ton") {
|
|
2115
2688
|
const isTestnet = this.config.network !== "mainnet";
|
|
2116
2689
|
const baseUrl = isTestnet ? "https://testnet.toncenter.com/api/v2" : "https://toncenter.com/api/v2";
|
|
2117
2690
|
try {
|
|
@@ -2127,36 +2700,25 @@ var WalletManager = class _WalletManager {
|
|
|
2127
2700
|
}
|
|
2128
2701
|
}
|
|
2129
2702
|
} catch (error) {
|
|
2130
|
-
console.warn(`Failed to fetch ${
|
|
2703
|
+
console.warn(`Failed to fetch ${chain2} balance:`, error);
|
|
2131
2704
|
}
|
|
2132
2705
|
const usdtJetton = USDT_ADDRESSES.ton?.[isTestnet ? "testnet" : "mainnet"];
|
|
2133
2706
|
if (usdtJetton) {
|
|
2134
|
-
const
|
|
2707
|
+
const v3BaseUrl = isTestnet ? "https://testnet.toncenter.com/api/v3" : "https://toncenter.com/api/v3";
|
|
2135
2708
|
try {
|
|
2136
|
-
const rawAddr = tonFriendlyToRaw(address);
|
|
2137
2709
|
const jettonResponse = await fetch(
|
|
2138
|
-
`${
|
|
2710
|
+
`${v3BaseUrl}/jetton/wallets?owner_address=${address}&jetton_address=${usdtJetton}&limit=1`,
|
|
2139
2711
|
{ headers: { "Accept": "application/json" } }
|
|
2140
2712
|
);
|
|
2141
2713
|
if (jettonResponse.ok) {
|
|
2142
2714
|
const jettonData = await jettonResponse.json();
|
|
2143
|
-
const
|
|
2144
|
-
if (
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
const rawBalance = jb.balance;
|
|
2151
|
-
if (rawBalance) {
|
|
2152
|
-
const decimals = jb.jetton?.decimals || 6;
|
|
2153
|
-
const usdtAmount = Number(BigInt(rawBalance)) / Math.pow(10, decimals);
|
|
2154
|
-
if (usdtAmount > 0) {
|
|
2155
|
-
tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2158
|
-
break;
|
|
2159
|
-
}
|
|
2715
|
+
const wallets = jettonData.jetton_wallets;
|
|
2716
|
+
if (wallets && wallets.length > 0) {
|
|
2717
|
+
const rawBalance = wallets[0].balance;
|
|
2718
|
+
if (rawBalance) {
|
|
2719
|
+
const usdtAmount = Number(BigInt(rawBalance)) / 1e6;
|
|
2720
|
+
if (usdtAmount > 0) {
|
|
2721
|
+
tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
|
|
2160
2722
|
}
|
|
2161
2723
|
}
|
|
2162
2724
|
}
|
|
@@ -2165,7 +2727,7 @@ var WalletManager = class _WalletManager {
|
|
|
2165
2727
|
console.warn("Failed to fetch TON USDT jetton balance:", error);
|
|
2166
2728
|
}
|
|
2167
2729
|
}
|
|
2168
|
-
} else if (
|
|
2730
|
+
} else if (chain2 === "spark") {
|
|
2169
2731
|
try {
|
|
2170
2732
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
|
|
2171
2733
|
method: "POST",
|
|
@@ -2184,14 +2746,14 @@ var WalletManager = class _WalletManager {
|
|
|
2184
2746
|
}
|
|
2185
2747
|
}
|
|
2186
2748
|
} catch (error) {
|
|
2187
|
-
console.warn(`Failed to fetch ${
|
|
2749
|
+
console.warn(`Failed to fetch ${chain2} balance:`, error);
|
|
2188
2750
|
}
|
|
2189
2751
|
}
|
|
2190
|
-
const priceUsd = await getPriceForChain(
|
|
2752
|
+
const priceUsd = await getPriceForChain(chain2);
|
|
2191
2753
|
const balanceNum = parseFloat(balance) || 0;
|
|
2192
2754
|
const balanceUsd = balanceNum * priceUsd;
|
|
2193
2755
|
return {
|
|
2194
|
-
chain,
|
|
2756
|
+
chain: chain2,
|
|
2195
2757
|
symbol: networkConfig.nativeCurrency.symbol,
|
|
2196
2758
|
balance,
|
|
2197
2759
|
balanceUsd,
|
|
@@ -2205,19 +2767,19 @@ var WalletManager = class _WalletManager {
|
|
|
2205
2767
|
*/
|
|
2206
2768
|
async fetchAllBalances() {
|
|
2207
2769
|
const balances = [];
|
|
2208
|
-
for (const
|
|
2770
|
+
for (const chain2 of this.config.enabledChains) {
|
|
2209
2771
|
try {
|
|
2210
|
-
const balance = await this.fetchBalanceForChain(
|
|
2772
|
+
const balance = await this.fetchBalanceForChain(chain2);
|
|
2211
2773
|
balances.push(balance);
|
|
2212
2774
|
} catch (error) {
|
|
2213
|
-
console.error(`Failed to fetch balance for ${
|
|
2214
|
-
const networkConfig = this.getChainConfig(
|
|
2775
|
+
console.error(`Failed to fetch balance for ${chain2}:`, error);
|
|
2776
|
+
const networkConfig = this.getChainConfig(chain2);
|
|
2215
2777
|
balances.push({
|
|
2216
|
-
chain,
|
|
2778
|
+
chain: chain2,
|
|
2217
2779
|
symbol: networkConfig.nativeCurrency.symbol,
|
|
2218
2780
|
balance: "0",
|
|
2219
2781
|
balanceUsd: 0,
|
|
2220
|
-
address: this.getAddressForChain(
|
|
2782
|
+
address: this.getAddressForChain(chain2) || "",
|
|
2221
2783
|
decimals: networkConfig.nativeCurrency.decimals
|
|
2222
2784
|
});
|
|
2223
2785
|
}
|
|
@@ -2247,13 +2809,13 @@ var WalletManager = class _WalletManager {
|
|
|
2247
2809
|
* @param token - Optional token symbol (e.g., 'USDT' for stablecoins)
|
|
2248
2810
|
* @returns Transaction result with hash and status
|
|
2249
2811
|
*/
|
|
2250
|
-
async sendTransaction(
|
|
2812
|
+
async sendTransaction(chain2, to, amount, token) {
|
|
2251
2813
|
if (!this.currentSeed) {
|
|
2252
2814
|
return { success: false, error: "Wallet is locked" };
|
|
2253
2815
|
}
|
|
2254
|
-
const fromAddress = this.getAddressForChain(
|
|
2816
|
+
const fromAddress = this.getAddressForChain(chain2);
|
|
2255
2817
|
if (!fromAddress) {
|
|
2256
|
-
return { success: false, error: `No address for chain ${
|
|
2818
|
+
return { success: false, error: `No address for chain ${chain2}` };
|
|
2257
2819
|
}
|
|
2258
2820
|
try {
|
|
2259
2821
|
const headers = {
|
|
@@ -2267,7 +2829,7 @@ var WalletManager = class _WalletManager {
|
|
|
2267
2829
|
headers,
|
|
2268
2830
|
body: JSON.stringify({
|
|
2269
2831
|
seed: this.currentSeed,
|
|
2270
|
-
chain,
|
|
2832
|
+
chain: chain2,
|
|
2271
2833
|
to,
|
|
2272
2834
|
amount,
|
|
2273
2835
|
token,
|
|
@@ -2276,12 +2838,12 @@ var WalletManager = class _WalletManager {
|
|
|
2276
2838
|
});
|
|
2277
2839
|
if (response.ok) {
|
|
2278
2840
|
const data = await response.json();
|
|
2279
|
-
console.log(`Transaction sent on ${
|
|
2841
|
+
console.log(`Transaction sent on ${chain2}:`, data);
|
|
2280
2842
|
let txHash = data.txHash || data.transactionHash || data.hash;
|
|
2281
2843
|
if (txHash && typeof txHash === "object" && "hash" in txHash) {
|
|
2282
2844
|
txHash = txHash.hash;
|
|
2283
2845
|
}
|
|
2284
|
-
if (
|
|
2846
|
+
if (chain2 === "ethereum" && txHash && (typeof txHash !== "string" || !txHash.startsWith("0x") || txHash.length !== 66)) {
|
|
2285
2847
|
console.warn(`Invalid Ethereum tx hash format: ${txHash} (length: ${txHash?.length}, expected: 66)`);
|
|
2286
2848
|
}
|
|
2287
2849
|
return {
|
|
@@ -2290,7 +2852,7 @@ var WalletManager = class _WalletManager {
|
|
|
2290
2852
|
from: fromAddress,
|
|
2291
2853
|
to,
|
|
2292
2854
|
amount,
|
|
2293
|
-
chain
|
|
2855
|
+
chain: chain2
|
|
2294
2856
|
};
|
|
2295
2857
|
}
|
|
2296
2858
|
const errorData = await response.json().catch(() => ({}));
|
|
@@ -2299,7 +2861,7 @@ var WalletManager = class _WalletManager {
|
|
|
2299
2861
|
error: errorData.error || `HTTP ${response.status}`
|
|
2300
2862
|
};
|
|
2301
2863
|
} catch (error) {
|
|
2302
|
-
console.error(`Transaction failed on ${
|
|
2864
|
+
console.error(`Transaction failed on ${chain2}:`, error);
|
|
2303
2865
|
return {
|
|
2304
2866
|
success: false,
|
|
2305
2867
|
error: error instanceof Error ? error.message : "Transaction failed"
|
|
@@ -2309,7 +2871,7 @@ var WalletManager = class _WalletManager {
|
|
|
2309
2871
|
/**
|
|
2310
2872
|
* Estimate transaction fee using Tether WDK
|
|
2311
2873
|
*/
|
|
2312
|
-
async estimateFee(
|
|
2874
|
+
async estimateFee(chain2, to, amount, token) {
|
|
2313
2875
|
try {
|
|
2314
2876
|
const headers = {
|
|
2315
2877
|
"Content-Type": "application/json"
|
|
@@ -2321,7 +2883,7 @@ var WalletManager = class _WalletManager {
|
|
|
2321
2883
|
method: "POST",
|
|
2322
2884
|
headers,
|
|
2323
2885
|
body: JSON.stringify({
|
|
2324
|
-
chain,
|
|
2886
|
+
chain: chain2,
|
|
2325
2887
|
to,
|
|
2326
2888
|
amount,
|
|
2327
2889
|
token,
|
|
@@ -2530,12 +3092,12 @@ function useWalletManager(options = {}) {
|
|
|
2530
3092
|
setIsLoading(false);
|
|
2531
3093
|
}
|
|
2532
3094
|
}, [manager]);
|
|
2533
|
-
const setSelectedChain = useCallback((
|
|
2534
|
-
manager.setSelectedChain(
|
|
2535
|
-
setSelectedChainState(
|
|
3095
|
+
const setSelectedChain = useCallback((chain2) => {
|
|
3096
|
+
manager.setSelectedChain(chain2);
|
|
3097
|
+
setSelectedChainState(chain2);
|
|
2536
3098
|
}, [manager]);
|
|
2537
3099
|
const getAddressForChain = useCallback(
|
|
2538
|
-
(
|
|
3100
|
+
(chain2) => manager.getAddressForChain(chain2),
|
|
2539
3101
|
[manager]
|
|
2540
3102
|
);
|
|
2541
3103
|
const getAllAddresses = useCallback(
|
|
@@ -2545,10 +3107,10 @@ function useWalletManager(options = {}) {
|
|
|
2545
3107
|
const hasWallet = useCallback(() => manager.hasWallet(), [manager]);
|
|
2546
3108
|
const getSeed = useCallback(() => manager.getSeed(), [manager]);
|
|
2547
3109
|
const sendTransaction = useCallback(
|
|
2548
|
-
async (
|
|
3110
|
+
async (chain2, to, amount, token) => {
|
|
2549
3111
|
setIsLoading(true);
|
|
2550
3112
|
try {
|
|
2551
|
-
const result = await manager.sendTransaction(
|
|
3113
|
+
const result = await manager.sendTransaction(chain2, to, amount, token);
|
|
2552
3114
|
if (result.success) {
|
|
2553
3115
|
try {
|
|
2554
3116
|
const balances = await manager.fetchAllBalances();
|
|
@@ -2565,8 +3127,8 @@ function useWalletManager(options = {}) {
|
|
|
2565
3127
|
[manager]
|
|
2566
3128
|
);
|
|
2567
3129
|
const estimateFee = useCallback(
|
|
2568
|
-
async (
|
|
2569
|
-
return manager.estimateFee(
|
|
3130
|
+
async (chain2, to, amount, token) => {
|
|
3131
|
+
return manager.estimateFee(chain2, to, amount, token);
|
|
2570
3132
|
},
|
|
2571
3133
|
[manager]
|
|
2572
3134
|
);
|
|
@@ -2600,6 +3162,14 @@ function useWalletManager(options = {}) {
|
|
|
2600
3162
|
manager
|
|
2601
3163
|
};
|
|
2602
3164
|
}
|
|
3165
|
+
/*! Bundled license information:
|
|
3166
|
+
|
|
3167
|
+
@scure/base/index.js:
|
|
3168
|
+
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
3169
|
+
|
|
3170
|
+
@scure/bip32/index.js:
|
|
3171
|
+
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
3172
|
+
*/
|
|
2603
3173
|
|
|
2604
3174
|
export { SUPPORTED_CHAINS, useWalletManager };
|
|
2605
3175
|
//# sourceMappingURL=index.mjs.map
|