hd-wallet-ui 1.2.1 → 1.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hd-wallet-ui",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "HD Wallet modal UI — login, keys, identity, trust map, and security bond. Attach to any button in your app.",
5
5
  "type": "module",
6
6
  "main": "src/app.js",
@@ -35,7 +35,7 @@
35
35
  "buffer": "^6.0.3",
36
36
  "flatbuffers": "^25.9.23",
37
37
  "flatc-wasm": "^25.12.19-wasm.43",
38
- "hd-wallet-wasm": "^1.2.1",
38
+ "hd-wallet-wasm": "^1.2.3",
39
39
  "qrcode": "^1.5.3",
40
40
  "spacedatastandards.org": "^23.3.3-0.3.4",
41
41
  "vcard-cryptoperson": "^1.1.11"
@@ -22,6 +22,7 @@ const isDev = import.meta.env?.DEV ?? false;
22
22
 
23
23
  const proxyMap = {
24
24
  'https://blockchain.info': '/api/blockchain',
25
+ 'https://blockstream.info': '/api/blockstream',
25
26
  'https://cloudflare-eth.com': '/api/eth',
26
27
  'https://api.mainnet-beta.solana.com': '/api/solana/official',
27
28
  'https://solana-rpc.publicnode.com': '/api/solana/publicnode',
@@ -387,18 +388,44 @@ export function truncateAddress(address) {
387
388
  * @returns {Promise<{balance: string, error?: string}>}
388
389
  */
389
390
  export async function fetchBtcBalance(address) {
391
+ let lastError = 'No available endpoint';
392
+
393
+ // Primary endpoint: blockchain.info (fast/simple satoshi response)
390
394
  try {
391
395
  const response = await fetch(apiUrl(`https://blockchain.info/q/addressbalance/${address}?cors=true`));
392
- if (!response.ok) {
393
- return { balance: '0', error: 'API error' };
396
+ if (response.ok) {
397
+ const satoshis = await response.text();
398
+ const satoshisInt = parseInt(satoshis, 10);
399
+ if (Number.isFinite(satoshisInt)) {
400
+ return { balance: (satoshisInt / 1e8).toFixed(8) };
401
+ }
402
+ lastError = 'Invalid BTC balance response from blockchain.info';
403
+ } else {
404
+ lastError = `blockchain.info HTTP ${response.status}`;
394
405
  }
395
- const satoshis = await response.text();
396
- const btc = parseInt(satoshis, 10) / 1e8;
397
- return { balance: btc.toFixed(8) };
398
406
  } catch (e) {
399
- console.debug('BTC balance fetch unavailable:', e.message);
400
- return { balance: '--', error: e.message };
407
+ lastError = `blockchain.info ${e.message || 'request failed'}`;
401
408
  }
409
+
410
+ // Fallback endpoint: blockstream.info (chain_stats + mempool_stats)
411
+ try {
412
+ const response = await fetch(apiUrl(`https://blockstream.info/api/address/${address}`));
413
+ if (response.ok) {
414
+ const data = await response.json();
415
+ const chainFunded = BigInt(data?.chain_stats?.funded_txo_sum ?? 0);
416
+ const chainSpent = BigInt(data?.chain_stats?.spent_txo_sum ?? 0);
417
+ const mempoolFunded = BigInt(data?.mempool_stats?.funded_txo_sum ?? 0);
418
+ const mempoolSpent = BigInt(data?.mempool_stats?.spent_txo_sum ?? 0);
419
+ const satoshis = chainFunded - chainSpent + mempoolFunded - mempoolSpent;
420
+ return { balance: (Number(satoshis) / 1e8).toFixed(8) };
421
+ }
422
+ lastError = `${lastError}; blockstream.info HTTP ${response.status}`;
423
+ } catch (e) {
424
+ lastError = `${lastError}; blockstream.info ${e.message || 'request failed'}`;
425
+ }
426
+
427
+ console.debug('BTC balance fetch unavailable:', lastError);
428
+ return { balance: '--', error: lastError };
402
429
  }
403
430
 
404
431
  /**
@@ -418,9 +445,12 @@ export async function fetchEthBalance(address) {
418
445
  params: [address, 'latest']
419
446
  })
420
447
  });
448
+ if (!response.ok) {
449
+ return { balance: '--', error: `HTTP ${response.status}` };
450
+ }
421
451
  const data = await response.json();
422
452
  if (data.error) {
423
- return { balance: '0', error: data.error.message };
453
+ return { balance: '--', error: data.error.message || 'ETH RPC error' };
424
454
  }
425
455
  const balanceWei = BigInt(data.result || '0x0');
426
456
  const balanceEth = Number(balanceWei) / 1e18;
@@ -438,10 +468,11 @@ export async function fetchEthBalance(address) {
438
468
  */
439
469
  export async function fetchSolBalance(address) {
440
470
  const endpoints = [
441
- 'https://api.mainnet-beta.solana.com',
442
471
  'https://solana-rpc.publicnode.com',
443
472
  'https://mainnet.helius-rpc.com/?api-key=1d8740dc-e5f4-421c-b823-e1bad1889eda',
473
+ 'https://api.mainnet-beta.solana.com',
444
474
  ];
475
+ let lastError = 'No available endpoint';
445
476
 
446
477
  for (const endpoint of endpoints) {
447
478
  try {
@@ -455,18 +486,25 @@ export async function fetchSolBalance(address) {
455
486
  params: [address]
456
487
  })
457
488
  });
458
- if (!response.ok) continue;
489
+ if (!response.ok) {
490
+ lastError = `HTTP ${response.status}`;
491
+ continue;
492
+ }
459
493
  const data = await response.json();
460
- if (data.error) continue;
494
+ if (data.error) {
495
+ lastError = data.error.message || 'SOL RPC error';
496
+ continue;
497
+ }
461
498
  const lamports = data.result?.value || 0;
462
499
  const sol = lamports / 1e9;
463
500
  return { balance: sol.toFixed(6) };
464
501
  } catch (e) {
502
+ lastError = e?.message || 'SOL RPC fetch error';
465
503
  continue;
466
504
  }
467
505
  }
468
506
  console.debug('SOL balance fetch unavailable: all endpoints failed');
469
- return { balance: '--', error: 'No available endpoint' };
507
+ return { balance: '--', error: lastError };
470
508
  }
471
509
 
472
510
  // Commented out — BTC/ETH/SOL only for now