@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.
package/dist/index.js CHANGED
@@ -1417,6 +1417,47 @@ function createZubariWdkService(config) {
1417
1417
  }
1418
1418
 
1419
1419
  // src/wallet/WalletManager.ts
1420
+ var COINGECKO_IDS = {
1421
+ ethereum: "ethereum",
1422
+ bitcoin: "bitcoin",
1423
+ ton: "the-open-network",
1424
+ tron: "tron",
1425
+ solana: "solana",
1426
+ spark: "bitcoin"
1427
+ // Spark uses BTC
1428
+ };
1429
+ var priceCache = null;
1430
+ var PRICE_CACHE_TTL = 6e4;
1431
+ async function fetchPrices() {
1432
+ if (priceCache && Date.now() - priceCache.timestamp < PRICE_CACHE_TTL) {
1433
+ return priceCache.prices;
1434
+ }
1435
+ const ids = Object.values(COINGECKO_IDS).filter((v, i, a) => a.indexOf(v) === i).join(",");
1436
+ try {
1437
+ const response = await fetch(
1438
+ `https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`,
1439
+ {
1440
+ headers: { "Accept": "application/json" }
1441
+ }
1442
+ );
1443
+ if (response.ok) {
1444
+ const data = await response.json();
1445
+ const prices = {};
1446
+ for (const [chain, geckoId] of Object.entries(COINGECKO_IDS)) {
1447
+ prices[chain] = data[geckoId]?.usd || 0;
1448
+ }
1449
+ priceCache = { prices, timestamp: Date.now() };
1450
+ return prices;
1451
+ }
1452
+ } catch (error) {
1453
+ console.warn("Failed to fetch prices from CoinGecko:", error);
1454
+ }
1455
+ return priceCache?.prices || {};
1456
+ }
1457
+ async function getPriceForChain(chain) {
1458
+ const prices = await fetchPrices();
1459
+ return prices[chain] || 0;
1460
+ }
1420
1461
  var STORAGE_KEYS = {
1421
1462
  ENCRYPTED_SEED: "encrypted_seed",
1422
1463
  ACTIVE_WALLET: "active_wallet"
@@ -1889,22 +1930,36 @@ var WalletManager = class _WalletManager {
1889
1930
  console.warn(`Failed to fetch ${chain} balance:`, error);
1890
1931
  }
1891
1932
  } else if (chain === "bitcoin") {
1892
- const baseUrl = this.config.network === "mainnet" ? "https://blockstream.info/api" : "https://blockstream.info/testnet/api";
1893
- try {
1894
- const response = await fetch(`${baseUrl}/address/${address}`, {
1895
- headers: { "Accept": "application/json" }
1896
- });
1897
- if (response.ok) {
1898
- const data = await response.json();
1899
- const chainFunded = data.chain_stats?.funded_txo_sum || 0;
1900
- const chainSpent = data.chain_stats?.spent_txo_sum || 0;
1901
- const mempoolFunded = data.mempool_stats?.funded_txo_sum || 0;
1902
- const mempoolSpent = data.mempool_stats?.spent_txo_sum || 0;
1903
- const satoshis = chainFunded - chainSpent + (mempoolFunded - mempoolSpent);
1904
- balance = (satoshis / 1e8).toFixed(8);
1933
+ const isMainnet = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
1934
+ const apisToTry = isMainnet ? ["https://mempool.space/api"] : [
1935
+ "https://mempool.space/testnet/api",
1936
+ // testnet3 first (more common)
1937
+ "https://mempool.space/testnet4/api"
1938
+ // then testnet4
1939
+ ];
1940
+ for (const apiUrl of apisToTry) {
1941
+ try {
1942
+ const response = await fetch(`${apiUrl}/address/${address}`, {
1943
+ headers: { "Accept": "application/json" }
1944
+ });
1945
+ if (response.ok) {
1946
+ const data = await response.json();
1947
+ const txCount = (data.chain_stats?.tx_count || 0) + (data.mempool_stats?.tx_count || 0);
1948
+ if (txCount > 0 || isMainnet) {
1949
+ const chainFunded = data.chain_stats?.funded_txo_sum || 0;
1950
+ const chainSpent = data.chain_stats?.spent_txo_sum || 0;
1951
+ const mempoolFunded = data.mempool_stats?.funded_txo_sum || 0;
1952
+ const mempoolSpent = data.mempool_stats?.spent_txo_sum || 0;
1953
+ const satoshis = chainFunded - chainSpent + (mempoolFunded - mempoolSpent);
1954
+ balance = (satoshis / 1e8).toFixed(8);
1955
+ console.log(`Bitcoin balance for ${address}: ${balance} BTC (${satoshis} sats) via ${apiUrl}`);
1956
+ break;
1957
+ }
1958
+ console.log(`No transactions found on ${apiUrl}, trying next...`);
1959
+ }
1960
+ } catch (error) {
1961
+ console.warn(`Failed to fetch from ${apiUrl}:`, error);
1905
1962
  }
1906
- } catch (error) {
1907
- console.warn(`Failed to fetch ${chain} balance:`, error);
1908
1963
  }
1909
1964
  } else if (chain === "solana") {
1910
1965
  const rpcUrl = this.config.network === "mainnet" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
@@ -1943,13 +1998,53 @@ var WalletManager = class _WalletManager {
1943
1998
  } catch (error) {
1944
1999
  console.warn(`Failed to fetch ${chain} balance:`, error);
1945
2000
  }
2001
+ } else if (chain === "ton") {
2002
+ const baseUrl = this.config.network === "mainnet" ? "https://toncenter.com/api/v2" : "https://testnet.toncenter.com/api/v2";
2003
+ try {
2004
+ const response = await fetch(`${baseUrl}/getAddressBalance?address=${address}`, {
2005
+ headers: { "Accept": "application/json" }
2006
+ });
2007
+ if (response.ok) {
2008
+ const data = await response.json();
2009
+ if (data.ok && data.result !== void 0) {
2010
+ const nanotons = BigInt(data.result);
2011
+ balance = (Number(nanotons) / 1e9).toFixed(9);
2012
+ console.log(`TON balance for ${address}: ${balance} TON`);
2013
+ }
2014
+ }
2015
+ } catch (error) {
2016
+ console.warn(`Failed to fetch ${chain} balance:`, error);
2017
+ }
2018
+ } else if (chain === "spark") {
2019
+ try {
2020
+ const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
2021
+ method: "POST",
2022
+ headers: { "Content-Type": "application/json" },
2023
+ body: JSON.stringify({
2024
+ chain: "spark",
2025
+ address,
2026
+ network: this.config.network
2027
+ })
2028
+ });
2029
+ if (response.ok) {
2030
+ const data = await response.json();
2031
+ if (data.success && data.balance !== void 0) {
2032
+ balance = (parseFloat(data.balance) / 1e8).toFixed(8);
2033
+ console.log(`Spark balance for ${address}: ${balance} BTC`);
2034
+ }
2035
+ }
2036
+ } catch (error) {
2037
+ console.warn(`Failed to fetch ${chain} balance:`, error);
2038
+ }
1946
2039
  }
