@zubari/sdk 0.5.2 → 0.5.4
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/{PayoutsProtocol-B5z8SEA-.d.ts → PayoutsProtocol-DAa-9A5C.d.ts} +8 -1
- package/dist/{PayoutsProtocol-CLiMFe54.d.mts → PayoutsProtocol-DKEQhwYH.d.mts} +8 -1
- package/dist/{TransactionService-BtWUjKt_.d.ts → TransactionService-BEkgF1T6.d.ts} +12 -2
- package/dist/{TransactionService-Lr_WS6iR.d.mts → TransactionService-CF_C3Kqm.d.mts} +12 -2
- package/dist/{WalletManager-DQQwVkoa.d.ts → WalletManager-CeLlZo2y.d.ts} +23 -2
- package/dist/{WalletManager-Sbpx4E1-.d.mts → WalletManager-DIx8nENh.d.mts} +23 -2
- package/dist/{contracts-B842YprC.d.mts → contracts-JfZDzaV7.d.ts} +11 -2
- package/dist/{contracts-s_CDIruh.d.ts → contracts-pugJnFzl.d.mts} +11 -2
- package/dist/{index-CTyZlHKg.d.mts → index-c90msmwW.d.mts} +2 -1
- package/dist/{index-CTyZlHKg.d.ts → index-c90msmwW.d.ts} +2 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +339 -916
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +337 -914
- package/dist/index.mjs.map +1 -1
- package/dist/protocols/index.d.mts +2 -2
- package/dist/protocols/index.d.ts +2 -2
- package/dist/protocols/index.js +24 -11
- package/dist/protocols/index.js.map +1 -1
- package/dist/protocols/index.mjs +24 -11
- package/dist/protocols/index.mjs.map +1 -1
- package/dist/react/index.d.mts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +255 -826
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +253 -824
- package/dist/react/index.mjs.map +1 -1
- package/dist/services/index.d.mts +2 -2
- package/dist/services/index.d.ts +2 -2
- package/dist/services/index.js +179 -767
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +177 -765
- package/dist/services/index.mjs.map +1 -1
- package/dist/storage/index.js +5 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +5 -2
- package/dist/storage/index.mjs.map +1 -1
- package/dist/wallet/index.d.mts +3 -3
- package/dist/wallet/index.d.ts +3 -3
- package/dist/wallet/index.js +262 -854
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +260 -852
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { HDNodeWallet, Wallet } from 'ethers';
|
|
2
2
|
import { mnemonicToSeedSync, validateMnemonic, generateMnemonic } from '@scure/bip39';
|
|
3
3
|
import { wordlist } from '@scure/bip39/wordlists/english';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { sha256, sha512 } from '@noble/hashes/sha2.js';
|
|
8
|
-
import { createView, concatBytes, abytes } from '@noble/hashes/utils.js';
|
|
9
|
-
import { sha256 as sha256$1 } from '@noble/hashes/sha256';
|
|
4
|
+
import { HDKey } from '@scure/bip32';
|
|
5
|
+
import { bech32, base58check } from '@scure/base';
|
|
6
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
10
7
|
import { ripemd160 } from '@noble/hashes/ripemd160';
|
|
11
8
|
import { createPublicClient, http, formatEther, getAddress } from 'viem';
|
|
12
9
|
import { mainnet, sepolia } from 'viem/chains';
|
|
@@ -138,8 +135,8 @@ var TESTNET_NETWORKS = {
|
|
|
138
135
|
var USDT_ADDRESSES = {
|
|
139
136
|
ethereum: {
|
|
140
137
|
mainnet: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
141
|
-
testnet: "
|
|
142
|
-
// Sepolia
|
|
138
|
+
testnet: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
|
|
139
|
+
// Sepolia (Test Tether USD)
|
|
143
140
|
},
|
|
144
141
|
tron: {
|
|
145
142
|
mainnet: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
|
@@ -157,11 +154,11 @@ var USDT_ADDRESSES = {
|
|
|
157
154
|
}
|
|
158
155
|
};
|
|
159
156
|
var DERIVATION_PATHS = {
|
|
160
|
-
bitcoin: "m/
|
|
157
|
+
bitcoin: "m/84'/0'/0'/0",
|
|
161
158
|
ethereum: "m/44'/60'/0'/0",
|
|
162
|
-
ton: "m/44'/607'/0'
|
|
159
|
+
ton: "m/44'/607'/0'",
|
|
163
160
|
tron: "m/44'/195'/0'/0",
|
|
164
|
-
solana: "m/44'/501'/0'
|
|
161
|
+
solana: "m/44'/501'/0'",
|
|
165
162
|
spark: "m/44'/998'/0'/0"
|
|
166
163
|
};
|
|
167
164
|
function getNetworkConfig(network, isTestnet2 = false) {
|
|
@@ -396,8 +393,8 @@ var TESTNET_FEE_WALLETS = {
|
|
|
396
393
|
network: "tron-nile"
|
|
397
394
|
}
|
|
398
395
|
};
|
|
399
|
-
function getFeeWallet(
|
|
400
|
-
return isMainnet2 ? MAINNET_FEE_WALLETS[
|
|
396
|
+
function getFeeWallet(chain, isMainnet2 = true) {
|
|
397
|
+
return isMainnet2 ? MAINNET_FEE_WALLETS[chain] : TESTNET_FEE_WALLETS[chain];
|
|
401
398
|
}
|
|
402
399
|
function getAllFeeWallets(useMainnet = false) {
|
|
403
400
|
return useMainnet ? MAINNET_FEE_WALLETS : TESTNET_FEE_WALLETS;
|
|
@@ -414,8 +411,8 @@ function getDefaultSubscriptionAddress() {
|
|
|
414
411
|
function getCurrentFeeWallets() {
|
|
415
412
|
return isMainnet() ? MAINNET_FEE_WALLETS : TESTNET_FEE_WALLETS;
|
|
416
413
|
}
|
|
417
|
-
function getCurrentFeeWallet(
|
|
418
|
-
return getCurrentFeeWallets()[
|
|
414
|
+
function getCurrentFeeWallet(chain) {
|
|
415
|
+
return getCurrentFeeWallets()[chain];
|
|
419
416
|
}
|
|
420
417
|
function getCurrentCurrencyAddresses() {
|
|
421
418
|
return CURRENCY_ADDRESSES[getZubariNetwork()];
|
|
@@ -427,8 +424,27 @@ var WdkApiClient = class {
|
|
|
427
424
|
constructor(config) {
|
|
428
425
|
this.config = {
|
|
429
426
|
baseUrl: config.baseUrl,
|
|
430
|
-
timeout: config.timeout || 3e4
|
|
427
|
+
timeout: config.timeout || 3e4,
|
|
428
|
+
authToken: config.authToken
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Set or update the auth token for authenticated requests
|
|
433
|
+
*/
|
|
434
|
+
setAuthToken(token) {
|
|
435
|
+
this.config.authToken = token;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Build headers for API requests, including Authorization when available
|
|
439
|
+
*/
|
|
440
|
+
getHeaders() {
|
|
441
|
+
const headers = {
|
|
442
|
+
"Content-Type": "application/json"
|
|
431
443
|
};
|
|
444
|
+
if (this.config.authToken) {
|
|
445
|
+
headers["Authorization"] = `Bearer ${this.config.authToken}`;
|
|
446
|
+
}
|
|
447
|
+
return headers;
|
|
432
448
|
}
|
|
433
449
|
/**
|
|
434
450
|
* Generate a new BIP-39 seed phrase using Tether WDK
|
|
@@ -437,9 +453,7 @@ var WdkApiClient = class {
|
|
|
437
453
|
try {
|
|
438
454
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/generate-seed`, {
|
|
439
455
|
method: "POST",
|
|
440
|
-
headers:
|
|
441
|
-
"Content-Type": "application/json"
|
|
442
|
-
}
|
|
456
|
+
headers: this.getHeaders()
|
|
443
457
|
});
|
|
444
458
|
return await response.json();
|
|
445
459
|
} catch (error) {
|
|
@@ -456,9 +470,7 @@ var WdkApiClient = class {
|
|
|
456
470
|
try {
|
|
457
471
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/validate-seed`, {
|
|
458
472
|
method: "POST",
|
|
459
|
-
headers:
|
|
460
|
-
"Content-Type": "application/json"
|
|
461
|
-
},
|
|
473
|
+
headers: this.getHeaders(),
|
|
462
474
|
body: JSON.stringify({ seed })
|
|
463
475
|
});
|
|
464
476
|
return await response.json();
|
|
@@ -472,14 +484,12 @@ var WdkApiClient = class {
|
|
|
472
484
|
/**
|
|
473
485
|
* Derive address for a specific chain using Tether WDK
|
|
474
486
|
*/
|
|
475
|
-
async deriveAddress(seed,
|
|
487
|
+
async deriveAddress(seed, chain, network = "mainnet") {
|
|
476
488
|
try {
|
|
477
489
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-address`, {
|
|
478
490
|
method: "POST",
|
|
479
|
-
headers:
|
|
480
|
-
|
|
481
|
-
},
|
|
482
|
-
body: JSON.stringify({ seed, chain: chain2, network })
|
|
491
|
+
headers: this.getHeaders(),
|
|
492
|
+
body: JSON.stringify({ seed, chain, network })
|
|
483
493
|
});
|
|
484
494
|
return await response.json();
|
|
485
495
|
} catch (error) {
|
|
@@ -496,9 +506,7 @@ var WdkApiClient = class {
|
|
|
496
506
|
try {
|
|
497
507
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-all`, {
|
|
498
508
|
method: "POST",
|
|
499
|
-
headers:
|
|
500
|
-
"Content-Type": "application/json"
|
|
501
|
-
},
|
|
509
|
+
headers: this.getHeaders(),
|
|
502
510
|
body: JSON.stringify({ seed, network })
|
|
503
511
|
});
|
|
504
512
|
return await response.json();
|
|
@@ -512,14 +520,12 @@ var WdkApiClient = class {
|
|
|
512
520
|
/**
|
|
513
521
|
* Send a transaction on a specific chain using Tether WDK
|
|
514
522
|
*/
|
|
515
|
-
async sendTransaction(seed,
|
|
523
|
+
async sendTransaction(seed, chain, to, amount, network = "mainnet") {
|
|
516
524
|
try {
|
|
517
525
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/send`, {
|
|
518
526
|
method: "POST",
|
|
519
|
-
headers:
|
|
520
|
-
|
|
521
|
-
},
|
|
522
|
-
body: JSON.stringify({ seed, chain: chain2, to, amount, network })
|
|
527
|
+
headers: this.getHeaders(),
|
|
528
|
+
body: JSON.stringify({ seed, chain, to, amount, network })
|
|
523
529
|
});
|
|
524
530
|
return await response.json();
|
|
525
531
|
} catch (error) {
|
|
@@ -533,14 +539,12 @@ var WdkApiClient = class {
|
|
|
533
539
|
* Get transaction history for an address on a specific chain
|
|
534
540
|
* Fetches from blockchain explorers (Etherscan, mempool.space, etc.)
|
|
535
541
|
*/
|
|
536
|
-
async getTransactionHistory(seed,
|
|
542
|
+
async getTransactionHistory(seed, chain, network = "mainnet", limit = 10) {
|
|
537
543
|
try {
|
|
538
544
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/history`, {
|
|
539
545
|
method: "POST",
|
|
540
|
-
headers:
|
|
541
|
-
|
|
542
|
-
},
|
|
543
|
-
body: JSON.stringify({ seed, chain: chain2, network, limit })
|
|
546
|
+
headers: this.getHeaders(),
|
|
547
|
+
body: JSON.stringify({ seed, chain, network, limit })
|
|
544
548
|
});
|
|
545
549
|
return await response.json();
|
|
546
550
|
} catch (error) {
|
|
@@ -554,14 +558,12 @@ var WdkApiClient = class {
|
|
|
554
558
|
* Get transaction status by hash
|
|
555
559
|
* Fetches from blockchain explorers to check confirmation status
|
|
556
560
|
*/
|
|
557
|
-
async getTransactionStatus(txHash,
|
|
561
|
+
async getTransactionStatus(txHash, chain, network = "mainnet") {
|
|
558
562
|
try {
|
|
559
563
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/tx-status`, {
|
|
560
564
|
method: "POST",
|
|
561
|
-
headers:
|
|
562
|
-
|
|
563
|
-
},
|
|
564
|
-
body: JSON.stringify({ txHash, chain: chain2, network })
|
|
565
|
+
headers: this.getHeaders(),
|
|
566
|
+
body: JSON.stringify({ txHash, chain, network })
|
|
565
567
|
});
|
|
566
568
|
return await response.json();
|
|
567
569
|
} catch (error) {
|
|
@@ -574,11 +576,14 @@ var WdkApiClient = class {
|
|
|
574
576
|
};
|
|
575
577
|
var DEFAULT_API_URL = process.env.NEXT_PUBLIC_API_URL || "https://ckgwifsxka.us-east-2.awsapprunner.com";
|
|
576
578
|
var wdkApiClient = null;
|
|
577
|
-
function getWdkApiClient(baseUrl) {
|
|
579
|
+
function getWdkApiClient(baseUrl, authToken) {
|
|
578
580
|
if (!wdkApiClient || baseUrl && wdkApiClient["config"].baseUrl !== baseUrl) {
|
|
579
581
|
wdkApiClient = new WdkApiClient({
|
|
580
|
-
baseUrl: baseUrl || DEFAULT_API_URL
|
|
582
|
+
baseUrl: baseUrl || DEFAULT_API_URL,
|
|
583
|
+
authToken
|
|
581
584
|
});
|
|
585
|
+
} else if (authToken !== void 0) {
|
|
586
|
+
wdkApiClient.setAuthToken(authToken);
|
|
582
587
|
}
|
|
583
588
|
return wdkApiClient;
|
|
584
589
|
}
|
|
@@ -596,597 +601,14 @@ __export(BrowserAddressDerivation_exports, {
|
|
|
596
601
|
generateSeedPhrase: () => generateSeedPhrase,
|
|
597
602
|
isValidSeed: () => isValidSeed
|
|
598
603
|
});
|
|
599
|
-
|
|
600
|
-
// node_modules/@scure/base/index.js
|
|
601
|
-
function isBytes(a) {
|
|
602
|
-
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
603
|
-
}
|
|
604
|
-
function isArrayOf(isString, arr) {
|
|
605
|
-
if (!Array.isArray(arr))
|
|
606
|
-
return false;
|
|
607
|
-
if (arr.length === 0)
|
|
608
|
-
return true;
|
|
609
|
-
if (isString) {
|
|
610
|
-
return arr.every((item) => typeof item === "string");
|
|
611
|
-
} else {
|
|
612
|
-
return arr.every((item) => Number.isSafeInteger(item));
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
function afn(input) {
|
|
616
|
-
if (typeof input !== "function")
|
|
617
|
-
throw new Error("function expected");
|
|
618
|
-
return true;
|
|
619
|
-
}
|
|
620
|
-
function astr(label, input) {
|
|
621
|
-
if (typeof input !== "string")
|
|
622
|
-
throw new Error(`${label}: string expected`);
|
|
623
|
-
return true;
|
|
624
|
-
}
|
|
625
|
-
function anumber(n) {
|
|
626
|
-
if (!Number.isSafeInteger(n))
|
|
627
|
-
throw new Error(`invalid integer: ${n}`);
|
|
628
|
-
}
|
|
629
|
-
function aArr(input) {
|
|
630
|
-
if (!Array.isArray(input))
|
|
631
|
-
throw new Error("array expected");
|
|
632
|
-
}
|
|
633
|
-
function astrArr(label, input) {
|
|
634
|
-
if (!isArrayOf(true, input))
|
|
635
|
-
throw new Error(`${label}: array of strings expected`);
|
|
636
|
-
}
|
|
637
|
-
function anumArr(label, input) {
|
|
638
|
-
if (!isArrayOf(false, input))
|
|
639
|
-
throw new Error(`${label}: array of numbers expected`);
|
|
640
|
-
}
|
|
641
|
-
// @__NO_SIDE_EFFECTS__
|
|
642
|
-
function chain(...args) {
|
|
643
|
-
const id = (a) => a;
|
|
644
|
-
const wrap = (a, b) => (c) => a(b(c));
|
|
645
|
-
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
|
|
646
|
-
const decode = args.map((x) => x.decode).reduce(wrap, id);
|
|
647
|
-
return { encode, decode };
|
|
648
|
-
}
|
|
649
|
-
// @__NO_SIDE_EFFECTS__
|
|
650
|
-
function alphabet(letters) {
|
|
651
|
-
const lettersA = typeof letters === "string" ? letters.split("") : letters;
|
|
652
|
-
const len = lettersA.length;
|
|
653
|
-
astrArr("alphabet", lettersA);
|
|
654
|
-
const indexes = new Map(lettersA.map((l, i) => [l, i]));
|
|
655
|
-
return {
|
|
656
|
-
encode: (digits) => {
|
|
657
|
-
aArr(digits);
|
|
658
|
-
return digits.map((i) => {
|
|
659
|
-
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
|
|
660
|
-
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
|
|
661
|
-
return lettersA[i];
|
|
662
|
-
});
|
|
663
|
-
},
|
|
664
|
-
decode: (input) => {
|
|
665
|
-
aArr(input);
|
|
666
|
-
return input.map((letter) => {
|
|
667
|
-
astr("alphabet.decode", letter);
|
|
668
|
-
const i = indexes.get(letter);
|
|
669
|
-
if (i === void 0)
|
|
670
|
-
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
|
|
671
|
-
return i;
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
// @__NO_SIDE_EFFECTS__
|
|
677
|
-
function join(separator = "") {
|
|
678
|
-
astr("join", separator);
|
|
679
|
-
return {
|
|
680
|
-
encode: (from) => {
|
|
681
|
-
astrArr("join.decode", from);
|
|
682
|
-
return from.join(separator);
|
|
683
|
-
},
|
|
684
|
-
decode: (to) => {
|
|
685
|
-
astr("join.decode", to);
|
|
686
|
-
return to.split(separator);
|
|
687
|
-
}
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
function convertRadix(data, from, to) {
|
|
691
|
-
if (from < 2)
|
|
692
|
-
throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
|
|
693
|
-
if (to < 2)
|
|
694
|
-
throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
|
|
695
|
-
aArr(data);
|
|
696
|
-
if (!data.length)
|
|
697
|
-
return [];
|
|
698
|
-
let pos = 0;
|
|
699
|
-
const res = [];
|
|
700
|
-
const digits = Array.from(data, (d) => {
|
|
701
|
-
anumber(d);
|
|
702
|
-
if (d < 0 || d >= from)
|
|
703
|
-
throw new Error(`invalid integer: ${d}`);
|
|
704
|
-
return d;
|
|
705
|
-
});
|
|
706
|
-
const dlen = digits.length;
|
|
707
|
-
while (true) {
|
|
708
|
-
let carry = 0;
|
|
709
|
-
let done = true;
|
|
710
|
-
for (let i = pos; i < dlen; i++) {
|
|
711
|
-
const digit = digits[i];
|
|
712
|
-
const fromCarry = from * carry;
|
|
713
|
-
const digitBase = fromCarry + digit;
|
|
714
|
-
if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) {
|
|
715
|
-
throw new Error("convertRadix: carry overflow");
|
|
716
|
-
}
|
|
717
|
-
const div = digitBase / to;
|
|
718
|
-
carry = digitBase % to;
|
|
719
|
-
const rounded = Math.floor(div);
|
|
720
|
-
digits[i] = rounded;
|
|
721
|
-
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
|
|
722
|
-
throw new Error("convertRadix: carry overflow");
|
|
723
|
-
if (!done)
|
|
724
|
-
continue;
|
|
725
|
-
else if (!rounded)
|
|
726
|
-
pos = i;
|
|
727
|
-
else
|
|
728
|
-
done = false;
|
|
729
|
-
}
|
|
730
|
-
res.push(carry);
|
|
731
|
-
if (done)
|
|
732
|
-
break;
|
|
733
|
-
}
|
|
734
|
-
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
|
735
|
-
res.push(0);
|
|
736
|
-
return res.reverse();
|
|
737
|
-
}
|
|
738
|
-
var gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
|
|
739
|
-
var radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
|
|
740
|
-
var powers = /* @__PURE__ */ (() => {
|
|
741
|
-
let res = [];
|
|
742
|
-
for (let i = 0; i < 40; i++)
|
|
743
|
-
res.push(2 ** i);
|
|
744
|
-
return res;
|
|
745
|
-
})();
|
|
746
|
-
function convertRadix2(data, from, to, padding) {
|
|
747
|
-
aArr(data);
|
|
748
|
-
if (from <= 0 || from > 32)
|
|
749
|
-
throw new Error(`convertRadix2: wrong from=${from}`);
|
|
750
|
-
if (to <= 0 || to > 32)
|
|
751
|
-
throw new Error(`convertRadix2: wrong to=${to}`);
|
|
752
|
-
if (/* @__PURE__ */ radix2carry(from, to) > 32) {
|
|
753
|
-
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${/* @__PURE__ */ radix2carry(from, to)}`);
|
|
754
|
-
}
|
|
755
|
-
let carry = 0;
|
|
756
|
-
let pos = 0;
|
|
757
|
-
const max = powers[from];
|
|
758
|
-
const mask = powers[to] - 1;
|
|
759
|
-
const res = [];
|
|
760
|
-
for (const n of data) {
|
|
761
|
-
anumber(n);
|
|
762
|
-
if (n >= max)
|
|
763
|
-
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
|
764
|
-
carry = carry << from | n;
|
|
765
|
-
if (pos + from > 32)
|
|
766
|
-
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
|
767
|
-
pos += from;
|
|
768
|
-
for (; pos >= to; pos -= to)
|
|
769
|
-
res.push((carry >> pos - to & mask) >>> 0);
|
|
770
|
-
const pow = powers[pos];
|
|
771
|
-
if (pow === void 0)
|
|
772
|
-
throw new Error("invalid carry");
|
|
773
|
-
carry &= pow - 1;
|
|
774
|
-
}
|
|
775
|
-
carry = carry << to - pos & mask;
|
|
776
|
-
if (!padding && pos >= from)
|
|
777
|
-
throw new Error("Excess padding");
|
|
778
|
-
if (!padding && carry > 0)
|
|
779
|
-
throw new Error(`Non-zero padding: ${carry}`);
|
|
780
|
-
if (padding && pos > 0)
|
|
781
|
-
res.push(carry >>> 0);
|
|
782
|
-
return res;
|
|
783
|
-
}
|
|
784
|
-
// @__NO_SIDE_EFFECTS__
|
|
785
|
-
function radix(num) {
|
|
786
|
-
anumber(num);
|
|
787
|
-
const _256 = 2 ** 8;
|
|
788
|
-
return {
|
|
789
|
-
encode: (bytes) => {
|
|
790
|
-
if (!isBytes(bytes))
|
|
791
|
-
throw new Error("radix.encode input should be Uint8Array");
|
|
792
|
-
return convertRadix(Array.from(bytes), _256, num);
|
|
793
|
-
},
|
|
794
|
-
decode: (digits) => {
|
|
795
|
-
anumArr("radix.decode", digits);
|
|
796
|
-
return Uint8Array.from(convertRadix(digits, num, _256));
|
|
797
|
-
}
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
// @__NO_SIDE_EFFECTS__
|
|
801
|
-
function radix2(bits, revPadding = false) {
|
|
802
|
-
anumber(bits);
|
|
803
|
-
if (/* @__PURE__ */ radix2carry(8, bits) > 32 || /* @__PURE__ */ radix2carry(bits, 8) > 32)
|
|
804
|
-
throw new Error("radix2: carry overflow");
|
|
805
|
-
return {
|
|
806
|
-
encode: (bytes) => {
|
|
807
|
-
if (!isBytes(bytes))
|
|
808
|
-
throw new Error("radix2.encode input should be Uint8Array");
|
|
809
|
-
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
|
810
|
-
},
|
|
811
|
-
decode: (digits) => {
|
|
812
|
-
anumArr("radix2.decode", digits);
|
|
813
|
-
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
|
814
|
-
}
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
function unsafeWrapper(fn) {
|
|
818
|
-
afn(fn);
|
|
819
|
-
return function(...args) {
|
|
820
|
-
try {
|
|
821
|
-
return fn.apply(null, args);
|
|
822
|
-
} catch (e) {
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
}
|
|
826
|
-
function checksum(len, fn) {
|
|
827
|
-
anumber(len);
|
|
828
|
-
afn(fn);
|
|
829
|
-
return {
|
|
830
|
-
encode(data) {
|
|
831
|
-
if (!isBytes(data))
|
|
832
|
-
throw new Error("checksum.encode: input should be Uint8Array");
|
|
833
|
-
const sum = fn(data).slice(0, len);
|
|
834
|
-
const res = new Uint8Array(data.length + len);
|
|
835
|
-
res.set(data);
|
|
836
|
-
res.set(sum, data.length);
|
|
837
|
-
return res;
|
|
838
|
-
},
|
|
839
|
-
decode(data) {
|
|
840
|
-
if (!isBytes(data))
|
|
841
|
-
throw new Error("checksum.decode: input should be Uint8Array");
|
|
842
|
-
const payload = data.slice(0, -len);
|
|
843
|
-
const oldChecksum = data.slice(-len);
|
|
844
|
-
const newChecksum = fn(payload).slice(0, len);
|
|
845
|
-
for (let i = 0; i < len; i++)
|
|
846
|
-
if (newChecksum[i] !== oldChecksum[i])
|
|
847
|
-
throw new Error("Invalid checksum");
|
|
848
|
-
return payload;
|
|
849
|
-
}
|
|
850
|
-
};
|
|
851
|
-
}
|
|
852
|
-
var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
|
|
853
|
-
var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
854
|
-
var createBase58check = (sha2563) => /* @__PURE__ */ chain(checksum(4, (data) => sha2563(sha2563(data))), base58);
|
|
855
|
-
var base58check = createBase58check;
|
|
856
|
-
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join(""));
|
|
857
|
-
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
858
|
-
function bech32Polymod(pre) {
|
|
859
|
-
const b = pre >> 25;
|
|
860
|
-
let chk = (pre & 33554431) << 5;
|
|
861
|
-
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
|
862
|
-
if ((b >> i & 1) === 1)
|
|
863
|
-
chk ^= POLYMOD_GENERATORS[i];
|
|
864
|
-
}
|
|
865
|
-
return chk;
|
|
866
|
-
}
|
|
867
|
-
function bechChecksum(prefix, words, encodingConst = 1) {
|
|
868
|
-
const len = prefix.length;
|
|
869
|
-
let chk = 1;
|
|
870
|
-
for (let i = 0; i < len; i++) {
|
|
871
|
-
const c = prefix.charCodeAt(i);
|
|
872
|
-
if (c < 33 || c > 126)
|
|
873
|
-
throw new Error(`Invalid prefix (${prefix})`);
|
|
874
|
-
chk = bech32Polymod(chk) ^ c >> 5;
|
|
875
|
-
}
|
|
876
|
-
chk = bech32Polymod(chk);
|
|
877
|
-
for (let i = 0; i < len; i++)
|
|
878
|
-
chk = bech32Polymod(chk) ^ prefix.charCodeAt(i) & 31;
|
|
879
|
-
for (let v of words)
|
|
880
|
-
chk = bech32Polymod(chk) ^ v;
|
|
881
|
-
for (let i = 0; i < 6; i++)
|
|
882
|
-
chk = bech32Polymod(chk);
|
|
883
|
-
chk ^= encodingConst;
|
|
884
|
-
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
|
|
885
|
-
}
|
|
886
|
-
// @__NO_SIDE_EFFECTS__
|
|
887
|
-
function genBech32(encoding) {
|
|
888
|
-
const ENCODING_CONST = 1 ;
|
|
889
|
-
const _words = /* @__PURE__ */ radix2(5);
|
|
890
|
-
const fromWords = _words.decode;
|
|
891
|
-
const toWords = _words.encode;
|
|
892
|
-
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
|
893
|
-
function encode(prefix, words, limit = 90) {
|
|
894
|
-
astr("bech32.encode prefix", prefix);
|
|
895
|
-
if (isBytes(words))
|
|
896
|
-
words = Array.from(words);
|
|
897
|
-
anumArr("bech32.encode", words);
|
|
898
|
-
const plen = prefix.length;
|
|
899
|
-
if (plen === 0)
|
|
900
|
-
throw new TypeError(`Invalid prefix length ${plen}`);
|
|
901
|
-
const actualLength = plen + 7 + words.length;
|
|
902
|
-
if (limit !== false && actualLength > limit)
|
|
903
|
-
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
|
904
|
-
const lowered = prefix.toLowerCase();
|
|
905
|
-
const sum = bechChecksum(lowered, words, ENCODING_CONST);
|
|
906
|
-
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
|
|
907
|
-
}
|
|
908
|
-
function decode(str, limit = 90) {
|
|
909
|
-
astr("bech32.decode input", str);
|
|
910
|
-
const slen = str.length;
|
|
911
|
-
if (slen < 8 || limit !== false && slen > limit)
|
|
912
|
-
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
|
|
913
|
-
const lowered = str.toLowerCase();
|
|
914
|
-
if (str !== lowered && str !== str.toUpperCase())
|
|
915
|
-
throw new Error(`String must be lowercase or uppercase`);
|
|
916
|
-
const sepIndex = lowered.lastIndexOf("1");
|
|
917
|
-
if (sepIndex === 0 || sepIndex === -1)
|
|
918
|
-
throw new Error(`Letter "1" must be present between prefix and data only`);
|
|
919
|
-
const prefix = lowered.slice(0, sepIndex);
|
|
920
|
-
const data = lowered.slice(sepIndex + 1);
|
|
921
|
-
if (data.length < 6)
|
|
922
|
-
throw new Error("Data must be at least 6 characters long");
|
|
923
|
-
const words = BECH_ALPHABET.decode(data).slice(0, -6);
|
|
924
|
-
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
|
925
|
-
if (!data.endsWith(sum))
|
|
926
|
-
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
|
927
|
-
return { prefix, words };
|
|
928
|
-
}
|
|
929
|
-
const decodeUnsafe = unsafeWrapper(decode);
|
|
930
|
-
function decodeToBytes(str) {
|
|
931
|
-
const { prefix, words } = decode(str, false);
|
|
932
|
-
return { prefix, words, bytes: fromWords(words) };
|
|
933
|
-
}
|
|
934
|
-
function encodeFromBytes(prefix, bytes) {
|
|
935
|
-
return encode(prefix, toWords(bytes));
|
|
936
|
-
}
|
|
937
|
-
return {
|
|
938
|
-
encode,
|
|
939
|
-
decode,
|
|
940
|
-
encodeFromBytes,
|
|
941
|
-
decodeToBytes,
|
|
942
|
-
decodeUnsafe,
|
|
943
|
-
fromWords,
|
|
944
|
-
fromWordsUnsafe,
|
|
945
|
-
toWords
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
var bech32 = /* @__PURE__ */ genBech32();
|
|
949
|
-
|
|
950
|
-
// node_modules/@scure/bip32/index.js
|
|
951
|
-
var Point = secp256k1.Point;
|
|
952
|
-
var { Fn } = Point;
|
|
953
|
-
var base58check2 = createBase58check(sha256);
|
|
954
|
-
var MASTER_SECRET = Uint8Array.from("Bitcoin seed".split(""), (char) => char.charCodeAt(0));
|
|
955
|
-
var BITCOIN_VERSIONS = { private: 76066276, public: 76067358 };
|
|
956
|
-
var HARDENED_OFFSET = 2147483648;
|
|
957
|
-
var hash160 = (data) => ripemd160$1(sha256(data));
|
|
958
|
-
var fromU32 = (data) => createView(data).getUint32(0, false);
|
|
959
|
-
var toU32 = (n) => {
|
|
960
|
-
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
|
961
|
-
throw new Error("invalid number, should be from 0 to 2**32-1, got " + n);
|
|
962
|
-
}
|
|
963
|
-
const buf = new Uint8Array(4);
|
|
964
|
-
createView(buf).setUint32(0, n, false);
|
|
965
|
-
return buf;
|
|
966
|
-
};
|
|
967
|
-
var HDKey = class _HDKey {
|
|
968
|
-
get fingerprint() {
|
|
969
|
-
if (!this.pubHash) {
|
|
970
|
-
throw new Error("No publicKey set!");
|
|
971
|
-
}
|
|
972
|
-
return fromU32(this.pubHash);
|
|
973
|
-
}
|
|
974
|
-
get identifier() {
|
|
975
|
-
return this.pubHash;
|
|
976
|
-
}
|
|
977
|
-
get pubKeyHash() {
|
|
978
|
-
return this.pubHash;
|
|
979
|
-
}
|
|
980
|
-
get privateKey() {
|
|
981
|
-
return this._privateKey || null;
|
|
982
|
-
}
|
|
983
|
-
get publicKey() {
|
|
984
|
-
return this._publicKey || null;
|
|
985
|
-
}
|
|
986
|
-
get privateExtendedKey() {
|
|
987
|
-
const priv = this._privateKey;
|
|
988
|
-
if (!priv) {
|
|
989
|
-
throw new Error("No private key");
|
|
990
|
-
}
|
|
991
|
-
return base58check2.encode(this.serialize(this.versions.private, concatBytes(Uint8Array.of(0), priv)));
|
|
992
|
-
}
|
|
993
|
-
get publicExtendedKey() {
|
|
994
|
-
if (!this._publicKey) {
|
|
995
|
-
throw new Error("No public key");
|
|
996
|
-
}
|
|
997
|
-
return base58check2.encode(this.serialize(this.versions.public, this._publicKey));
|
|
998
|
-
}
|
|
999
|
-
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
|
|
1000
|
-
abytes(seed);
|
|
1001
|
-
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
|
1002
|
-
throw new Error("HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got " + seed.length);
|
|
1003
|
-
}
|
|
1004
|
-
const I = hmac(sha512, MASTER_SECRET, seed);
|
|
1005
|
-
const privateKey = I.slice(0, 32);
|
|
1006
|
-
const chainCode = I.slice(32);
|
|
1007
|
-
return new _HDKey({ versions, chainCode, privateKey });
|
|
1008
|
-
}
|
|
1009
|
-
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
|
|
1010
|
-
const keyBuffer = base58check2.decode(base58key);
|
|
1011
|
-
const keyView = createView(keyBuffer);
|
|
1012
|
-
const version = keyView.getUint32(0, false);
|
|
1013
|
-
const opt = {
|
|
1014
|
-
versions,
|
|
1015
|
-
depth: keyBuffer[4],
|
|
1016
|
-
parentFingerprint: keyView.getUint32(5, false),
|
|
1017
|
-
index: keyView.getUint32(9, false),
|
|
1018
|
-
chainCode: keyBuffer.slice(13, 45)
|
|
1019
|
-
};
|
|
1020
|
-
const key = keyBuffer.slice(45);
|
|
1021
|
-
const isPriv = key[0] === 0;
|
|
1022
|
-
if (version !== versions[isPriv ? "private" : "public"]) {
|
|
1023
|
-
throw new Error("Version mismatch");
|
|
1024
|
-
}
|
|
1025
|
-
if (isPriv) {
|
|
1026
|
-
return new _HDKey({ ...opt, privateKey: key.slice(1) });
|
|
1027
|
-
} else {
|
|
1028
|
-
return new _HDKey({ ...opt, publicKey: key });
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
static fromJSON(json) {
|
|
1032
|
-
return _HDKey.fromExtendedKey(json.xpriv);
|
|
1033
|
-
}
|
|
1034
|
-
versions;
|
|
1035
|
-
depth = 0;
|
|
1036
|
-
index = 0;
|
|
1037
|
-
chainCode = null;
|
|
1038
|
-
parentFingerprint = 0;
|
|
1039
|
-
_privateKey;
|
|
1040
|
-
_publicKey;
|
|
1041
|
-
pubHash;
|
|
1042
|
-
constructor(opt) {
|
|
1043
|
-
if (!opt || typeof opt !== "object") {
|
|
1044
|
-
throw new Error("HDKey.constructor must not be called directly");
|
|
1045
|
-
}
|
|
1046
|
-
this.versions = opt.versions || BITCOIN_VERSIONS;
|
|
1047
|
-
this.depth = opt.depth || 0;
|
|
1048
|
-
this.chainCode = opt.chainCode || null;
|
|
1049
|
-
this.index = opt.index || 0;
|
|
1050
|
-
this.parentFingerprint = opt.parentFingerprint || 0;
|
|
1051
|
-
if (!this.depth) {
|
|
1052
|
-
if (this.parentFingerprint || this.index) {
|
|
1053
|
-
throw new Error("HDKey: zero depth with non-zero index/parent fingerprint");
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
if (this.depth > 255) {
|
|
1057
|
-
throw new Error("HDKey: depth exceeds the serializable value 255");
|
|
1058
|
-
}
|
|
1059
|
-
if (opt.publicKey && opt.privateKey) {
|
|
1060
|
-
throw new Error("HDKey: publicKey and privateKey at same time.");
|
|
1061
|
-
}
|
|
1062
|
-
if (opt.privateKey) {
|
|
1063
|
-
if (!secp256k1.utils.isValidSecretKey(opt.privateKey))
|
|
1064
|
-
throw new Error("Invalid private key");
|
|
1065
|
-
this._privateKey = opt.privateKey;
|
|
1066
|
-
this._publicKey = secp256k1.getPublicKey(opt.privateKey, true);
|
|
1067
|
-
} else if (opt.publicKey) {
|
|
1068
|
-
this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true);
|
|
1069
|
-
} else {
|
|
1070
|
-
throw new Error("HDKey: no public or private key provided");
|
|
1071
|
-
}
|
|
1072
|
-
this.pubHash = hash160(this._publicKey);
|
|
1073
|
-
}
|
|
1074
|
-
derive(path) {
|
|
1075
|
-
if (!/^[mM]'?/.test(path)) {
|
|
1076
|
-
throw new Error('Path must start with "m" or "M"');
|
|
1077
|
-
}
|
|
1078
|
-
if (/^[mM]'?$/.test(path)) {
|
|
1079
|
-
return this;
|
|
1080
|
-
}
|
|
1081
|
-
const parts = path.replace(/^[mM]'?\//, "").split("/");
|
|
1082
|
-
let child = this;
|
|
1083
|
-
for (const c of parts) {
|
|
1084
|
-
const m = /^(\d+)('?)$/.exec(c);
|
|
1085
|
-
const m1 = m && m[1];
|
|
1086
|
-
if (!m || m.length !== 3 || typeof m1 !== "string")
|
|
1087
|
-
throw new Error("invalid child index: " + c);
|
|
1088
|
-
let idx = +m1;
|
|
1089
|
-
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
|
|
1090
|
-
throw new Error("Invalid index");
|
|
1091
|
-
}
|
|
1092
|
-
if (m[2] === "'") {
|
|
1093
|
-
idx += HARDENED_OFFSET;
|
|
1094
|
-
}
|
|
1095
|
-
child = child.deriveChild(idx);
|
|
1096
|
-
}
|
|
1097
|
-
return child;
|
|
1098
|
-
}
|
|
1099
|
-
deriveChild(index) {
|
|
1100
|
-
if (!this._publicKey || !this.chainCode) {
|
|
1101
|
-
throw new Error("No publicKey or chainCode set");
|
|
1102
|
-
}
|
|
1103
|
-
let data = toU32(index);
|
|
1104
|
-
if (index >= HARDENED_OFFSET) {
|
|
1105
|
-
const priv = this._privateKey;
|
|
1106
|
-
if (!priv) {
|
|
1107
|
-
throw new Error("Could not derive hardened child key");
|
|
1108
|
-
}
|
|
1109
|
-
data = concatBytes(Uint8Array.of(0), priv, data);
|
|
1110
|
-
} else {
|
|
1111
|
-
data = concatBytes(this._publicKey, data);
|
|
1112
|
-
}
|
|
1113
|
-
const I = hmac(sha512, this.chainCode, data);
|
|
1114
|
-
const childTweak = I.slice(0, 32);
|
|
1115
|
-
const chainCode = I.slice(32);
|
|
1116
|
-
if (!secp256k1.utils.isValidSecretKey(childTweak)) {
|
|
1117
|
-
throw new Error("Tweak bigger than curve order");
|
|
1118
|
-
}
|
|
1119
|
-
const opt = {
|
|
1120
|
-
versions: this.versions,
|
|
1121
|
-
chainCode,
|
|
1122
|
-
depth: this.depth + 1,
|
|
1123
|
-
parentFingerprint: this.fingerprint,
|
|
1124
|
-
index
|
|
1125
|
-
};
|
|
1126
|
-
const ctweak = Fn.fromBytes(childTweak);
|
|
1127
|
-
try {
|
|
1128
|
-
if (this._privateKey) {
|
|
1129
|
-
const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak);
|
|
1130
|
-
if (!Fn.isValidNot0(added)) {
|
|
1131
|
-
throw new Error("The tweak was out of range or the resulted private key is invalid");
|
|
1132
|
-
}
|
|
1133
|
-
opt.privateKey = Fn.toBytes(added);
|
|
1134
|
-
} else {
|
|
1135
|
-
const added = Point.fromBytes(this._publicKey).add(Point.BASE.multiply(ctweak));
|
|
1136
|
-
if (added.equals(Point.ZERO)) {
|
|
1137
|
-
throw new Error("The tweak was equal to negative P, which made the result key invalid");
|
|
1138
|
-
}
|
|
1139
|
-
opt.publicKey = added.toBytes(true);
|
|
1140
|
-
}
|
|
1141
|
-
return new _HDKey(opt);
|
|
1142
|
-
} catch (err) {
|
|
1143
|
-
return this.deriveChild(index + 1);
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
sign(hash) {
|
|
1147
|
-
if (!this._privateKey) {
|
|
1148
|
-
throw new Error("No privateKey set!");
|
|
1149
|
-
}
|
|
1150
|
-
abytes(hash, 32);
|
|
1151
|
-
return secp256k1.sign(hash, this._privateKey, { prehash: false });
|
|
1152
|
-
}
|
|
1153
|
-
verify(hash, signature) {
|
|
1154
|
-
abytes(hash, 32);
|
|
1155
|
-
abytes(signature, 64);
|
|
1156
|
-
if (!this._publicKey) {
|
|
1157
|
-
throw new Error("No publicKey set!");
|
|
1158
|
-
}
|
|
1159
|
-
return secp256k1.verify(signature, hash, this._publicKey, { prehash: false });
|
|
1160
|
-
}
|
|
1161
|
-
wipePrivateData() {
|
|
1162
|
-
if (this._privateKey) {
|
|
1163
|
-
this._privateKey.fill(0);
|
|
1164
|
-
this._privateKey = void 0;
|
|
1165
|
-
}
|
|
1166
|
-
return this;
|
|
1167
|
-
}
|
|
1168
|
-
toJSON() {
|
|
1169
|
-
return {
|
|
1170
|
-
xpriv: this.privateExtendedKey,
|
|
1171
|
-
xpub: this.publicExtendedKey
|
|
1172
|
-
};
|
|
1173
|
-
}
|
|
1174
|
-
serialize(version, key) {
|
|
1175
|
-
if (!this.chainCode) {
|
|
1176
|
-
throw new Error("No chainCode set");
|
|
1177
|
-
}
|
|
1178
|
-
abytes(key, 33);
|
|
1179
|
-
return concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
|
|
1180
|
-
}
|
|
1181
|
-
};
|
|
1182
604
|
var DERIVATION_PATHS2 = {
|
|
1183
|
-
ethereum:
|
|
1184
|
-
bitcoin_mainnet:
|
|
605
|
+
ethereum: `${DERIVATION_PATHS.ethereum}/0`,
|
|
606
|
+
bitcoin_mainnet: `${DERIVATION_PATHS.bitcoin}/0`,
|
|
1185
607
|
bitcoin_testnet: "m/84'/1'/0'/0/0",
|
|
1186
|
-
ton:
|
|
1187
|
-
tron:
|
|
1188
|
-
solana:
|
|
1189
|
-
spark:
|
|
608
|
+
ton: `${DERIVATION_PATHS.ton}/0'/0'`,
|
|
609
|
+
tron: `${DERIVATION_PATHS.tron}/0`,
|
|
610
|
+
solana: `${DERIVATION_PATHS.solana}/0'`,
|
|
611
|
+
spark: `${DERIVATION_PATHS.spark}/0`
|
|
1190
612
|
};
|
|
1191
613
|
function deriveEthereumAddress(seed) {
|
|
1192
614
|
const hdNode = HDNodeWallet.fromPhrase(seed, void 0, DERIVATION_PATHS2.ethereum);
|
|
@@ -1201,7 +623,7 @@ function deriveBitcoinAddress(seed, network = "mainnet") {
|
|
|
1201
623
|
if (!child.publicKey) {
|
|
1202
624
|
throw new Error("Failed to derive public key");
|
|
1203
625
|
}
|
|
1204
|
-
const pubKeyHash = ripemd160(sha256
|
|
626
|
+
const pubKeyHash = ripemd160(sha256(child.publicKey));
|
|
1205
627
|
const witnessVersion = 0;
|
|
1206
628
|
const words = bech32.toWords(pubKeyHash);
|
|
1207
629
|
words.unshift(witnessVersion);
|
|
@@ -1242,7 +664,7 @@ async function deriveTonAddress(seed) {
|
|
|
1242
664
|
const publicKey = keypair.publicKey;
|
|
1243
665
|
const workchain = 0;
|
|
1244
666
|
const flags = 17;
|
|
1245
|
-
const hash = sha256
|
|
667
|
+
const hash = sha256(publicKey);
|
|
1246
668
|
const addressData = new Uint8Array(34);
|
|
1247
669
|
addressData[0] = flags;
|
|
1248
670
|
addressData[1] = workchain;
|
|
@@ -1279,7 +701,7 @@ function deriveTronAddress(seed) {
|
|
|
1279
701
|
for (let i = 0; i < 20; i++) {
|
|
1280
702
|
addressBytes[i + 1] = parseInt(ethAddressHex.slice(i * 2, i * 2 + 2), 16);
|
|
1281
703
|
}
|
|
1282
|
-
const tronBase58check = base58check(sha256
|
|
704
|
+
const tronBase58check = base58check(sha256);
|
|
1283
705
|
return tronBase58check.encode(addressBytes);
|
|
1284
706
|
} catch (error) {
|
|
1285
707
|
console.error("TRON address derivation failed:", error);
|
|
@@ -1294,7 +716,7 @@ function deriveSparkAddress(seed, network = "mainnet") {
|
|
|
1294
716
|
if (!child.publicKey) {
|
|
1295
717
|
throw new Error("Failed to derive public key");
|
|
1296
718
|
}
|
|
1297
|
-
const pubKeyHash = ripemd160(sha256
|
|
719
|
+
const pubKeyHash = ripemd160(sha256(child.publicKey));
|
|
1298
720
|
const witnessVersion = 0;
|
|
1299
721
|
const words = bech32.toWords(pubKeyHash);
|
|
1300
722
|
words.unshift(witnessVersion);
|
|
@@ -1395,9 +817,9 @@ var CHAIN_ERROR_MESSAGES = {
|
|
|
1395
817
|
"no route": "NETWORK_ERROR"
|
|
1396
818
|
}
|
|
1397
819
|
};
|
|
1398
|
-
function parseChainError(
|
|
820
|
+
function parseChainError(chain, errorMessage) {
|
|
1399
821
|
const errorLower = errorMessage.toLowerCase();
|
|
1400
|
-
const chainErrors = CHAIN_ERROR_MESSAGES[
|
|
822
|
+
const chainErrors = CHAIN_ERROR_MESSAGES[chain];
|
|
1401
823
|
for (const [pattern, code] of Object.entries(chainErrors)) {
|
|
1402
824
|
if (errorLower.includes(pattern)) {
|
|
1403
825
|
return code;
|
|
@@ -1535,38 +957,38 @@ var ZubariWdkService = class {
|
|
|
1535
957
|
* For Ethereum, falls back to local derivation if API fails.
|
|
1536
958
|
* For other chains, WDK API is required - no placeholder fallback.
|
|
1537
959
|
*/
|
|
1538
|
-
async deriveAddress(seed,
|
|
960
|
+
async deriveAddress(seed, chain) {
|
|
1539
961
|
await this.initialize();
|
|
1540
|
-
const path = this.getDerivationPath(
|
|
962
|
+
const path = this.getDerivationPath(chain);
|
|
1541
963
|
try {
|
|
1542
|
-
const response = await this.apiClient.deriveAddress(seed,
|
|
964
|
+
const response = await this.apiClient.deriveAddress(seed, chain, this.config.network);
|
|
1543
965
|
if (response.success && response.address) {
|
|
1544
966
|
return {
|
|
1545
|
-
chain
|
|
967
|
+
chain,
|
|
1546
968
|
address: response.address,
|
|
1547
969
|
path: response.path || path
|
|
1548
970
|
};
|
|
1549
971
|
}
|
|
1550
972
|
} catch (error) {
|
|
1551
|
-
console.warn(`API address derivation failed for ${
|
|
1552
|
-
if (
|
|
1553
|
-
return this.deriveBrowserAddress(seed,
|
|
973
|
+
console.warn(`API address derivation failed for ${chain}:`, error);
|
|
974
|
+
if (chain === "ethereum") {
|
|
975
|
+
return this.deriveBrowserAddress(seed, chain);
|
|
1554
976
|
}
|
|
1555
977
|
}
|
|
1556
978
|
if (this.useNativeWdk && this.nativeWdkService) {
|
|
1557
979
|
try {
|
|
1558
980
|
const wdk = this.nativeWdkService;
|
|
1559
981
|
await wdk.initialize(seed);
|
|
1560
|
-
return await wdk.deriveAddress(
|
|
982
|
+
return await wdk.deriveAddress(chain);
|
|
1561
983
|
} catch (error) {
|
|
1562
|
-
console.warn(`Native WDK address derivation failed for ${
|
|
984
|
+
console.warn(`Native WDK address derivation failed for ${chain}:`, error);
|
|
1563
985
|
}
|
|
1564
986
|
}
|
|
1565
|
-
if (
|
|
1566
|
-
return this.deriveBrowserAddress(seed,
|
|
987
|
+
if (chain === "ethereum") {
|
|
988
|
+
return this.deriveBrowserAddress(seed, chain);
|
|
1567
989
|
}
|
|
1568
990
|
throw new Error(
|
|
1569
|
-
`WDK API required for ${
|
|
991
|
+
`WDK API required for ${chain} address derivation. Ensure the backend is running.`
|
|
1570
992
|
);
|
|
1571
993
|
}
|
|
1572
994
|
/**
|
|
@@ -1646,13 +1068,13 @@ var ZubariWdkService = class {
|
|
|
1646
1068
|
/**
|
|
1647
1069
|
* Get fee rates for a chain
|
|
1648
1070
|
*/
|
|
1649
|
-
async getFeeRates(seed,
|
|
1071
|
+
async getFeeRates(seed, chain) {
|
|
1650
1072
|
await this.initialize();
|
|
1651
1073
|
try {
|
|
1652
1074
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/fee-rates`, {
|
|
1653
1075
|
method: "POST",
|
|
1654
1076
|
headers: { "Content-Type": "application/json" },
|
|
1655
|
-
body: JSON.stringify({ seed, chain
|
|
1077
|
+
body: JSON.stringify({ seed, chain, network: this.config.network })
|
|
1656
1078
|
});
|
|
1657
1079
|
if (response.ok) {
|
|
1658
1080
|
const data = await response.json();
|
|
@@ -1661,20 +1083,20 @@ var ZubariWdkService = class {
|
|
|
1661
1083
|
}
|
|
1662
1084
|
}
|
|
1663
1085
|
} catch (error) {
|
|
1664
|
-
console.warn(`Failed to fetch fee rates for ${
|
|
1086
|
+
console.warn(`Failed to fetch fee rates for ${chain}:`, error);
|
|
1665
1087
|
}
|
|
1666
1088
|
return { slow: "0", normal: "0", fast: "0" };
|
|
1667
1089
|
}
|
|
1668
1090
|
/**
|
|
1669
1091
|
* Estimate transaction fee
|
|
1670
1092
|
*/
|
|
1671
|
-
async estimateFee(seed,
|
|
1093
|
+
async estimateFee(seed, chain, to, amount) {
|
|
1672
1094
|
await this.initialize();
|
|
1673
1095
|
try {
|
|
1674
1096
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/estimate-fee`, {
|
|
1675
1097
|
method: "POST",
|
|
1676
1098
|
headers: { "Content-Type": "application/json" },
|
|
1677
|
-
body: JSON.stringify({ seed, chain
|
|
1099
|
+
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1678
1100
|
});
|
|
1679
1101
|
if (response.ok) {
|
|
1680
1102
|
const data = await response.json();
|
|
@@ -1683,9 +1105,9 @@ var ZubariWdkService = class {
|
|
|
1683
1105
|
}
|
|
1684
1106
|
}
|
|
1685
1107
|
} catch (error) {
|
|
1686
|
-
console.warn(`Failed to estimate fee for ${
|
|
1108
|
+
console.warn(`Failed to estimate fee for ${chain}:`, error);
|
|
1687
1109
|
}
|
|
1688
|
-
return { fee: "0", symbol: this.getChainSymbol(
|
|
1110
|
+
return { fee: "0", symbol: this.getChainSymbol(chain) };
|
|
1689
1111
|
}
|
|
1690
1112
|
/**
|
|
1691
1113
|
* Send a transaction on any supported chain
|
|
@@ -1696,19 +1118,14 @@ var ZubariWdkService = class {
|
|
|
1696
1118
|
* @param amount - Amount to send (in native units: ETH, BTC, SOL, etc.)
|
|
1697
1119
|
* @returns Transaction result with hash on success, or error details on failure
|
|
1698
1120
|
*/
|
|
1699
|
-
async sendTransaction(seed,
|
|
1121
|
+
async sendTransaction(seed, chain, to, amount) {
|
|
1700
1122
|
await this.initialize();
|
|
1701
1123
|
const startTime = Date.now();
|
|
1702
|
-
console.log(`[ZubariWdkService] Sending ${chain2} transaction`, {
|
|
1703
|
-
to: `${to.slice(0, 10)}...${to.slice(-6)}`,
|
|
1704
|
-
amount,
|
|
1705
|
-
network: this.config.network
|
|
1706
|
-
});
|
|
1707
1124
|
try {
|
|
1708
1125
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/send`, {
|
|
1709
1126
|
method: "POST",
|
|
1710
1127
|
headers: { "Content-Type": "application/json" },
|
|
1711
|
-
body: JSON.stringify({ seed, chain
|
|
1128
|
+
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1712
1129
|
});
|
|
1713
1130
|
const elapsed = Date.now() - startTime;
|
|
1714
1131
|
if (response.ok) {
|
|
@@ -1718,22 +1135,18 @@ var ZubariWdkService = class {
|
|
|
1718
1135
|
txHash = txHash.hash;
|
|
1719
1136
|
}
|
|
1720
1137
|
if (txHash) {
|
|
1721
|
-
const isValid = this.validateTxHash(
|
|
1138
|
+
const isValid = this.validateTxHash(chain, txHash);
|
|
1722
1139
|
if (!isValid) {
|
|
1723
|
-
console.warn(`[ZubariWdkService] Invalid ${
|
|
1140
|
+
console.warn(`[ZubariWdkService] Invalid ${chain} tx hash format:`, txHash);
|
|
1724
1141
|
}
|
|
1725
1142
|
}
|
|
1726
|
-
console.log(`[ZubariWdkService] ${chain2} transaction ${data.success ? "SUCCESS" : "FAILED"}`, {
|
|
1727
|
-
txHash: txHash ? `${txHash.slice(0, 16)}...` : "N/A",
|
|
1728
|
-
elapsed: `${elapsed}ms`
|
|
1729
|
-
});
|
|
1730
1143
|
if (!data.success) {
|
|
1731
|
-
const errorCode2 = parseChainError(
|
|
1144
|
+
const errorCode2 = parseChainError(chain, data.error || "");
|
|
1732
1145
|
return {
|
|
1733
1146
|
success: false,
|
|
1734
1147
|
error: data.error,
|
|
1735
1148
|
errorCode: errorCode2,
|
|
1736
|
-
chain
|
|
1149
|
+
chain
|
|
1737
1150
|
};
|
|
1738
1151
|
}
|
|
1739
1152
|
return {
|
|
@@ -1742,47 +1155,35 @@ var ZubariWdkService = class {
|
|
|
1742
1155
|
from: data.from,
|
|
1743
1156
|
to: data.to,
|
|
1744
1157
|
amount: data.amount,
|
|
1745
|
-
chain: data.chain ||
|
|
1158
|
+
chain: data.chain || chain,
|
|
1746
1159
|
network: data.network || this.config.network
|
|
1747
1160
|
};
|
|
1748
1161
|
}
|
|
1749
1162
|
const errorData = await response.json().catch(() => ({}));
|
|
1750
1163
|
const errorMessage = errorData.error || `HTTP ${response.status}`;
|
|
1751
|
-
const errorCode = parseChainError(
|
|
1752
|
-
console.error(`[ZubariWdkService] ${chain2} transaction FAILED`, {
|
|
1753
|
-
status: response.status,
|
|
1754
|
-
error: errorMessage,
|
|
1755
|
-
errorCode,
|
|
1756
|
-
elapsed: `${elapsed}ms`
|
|
1757
|
-
});
|
|
1164
|
+
const errorCode = parseChainError(chain, errorMessage);
|
|
1758
1165
|
return {
|
|
1759
1166
|
success: false,
|
|
1760
1167
|
error: errorMessage,
|
|
1761
1168
|
errorCode,
|
|
1762
|
-
chain
|
|
1169
|
+
chain
|
|
1763
1170
|
};
|
|
1764
1171
|
} catch (error) {
|
|
1765
|
-
const elapsed = Date.now() - startTime;
|
|
1766
1172
|
const errorMessage = error instanceof Error ? error.message : "Transaction failed";
|
|
1767
|
-
const errorCode = parseChainError(
|
|
1768
|
-
console.error(`[ZubariWdkService] ${chain2} transaction ERROR`, {
|
|
1769
|
-
error: errorMessage,
|
|
1770
|
-
errorCode,
|
|
1771
|
-
elapsed: `${elapsed}ms`
|
|
1772
|
-
});
|
|
1173
|
+
const errorCode = parseChainError(chain, errorMessage);
|
|
1773
1174
|
return {
|
|
1774
1175
|
success: false,
|
|
1775
1176
|
error: errorMessage,
|
|
1776
1177
|
errorCode,
|
|
1777
|
-
chain
|
|
1178
|
+
chain
|
|
1778
1179
|
};
|
|
1779
1180
|
}
|
|
1780
1181
|
}
|
|
1781
1182
|
/**
|
|
1782
1183
|
* Validate transaction hash format for a specific chain
|
|
1783
1184
|
*/
|
|
1784
|
-
validateTxHash(
|
|
1785
|
-
switch (
|
|
1185
|
+
validateTxHash(chain, txHash) {
|
|
1186
|
+
switch (chain) {
|
|
1786
1187
|
case "ethereum":
|
|
1787
1188
|
return /^0x[a-fA-F0-9]{64}$/.test(txHash);
|
|
1788
1189
|
case "bitcoin":
|
|
@@ -1814,18 +1215,25 @@ var ZubariWdkService = class {
|
|
|
1814
1215
|
// ==========================================
|
|
1815
1216
|
// Private Helper Methods
|
|
1816
1217
|
// ==========================================
|
|
1817
|
-
getDerivationPath(
|
|
1818
|
-
const
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1218
|
+
getDerivationPath(chain) {
|
|
1219
|
+
const basePath = DERIVATION_PATHS[chain];
|
|
1220
|
+
if (chain === "bitcoin" && this.config.network === "testnet") {
|
|
1221
|
+
return "m/84'/1'/0'/0/0";
|
|
1222
|
+
}
|
|
1223
|
+
switch (chain) {
|
|
1224
|
+
case "ton":
|
|
1225
|
+
return `${basePath}/0'/0'`;
|
|
1226
|
+
case "solana":
|
|
1227
|
+
return `${basePath}/0'`;
|
|
1228
|
+
case "bitcoin":
|
|
1229
|
+
case "ethereum":
|
|
1230
|
+
case "tron":
|
|
1231
|
+
case "spark":
|
|
1232
|
+
default:
|
|
1233
|
+
return `${basePath}/0`;
|
|
1234
|
+
}
|
|
1827
1235
|
}
|
|
1828
|
-
getChainSymbol(
|
|
1236
|
+
getChainSymbol(chain) {
|
|
1829
1237
|
const symbols = {
|
|
1830
1238
|
ethereum: "ETH",
|
|
1831
1239
|
bitcoin: "BTC",
|
|
@@ -1834,16 +1242,16 @@ var ZubariWdkService = class {
|
|
|
1834
1242
|
solana: "SOL",
|
|
1835
1243
|
spark: "SAT"
|
|
1836
1244
|
};
|
|
1837
|
-
return symbols[
|
|
1245
|
+
return symbols[chain];
|
|
1838
1246
|
}
|
|
1839
1247
|
/**
|
|
1840
1248
|
* Derive address using browser-compatible libraries
|
|
1841
1249
|
*/
|
|
1842
|
-
async deriveBrowserAddress(seed,
|
|
1843
|
-
const path = this.getDerivationPath(
|
|
1250
|
+
async deriveBrowserAddress(seed, chain) {
|
|
1251
|
+
const path = this.getDerivationPath(chain);
|
|
1844
1252
|
try {
|
|
1845
1253
|
let address;
|
|
1846
|
-
switch (
|
|
1254
|
+
switch (chain) {
|
|
1847
1255
|
case "ethereum":
|
|
1848
1256
|
address = deriveEthereumAddress(seed);
|
|
1849
1257
|
break;
|
|
@@ -1863,11 +1271,11 @@ var ZubariWdkService = class {
|
|
|
1863
1271
|
address = await deriveTonAddress(seed);
|
|
1864
1272
|
break;
|
|
1865
1273
|
default:
|
|
1866
|
-
throw new Error(`Unsupported chain: ${
|
|
1274
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
1867
1275
|
}
|
|
1868
|
-
return { chain
|
|
1276
|
+
return { chain, address, path };
|
|
1869
1277
|
} catch (error) {
|
|
1870
|
-
console.error(`Browser derivation failed for ${
|
|
1278
|
+
console.error(`Browser derivation failed for ${chain}:`, error);
|
|
1871
1279
|
throw error;
|
|
1872
1280
|
}
|
|
1873
1281
|
}
|
|
@@ -1880,7 +1288,7 @@ var ZubariWdkService = class {
|
|
|
1880
1288
|
};
|
|
1881
1289
|
var defaultService = null;
|
|
1882
1290
|
function getZubariWdkService(config) {
|
|
1883
|
-
if (!defaultService || config && config.network !== defaultService.getNetwork()) {
|
|
1291
|
+
if (!defaultService || config && (config.network !== defaultService.getNetwork() || config.apiUrl && config.apiUrl !== defaultService.getApiUrl())) {
|
|
1884
1292
|
defaultService = new ZubariWdkService(config);
|
|
1885
1293
|
}
|
|
1886
1294
|
return defaultService;
|
|
@@ -1890,12 +1298,21 @@ function createZubariWdkService(config) {
|
|
|
1890
1298
|
}
|
|
1891
1299
|
|
|
1892
1300
|
// src/wallet/ZubariWallet.ts
|
|
1893
|
-
var ZubariWallet = class {
|
|
1301
|
+
var ZubariWallet = class _ZubariWallet {
|
|
1894
1302
|
seed;
|
|
1895
1303
|
config;
|
|
1896
1304
|
accounts = /* @__PURE__ */ new Map();
|
|
1897
1305
|
wdkService;
|
|
1898
1306
|
initialized = false;
|
|
1307
|
+
/** Mapping from NetworkType to SupportedChain (identity map, shared across methods) */
|
|
1308
|
+
static CHAIN_MAP = {
|
|
1309
|
+
ethereum: "ethereum",
|
|
1310
|
+
bitcoin: "bitcoin",
|
|
1311
|
+
ton: "ton",
|
|
1312
|
+
tron: "tron",
|
|
1313
|
+
solana: "solana",
|
|
1314
|
+
spark: "spark"
|
|
1315
|
+
};
|
|
1899
1316
|
constructor(seed, config) {
|
|
1900
1317
|
this.seed = seed;
|
|
1901
1318
|
this.config = {
|
|
@@ -1928,20 +1345,12 @@ var ZubariWallet = class {
|
|
|
1928
1345
|
async deriveAccount(network, index = 0) {
|
|
1929
1346
|
const basePath = DERIVATION_PATHS[network];
|
|
1930
1347
|
const derivationPath = `${basePath}/${index}`;
|
|
1931
|
-
const
|
|
1932
|
-
|
|
1933
|
-
bitcoin: "bitcoin",
|
|
1934
|
-
ton: "ton",
|
|
1935
|
-
tron: "tron",
|
|
1936
|
-
solana: "solana",
|
|
1937
|
-
spark: "spark"
|
|
1938
|
-
};
|
|
1939
|
-
const chain2 = chainMap[network];
|
|
1940
|
-
if (!chain2) {
|
|
1348
|
+
const chain = _ZubariWallet.CHAIN_MAP[network];
|
|
1349
|
+
if (!chain) {
|
|
1941
1350
|
throw new Error(`Unsupported network: ${network}`);
|
|
1942
1351
|
}
|
|
1943
1352
|
try {
|
|
1944
|
-
const result = await this.wdkService.deriveAddress(this.seed,
|
|
1353
|
+
const result = await this.wdkService.deriveAddress(this.seed, chain);
|
|
1945
1354
|
const account = {
|
|
1946
1355
|
network,
|
|
1947
1356
|
address: result.address,
|
|
@@ -1988,21 +1397,13 @@ var ZubariWallet = class {
|
|
|
1988
1397
|
*/
|
|
1989
1398
|
async getBalance(network) {
|
|
1990
1399
|
const networkConfig = getNetworkConfig(network, this.config.network === "testnet");
|
|
1991
|
-
const
|
|
1992
|
-
|
|
1993
|
-
bitcoin: "bitcoin",
|
|
1994
|
-
ton: "ton",
|
|
1995
|
-
tron: "tron",
|
|
1996
|
-
solana: "solana",
|
|
1997
|
-
spark: "spark"
|
|
1998
|
-
};
|
|
1999
|
-
const chain2 = chainMap[network];
|
|
2000
|
-
if (!chain2) {
|
|
1400
|
+
const chain = _ZubariWallet.CHAIN_MAP[network];
|
|
1401
|
+
if (!chain) {
|
|
2001
1402
|
throw new Error(`Unsupported network: ${network}`);
|
|
2002
1403
|
}
|
|
2003
1404
|
try {
|
|
2004
1405
|
const balances = await this.wdkService.getAllBalances(this.seed);
|
|
2005
|
-
const chainBalance = balances[
|
|
1406
|
+
const chainBalance = balances[chain];
|
|
2006
1407
|
if (chainBalance) {
|
|
2007
1408
|
const balanceValue = BigInt(chainBalance.balance || "0");
|
|
2008
1409
|
const decimals = networkConfig.nativeCurrency.decimals;
|
|
@@ -2083,22 +1484,14 @@ var ZubariWallet = class {
|
|
|
2083
1484
|
*/
|
|
2084
1485
|
async send(network, params) {
|
|
2085
1486
|
const { to, amount } = params;
|
|
2086
|
-
const
|
|
2087
|
-
|
|
2088
|
-
bitcoin: "bitcoin",
|
|
2089
|
-
ton: "ton",
|
|
2090
|
-
tron: "tron",
|
|
2091
|
-
solana: "solana",
|
|
2092
|
-
spark: "spark"
|
|
2093
|
-
};
|
|
2094
|
-
const chain2 = chainMap[network];
|
|
2095
|
-
if (!chain2) {
|
|
1487
|
+
const chain = _ZubariWallet.CHAIN_MAP[network];
|
|
1488
|
+
if (!chain) {
|
|
2096
1489
|
throw new Error(`Unsupported network: ${network}`);
|
|
2097
1490
|
}
|
|
2098
1491
|
try {
|
|
2099
1492
|
const result = await this.wdkService.sendTransaction(
|
|
2100
1493
|
this.seed,
|
|
2101
|
-
|
|
1494
|
+
chain,
|
|
2102
1495
|
to,
|
|
2103
1496
|
amount.toString()
|
|
2104
1497
|
);
|
|
@@ -2396,7 +1789,10 @@ var KeyManager = class {
|
|
|
2396
1789
|
static KEY_LENGTH = 256;
|
|
2397
1790
|
static IV_LENGTH = 12;
|
|
2398
1791
|
static SALT_LENGTH = 16;
|
|
2399
|
-
|
|
1792
|
+
// OWASP 2023 recommends 600,000 iterations for PBKDF2-SHA256 to resist
|
|
1793
|
+
// brute-force attacks with modern GPU hardware.
|
|
1794
|
+
// See: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
|
1795
|
+
static PBKDF2_ITERATIONS = 6e5;
|
|
2400
1796
|
/**
|
|
2401
1797
|
* Encrypt a seed phrase with a password
|
|
2402
1798
|
*/
|
|
@@ -2635,7 +2031,7 @@ var WebEncryptedStorageAdapter = class {
|
|
|
2635
2031
|
{
|
|
2636
2032
|
name: "PBKDF2",
|
|
2637
2033
|
salt: salt.buffer,
|
|
2638
|
-
iterations:
|
|
2034
|
+
iterations: 6e5,
|
|
2639
2035
|
hash: "SHA-256"
|
|
2640
2036
|
},
|
|
2641
2037
|
keyMaterial,
|
|
@@ -2773,8 +2169,8 @@ async function fetchPrices() {
|
|
|
2773
2169
|
if (response.ok) {
|
|
2774
2170
|
const data = await response.json();
|
|
2775
2171
|
const prices = {};
|
|
2776
|
-
for (const [
|
|
2777
|
-
prices[
|
|
2172
|
+
for (const [chain, geckoId] of Object.entries(COINGECKO_IDS)) {
|
|
2173
|
+
prices[chain] = data[geckoId]?.usd || 0;
|
|
2778
2174
|
}
|
|
2779
2175
|
priceCache = { prices, timestamp: Date.now() };
|
|
2780
2176
|
return prices;
|
|
@@ -2784,9 +2180,22 @@ async function fetchPrices() {
|
|
|
2784
2180
|
}
|
|
2785
2181
|
return priceCache?.prices || {};
|
|
2786
2182
|
}
|
|
2787
|
-
async function getPriceForChain(
|
|
2183
|
+
async function getPriceForChain(chain) {
|
|
2788
2184
|
const prices = await fetchPrices();
|
|
2789
|
-
return prices[
|
|
2185
|
+
return prices[chain] || 0;
|
|
2186
|
+
}
|
|
2187
|
+
function tonFriendlyToRaw(addr) {
|
|
2188
|
+
if (addr.includes(":")) return addr;
|
|
2189
|
+
try {
|
|
2190
|
+
const b64 = addr.replace(/-/g, "+").replace(/_/g, "/");
|
|
2191
|
+
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
2192
|
+
if (bytes.length !== 36) return addr;
|
|
2193
|
+
const workchain = bytes[1] === 255 ? -1 : bytes[1];
|
|
2194
|
+
const hash = Array.from(bytes.slice(2, 34)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
2195
|
+
return `${workchain}:${hash}`;
|
|
2196
|
+
} catch {
|
|
2197
|
+
return addr;
|
|
2198
|
+
}
|
|
2790
2199
|
}
|
|
2791
2200
|
var STORAGE_KEYS = {
|
|
2792
2201
|
ENCRYPTED_SEED: "encrypted_seed",
|
|
@@ -2935,6 +2344,16 @@ var WalletManager = class _WalletManager {
|
|
|
2935
2344
|
}
|
|
2936
2345
|
/**
|
|
2937
2346
|
* Lock wallet (clear seed from memory)
|
|
2347
|
+
*
|
|
2348
|
+
* SECURITY NOTE: JavaScript strings are immutable and cannot be overwritten
|
|
2349
|
+
* in place. Setting `this.currentSeed = null` removes the reference, but
|
|
2350
|
+
* the original string may persist in memory until garbage collected.
|
|
2351
|
+
* There is no reliable way to zero out a JS string.
|
|
2352
|
+
*
|
|
2353
|
+
* TODO: In a future version, store the seed as a Uint8Array instead of a
|
|
2354
|
+
* string. Uint8Array contents can be explicitly zeroed (e.g.,
|
|
2355
|
+
* `seedBytes.fill(0)`) before releasing the reference, which provides
|
|
2356
|
+
* stronger guarantees that sensitive material is scrubbed from memory.
|
|
2938
2357
|
*/
|
|
2939
2358
|
lock() {
|
|
2940
2359
|
this.currentSeed = null;
|
|
@@ -2992,9 +2411,9 @@ var WalletManager = class _WalletManager {
|
|
|
2992
2411
|
if (!this.derivedAddress) {
|
|
2993
2412
|
throw new Error("Wallet not initialized");
|
|
2994
2413
|
}
|
|
2995
|
-
const
|
|
2414
|
+
const chain = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
2996
2415
|
const client = createPublicClient({
|
|
2997
|
-
chain
|
|
2416
|
+
chain,
|
|
2998
2417
|
transport: http(this.config.rpcUrl, {
|
|
2999
2418
|
timeout: 15e3,
|
|
3000
2419
|
// 15 second timeout
|
|
@@ -3016,9 +2435,9 @@ var WalletManager = class _WalletManager {
|
|
|
3016
2435
|
* Create viem public client for the current network
|
|
3017
2436
|
*/
|
|
3018
2437
|
getPublicClient() {
|
|
3019
|
-
const
|
|
2438
|
+
const chain = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
3020
2439
|
return createPublicClient({
|
|
3021
|
-
chain
|
|
2440
|
+
chain,
|
|
3022
2441
|
transport: http(this.config.rpcUrl, {
|
|
3023
2442
|
timeout: 15e3,
|
|
3024
2443
|
// 15 second timeout
|
|
@@ -3072,11 +2491,11 @@ var WalletManager = class _WalletManager {
|
|
|
3072
2491
|
*
|
|
3073
2492
|
* No fallback to placeholder addresses - WDK API is required for real addresses.
|
|
3074
2493
|
*/
|
|
3075
|
-
static async deriveAddressForChainAsync(seed,
|
|
3076
|
-
if (
|
|
2494
|
+
static async deriveAddressForChainAsync(seed, chain, network = "mainnet", apiUrl) {
|
|
2495
|
+
if (chain === "ethereum") {
|
|
3077
2496
|
try {
|
|
3078
2497
|
const wdkService2 = getZubariWdkService({ network, apiUrl });
|
|
3079
|
-
const result2 = await wdkService2.deriveAddress(seed,
|
|
2498
|
+
const result2 = await wdkService2.deriveAddress(seed, chain);
|
|
3080
2499
|
return result2.address;
|
|
3081
2500
|
} catch (error) {
|
|
3082
2501
|
console.warn("WDK service failed for Ethereum, using local derivation:", error);
|
|
@@ -3084,7 +2503,7 @@ var WalletManager = class _WalletManager {
|
|
|
3084
2503
|
}
|
|
3085
2504
|
}
|
|
3086
2505
|
const wdkService = getZubariWdkService({ network, apiUrl });
|
|
3087
|
-
const result = await wdkService.deriveAddress(seed,
|
|
2506
|
+
const result = await wdkService.deriveAddress(seed, chain);
|
|
3088
2507
|
return result.address;
|
|
3089
2508
|
}
|
|
3090
2509
|
/**
|
|
@@ -3093,14 +2512,14 @@ var WalletManager = class _WalletManager {
|
|
|
3093
2512
|
*
|
|
3094
2513
|
* @throws Error for non-Ethereum chains - use WDK API instead
|
|
3095
2514
|
*/
|
|
3096
|
-
static deriveAddressForChain(seed,
|
|
3097
|
-
if (
|
|
2515
|
+
static deriveAddressForChain(seed, chain) {
|
|
2516
|
+
if (chain === "ethereum") {
|
|
3098
2517
|
const ethPath = DERIVATION_PATHS["ethereum"];
|
|
3099
2518
|
const ethNode = HDNodeWallet.fromPhrase(seed, void 0, `${ethPath}/0`);
|
|
3100
2519
|
return ethNode.address;
|
|
3101
2520
|
}
|
|
3102
2521
|
throw new Error(
|
|
3103
|
-
`Sync derivation not supported for ${
|
|
2522
|
+
`Sync derivation not supported for ${chain}. Use deriveAddressForChainAsync() with WDK API.`
|
|
3104
2523
|
);
|
|
3105
2524
|
}
|
|
3106
2525
|
/**
|
|
@@ -3132,9 +2551,9 @@ var WalletManager = class _WalletManager {
|
|
|
3132
2551
|
const wdkAddresses = await this.wdkService.deriveAllAddresses(this.currentSeed);
|
|
3133
2552
|
const enabledChainsSet = new Set(this.config.enabledChains);
|
|
3134
2553
|
const addresses = {};
|
|
3135
|
-
for (const [
|
|
3136
|
-
if (enabledChainsSet.has(
|
|
3137
|
-
addresses[
|
|
2554
|
+
for (const [chain, address] of Object.entries(wdkAddresses)) {
|
|
2555
|
+
if (enabledChainsSet.has(chain) && address) {
|
|
2556
|
+
addresses[chain] = address;
|
|
3138
2557
|
}
|
|
3139
2558
|
}
|
|
3140
2559
|
this.derivedAddresses = addresses;
|
|
@@ -3151,7 +2570,6 @@ var WalletManager = class _WalletManager {
|
|
|
3151
2570
|
async saveAddressesToStorage(addresses) {
|
|
3152
2571
|
try {
|
|
3153
2572
|
await this.storage.setItem(STORAGE_KEYS.DERIVED_ADDRESSES, JSON.stringify(addresses));
|
|
3154
|
-
console.log("Saved derived addresses to storage:", Object.keys(addresses));
|
|
3155
2573
|
} catch (error) {
|
|
3156
2574
|
console.warn("Failed to save addresses to storage:", error);
|
|
3157
2575
|
}
|
|
@@ -3175,10 +2593,10 @@ var WalletManager = class _WalletManager {
|
|
|
3175
2593
|
*/
|
|
3176
2594
|
normalizeAddresses(addresses) {
|
|
3177
2595
|
const normalized = {};
|
|
3178
|
-
for (const [
|
|
2596
|
+
for (const [chain, value] of Object.entries(addresses)) {
|
|
3179
2597
|
const addr = this.normalizeAddress(value);
|
|
3180
2598
|
if (addr) {
|
|
3181
|
-
normalized[
|
|
2599
|
+
normalized[chain] = addr;
|
|
3182
2600
|
}
|
|
3183
2601
|
}
|
|
3184
2602
|
return normalized;
|
|
@@ -3191,9 +2609,7 @@ var WalletManager = class _WalletManager {
|
|
|
3191
2609
|
const stored = await this.storage.getItem(STORAGE_KEYS.DERIVED_ADDRESSES);
|
|
3192
2610
|
if (stored) {
|
|
3193
2611
|
const rawAddresses = JSON.parse(stored);
|
|
3194
|
-
console.log("[WalletManager] Raw addresses from storage:", rawAddresses);
|
|
3195
2612
|
const addresses = this.normalizeAddresses(rawAddresses);
|
|
3196
|
-
console.log("[WalletManager] Normalized addresses:", addresses);
|
|
3197
2613
|
await this.saveAddressesToStorage(addresses);
|
|
3198
2614
|
return addresses;
|
|
3199
2615
|
}
|
|
@@ -3218,11 +2634,8 @@ var WalletManager = class _WalletManager {
|
|
|
3218
2634
|
if (storedAddresses && Object.keys(storedAddresses).length > 1) {
|
|
3219
2635
|
const expectedEthAddress = _WalletManager.deriveAddress(this.currentSeed);
|
|
3220
2636
|
if (storedAddresses.ethereum === expectedEthAddress) {
|
|
3221
|
-
console.log("Using addresses from storage (verified by Ethereum address)");
|
|
3222
2637
|
this.derivedAddresses = storedAddresses;
|
|
3223
2638
|
return storedAddresses;
|
|
3224
|
-
} else {
|
|
3225
|
-
console.log("Stored addresses do not match current seed, re-deriving...");
|
|
3226
2639
|
}
|
|
3227
2640
|
}
|
|
3228
2641
|
return await this.deriveAllAddressesWithWdk();
|
|
@@ -3231,20 +2644,18 @@ var WalletManager = class _WalletManager {
|
|
|
3231
2644
|
* Get address for a specific chain
|
|
3232
2645
|
* Returns cached address or null - use deriveAllAddressesAsync to derive addresses
|
|
3233
2646
|
*/
|
|
3234
|
-
getAddressForChain(
|
|
3235
|
-
const cachedValue = this.derivedAddresses[
|
|
2647
|
+
getAddressForChain(chain) {
|
|
2648
|
+
const cachedValue = this.derivedAddresses[chain];
|
|
3236
2649
|
if (cachedValue) {
|
|
3237
|
-
console.log(`[WalletManager] getAddressForChain(${chain2}) cached value:`, cachedValue, "type:", typeof cachedValue);
|
|
3238
2650
|
const addr = this.normalizeAddress(cachedValue);
|
|
3239
|
-
console.log(`[WalletManager] getAddressForChain(${chain2}) normalized:`, addr);
|
|
3240
2651
|
if (addr) {
|
|
3241
|
-
this.derivedAddresses[
|
|
2652
|
+
this.derivedAddresses[chain] = addr;
|
|
3242
2653
|
return addr;
|
|
3243
2654
|
}
|
|
3244
2655
|
}
|
|
3245
|
-
if (
|
|
3246
|
-
this.derivedAddresses[
|
|
3247
|
-
return this.derivedAddresses[
|
|
2656
|
+
if (chain === "ethereum" && this.currentSeed) {
|
|
2657
|
+
this.derivedAddresses[chain] = _WalletManager.deriveAddressForChain(this.currentSeed, chain);
|
|
2658
|
+
return this.derivedAddresses[chain];
|
|
3248
2659
|
}
|
|
3249
2660
|
return null;
|
|
3250
2661
|
}
|
|
@@ -3257,11 +2668,11 @@ var WalletManager = class _WalletManager {
|
|
|
3257
2668
|
/**
|
|
3258
2669
|
* Set the selected chain
|
|
3259
2670
|
*/
|
|
3260
|
-
setSelectedChain(
|
|
3261
|
-
if (!this.config.enabledChains.includes(
|
|
3262
|
-
throw new Error(`Chain ${
|
|
2671
|
+
setSelectedChain(chain) {
|
|
2672
|
+
if (!this.config.enabledChains.includes(chain)) {
|
|
2673
|
+
throw new Error(`Chain ${chain} is not enabled`);
|
|
3263
2674
|
}
|
|
3264
|
-
this.selectedChain =
|
|
2675
|
+
this.selectedChain = chain;
|
|
3265
2676
|
}
|
|
3266
2677
|
/**
|
|
3267
2678
|
* Get the currently selected chain
|
|
@@ -3278,22 +2689,22 @@ var WalletManager = class _WalletManager {
|
|
|
3278
2689
|
/**
|
|
3279
2690
|
* Get chain configuration
|
|
3280
2691
|
*/
|
|
3281
|
-
getChainConfig(
|
|
3282
|
-
return getNetworkConfig(
|
|
2692
|
+
getChainConfig(chain) {
|
|
2693
|
+
return getNetworkConfig(chain, this.config.network === "testnet");
|
|
3283
2694
|
}
|
|
3284
2695
|
/**
|
|
3285
2696
|
* Fetch balance for a specific chain
|
|
3286
2697
|
* Note: Currently only Ethereum is implemented
|
|
3287
2698
|
*/
|
|
3288
|
-
async fetchBalanceForChain(
|
|
3289
|
-
const address = this.getAddressForChain(
|
|
2699
|
+
async fetchBalanceForChain(chain) {
|
|
2700
|
+
const address = this.getAddressForChain(chain);
|
|
3290
2701
|
if (!address) {
|
|
3291
|
-
throw new Error(`No address for chain ${
|
|
2702
|
+
throw new Error(`No address for chain ${chain}`);
|
|
3292
2703
|
}
|
|
3293
|
-
const networkConfig = this.getChainConfig(
|
|
2704
|
+
const networkConfig = this.getChainConfig(chain);
|
|
3294
2705
|
let balance = "0";
|
|
3295
2706
|
const tokenBalances = {};
|
|
3296
|
-
if (
|
|
2707
|
+
if (chain === "ethereum") {
|
|
3297
2708
|
const viemChain = this.config.network === "mainnet" ? mainnet : sepolia;
|
|
3298
2709
|
const isTestnet2 = this.config.network !== "mainnet";
|
|
3299
2710
|
const client = createPublicClient({
|
|
@@ -3340,7 +2751,7 @@ var WalletManager = class _WalletManager {
|
|
|
3340
2751
|
} else if (usdtResult.status === "rejected") {
|
|
3341
2752
|
console.warn("[WalletManager] Failed to fetch ETH USDT balance:", usdtResult.reason);
|
|
3342
2753
|
}
|
|
3343
|
-
} else if (
|
|
2754
|
+
} else if (chain === "bitcoin") {
|
|
3344
2755
|
const isMainnet2 = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
|
|
3345
2756
|
const apisToTry = isMainnet2 ? ["https://mempool.space/api"] : [
|
|
3346
2757
|
"https://mempool.space/testnet/api",
|
|
@@ -3363,16 +2774,14 @@ var WalletManager = class _WalletManager {
|
|
|
3363
2774
|
const mempoolSpent = data.mempool_stats?.spent_txo_sum || 0;
|
|
3364
2775
|
const satoshis = chainFunded - chainSpent + (mempoolFunded - mempoolSpent);
|
|
3365
2776
|
balance = (satoshis / 1e8).toFixed(8);
|
|
3366
|
-
console.log(`Bitcoin balance for ${address}: ${balance} BTC (${satoshis} sats) via ${apiUrl}`);
|
|
3367
2777
|
break;
|
|
3368
2778
|
}
|
|
3369
|
-
console.log(`No transactions found on ${apiUrl}, trying next...`);
|
|
3370
2779
|
}
|
|
3371
2780
|
} catch (error) {
|
|
3372
2781
|
console.warn(`Failed to fetch from ${apiUrl}:`, error);
|
|
3373
2782
|
}
|
|
3374
2783
|
}
|
|
3375
|
-
} else if (
|
|
2784
|
+
} else if (chain === "solana") {
|
|
3376
2785
|
const rpcUrl = this.config.network === "mainnet" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
|
|
3377
2786
|
try {
|
|
3378
2787
|
const response = await fetch(rpcUrl, {
|
|
@@ -3392,7 +2801,7 @@ var WalletManager = class _WalletManager {
|
|
|
3392
2801
|
}
|
|
3393
2802
|
}
|
|
3394
2803
|
} catch (error) {
|
|
3395
|
-
console.warn(`Failed to fetch ${
|
|
2804
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
3396
2805
|
}
|
|
3397
2806
|
const isTestnet2 = this.config.network !== "mainnet";
|
|
3398
2807
|
const usdtMint = USDT_ADDRESSES.solana?.[isTestnet2 ? "testnet" : "mainnet"];
|
|
@@ -3426,7 +2835,7 @@ var WalletManager = class _WalletManager {
|
|
|
3426
2835
|
console.warn("Failed to fetch Solana USDT balance:", error);
|
|
3427
2836
|
}
|
|
3428
2837
|
}
|
|
3429
|
-
} else if (
|
|
2838
|
+
} else if (chain === "tron") {
|
|
3430
2839
|
const tronConfig = getNetworkConfig("tron", this.config.network !== "mainnet");
|
|
3431
2840
|
const baseUrl = tronConfig.rpcUrl;
|
|
3432
2841
|
try {
|
|
@@ -3455,9 +2864,9 @@ var WalletManager = class _WalletManager {
|
|
|
3455
2864
|
}
|
|
3456
2865
|
}
|
|
3457
2866
|
} catch (error) {
|
|
3458
|
-
console.warn(`Failed to fetch ${
|
|
2867
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
3459
2868
|
}
|
|
3460
|
-
} else if (
|
|
2869
|
+
} else if (chain === "ton") {
|
|
3461
2870
|
const isTestnet2 = this.config.network !== "mainnet";
|
|
3462
2871
|
const baseUrl = isTestnet2 ? "https://testnet.toncenter.com/api/v2" : "https://toncenter.com/api/v2";
|
|
3463
2872
|
try {
|
|
@@ -3469,29 +2878,39 @@ var WalletManager = class _WalletManager {
|
|
|
3469
2878
|
if (data.ok && data.result !== void 0) {
|
|
3470
2879
|
const nanotons = BigInt(data.result);
|
|
3471
2880
|
balance = (Number(nanotons) / 1e9).toFixed(9);
|
|
3472
|
-
console.log(`TON balance for ${address}: ${balance} TON`);
|
|
3473
2881
|
}
|
|
3474
2882
|
}
|
|
3475
2883
|
} catch (error) {
|
|
3476
|
-
console.warn(`Failed to fetch ${
|
|
2884
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
3477
2885
|
}
|
|
3478
2886
|
const usdtJetton = USDT_ADDRESSES.ton?.[isTestnet2 ? "testnet" : "mainnet"];
|
|
3479
2887
|
if (usdtJetton) {
|
|
3480
|
-
const
|
|
2888
|
+
const tonapiBaseUrl = isTestnet2 ? "https://testnet.tonapi.io/v2" : "https://tonapi.io/v2";
|
|
3481
2889
|
try {
|
|
2890
|
+
const rawAddr = tonFriendlyToRaw(address);
|
|
3482
2891
|
const jettonResponse = await fetch(
|
|
3483
|
-
`${
|
|
2892
|
+
`${tonapiBaseUrl}/accounts/${encodeURIComponent(rawAddr)}/jettons?currencies=usd`,
|
|
3484
2893
|
{ headers: { "Accept": "application/json" } }
|
|
3485
2894
|
);
|
|
3486
2895
|
if (jettonResponse.ok) {
|
|
3487
2896
|
const jettonData = await jettonResponse.json();
|
|
3488
|
-
const
|
|
3489
|
-
if (
|
|
3490
|
-
const
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
2897
|
+
const balances = jettonData.balances;
|
|
2898
|
+
if (balances && balances.length > 0) {
|
|
2899
|
+
for (const jb of balances) {
|
|
2900
|
+
const jettonAddr = jb.jetton?.address;
|
|
2901
|
+
if (jettonAddr) {
|
|
2902
|
+
const usdtRaw = tonFriendlyToRaw(usdtJetton);
|
|
2903
|
+
if (jettonAddr.toLowerCase() === usdtRaw.toLowerCase()) {
|
|
2904
|
+
const rawBalance = jb.balance;
|
|
2905
|
+
if (rawBalance) {
|
|
2906
|
+
const decimals = jb.jetton?.decimals || 6;
|
|
2907
|
+
const usdtAmount = Number(BigInt(rawBalance)) / Math.pow(10, decimals);
|
|
2908
|
+
if (usdtAmount > 0) {
|
|
2909
|
+
tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
break;
|
|
2913
|
+
}
|
|
3495
2914
|
}
|
|
3496
2915
|
}
|
|
3497
2916
|
}
|
|
@@ -3500,7 +2919,7 @@ var WalletManager = class _WalletManager {
|
|
|
3500
2919
|
console.warn("Failed to fetch TON USDT jetton balance:", error);
|
|
3501
2920
|
}
|
|
3502
2921
|
}
|
|
3503
|
-
} else if (
|
|
2922
|
+
} else if (chain === "spark") {
|
|
3504
2923
|
try {
|
|
3505
2924
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
|
|
3506
2925
|
method: "POST",
|
|
@@ -3515,18 +2934,17 @@ var WalletManager = class _WalletManager {
|
|
|
3515
2934
|
const data = await response.json();
|
|
3516
2935
|
if (data.success && data.balance !== void 0) {
|
|
3517
2936
|
balance = (parseFloat(data.balance) / 1e8).toFixed(8);
|
|
3518
|
-
console.log(`Spark balance for ${address}: ${balance} BTC`);
|
|
3519
2937
|
}
|
|
3520
2938
|
}
|
|
3521
2939
|
} catch (error) {
|
|
3522
|
-
console.warn(`Failed to fetch ${
|
|
2940
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
3523
2941
|
}
|
|
3524
2942
|
}
|
|
3525
|
-
const priceUsd = await getPriceForChain(
|
|
2943
|
+
const priceUsd = await getPriceForChain(chain);
|
|
3526
2944
|
const balanceNum = parseFloat(balance) || 0;
|
|
3527
2945
|
const balanceUsd = balanceNum * priceUsd;
|
|
3528
2946
|
return {
|
|
3529
|
-
chain
|
|
2947
|
+
chain,
|
|
3530
2948
|
symbol: networkConfig.nativeCurrency.symbol,
|
|
3531
2949
|
balance,
|
|
3532
2950
|
balanceUsd,
|
|
@@ -3536,28 +2954,29 @@ var WalletManager = class _WalletManager {
|
|
|
3536
2954
|
};
|
|
3537
2955
|
}
|
|
3538
2956
|
/**
|
|
3539
|
-
* Fetch balances for all enabled chains
|
|
2957
|
+
* Fetch balances for all enabled chains in parallel.
|
|
2958
|
+
* Uses Promise.allSettled so that one chain failing does not block others.
|
|
3540
2959
|
*/
|
|
3541
2960
|
async fetchAllBalances() {
|
|
3542
|
-
const
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
const networkConfig = this.getChainConfig(chain2);
|
|
3550
|
-
balances.push({
|
|
3551
|
-
chain: chain2,
|
|
3552
|
-
symbol: networkConfig.nativeCurrency.symbol,
|
|
3553
|
-
balance: "0",
|
|
3554
|
-
balanceUsd: 0,
|
|
3555
|
-
address: this.getAddressForChain(chain2) || "",
|
|
3556
|
-
decimals: networkConfig.nativeCurrency.decimals
|
|
3557
|
-
});
|
|
2961
|
+
const results = await Promise.allSettled(
|
|
2962
|
+
this.config.enabledChains.map((chain) => this.fetchBalanceForChain(chain))
|
|
2963
|
+
);
|
|
2964
|
+
return results.map((result, index) => {
|
|
2965
|
+
const chain = this.config.enabledChains[index];
|
|
2966
|
+
if (result.status === "fulfilled") {
|
|
2967
|
+
return result.value;
|
|
3558
2968
|
}
|
|
3559
|
-
|
|
3560
|
-
|
|
2969
|
+
console.error(`Failed to fetch balance for ${chain}:`, result.reason);
|
|
2970
|
+
const networkConfig = this.getChainConfig(chain);
|
|
2971
|
+
return {
|
|
2972
|
+
chain,
|
|
2973
|
+
symbol: networkConfig.nativeCurrency.symbol,
|
|
2974
|
+
balance: "0",
|
|
2975
|
+
balanceUsd: 0,
|
|
2976
|
+
address: this.getAddressForChain(chain) || "",
|
|
2977
|
+
decimals: networkConfig.nativeCurrency.decimals
|
|
2978
|
+
};
|
|
2979
|
+
});
|
|
3561
2980
|
}
|
|
3562
2981
|
/**
|
|
3563
2982
|
* Get extended wallet state with multi-chain info
|
|
@@ -3582,13 +3001,13 @@ var WalletManager = class _WalletManager {
|
|
|
3582
3001
|
* @param token - Optional token symbol (e.g., 'USDT' for stablecoins)
|
|
3583
3002
|
* @returns Transaction result with hash and status
|
|
3584
3003
|
*/
|
|
3585
|
-
async sendTransaction(
|
|
3004
|
+
async sendTransaction(chain, to, amount, token) {
|
|
3586
3005
|
if (!this.currentSeed) {
|
|
3587
3006
|
return { success: false, error: "Wallet is locked" };
|
|
3588
3007
|
}
|
|
3589
|
-
const fromAddress = this.getAddressForChain(
|
|
3008
|
+
const fromAddress = this.getAddressForChain(chain);
|
|
3590
3009
|
if (!fromAddress) {
|
|
3591
|
-
return { success: false, error: `No address for chain ${
|
|
3010
|
+
return { success: false, error: `No address for chain ${chain}` };
|
|
3592
3011
|
}
|
|
3593
3012
|
try {
|
|
3594
3013
|
const headers = {
|
|
@@ -3602,7 +3021,7 @@ var WalletManager = class _WalletManager {
|
|
|
3602
3021
|
headers,
|
|
3603
3022
|
body: JSON.stringify({
|
|
3604
3023
|
seed: this.currentSeed,
|
|
3605
|
-
chain
|
|
3024
|
+
chain,
|
|
3606
3025
|
to,
|
|
3607
3026
|
amount,
|
|
3608
3027
|
token,
|
|
@@ -3611,12 +3030,11 @@ var WalletManager = class _WalletManager {
|
|
|
3611
3030
|
});
|
|
3612
3031
|
if (response.ok) {
|
|
3613
3032
|
const data = await response.json();
|
|
3614
|
-
console.log(`Transaction sent on ${chain2}:`, data);
|
|
3615
3033
|
let txHash = data.txHash || data.transactionHash || data.hash;
|
|
3616
3034
|
if (txHash && typeof txHash === "object" && "hash" in txHash) {
|
|
3617
3035
|
txHash = txHash.hash;
|
|
3618
3036
|
}
|
|
3619
|
-
if (
|
|
3037
|
+
if (chain === "ethereum" && txHash && (typeof txHash !== "string" || !txHash.startsWith("0x") || txHash.length !== 66)) {
|
|
3620
3038
|
console.warn(`Invalid Ethereum tx hash format: ${txHash} (length: ${txHash?.length}, expected: 66)`);
|
|
3621
3039
|
}
|
|
3622
3040
|
return {
|
|
@@ -3625,7 +3043,7 @@ var WalletManager = class _WalletManager {
|
|
|
3625
3043
|
from: fromAddress,
|
|
3626
3044
|
to,
|
|
3627
3045
|
amount,
|
|
3628
|
-
chain
|
|
3046
|
+
chain
|
|
3629
3047
|
};
|
|
3630
3048
|
}
|
|
3631
3049
|
const errorData = await response.json().catch(() => ({}));
|
|
@@ -3634,7 +3052,7 @@ var WalletManager = class _WalletManager {
|
|
|
3634
3052
|
error: errorData.error || `HTTP ${response.status}`
|
|
3635
3053
|
};
|
|
3636
3054
|
} catch (error) {
|
|
3637
|
-
console.error(`Transaction failed on ${
|
|
3055
|
+
console.error(`Transaction failed on ${chain}:`, error);
|
|
3638
3056
|
return {
|
|
3639
3057
|
success: false,
|
|
3640
3058
|
error: error instanceof Error ? error.message : "Transaction failed"
|
|
@@ -3644,7 +3062,7 @@ var WalletManager = class _WalletManager {
|
|
|
3644
3062
|
/**
|
|
3645
3063
|
* Estimate transaction fee using Tether WDK
|
|
3646
3064
|
*/
|
|
3647
|
-
async estimateFee(
|
|
3065
|
+
async estimateFee(chain, to, amount, token) {
|
|
3648
3066
|
try {
|
|
3649
3067
|
const headers = {
|
|
3650
3068
|
"Content-Type": "application/json"
|
|
@@ -3656,7 +3074,7 @@ var WalletManager = class _WalletManager {
|
|
|
3656
3074
|
method: "POST",
|
|
3657
3075
|
headers,
|
|
3658
3076
|
body: JSON.stringify({
|
|
3659
|
-
chain
|
|
3077
|
+
chain,
|
|
3660
3078
|
to,
|
|
3661
3079
|
amount,
|
|
3662
3080
|
token,
|
|
@@ -7226,10 +6644,23 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7226
6644
|
contractAddress;
|
|
7227
6645
|
chainId;
|
|
7228
6646
|
abi = ZubariSubscription_default;
|
|
6647
|
+
/** Cached ethers Interface instance (lazy-initialized) */
|
|
6648
|
+
_iface = null;
|
|
7229
6649
|
constructor(contractAddress, chainId) {
|
|
7230
6650
|
this.contractAddress = contractAddress;
|
|
7231
6651
|
this.chainId = chainId;
|
|
7232
6652
|
}
|
|
6653
|
+
/**
|
|
6654
|
+
* Get or create the cached ethers Interface for encoding/decoding contract calls.
|
|
6655
|
+
* The Interface is created once on first use and reused for all subsequent calls.
|
|
6656
|
+
*/
|
|
6657
|
+
async getInterface() {
|
|
6658
|
+
if (!this._iface) {
|
|
6659
|
+
const { Interface } = await import('ethers');
|
|
6660
|
+
this._iface = new Interface(this.abi);
|
|
6661
|
+
}
|
|
6662
|
+
return this._iface;
|
|
6663
|
+
}
|
|
7233
6664
|
/**
|
|
7234
6665
|
* Get the contract ABI
|
|
7235
6666
|
*/
|
|
@@ -7257,7 +6688,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7257
6688
|
if (plan.duration <= 0) {
|
|
7258
6689
|
throw new Error("Plan duration must be greater than 0");
|
|
7259
6690
|
}
|
|
7260
|
-
const iface =
|
|
6691
|
+
const iface = await this.getInterface();
|
|
7261
6692
|
const durationDays = Math.ceil(plan.duration / (24 * 60 * 60));
|
|
7262
6693
|
const data = iface.encodeFunctionData("createPlan", [
|
|
7263
6694
|
plan.name,
|
|
@@ -7282,7 +6713,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7282
6713
|
* @param signer Wallet signer
|
|
7283
6714
|
*/
|
|
7284
6715
|
async deactivatePlan(planId, signer) {
|
|
7285
|
-
const iface =
|
|
6716
|
+
const iface = await this.getInterface();
|
|
7286
6717
|
const data = iface.encodeFunctionData("deactivatePlan", [planId]);
|
|
7287
6718
|
const result = await signer.sendTransaction({
|
|
7288
6719
|
to: this.contractAddress,
|
|
@@ -7306,7 +6737,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7306
6737
|
if (months <= 0) {
|
|
7307
6738
|
throw new Error("Subscription duration must be at least 1 month");
|
|
7308
6739
|
}
|
|
7309
|
-
const iface =
|
|
6740
|
+
const iface = await this.getInterface();
|
|
7310
6741
|
const data = iface.encodeFunctionData("subscribe", [planId, months]);
|
|
7311
6742
|
const result = await signer.sendTransaction({
|
|
7312
6743
|
to: this.contractAddress,
|
|
@@ -7325,7 +6756,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7325
6756
|
* @param signer Wallet signer
|
|
7326
6757
|
*/
|
|
7327
6758
|
async cancel(subscriptionId, signer) {
|
|
7328
|
-
const iface =
|
|
6759
|
+
const iface = await this.getInterface();
|
|
7329
6760
|
const data = iface.encodeFunctionData("cancel", [subscriptionId]);
|
|
7330
6761
|
const result = await signer.sendTransaction({
|
|
7331
6762
|
to: this.contractAddress,
|
|
@@ -7345,7 +6776,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7345
6776
|
* @param signer Wallet signer
|
|
7346
6777
|
*/
|
|
7347
6778
|
async setAutoRenew(subscriptionId, autoRenew, signer) {
|
|
7348
|
-
const iface =
|
|
6779
|
+
const iface = await this.getInterface();
|
|
7349
6780
|
const data = iface.encodeFunctionData("setAutoRenew", [subscriptionId, autoRenew]);
|
|
7350
6781
|
const result = await signer.sendTransaction({
|
|
7351
6782
|
to: this.contractAddress,
|
|
@@ -7365,7 +6796,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7365
6796
|
* @param provider JSON-RPC provider
|
|
7366
6797
|
*/
|
|
7367
6798
|
async isSubscribed(subscriber, creator, provider) {
|
|
7368
|
-
const iface =
|
|
6799
|
+
const iface = await this.getInterface();
|
|
7369
6800
|
const data = iface.encodeFunctionData("isSubscribed", [subscriber, creator]);
|
|
7370
6801
|
try {
|
|
7371
6802
|
const result = await provider.call({
|
|
@@ -7385,7 +6816,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7385
6816
|
* @param provider JSON-RPC provider
|
|
7386
6817
|
*/
|
|
7387
6818
|
async getActiveSubscriptionId(subscriber, creator, provider) {
|
|
7388
|
-
const iface =
|
|
6819
|
+
const iface = await this.getInterface();
|
|
7389
6820
|
const data = iface.encodeFunctionData("activeSubscription", [subscriber, creator]);
|
|
7390
6821
|
try {
|
|
7391
6822
|
const result = await provider.call({
|
|
@@ -7408,7 +6839,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7408
6839
|
* @param provider JSON-RPC provider
|
|
7409
6840
|
*/
|
|
7410
6841
|
async getSubscription(subscriptionId, provider) {
|
|
7411
|
-
const iface =
|
|
6842
|
+
const iface = await this.getInterface();
|
|
7412
6843
|
const data = iface.encodeFunctionData("getSubscription", [subscriptionId]);
|
|
7413
6844
|
try {
|
|
7414
6845
|
const result = await provider.call({
|
|
@@ -7454,7 +6885,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7454
6885
|
* @param provider JSON-RPC provider
|
|
7455
6886
|
*/
|
|
7456
6887
|
async getPlan(planId, provider) {
|
|
7457
|
-
const iface =
|
|
6888
|
+
const iface = await this.getInterface();
|
|
7458
6889
|
const data = iface.encodeFunctionData("getPlan", [planId]);
|
|
7459
6890
|
try {
|
|
7460
6891
|
const result = await provider.call({
|
|
@@ -7490,7 +6921,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7490
6921
|
* @param provider JSON-RPC provider
|
|
7491
6922
|
*/
|
|
7492
6923
|
async getCreatorPlanIds(creator, provider) {
|
|
7493
|
-
const iface =
|
|
6924
|
+
const iface = await this.getInterface();
|
|
7494
6925
|
const data = iface.encodeFunctionData("getCreatorPlans", [creator]);
|
|
7495
6926
|
try {
|
|
7496
6927
|
const result = await provider.call({
|
|
@@ -7524,7 +6955,7 @@ var ZubariSubscriptionProtocol = class {
|
|
|
7524
6955
|
* @param provider JSON-RPC provider
|
|
7525
6956
|
*/
|
|
7526
6957
|
async getPlatformFeeBps(provider) {
|
|
7527
|
-
const iface =
|
|
6958
|
+
const iface = await this.getInterface();
|
|
7528
6959
|
const data = iface.encodeFunctionData("platformFeeBps", []);
|
|
7529
6960
|
try {
|
|
7530
6961
|
const result = await provider.call({
|
|
@@ -8140,8 +7571,8 @@ async function fetchPrices2() {
|
|
|
8140
7571
|
if (response.ok) {
|
|
8141
7572
|
const data = await response.json();
|
|
8142
7573
|
const prices = {};
|
|
8143
|
-
for (const [
|
|
8144
|
-
prices[
|
|
7574
|
+
for (const [chain, geckoId] of Object.entries(COINGECKO_IDS2)) {
|
|
7575
|
+
prices[chain] = data[geckoId]?.usd || 0;
|
|
8145
7576
|
}
|
|
8146
7577
|
priceCache2 = { prices, timestamp: Date.now() };
|
|
8147
7578
|
return prices;
|
|
@@ -8151,9 +7582,9 @@ async function fetchPrices2() {
|
|
|
8151
7582
|
}
|
|
8152
7583
|
return priceCache2?.prices || {};
|
|
8153
7584
|
}
|
|
8154
|
-
async function getPriceForChain2(
|
|
7585
|
+
async function getPriceForChain2(chain) {
|
|
8155
7586
|
const prices = await fetchPrices2();
|
|
8156
|
-
return prices[
|
|
7587
|
+
return prices[chain] || 0;
|
|
8157
7588
|
}
|
|
8158
7589
|
var dynamicImport2 = new Function("specifier", "return import(specifier)");
|
|
8159
7590
|
async function loadWdkModules() {
|
|
@@ -8243,19 +7674,19 @@ var TransactionService = class {
|
|
|
8243
7674
|
/**
|
|
8244
7675
|
* Get RPC URL for a chain
|
|
8245
7676
|
*/
|
|
8246
|
-
getRpcUrl(
|
|
7677
|
+
getRpcUrl(chain) {
|
|
8247
7678
|
const networkUrls = DEFAULT_RPC_URLS[this.config.network];
|
|
8248
|
-
if (this.config.rpcUrls?.[
|
|
8249
|
-
return this.config.rpcUrls[
|
|
7679
|
+
if (this.config.rpcUrls?.[chain]) {
|
|
7680
|
+
return this.config.rpcUrls[chain];
|
|
8250
7681
|
}
|
|
8251
|
-
return networkUrls[
|
|
7682
|
+
return networkUrls[chain] || "";
|
|
8252
7683
|
}
|
|
8253
7684
|
/**
|
|
8254
7685
|
* Get explorer URL for a transaction
|
|
8255
7686
|
*/
|
|
8256
|
-
getExplorerUrl(
|
|
7687
|
+
getExplorerUrl(chain, txHash) {
|
|
8257
7688
|
const explorers = EXPLORER_URLS[this.config.network];
|
|
8258
|
-
const baseUrl = explorers[
|
|
7689
|
+
const baseUrl = explorers[chain] || "";
|
|
8259
7690
|
return `${baseUrl}${txHash}`;
|
|
8260
7691
|
}
|
|
8261
7692
|
/**
|
|
@@ -8279,27 +7710,27 @@ var TransactionService = class {
|
|
|
8279
7710
|
* Get or create wallet instance for a specific chain
|
|
8280
7711
|
*/
|
|
8281
7712
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8282
|
-
async getWallet(
|
|
7713
|
+
async getWallet(chain) {
|
|
8283
7714
|
if (!this.seed) {
|
|
8284
7715
|
throw new Error("TransactionService not initialized. Call initialize() first.");
|
|
8285
7716
|
}
|
|
8286
|
-
if (this.wallets[
|
|
8287
|
-
return this.wallets[
|
|
7717
|
+
if (this.wallets[chain]) {
|
|
7718
|
+
return this.wallets[chain];
|
|
8288
7719
|
}
|
|
8289
7720
|
const isTestnet2 = this.config.network === "testnet";
|
|
8290
7721
|
try {
|
|
8291
|
-
switch (
|
|
7722
|
+
switch (chain) {
|
|
8292
7723
|
case "ethereum": {
|
|
8293
7724
|
const rpcUrl = this.getRpcUrl("ethereum");
|
|
8294
7725
|
const wallet = new WalletManagerEvm(this.seed, { provider: rpcUrl });
|
|
8295
|
-
this.wallets[
|
|
7726
|
+
this.wallets[chain] = wallet;
|
|
8296
7727
|
return wallet;
|
|
8297
7728
|
}
|
|
8298
7729
|
case "bitcoin": {
|
|
8299
7730
|
const wallet = new WalletManagerBtc(this.seed, {
|
|
8300
7731
|
network: isTestnet2 ? "testnet" : "bitcoin"
|
|
8301
7732
|
});
|
|
8302
|
-
this.wallets[
|
|
7733
|
+
this.wallets[chain] = wallet;
|
|
8303
7734
|
return wallet;
|
|
8304
7735
|
}
|
|
8305
7736
|
case "solana": {
|
|
@@ -8307,7 +7738,7 @@ var TransactionService = class {
|
|
|
8307
7738
|
const wallet = new WalletManagerSolana(this.seed, {
|
|
8308
7739
|
rpcUrl
|
|
8309
7740
|
});
|
|
8310
|
-
this.wallets[
|
|
7741
|
+
this.wallets[chain] = wallet;
|
|
8311
7742
|
return wallet;
|
|
8312
7743
|
}
|
|
8313
7744
|
case "ton": {
|
|
@@ -8315,7 +7746,7 @@ var TransactionService = class {
|
|
|
8315
7746
|
const wallet = new WalletManagerTon(this.seed, {
|
|
8316
7747
|
tonClient: { url }
|
|
8317
7748
|
});
|
|
8318
|
-
this.wallets[
|
|
7749
|
+
this.wallets[chain] = wallet;
|
|
8319
7750
|
return wallet;
|
|
8320
7751
|
}
|
|
8321
7752
|
case "tron": {
|
|
@@ -8323,32 +7754,32 @@ var TransactionService = class {
|
|
|
8323
7754
|
const wallet = new WalletManagerTron(this.seed, {
|
|
8324
7755
|
provider: fullHost
|
|
8325
7756
|
});
|
|
8326
|
-
this.wallets[
|
|
7757
|
+
this.wallets[chain] = wallet;
|
|
8327
7758
|
return wallet;
|
|
8328
7759
|
}
|
|
8329
7760
|
case "spark": {
|
|
8330
7761
|
const wallet = new WalletManagerSpark(this.seed, {
|
|
8331
7762
|
network: isTestnet2 ? "TESTNET" : "MAINNET"
|
|
8332
7763
|
});
|
|
8333
|
-
this.wallets[
|
|
7764
|
+
this.wallets[chain] = wallet;
|
|
8334
7765
|
return wallet;
|
|
8335
7766
|
}
|
|
8336
7767
|
default:
|
|
8337
|
-
throw new Error(`Unsupported chain: ${
|
|
7768
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
8338
7769
|
}
|
|
8339
7770
|
} catch (error) {
|
|
8340
|
-
console.error(`Failed to initialize ${
|
|
7771
|
+
console.error(`Failed to initialize ${chain} wallet:`, error);
|
|
8341
7772
|
throw error;
|
|
8342
7773
|
}
|
|
8343
7774
|
}
|
|
8344
7775
|
/**
|
|
8345
7776
|
* Estimate transaction fee
|
|
8346
7777
|
*/
|
|
8347
|
-
async estimateFee(
|
|
8348
|
-
const wallet = await this.getWallet(
|
|
7778
|
+
async estimateFee(chain, params) {
|
|
7779
|
+
const wallet = await this.getWallet(chain);
|
|
8349
7780
|
try {
|
|
8350
7781
|
const feeRates = await wallet.getFeeRates();
|
|
8351
|
-
if (
|
|
7782
|
+
if (chain === "ethereum") {
|
|
8352
7783
|
return {
|
|
8353
7784
|
slow: {
|
|
8354
7785
|
fee: `${feeRates.slow || "0"} Gwei`,
|
|
@@ -8363,7 +7794,7 @@ var TransactionService = class {
|
|
|
8363
7794
|
estimatedTime: "~30 sec"
|
|
8364
7795
|
}
|
|
8365
7796
|
};
|
|
8366
|
-
} else if (
|
|
7797
|
+
} else if (chain === "bitcoin") {
|
|
8367
7798
|
return {
|
|
8368
7799
|
slow: {
|
|
8369
7800
|
fee: `${feeRates.slow || feeRates.low || "0"} sat/vB`,
|
|
@@ -8395,7 +7826,7 @@ var TransactionService = class {
|
|
|
8395
7826
|
};
|
|
8396
7827
|
}
|
|
8397
7828
|
} catch (error) {
|
|
8398
|
-
console.error(`Error estimating fee for ${
|
|
7829
|
+
console.error(`Error estimating fee for ${chain}:`, error);
|
|
8399
7830
|
return {
|
|
8400
7831
|
slow: { fee: "0", estimatedTime: "Unknown" },
|
|
8401
7832
|
medium: { fee: "0", estimatedTime: "Unknown" },
|
|
@@ -8406,8 +7837,8 @@ var TransactionService = class {
|
|
|
8406
7837
|
/**
|
|
8407
7838
|
* Send a transaction
|
|
8408
7839
|
*/
|
|
8409
|
-
async send(
|
|
8410
|
-
const wallet = await this.getWallet(
|
|
7840
|
+
async send(chain, params) {
|
|
7841
|
+
const wallet = await this.getWallet(chain);
|
|
8411
7842
|
const account = await wallet.getAccount(0);
|
|
8412
7843
|
const timestamp = Date.now();
|
|
8413
7844
|
try {
|
|
@@ -8427,17 +7858,17 @@ var TransactionService = class {
|
|
|
8427
7858
|
}
|
|
8428
7859
|
return {
|
|
8429
7860
|
hash: txHash,
|
|
8430
|
-
network:
|
|
7861
|
+
network: chain,
|
|
8431
7862
|
status: "pending",
|
|
8432
|
-
explorerUrl: this.getExplorerUrl(
|
|
7863
|
+
explorerUrl: this.getExplorerUrl(chain, txHash),
|
|
8433
7864
|
timestamp
|
|
8434
7865
|
};
|
|
8435
7866
|
} catch (error) {
|
|
8436
7867
|
const errorMessage = error instanceof Error ? error.message : "Transaction failed";
|
|
8437
|
-
console.error(`Transaction failed on ${
|
|
7868
|
+
console.error(`Transaction failed on ${chain}:`, error);
|
|
8438
7869
|
return {
|
|
8439
7870
|
hash: "",
|
|
8440
|
-
network:
|
|
7871
|
+
network: chain,
|
|
8441
7872
|
status: "failed",
|
|
8442
7873
|
error: errorMessage,
|
|
8443
7874
|
timestamp
|
|
@@ -8447,27 +7878,27 @@ var TransactionService = class {
|
|
|
8447
7878
|
/**
|
|
8448
7879
|
* Get transaction status
|
|
8449
7880
|
*/
|
|
8450
|
-
async getTransactionStatus(
|
|
8451
|
-
const wallet = await this.getWallet(
|
|
7881
|
+
async getTransactionStatus(chain, txHash) {
|
|
7882
|
+
const wallet = await this.getWallet(chain);
|
|
8452
7883
|
try {
|
|
8453
7884
|
const tx = await wallet.getTransaction(txHash);
|
|
8454
7885
|
return {
|
|
8455
7886
|
hash: txHash,
|
|
8456
|
-
network:
|
|
7887
|
+
network: chain,
|
|
8457
7888
|
status: tx.confirmed ? "confirmed" : "pending",
|
|
8458
7889
|
blockNumber: tx.blockNumber,
|
|
8459
7890
|
gasUsed: tx.gasUsed?.toString(),
|
|
8460
7891
|
fee: tx.fee?.toString(),
|
|
8461
|
-
explorerUrl: this.getExplorerUrl(
|
|
7892
|
+
explorerUrl: this.getExplorerUrl(chain, txHash),
|
|
8462
7893
|
timestamp: tx.timestamp || Date.now()
|
|
8463
7894
|
};
|
|
8464
7895
|
} catch (error) {
|
|
8465
7896
|
console.error(`Error getting transaction status for ${txHash}:`, error);
|
|
8466
7897
|
return {
|
|
8467
7898
|
hash: txHash,
|
|
8468
|
-
network:
|
|
7899
|
+
network: chain,
|
|
8469
7900
|
status: "pending",
|
|
8470
|
-
explorerUrl: this.getExplorerUrl(
|
|
7901
|
+
explorerUrl: this.getExplorerUrl(chain, txHash),
|
|
8471
7902
|
timestamp: Date.now()
|
|
8472
7903
|
};
|
|
8473
7904
|
}
|
|
@@ -8475,14 +7906,14 @@ var TransactionService = class {
|
|
|
8475
7906
|
/**
|
|
8476
7907
|
* Get transaction history for an address
|
|
8477
7908
|
*/
|
|
8478
|
-
async getTransactionHistory(
|
|
8479
|
-
const wallet = await this.getWallet(
|
|
7909
|
+
async getTransactionHistory(chain, limit = 10) {
|
|
7910
|
+
const wallet = await this.getWallet(chain);
|
|
8480
7911
|
const account = await wallet.getAccount(0);
|
|
8481
7912
|
try {
|
|
8482
7913
|
const history = await account.getTransactions({ limit });
|
|
8483
7914
|
return history.map((tx) => ({
|
|
8484
7915
|
hash: tx.hash || tx.txHash,
|
|
8485
|
-
network:
|
|
7916
|
+
network: chain,
|
|
8486
7917
|
type: tx.type || (tx.from === account.address ? "send" : "receive"),
|
|
8487
7918
|
from: tx.from,
|
|
8488
7919
|
to: tx.to,
|
|
@@ -8494,20 +7925,20 @@ var TransactionService = class {
|
|
|
8494
7925
|
blockNumber: tx.blockNumber
|
|
8495
7926
|
}));
|
|
8496
7927
|
} catch (error) {
|
|
8497
|
-
console.error(`Error getting transaction history for ${
|
|
7928
|
+
console.error(`Error getting transaction history for ${chain}:`, error);
|
|
8498
7929
|
return [];
|
|
8499
7930
|
}
|
|
8500
7931
|
}
|
|
8501
7932
|
/**
|
|
8502
7933
|
* Get balance for a specific chain
|
|
8503
7934
|
*/
|
|
8504
|
-
async getBalance(
|
|
8505
|
-
const wallet = await this.getWallet(
|
|
7935
|
+
async getBalance(chain) {
|
|
7936
|
+
const wallet = await this.getWallet(chain);
|
|
8506
7937
|
const account = await wallet.getAccount(0);
|
|
8507
7938
|
try {
|
|
8508
7939
|
const balance = await account.getBalance();
|
|
8509
7940
|
const balanceStr = balance.toString();
|
|
8510
|
-
const priceUsd = await getPriceForChain2(
|
|
7941
|
+
const priceUsd = await getPriceForChain2(chain);
|
|
8511
7942
|
const balanceNum = parseFloat(balanceStr) || 0;
|
|
8512
7943
|
const balanceUsd = balanceNum * priceUsd;
|
|
8513
7944
|
return {
|
|
@@ -8515,7 +7946,7 @@ var TransactionService = class {
|
|
|
8515
7946
|
balanceUsd
|
|
8516
7947
|
};
|
|
8517
7948
|
} catch (error) {
|
|
8518
|
-
console.error(`Error getting balance for ${
|
|
7949
|
+
console.error(`Error getting balance for ${chain}:`, error);
|
|
8519
7950
|
return { balance: "0", balanceUsd: 0 };
|
|
8520
7951
|
}
|
|
8521
7952
|
}
|
|
@@ -8583,14 +8014,6 @@ function normalizeAddress(address) {
|
|
|
8583
8014
|
}
|
|
8584
8015
|
return address.toLowerCase();
|
|
8585
8016
|
}
|
|
8586
|
-
/*! Bundled license information:
|
|
8587
|
-
|
|
8588
|
-
@scure/base/index.js:
|
|
8589
|
-
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
8590
|
-
|
|
8591
|
-
@scure/bip32/index.js:
|
|
8592
|
-
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
8593
|
-
*/
|
|
8594
8017
|
|
|
8595
8018
|
export { BrowserAddressDerivation_exports as BrowserAddressDerivation, CURRENCY_ADDRESSES, DEFAULT_CONTRACTS, DERIVATION_PATHS, KeyManager, MAINNET_FEE_WALLETS, MemoryStorageAdapter, NETWORKS, NFT_VOUCHER_DOMAIN, NFT_VOUCHER_TYPES, PLATFORM_CONFIG, SwapService, TESTNET_FEE_WALLETS, TESTNET_NETWORKS, TransactionService, WalletManager, WdkApiClient, WebEncryptedStorageAdapter, ZERO_ADDRESS, ZUBARI_CONTRACTS, ZubariError, ZubariMarketProtocol, ZubariNFTProtocol, ZubariPayoutsProtocol, ZubariSubscriptionProtocol, ZubariTipsProtocol, ZubariWallet, ZubariWdkService, createSecureStorage, createTransactionService, createZubariWdkService, formatAddress, formatBalance, getAllFeeWallets, getChainId, getContractAddresses, getCurrentContractAddresses, getCurrentCurrencyAddresses, getCurrentFeeWallet, getCurrentFeeWallets, getDefaultSubscriptionAddress, getExplorerUrl, getFeeWallet, getNetworkConfig, getNetworkName, getRpcUrl, getTransactionService, getWdkApiClient, getZubariNetwork, getZubariWdkService, isBrowser, isMainnet, isTestnet, isValidAddress, logNetworkStatus, normalizeAddress };
|
|
8596
8019
|
//# sourceMappingURL=index.mjs.map
|