@zubari/sdk 0.1.6 → 0.1.8

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.
@@ -1068,6 +1068,47 @@ function getZubariWdkService(config) {
1068
1068
  }
1069
1069
 
1070
1070
  // src/wallet/WalletManager.ts
1071
+ var COINGECKO_IDS = {
1072
+ ethereum: "ethereum",
1073
+ bitcoin: "bitcoin",
1074
+ ton: "the-open-network",
1075
+ tron: "tron",
1076
+ solana: "solana",
1077
+ spark: "bitcoin"
1078
+ // Spark uses BTC
1079
+ };
1080
+ var priceCache = null;
1081
+ var PRICE_CACHE_TTL = 6e4;
1082
+ async function fetchPrices() {
1083
+ if (priceCache && Date.now() - priceCache.timestamp < PRICE_CACHE_TTL) {
1084
+ return priceCache.prices;
1085
+ }
1086
+ const ids = Object.values(COINGECKO_IDS).filter((v, i, a) => a.indexOf(v) === i).join(",");
1087
+ try {
1088
+ const response = await fetch(
1089
+ `https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`,
1090
+ {
1091
+ headers: { "Accept": "application/json" }
1092
+ }
1093
+ );
1094
+ if (response.ok) {
1095
+ const data = await response.json();
1096
+ const prices = {};
1097
+ for (const [chain, geckoId] of Object.entries(COINGECKO_IDS)) {
1098
+ prices[chain] = data[geckoId]?.usd || 0;
1099
+ }
1100
+ priceCache = { prices, timestamp: Date.now() };
1101
+ return prices;
1102
+ }
1103
+ } catch (error) {
1104
+ console.warn("Failed to fetch prices from CoinGecko:", error);
1105
+ }
1106
+ return priceCache?.prices || {};
1107
+ }
1108
+ async function getPriceForChain(chain) {
1109
+ const prices = await fetchPrices();
1110
+ return prices[chain] || 0;
1111
+ }
1071
1112
  var STORAGE_KEYS = {
1072
1113
  ENCRYPTED_SEED: "encrypted_seed",
1073
1114
  ACTIVE_WALLET: "active_wallet"
@@ -1540,22 +1581,36 @@ var WalletManager = class _WalletManager {
1540
1581
  console.warn(`Failed to fetch ${chain} balance:`, error);
1541
1582
  }
1542
1583
  } else if (chain === "bitcoin") {
1543
- const baseUrl = this.config.network === "mainnet" ? "https://blockstream.info/api" : "https://blockstream.info/testnet/api";
1544
- try {
1545
- const response = await fetch(`${baseUrl}/address/${address}`, {
1546
- headers: { "Accept": "application/json" }
1547
- });
1548
- if (response.ok) {
1549
- const data = await response.json();
1550
- const chainFunded = data.chain_stats?.funded_txo_sum || 0;
1551
- const chainSpent = data.chain_stats?.spent_txo_sum || 0;
1552
- const mempoolFunded = data.mempool_stats?.funded_txo_sum || 0;
1553
- const mempoolSpent = data.mempool_stats?.spent_txo_sum || 0;
1554
- const satoshis = chainFunded - chainSpent + (mempoolFunded - mempoolSpent);
1555
- balance = (satoshis / 1e8).toFixed(8);
1584
+ const isMainnet = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
1585
+ const apisToTry = isMainnet ? ["https://mempool.space/api"] : [
1586
+ "https://mempool.space/testnet/api",
1587
+ // testnet3 first (more common)
1588
+ "https://mempool.space/testnet4/api"
1589
+ // then testnet4
1590
+ ];
1591
+ for (const apiUrl of apisToTry) {
1592
+ try {
1593
+ const response = await fetch(`${apiUrl}/address/${address}`, {
1594
+ headers: { "Accept": "application/json" }
1595
+ });
1596
+ if (response.ok) {
1597
+ const data = await response.json();
1598
+ const txCount = (data.chain_stats?.tx_count || 0) + (data.mempool_stats?.tx_count || 0);
1599
+ if (txCount > 0 || isMainnet) {
1600
+ const chainFunded = data.chain_stats?.funded_txo_sum || 0;
1601
+ const chainSpent = data.chain_stats?.spent_txo_sum || 0;
1602
+ const mempoolFunded = data.mempool_stats?.funded_txo_sum || 0;
1603
+ const mempoolSpent = data.mempool_stats?.spent_txo_sum || 0;
1604
+ const satoshis = chainFunded - chainSpent + (mempoolFunded - mempoolSpent);
1605
+ balance = (satoshis / 1e8).toFixed(8);
1606
+ console.log(`Bitcoin balance for ${address}: ${balance} BTC (${satoshis} sats) via ${apiUrl}`);
1607
+ break;
1608
+ }
1609
+ console.log(`No transactions found on ${apiUrl}, trying next...`);
1610
+ }
1611
+ } catch (error) {
1612
+ console.warn(`Failed to fetch from ${apiUrl}:`, error);
1556
1613
  }
1557
- } catch (error) {
1558
- console.warn(`Failed to fetch ${chain} balance:`, error);
1559
1614
  }
1560
1615
  } else if (chain === "solana") {
1561
1616
  const rpcUrl = this.config.network === "mainnet" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
@@ -1594,13 +1649,53 @@ var WalletManager = class _WalletManager {
1594
1649
  } catch (error) {
1595
1650
  console.warn(`Failed to fetch ${chain} balance:`, error);
1596
1651
  }
1652
+ } else if (chain === "ton") {
1653
+ const baseUrl = this.config.network === "mainnet" ? "https://toncenter.com/api/v2" : "https://testnet.toncenter.com/api/v2";
1654
+ try {
1655
+ const response = await fetch(`${baseUrl}/getAddressBalance?address=${address}`, {
1656
+ headers: { "Accept": "application/json" }
1657
+ });
1658
+ if (response.ok) {
1659
+ const data = await response.json();
1660
+ if (data.ok && data.result !== void 0) {
1661
+ const nanotons = BigInt(data.result);
1662
+ balance = (Number(nanotons) / 1e9).toFixed(9);
1663
+ console.log(`TON balance for ${address}: ${balance} TON`);
1664
+ }
1665
+ }
1666
+ } catch (error) {
1667
+ console.warn(`Failed to fetch ${chain} balance:`, error);
1668
+ }
1669
+ } else if (chain === "spark") {
1670
+ try {
1671
+ const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
1672
+ method: "POST",
1673
+ headers: { "Content-Type": "application/json" },
1674
+ body: JSON.stringify({
1675
+ chain: "spark",
1676
+ address,
1677
+ network: this.config.network
1678
+ })
1679
+ });
1680
+ if (response.ok) {
1681
+ const data = await response.json();
1682
+ if (data.success && data.balance !== void 0) {
1683
+ balance = (parseFloat(data.balance) / 1e8).toFixed(8);
1684
+ console.log(`Spark balance for ${address}: ${balance} BTC`);
1685
+ }
1686
+ }
1687
+ } catch (error) {
1688
+ console.warn(`Failed to fetch ${chain} balance:`, error);
1689
+ }
1597
1690
  }
1691
+ const priceUsd = await getPriceForChain(chain);
1692
+ const balanceNum = parseFloat(balance) || 0;
1693
+ const balanceUsd = balanceNum * priceUsd;
1598
1694
  return {
1599
1695
  chain,
1600
1696
  symbol: networkConfig.nativeCurrency.symbol,
1601
1697
  balance,
1602
- balanceUsd: 0,
1603
- // TODO: Implement price fetching
1698
+ balanceUsd,
1604
1699
  address,
1605
1700
  decimals: networkConfig.nativeCurrency.decimals
1606
1701
  };