2040
+ const priceUsd = await getPriceForChain(chain);
2041
+ const balanceNum = parseFloat(balance) || 0;
2042
+ const balanceUsd = balanceNum * priceUsd;
1947
2043
  return {
1948
2044
  chain,
1949
2045
  symbol: networkConfig.nativeCurrency.symbol,
1950
2046
  balance,
1951
- balanceUsd: 0,
1952
- // TODO: Implement price fetching
2047
+ balanceUsd,
1953
2048
  address,
1954
2049
  decimals: networkConfig.nativeCurrency.decimals
1955
2050
  };
@@ -2465,6 +2560,47 @@ var WalletManagerTron;
2465
2560
  var WalletManagerSpark;
2466
2561
  var wdkLoaded = false;
2467
2562
  var wdkLoadError = null;
2563
+ var COINGECKO_IDS2 = {
2564
+ ethereum: "ethereum",
2565
+ bitcoin: "bitcoin",
2566
+ ton: "the-open-network",
2567
+ tron: "tron",
2568
+ solana: "solana",
2569
+ spark: "bitcoin"
2570
+ // Spark uses BTC
2571
+ };
2572
+ var priceCache2 = null;
2573
+ var PRICE_CACHE_TTL2 = 6e4;
2574
+ async function fetchPrices2() {
2575
+ if (priceCache2 && Date.now() - priceCache2.timestamp < PRICE_CACHE_TTL2) {
2576
+ return priceCache2.prices;
2577
+ }
2578
+ const ids = Object.values(COINGECKO_IDS2).filter((v, i, a) => a.indexOf(v) === i).join(",");
2579
+ try {
2580
+ const response = await fetch(
2581
+ `https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd`,
2582
+ {
2583
+ headers: { "Accept": "application/json" }
2584
+ }
2585
+ );
2586
+ if (response.ok) {
2587
+ const data = await response.json();
2588
+ const prices = {};
2589
+ for (const [chain, geckoId] of Object.entries(COINGECKO_IDS2)) {
2590
+ prices[chain] = data[geckoId]?.usd || 0;
2591
+ }
2592
+ priceCache2 = { prices, timestamp: Date.now() };
2593
+ return prices;
2594
+ }
2595
+ } catch (error) {
2596
+ console.warn("Failed to fetch prices from CoinGecko:", error);
2597
+ }
2598
+ return priceCache2?.prices || {};
2599
+ }
2600
+ async function getPriceForChain2(chain) {
2601
+ const prices = await fetchPrices2();
2602
+ return prices[chain] || 0;
2603
+ }
2468
2604
  var dynamicImport2 = new Function("specifier", "return import(specifier)");
2469
2605
  async function loadWdkModules() {
2470
2606
  if (wdkLoaded) return;
@@ -2816,10 +2952,13 @@ var TransactionService = class {
2816
2952
  const account = await wallet.getAccount(0);
2817
2953
  try {
2818
2954
  const balance = await account.getBalance();
2955
+ const balanceStr = balance.toString();
2956
+ const priceUsd = await getPriceForChain2(chain);
2957
+ const balanceNum = parseFloat(balanceStr) || 0;
2958
+ const balanceUsd = balanceNum * priceUsd;
2819
2959
  return {
2820
- balance: balance.toString(),
2821
- balanceUsd: 0
2822
- // TODO: Implement price fetching
2960
+ balance: balanceStr,
2961
+ balanceUsd
2823
2962
  };
2824
2963
  } catch (error) {
2825
2964
  console.error(`Error getting balance for ${chain}:`, error);