hd-wallet-ui 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -3
- package/src/address-derivation.js +50 -12
- package/src/app.js +2215 -440
- package/src/blockchain-trust.js +81 -28
- package/src/template.js +342 -206
- package/styles/main.css +1265 -43
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hd-wallet-ui",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
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",
|
|
@@ -34,9 +34,11 @@
|
|
|
34
34
|
"bip39": "^3.1.0",
|
|
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.2",
|
|
38
39
|
"qrcode": "^1.5.3",
|
|
39
|
-
"
|
|
40
|
+
"spacedatastandards.org": "^23.3.3-0.3.4",
|
|
41
|
+
"vcard-cryptoperson": "^1.1.11"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|
|
42
44
|
"vite": "^5.0.0",
|
|
@@ -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 (
|
|
393
|
-
|
|
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
|
-
|
|
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: '
|
|
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)
|
|
489
|
+
if (!response.ok) {
|
|
490
|
+
lastError = `HTTP ${response.status}`;
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
459
493
|
const data = await response.json();
|
|
460
|
-
if (data.error)
|
|
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:
|
|
507
|
+
return { balance: '--', error: lastError };
|
|
470
508
|
}
|
|
471
509
|
|
|
472
510
|
// Commented out — BTC/ETH/SOL only for now
|