hd-wallet-ui 2.0.7 → 2.0.10

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": "2.0.7",
3
+ "version": "2.0.10",
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",
@@ -40,7 +40,7 @@
40
40
  "buffer": "^6.0.3",
41
41
  "flatbuffers": "^25.9.23",
42
42
  "flatc-wasm": "^26.1.32",
43
- "hd-wallet-wasm": "^2.0.7",
43
+ "hd-wallet-wasm": "^2.0.10",
44
44
  "qrcode": "^1.5.3",
45
45
  "spacedatastandards.org": "^1.93.3",
46
46
  "vcard-cryptoperson": "^1.1.11"
package/src/app.js CHANGED
@@ -526,6 +526,50 @@ function deriveAccountPeerId() {
526
526
  }
527
527
  }
528
528
 
529
+ function getWalletIdentityPath(wallet = getCurrentWallet()) {
530
+ if (!wallet) return "m/44'/0'/0'";
531
+ return `m/44'/0'/${wallet.accountIndex}'`;
532
+ }
533
+
534
+ function getCurrentWalletIdentity(wallet = getCurrentWallet()) {
535
+ if (!state.hdRoot || !wallet) return { xpub: '', peerId: '', path: getWalletIdentityPath(wallet) };
536
+ const path = getWalletIdentityPath(wallet);
537
+ try {
538
+ const accountKey = deriveHDKey(path);
539
+ return {
540
+ xpub: accountKey?.toXpub?.() || '',
541
+ peerId: accountKey?.peerIdString?.() || '',
542
+ path,
543
+ };
544
+ } catch (e) {
545
+ console.warn('Failed to derive wallet identity keys:', e);
546
+ return { xpub: '', peerId: '', path };
547
+ }
548
+ }
549
+
550
+ function getCurrentWalletSigningAccounts(wallet = getCurrentWallet()) {
551
+ if (!wallet) return [];
552
+ return state.activeAccounts.filter(a => a.active && getAccountWalletId(a) === wallet.id && isSigningAccountForWallet(a, wallet));
553
+ }
554
+
555
+ function getCurrentWalletSignatureKey(wallet = getCurrentWallet()) {
556
+ if (!state.hdRoot || !wallet) return null;
557
+ const accountIndex = wallet.accountIndex;
558
+ try {
559
+ const path = buildSigningPath(501, accountIndex, 0);
560
+ const derived = deriveHDKey(path);
561
+ return {
562
+ privateKey: derived.privateKey(),
563
+ accountIndex,
564
+ index: 0,
565
+ path,
566
+ };
567
+ } catch (e) {
568
+ console.warn('Failed to derive selected wallet signature key:', e);
569
+ return null;
570
+ }
571
+ }
572
+
529
573
  function updatePathDisplay() {
530
574
  const coin = $('hd-coin')?.value;
531
575
  const account = $('hd-account')?.value || '0';
@@ -778,29 +822,41 @@ function updateCustomPathDefault() {
778
822
  }
779
823
 
780
824
  function renderWalletSelector() {
781
- const select = $('wallet-active-select');
782
- if (!select) return;
825
+ const selects = [$('account-wallet-select'), $('wallet-active-select')].filter(Boolean);
826
+ if (selects.length === 0) return;
783
827
  ensureWalletNamesNormalized();
784
828
 
785
829
  const currentWallet = getCurrentWallet();
786
830
  if (!currentWallet) {
787
- select.innerHTML = '';
831
+ selects.forEach((select) => { select.innerHTML = ''; });
788
832
  return;
789
833
  }
790
834
  state.activeWalletId = currentWallet.id;
791
835
 
792
- select.innerHTML = '';
793
836
  const displayCurrency = state.walletFiatCurrency || getSelectedCurrency();
794
837
  const activeWallets = getActiveWallets();
795
- activeWallets.forEach((wallet) => {
796
- const option = document.createElement('option');
797
- option.value = String(wallet.id);
798
- const walletValue = state.walletFiatTotals[wallet.id] ?? 0;
799
- option.textContent = `${wallet.name} (${formatCurrencyValue(walletValue, displayCurrency)})`;
800
- select.appendChild(option);
838
+ selects.forEach((select) => {
839
+ select.innerHTML = '';
840
+ activeWallets.forEach((wallet) => {
841
+ const option = document.createElement('option');
842
+ option.value = String(wallet.id);
843
+ const walletValue = state.walletFiatTotals[wallet.id] ?? 0;
844
+ option.textContent = `${wallet.name} (${formatCurrencyValue(walletValue, displayCurrency)})`;
845
+ select.appendChild(option);
846
+ });
847
+ select.value = String(state.activeWalletId);
801
848
  });
802
- select.value = String(state.activeWalletId);
803
849
  updateCustomPathWalletLabel();
850
+ updateIdentityWalletKeys();
851
+ }
852
+
853
+ function updateIdentityWalletKeys() {
854
+ const identity = getCurrentWalletIdentity();
855
+ const xpubEl = $('identity-wallet-xpub');
856
+ const peerIdEl = $('identity-wallet-peerid');
857
+
858
+ if (xpubEl) setTruncatedValue(xpubEl, identity.xpub || 'N/A');
859
+ if (peerIdEl) setTruncatedValue(peerIdEl, identity.peerId || 'N/A');
804
860
  }
805
861
 
806
862
  function sleep(ms) {
@@ -1221,6 +1277,7 @@ function hideWalletOverlays() {
1221
1277
  function showWalletMainView() {
1222
1278
  const main = $('wallet-main-view');
1223
1279
  hideWalletOverlays();
1280
+ closeAssetActionOverlay();
1224
1281
  if (main) main.style.display = 'block';
1225
1282
  }
1226
1283
 
@@ -1523,6 +1580,49 @@ function closeWalletActionMenus() {
1523
1580
  $('wallet-receive-menu')?.classList.remove('visible');
1524
1581
  }
1525
1582
 
1583
+ function closeAssetActionOverlay() {
1584
+ const overlay = $('wallet-asset-action-overlay');
1585
+ if (overlay) overlay.style.display = 'none';
1586
+ state.selectedWalletAssetIdx = null;
1587
+ }
1588
+
1589
+ function showAssetActionOverlay(acct, idx) {
1590
+ const overlay = $('wallet-asset-action-overlay');
1591
+ if (!overlay || !acct) return;
1592
+
1593
+ state.selectedWalletAssetIdx = idx;
1594
+ const icon = CHAIN_ICONS[acct.name] || { symbol: '?' };
1595
+ const fullName = CHAIN_FULL_NAMES[acct.name] || acct.name;
1596
+ const pathLabel = acct.path || `m/44'/${acct.coinType}'/${acct.account}'/0/${acct.index}`;
1597
+
1598
+ const titleEl = $('wallet-asset-action-title');
1599
+ const pathEl = $('wallet-asset-action-path');
1600
+ const addressEl = $('wallet-asset-action-address');
1601
+ if (titleEl) titleEl.textContent = `${icon.symbol} ${fullName}`;
1602
+ if (pathEl) pathEl.textContent = pathLabel;
1603
+ if (addressEl) {
1604
+ addressEl.textContent = acct.address || '';
1605
+ addressEl.title = acct.address || '';
1606
+ }
1607
+
1608
+ const sendBtn = $('wallet-asset-send');
1609
+ const receiveBtn = $('wallet-asset-receive');
1610
+ if (sendBtn) {
1611
+ sendBtn.onclick = () => {
1612
+ closeAssetActionOverlay();
1613
+ showSendView(idx);
1614
+ };
1615
+ }
1616
+ if (receiveBtn) {
1617
+ receiveBtn.onclick = () => {
1618
+ closeAssetActionOverlay();
1619
+ showReceiveModal(acct);
1620
+ };
1621
+ }
1622
+
1623
+ overlay.style.display = 'flex';
1624
+ }
1625
+
1526
1626
  function renderAccountsList() {
1527
1627
  const listEl = $('wallet-accounts-list');
1528
1628
  const emptyEl = $('wallet-accounts-empty');
@@ -1571,7 +1671,7 @@ function renderAccountsList() {
1571
1671
  '</div>';
1572
1672
 
1573
1673
  row.addEventListener('click', () => {
1574
- showReceiveModal(acct);
1674
+ showAssetActionOverlay(acct, idx);
1575
1675
  });
1576
1676
 
1577
1677
  listEl.appendChild(row);
@@ -2559,21 +2659,6 @@ function login(keys) {
2559
2659
  if (xpubEl) {
2560
2660
  setTruncatedValue(xpubEl, state.hdRoot.toXpub() || 'N/A');
2561
2661
  }
2562
- // Populate wallet tab xpub display
2563
- const walletTabXpubEl = $('wallet-tab-xpub');
2564
- if (walletTabXpubEl) {
2565
- setTruncatedValue(walletTabXpubEl, state.hdRoot.toXpub() || 'N/A');
2566
- }
2567
- // Populate wallet tab PeerID display
2568
- const walletTabPeerIdEl = $('wallet-tab-peerid');
2569
- const peerIdRow = $('ph-portfolio-peerid-row');
2570
- if (walletTabPeerIdEl && peerIdRow) {
2571
- const peerIdStr = deriveAccountPeerId();
2572
- if (peerIdStr) {
2573
- setTruncatedValue(walletTabPeerIdEl, peerIdStr);
2574
- peerIdRow.style.display = '';
2575
- }
2576
- }
2577
2662
  populateAccountAddressDropdown();
2578
2663
  if (xprvEl) {
2579
2664
  xprvEl.textContent = 'Hidden (click reveal)';
@@ -2817,43 +2902,9 @@ function downloadData(data, filename, mimeType) {
2817
2902
  // Wallet Address Population & Balance Fetching
2818
2903
  // =============================================================================
2819
2904
 
2820
- // Account header — show xpub only
2821
2905
  function populateAccountAddressDropdown() {
2822
- const addrEl = $('account-address-display');
2823
- if (!addrEl) return;
2824
-
2825
- const xpubStr = state.hdRoot ? state.hdRoot.toXpub() : '';
2826
- addrEl.textContent = `${xpubStr.slice(0,10)}...${xpubStr.slice(-10)}`;
2827
- addrEl.title = xpubStr;
2828
-
2829
- const copyBtn = $('account-address-copy');
2830
- if (copyBtn) {
2831
- copyBtn.onclick = async () => {
2832
- if (xpubStr && await safeCopyText(xpubStr)) {
2833
- copyBtn.title = 'Copied!';
2834
- setTimeout(() => { copyBtn.title = 'Copy xpub'; }, 1500);
2835
- }
2836
- };
2837
- }
2838
-
2839
- // Populate PeerID row (derived from account-level secp256k1 key)
2840
- const peerIdStr = deriveAccountPeerId();
2841
- const peerIdRow = $('account-peerid-row');
2842
- const peerIdEl = $('account-peerid-display');
2843
- if (peerIdStr && peerIdRow && peerIdEl) {
2844
- peerIdRow.style.display = '';
2845
- peerIdEl.textContent = `${peerIdStr.slice(0,8)}...${peerIdStr.slice(-8)}`;
2846
- peerIdEl.title = peerIdStr;
2847
- }
2848
- const peerCopyBtn = $('account-peerid-copy');
2849
- if (peerCopyBtn) {
2850
- peerCopyBtn.onclick = async () => {
2851
- if (peerIdStr && await safeCopyText(peerIdStr)) {
2852
- peerCopyBtn.title = 'Copied!';
2853
- setTimeout(() => { peerCopyBtn.title = 'Copy PeerID'; }, 1500);
2854
- }
2855
- };
2856
- }
2906
+ renderWalletSelector();
2907
+ updateIdentityWalletKeys();
2857
2908
  }
2858
2909
 
2859
2910
  function populateWalletAddresses() {
@@ -3312,10 +3363,11 @@ function generateVCard(info, { skipPhoto = false } = {}) {
3312
3363
  }
3313
3364
 
3314
3365
  if (info.includeKeys && state.wallet?.x25519) {
3366
+ const identity = getCurrentWalletIdentity();
3315
3367
  person.KEY = [
3316
- // Always include xPub
3317
- ...(state.hdRoot?.toXpub ? [{
3318
- XPUB: state.hdRoot.toXpub(),
3368
+ // Always include the selected wallet xPub.
3369
+ ...(identity.xpub ? [{
3370
+ XPUB: identity.xpub,
3319
3371
  LABEL: '',
3320
3372
  }] : []),
3321
3373
  // X25519 encryption key
@@ -3324,8 +3376,7 @@ function generateVCard(info, { skipPhoto = false } = {}) {
3324
3376
  LABEL: 'X25519',
3325
3377
  },
3326
3378
  // Active accounts from wallet scan
3327
- ...state.activeAccounts
3328
- .filter(a => a.active && isSigningAccount(a))
3379
+ ...getCurrentWalletSigningAccounts()
3329
3380
  .flatMap(a => {
3330
3381
  const entries = [];
3331
3382
  const pathLabel = a.path || `m/44'/${a.coinType}'/${a.account}'/0/${a.index}`;
@@ -3346,8 +3397,9 @@ function generateVCard(info, { skipPhoto = false } = {}) {
3346
3397
  return entries;
3347
3398
  }),
3348
3399
  ];
3349
- } else if (info.xpubOnly && state.hdRoot?.toXpub) {
3350
- person.KEY = [{ XPUB: state.hdRoot.toXpub(), LABEL: '' }];
3400
+ } else if (info.xpubOnly) {
3401
+ const identity = getCurrentWalletIdentity();
3402
+ if (identity.xpub) person.KEY = [{ XPUB: identity.xpub, LABEL: '' }];
3351
3403
  }
3352
3404
 
3353
3405
  const note = info.includeKeys
@@ -3399,15 +3451,16 @@ function getSignableBody(vcardText) {
3399
3451
  }
3400
3452
 
3401
3453
  function signVCard(vcardText) {
3402
- if (!state.wallet?.ed25519?.privateKey) return vcardText;
3454
+ const signatureKey = getCurrentWalletSignatureKey();
3455
+ if (!signatureKey?.privateKey) return vcardText;
3403
3456
 
3404
3457
  const body = getSignableBody(vcardText);
3405
3458
  const messageBytes = new TextEncoder().encode(body);
3406
- const signature = hdWallet().curves.ed25519.sign(messageBytes, state.wallet.ed25519.privateKey);
3459
+ const signature = hdWallet().curves.ed25519.sign(messageBytes, signatureKey.privateKey);
3407
3460
  const sigB64 = toBase64(signature);
3408
3461
 
3409
- // Encode signature + derivation path (coinType=501, account=0, index=0)
3410
- const sigValue = `${sigB64}:501:0:0`;
3462
+ // Encode signature + selected wallet derivation path.
3463
+ const sigValue = `${sigB64}:501:${signatureKey.accountIndex}:${signatureKey.index}`;
3411
3464
 
3412
3465
  // Find highest itemN and key index
3413
3466
  let maxItem = 0;
@@ -4650,10 +4703,12 @@ function setupMainAppHandlers() {
4650
4703
  if (targetEl) {
4651
4704
  try {
4652
4705
  let value = '';
4653
- if (targetId === 'wallet-xpub' || targetId === 'wallet-tab-xpub') {
4706
+ if (targetId === 'wallet-xpub') {
4654
4707
  value = state.hdRoot?.toXpub?.() || '';
4655
- } else if (targetId === 'wallet-tab-peerid') {
4656
- value = deriveAccountPeerId() || '';
4708
+ } else if (targetId === 'identity-wallet-xpub') {
4709
+ value = getCurrentWalletIdentity().xpub || '';
4710
+ } else if (targetId === 'identity-wallet-peerid') {
4711
+ value = getCurrentWalletIdentity().peerId || '';
4657
4712
  } else if (targetId === 'wallet-xprv') {
4658
4713
  if (targetEl.dataset.revealed !== 'true') {
4659
4714
  alert('Reveal the xprv first to copy it.');
@@ -4746,74 +4801,42 @@ function setupMainAppHandlers() {
4746
4801
  });
4747
4802
 
4748
4803
  // Wallet tab controls
4749
- $('wallet-active-select')?.addEventListener('change', (e) => {
4804
+ const handleWalletSelectChange = (e) => {
4750
4805
  const walletId = Number.parseInt(e.target.value, 10);
4751
4806
  if (Number.isNaN(walletId)) return;
4752
4807
  state.activeWalletId = walletId;
4753
4808
  closeWalletActionMenus();
4809
+ closeAssetActionOverlay();
4754
4810
  renderWalletSelector();
4755
4811
  renderAccountsList();
4756
4812
  updateCustomPathDefault();
4813
+ };
4814
+ $('account-wallet-select')?.addEventListener('change', handleWalletSelectChange);
4815
+ $('wallet-active-select')?.addEventListener('change', handleWalletSelectChange);
4816
+ $('account-wallet-manage-btn')?.addEventListener('click', () => {
4817
+ closeWalletActionMenus();
4818
+ closeAssetActionOverlay();
4819
+ const walletTab = _root.querySelector?.('.modal-tab[data-modal-tab="wallet-tab-content"]');
4820
+ if (walletTab) walletTab.click();
4821
+ showWalletsView();
4757
4822
  });
4758
4823
  $('wallet-manage-btn')?.addEventListener('click', () => {
4759
4824
  closeWalletActionMenus();
4825
+ closeAssetActionOverlay();
4760
4826
  showWalletsView();
4761
4827
  });
4762
4828
  $('wallet-scan-btn')?.addEventListener('click', () => {
4763
4829
  scanActiveAccounts();
4764
4830
  });
4765
- const sendAction = $('wallet-send-action');
4766
- const receiveAction = $('wallet-receive-action');
4767
- $('wallet-send-btn')?.addEventListener('click', (e) => {
4768
- e.stopPropagation();
4769
- updateWalletActionMenus();
4770
- const sendMenu = $('wallet-send-menu');
4771
- const receiveMenu = $('wallet-receive-menu');
4772
- if (!sendMenu || !receiveMenu) return;
4773
- const nextVisible = !sendMenu.classList.contains('visible');
4774
- receiveMenu.classList.remove('visible');
4775
- sendMenu.classList.toggle('visible', nextVisible);
4776
- });
4777
- $('wallet-receive-btn-main')?.addEventListener('click', (e) => {
4778
- e.stopPropagation();
4779
- updateWalletActionMenus();
4780
- const sendMenu = $('wallet-send-menu');
4781
- const receiveMenu = $('wallet-receive-menu');
4782
- if (!sendMenu || !receiveMenu) return;
4783
- const nextVisible = !receiveMenu.classList.contains('visible');
4784
- sendMenu.classList.remove('visible');
4785
- receiveMenu.classList.toggle('visible', nextVisible);
4786
- });
4787
- $qa('#wallet-send-menu .ph-action-menu-item').forEach((btn) => {
4788
- btn.addEventListener('click', (e) => {
4789
- e.stopPropagation();
4790
- const chain = btn.dataset.chain;
4791
- const acct = getWalletAccountForChain(chain);
4792
- closeWalletActionMenus();
4793
- if (!acct) return;
4794
- showSendView(state.activeAccounts.indexOf(acct));
4795
- });
4796
- });
4797
- $qa('#wallet-receive-menu .ph-action-menu-item').forEach((btn) => {
4798
- btn.addEventListener('click', (e) => {
4799
- e.stopPropagation();
4800
- const chain = btn.dataset.chain;
4801
- const acct = getWalletAccountForChain(chain);
4802
- closeWalletActionMenus();
4803
- if (!acct) return;
4804
- showReceiveModal(acct);
4805
- });
4806
- });
4807
- _root.addEventListener('click', (e) => {
4808
- if (sendAction?.contains(e.target) || receiveAction?.contains(e.target)) return;
4809
- closeWalletActionMenus();
4810
- });
4831
+ $('wallet-asset-action-close')?.addEventListener('click', closeAssetActionOverlay);
4811
4832
  $('wallet-export-btn-main')?.addEventListener('click', () => {
4812
4833
  closeWalletActionMenus();
4834
+ closeAssetActionOverlay();
4813
4835
  showExportView();
4814
4836
  });
4815
4837
  $('wallet-advanced-btn-main')?.addEventListener('click', () => {
4816
4838
  closeWalletActionMenus();
4839
+ closeAssetActionOverlay();
4817
4840
  showAdvancedView();
4818
4841
  });
4819
4842
  $('wallet-wallets-back')?.addEventListener('click', () => {
package/src/template.js CHANGED
@@ -3,7 +3,7 @@ export function getModalHTML() {
3
3
  <!-- Keys Modal -->
4
4
  <div id="keys-modal" class="modal">
5
5
  <div class="modal-glass modal-wide">
6
- <div class="modal-header"><div class="account-header-info"><div class="account-header-top"><h3>Account</h3><h3 class="account-total-value" id="account-total-value"></h3></div><div class="account-address-row"><span class="account-address-label">xpub</span><code class="account-address-display" id="account-address-display"></code><button class="account-address-copy" id="account-address-copy" title="Copy xpub"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button></div><div class="account-address-row" id="account-peerid-row" style="display:none"><span class="account-address-label">PeerID</span><code class="account-address-display" id="account-peerid-display"></code><button class="account-address-copy" id="account-peerid-copy" title="Copy PeerID"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button></div></div><button class="modal-close">&times;</button></div>
6
+ <div class="modal-header"><div class="account-header-info"><div class="account-header-top"><h3>Account</h3><h3 class="account-total-value" id="account-total-value"></h3></div><div class="account-wallet-row"><select id="account-wallet-select" class="glass-input compact account-wallet-select" aria-label="Select wallet"></select><button id="account-wallet-manage-btn" class="glass-btn small">Manage</button></div></div><button class="modal-close">&times;</button></div>
7
7
  <div class="modal-tabs">
8
8
  <button class="modal-tab active" data-modal-tab="vcard-tab-content">Identity</button>
9
9
  <button class="modal-tab" data-modal-tab="trust-tab-content">Trust Map</button>
@@ -19,21 +19,6 @@ export function getModalHTML() {
19
19
  <div class="ph-portfolio">
20
20
  <div class="ph-portfolio-value" id="wallet-bond-value">$0.00</div>
21
21
  <div class="ph-portfolio-label">Total Balance</div>
22
- <div class="ph-portfolio-xpub">
23
- <code id="wallet-tab-xpub" class="ph-xpub-text truncate"></code>
24
- <button class="ph-xpub-copy copy-key-btn" data-copy="wallet-tab-xpub" title="Copy xPub"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
25
- </div>
26
- <div class="ph-portfolio-xpub" id="ph-portfolio-peerid-row" style="display:none">
27
- <code id="wallet-tab-peerid" class="ph-xpub-text truncate"></code>
28
- <button class="ph-xpub-copy copy-key-btn" data-copy="wallet-tab-peerid" title="Copy PeerID"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
29
- </div>
30
- </div>
31
-
32
- <div class="wallet-selector-row">
33
- <div class="wallet-selector-control">
34
- <select id="wallet-active-select" class="glass-input compact wallet-selector-input"></select>
35
- <button id="wallet-manage-btn" class="glass-btn small">Manage</button>
36
- </div>
37
22
  </div>
38
23
 
39
24
  <!-- Action Buttons Row -->
@@ -42,28 +27,6 @@ export function getModalHTML() {
42
27
  <div class="ph-action-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg></div>
43
28
  <span>Scan</span>
44
29
  </button>
45
- <div class="ph-action-wrap" id="wallet-send-action">
46
- <button class="ph-action-btn" id="wallet-send-btn">
47
- <div class="ph-action-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg></div>
48
- <span>Send</span>
49
- </button>
50
- <div class="ph-action-menu" id="wallet-send-menu">
51
- <button class="ph-action-menu-item" type="button" data-chain="BTC">Bitcoin (BTC)</button>
52
- <button class="ph-action-menu-item" type="button" data-chain="ETH">Ethereum (ETH)</button>
53
- <button class="ph-action-menu-item" type="button" data-chain="SOL">Solana (SOL)</button>
54
- </div>
55
- </div>
56
- <div class="ph-action-wrap" id="wallet-receive-action">
57
- <button class="ph-action-btn" id="wallet-receive-btn-main">
58
- <div class="ph-action-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg></div>
59
- <span>Receive</span>
60
- </button>
61
- <div class="ph-action-menu" id="wallet-receive-menu">
62
- <button class="ph-action-menu-item" type="button" data-chain="BTC">Bitcoin (BTC)</button>
63
- <button class="ph-action-menu-item" type="button" data-chain="ETH">Ethereum (ETH)</button>
64
- <button class="ph-action-menu-item" type="button" data-chain="SOL">Solana (SOL)</button>
65
- </div>
66
- </div>
67
30
  <button class="ph-action-btn" id="wallet-export-btn-main">
68
31
  <div class="ph-action-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg></div>
69
32
  <span>Export</span>
@@ -89,6 +52,22 @@ export function getModalHTML() {
89
52
  <p class="ph-token-empty-sub">Log in and tap Scan to discover your accounts</p>
90
53
  </div>
91
54
  </div>
55
+ <div id="wallet-asset-action-overlay" class="wallet-asset-action-overlay" style="display:none;">
56
+ <div class="wallet-asset-action-card">
57
+ <div class="wallet-asset-action-header">
58
+ <div>
59
+ <h4 id="wallet-asset-action-title"></h4>
60
+ <div id="wallet-asset-action-path" class="wallet-asset-action-path"></div>
61
+ </div>
62
+ <button id="wallet-asset-action-close" class="modal-close" type="button">&times;</button>
63
+ </div>
64
+ <code id="wallet-asset-action-address" class="wallet-asset-action-address"></code>
65
+ <div class="wallet-asset-action-buttons">
66
+ <button id="wallet-asset-send" class="glass-btn primary">Send</button>
67
+ <button id="wallet-asset-receive" class="glass-btn">Receive</button>
68
+ </div>
69
+ </div>
70
+ </div>
92
71
  </div>
93
72
 
94
73
  <!-- Wallets View (replaces main view) -->
@@ -241,6 +220,19 @@ export function getModalHTML() {
241
220
  </div>
242
221
  </div>
243
222
 
223
+ <div class="identity-wallet-keys">
224
+ <div class="identity-wallet-key-row">
225
+ <span class="identity-wallet-key-label">XPUB</span>
226
+ <code id="identity-wallet-xpub" class="identity-wallet-key-value truncate"></code>
227
+ <button class="identity-wallet-copy copy-key-btn" data-copy="identity-wallet-xpub" title="Copy XPUB"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
228
+ </div>
229
+ <div class="identity-wallet-key-row">
230
+ <span class="identity-wallet-key-label">PeerID</span>
231
+ <code id="identity-wallet-peerid" class="identity-wallet-key-value truncate"></code>
232
+ <button class="identity-wallet-copy copy-key-btn" data-copy="identity-wallet-peerid" title="Copy PeerID"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
233
+ </div>
234
+ </div>
235
+
244
236
  <div class="vcard-actions-footer">
245
237
  <div class="vcard-split-btn-group">
246
238
  <button id="generate-vcard" class="glass-btn vcard-split-btn vcard-split-export">Export vCard</button>
package/styles/main.css CHANGED
@@ -653,42 +653,42 @@ body:has(.modal.active) .nav-bar {
653
653
  display: block;
654
654
  }
655
655
 
656
- /* Modal Tabs (Account modal - Keys / vCard) - Bootstrap-style nav tabs */
656
+ /* Modal Tabs */
657
657
  .modal-tabs {
658
658
  display: flex;
659
- gap: 0;
659
+ gap: 6px;
660
660
  margin: 0;
661
- padding: 0 24px;
661
+ padding: 8px 24px;
662
662
  background: transparent;
663
- border-bottom: 2px solid var(--white-10, rgba(255,255,255,0.1));
663
+ border-bottom: 1px solid var(--white-10, rgba(255,255,255,0.1));
664
664
  }
665
665
 
666
666
  .modal-tab {
667
- padding: 10px 16px;
667
+ padding: 8px 14px;
668
668
  background: transparent;
669
- border: none;
670
- border-bottom: 2px solid transparent;
671
- margin-bottom: -2px;
669
+ border: 1px solid transparent;
670
+ border-radius: 8px;
672
671
  color: var(--white-60);
673
672
  font-family: var(--font-sans);
674
673
  font-size: 13px;
675
674
  font-weight: 500;
676
675
  line-height: 1;
677
676
  cursor: pointer;
678
- transition: color 0.2s, border-color 0.2s;
677
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
679
678
  text-align: center;
680
679
  white-space: nowrap;
681
680
  }
682
681
 
683
682
  .modal-tab:hover {
684
683
  color: var(--white, #fff);
685
- border-bottom-color: var(--white-30, rgba(255,255,255,0.3));
684
+ background: var(--white-05);
685
+ border-color: var(--white-10);
686
686
  }
687
687
 
688
688
  .modal-tab.active {
689
689
  color: var(--white, #fff);
690
- border-bottom-color: var(--accent, #00dc82);
691
- background: transparent;
690
+ border-color: var(--white-20);
691
+ background: var(--white-10);
692
692
  }
693
693
 
694
694
  .modal-tab-content {
@@ -1194,6 +1194,8 @@ body:has(.modal.active) .nav-bar {
1194
1194
  display: flex;
1195
1195
  flex-direction: column;
1196
1196
  gap: 2px;
1197
+ flex: 1 1 auto;
1198
+ min-width: 0;
1197
1199
  }
1198
1200
 
1199
1201
  .account-header-top {
@@ -1209,63 +1211,42 @@ body:has(.modal.active) .nav-bar {
1209
1211
  opacity: 0.9;
1210
1212
  }
1211
1213
 
1212
- .account-address-row {
1214
+ .account-wallet-row {
1213
1215
  display: flex;
1214
1216
  align-items: center;
1215
1217
  gap: 10px;
1216
1218
  margin-top: 4px;
1219
+ width: 100%;
1217
1220
  min-width: 0;
1218
1221
  }
1219
1222
 
1220
- .account-address-label {
1221
- flex: 0 0 auto;
1222
- }
1223
-
1224
- .account-address-select {
1225
- min-width: 90px;
1226
- max-width: 130px;
1227
- font-size: 12px;
1228
- padding: 4px 28px 4px 10px;
1229
- height: 28px;
1230
- background-position: right 6px center;
1231
- color: var(--white-90);
1232
- user-select: none;
1233
- -webkit-user-select: none;
1234
- }
1235
-
1236
- .account-address-display {
1237
- font-family: var(--font-mono, 'SF Mono', monospace);
1238
- font-size: 11px;
1239
- color: var(--white-50);
1240
- letter-spacing: 0.04em;
1241
- white-space: nowrap;
1242
- overflow: hidden;
1243
- text-overflow: ellipsis;
1223
+ .account-wallet-select.glass-input.compact {
1244
1224
  flex: 1 1 auto;
1245
- min-width: 12ch;
1225
+ min-width: 180px;
1246
1226
  width: 100%;
1227
+ height: 32px;
1228
+ font-size: 13px;
1229
+ padding: 4px 34px 4px 10px;
1230
+ color: var(--white-90);
1231
+ appearance: none;
1232
+ -webkit-appearance: none;
1233
+ -moz-appearance: none;
1234
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4 4.5-4' stroke='rgba(255,255,255,0.9)' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
1235
+ background-repeat: no-repeat;
1236
+ background-position: right 11px center;
1247
1237
  }
1248
1238
 
1249
- .account-address-copy {
1250
- background: none;
1251
- border: none;
1252
- color: var(--white-30);
1253
- cursor: pointer;
1254
- height: 24px;
1255
- padding: 2px;
1256
- width: 24px;
1257
- flex-shrink: 0;
1258
- display: flex;
1259
- align-items: center;
1260
- justify-content: center;
1261
- }
1262
- .account-address-copy:hover {
1263
- color: var(--white-70);
1239
+ #account-wallet-manage-btn {
1240
+ flex: 0 0 auto;
1264
1241
  }
1265
1242
 
1266
1243
  @media (max-width: 600px) {
1267
- .account-address-display {
1268
- min-width: 10ch;
1244
+ .account-wallet-row {
1245
+ gap: 8px;
1246
+ }
1247
+
1248
+ .account-wallet-select.glass-input.compact {
1249
+ min-width: 0;
1269
1250
  }
1270
1251
  }
1271
1252
 
@@ -1934,6 +1915,10 @@ body:has(.modal.active) .nav-bar {
1934
1915
  ============================================================================= */
1935
1916
 
1936
1917
  /* Portfolio Hero */
1918
+ #wallet-main-view {
1919
+ position: relative;
1920
+ }
1921
+
1937
1922
  .ph-portfolio {
1938
1923
  text-align: center;
1939
1924
  padding: 24px 0 20px;
@@ -1960,12 +1945,21 @@ body:has(.modal.active) .nav-bar {
1960
1945
  justify-content: center;
1961
1946
  gap: 6px;
1962
1947
  margin-top: 10px;
1948
+ width: 100%;
1949
+ max-width: 100%;
1963
1950
  }
1964
1951
 
1965
1952
  .ph-xpub-text {
1953
+ box-sizing: border-box;
1966
1954
  font-size: 11px;
1967
- color: var(--white-40);
1968
- max-width: 200px;
1955
+ color: var(--white-90);
1956
+ background: var(--white-05);
1957
+ border: 1px solid var(--glass-border);
1958
+ border-radius: 6px;
1959
+ padding: 2px 6px;
1960
+ flex: 1 1 auto;
1961
+ min-width: 0;
1962
+ width: 100%;
1969
1963
  overflow: hidden;
1970
1964
  text-overflow: ellipsis;
1971
1965
  white-space: nowrap;
@@ -2191,6 +2185,68 @@ body:has(.modal.active) .nav-bar {
2191
2185
  opacity: 0.45;
2192
2186
  }
2193
2187
 
2188
+ .wallet-asset-action-overlay {
2189
+ position: absolute;
2190
+ inset: 0;
2191
+ z-index: 40;
2192
+ display: none;
2193
+ align-items: flex-end;
2194
+ justify-content: center;
2195
+ padding: 16px;
2196
+ background: rgba(0, 0, 0, 0.42);
2197
+ }
2198
+
2199
+ .wallet-asset-action-card {
2200
+ width: min(100%, 420px);
2201
+ border: 1px solid var(--glass-border);
2202
+ border-radius: 12px;
2203
+ background: rgba(28, 28, 31, 0.98);
2204
+ box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4);
2205
+ padding: 16px;
2206
+ }
2207
+
2208
+ .wallet-asset-action-header {
2209
+ display: flex;
2210
+ align-items: flex-start;
2211
+ justify-content: space-between;
2212
+ gap: 12px;
2213
+ margin-bottom: 12px;
2214
+ }
2215
+
2216
+ .wallet-asset-action-header h4 {
2217
+ margin: 0 0 4px;
2218
+ font-size: 16px;
2219
+ line-height: 1.2;
2220
+ }
2221
+
2222
+ .wallet-asset-action-path {
2223
+ font-size: 11px;
2224
+ color: var(--muted);
2225
+ font-family: var(--font-mono);
2226
+ }
2227
+
2228
+ .wallet-asset-action-address {
2229
+ display: block;
2230
+ box-sizing: border-box;
2231
+ width: 100%;
2232
+ padding: 8px 10px;
2233
+ border: 1px solid var(--glass-border);
2234
+ border-radius: 8px;
2235
+ background: var(--white-05);
2236
+ color: var(--white-90);
2237
+ font-size: 12px;
2238
+ overflow: hidden;
2239
+ text-overflow: ellipsis;
2240
+ white-space: nowrap;
2241
+ }
2242
+
2243
+ .wallet-asset-action-buttons {
2244
+ display: grid;
2245
+ grid-template-columns: 1fr 1fr;
2246
+ gap: 10px;
2247
+ margin-top: 14px;
2248
+ }
2249
+
2194
2250
  .ph-token-icon {
2195
2251
  width: 40px;
2196
2252
  height: 40px;
@@ -5211,6 +5267,63 @@ body:has(.modal.active) .nav-bar {
5211
5267
  display: none;
5212
5268
  }
5213
5269
 
5270
+ .identity-wallet-keys {
5271
+ display: flex;
5272
+ flex-direction: column;
5273
+ gap: 8px;
5274
+ margin: 14px 0 4px;
5275
+ }
5276
+
5277
+ .identity-wallet-key-row {
5278
+ display: grid;
5279
+ grid-template-columns: 62px minmax(0, 1fr) 28px;
5280
+ align-items: center;
5281
+ gap: 8px;
5282
+ min-width: 0;
5283
+ }
5284
+
5285
+ .identity-wallet-key-label {
5286
+ color: var(--muted);
5287
+ font-family: var(--font-mono);
5288
+ font-size: 11px;
5289
+ text-transform: uppercase;
5290
+ }
5291
+
5292
+ .identity-wallet-key-value {
5293
+ box-sizing: border-box;
5294
+ min-width: 0;
5295
+ width: 100%;
5296
+ padding: 5px 8px;
5297
+ border: 1px solid var(--glass-border);
5298
+ border-radius: 7px;
5299
+ background: var(--white-05);
5300
+ color: var(--white-90);
5301
+ font-family: var(--font-mono);
5302
+ font-size: 12px;
5303
+ line-height: 1.3;
5304
+ overflow: hidden;
5305
+ text-overflow: ellipsis;
5306
+ white-space: nowrap;
5307
+ }
5308
+
5309
+ .identity-wallet-copy {
5310
+ width: 28px;
5311
+ height: 28px;
5312
+ padding: 0;
5313
+ border: 1px solid var(--glass-border);
5314
+ border-radius: 7px;
5315
+ background: var(--white-05);
5316
+ color: var(--white-50);
5317
+ display: inline-flex;
5318
+ align-items: center;
5319
+ justify-content: center;
5320
+ }
5321
+
5322
+ .identity-wallet-copy:hover {
5323
+ color: var(--white);
5324
+ background: var(--white-10);
5325
+ }
5326
+
5214
5327
  /* Identity edit button (pencil icon in card) */
5215
5328
  .identity-edit-btn {
5216
5329
  position: absolute;
package/styles/widget.css CHANGED
@@ -656,42 +656,42 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
656
656
  display: block;
657
657
  }
658
658
 
659
- /* Modal Tabs (Account modal - Keys / vCard) - Bootstrap-style nav tabs */
659
+ /* Modal Tabs */
660
660
  #hd-wallet-ui-container .modal-tabs {
661
661
  display: flex;
662
- gap: 0;
662
+ gap: 6px;
663
663
  margin: 0;
664
- padding: 0 24px;
664
+ padding: 8px 24px;
665
665
  background: transparent;
666
- border-bottom: 2px solid var(--white-10, rgba(255,255,255,0.1));
666
+ border-bottom: 1px solid var(--white-10, rgba(255,255,255,0.1));
667
667
  }
668
668
 
669
669
  #hd-wallet-ui-container .modal-tab {
670
- padding: 10px 16px;
670
+ padding: 8px 14px;
671
671
  background: transparent;
672
- border: none;
673
- border-bottom: 2px solid transparent;
674
- margin-bottom: -2px;
672
+ border: 1px solid transparent;
673
+ border-radius: 8px;
675
674
  color: var(--white-60);
676
675
  font-family: var(--font-sans);
677
676
  font-size: 13px;
678
677
  font-weight: 500;
679
678
  line-height: 1;
680
679
  cursor: pointer;
681
- transition: color 0.2s, border-color 0.2s;
680
+ transition: color 0.2s, border-color 0.2s, background 0.2s;
682
681
  text-align: center;
683
682
  white-space: nowrap;
684
683
  }
685
684
 
686
685
  #hd-wallet-ui-container .modal-tab:hover {
687
686
  color: var(--white, #fff);
688
- border-bottom-color: var(--white-30, rgba(255,255,255,0.3));
687
+ background: var(--white-05);
688
+ border-color: var(--white-10);
689
689
  }
690
690
 
691
691
  #hd-wallet-ui-container .modal-tab.active {
692
692
  color: var(--white, #fff);
693
- border-bottom-color: var(--accent, #00dc82);
694
- background: transparent;
693
+ border-color: var(--white-20);
694
+ background: var(--white-10);
695
695
  }
696
696
 
697
697
  #hd-wallet-ui-container .modal-tab-content {
@@ -1196,6 +1196,8 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
1196
1196
  display: flex;
1197
1197
  flex-direction: column;
1198
1198
  gap: 2px;
1199
+ flex: 1 1 auto;
1200
+ min-width: 0;
1199
1201
  }
1200
1202
 
1201
1203
  #hd-wallet-ui-container .account-header-top {
@@ -1211,63 +1213,42 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
1211
1213
  opacity: 0.9;
1212
1214
  }
1213
1215
 
1214
- #hd-wallet-ui-container .account-address-row {
1216
+ #hd-wallet-ui-container .account-wallet-row {
1215
1217
  display: flex;
1216
1218
  align-items: center;
1217
1219
  gap: 10px;
1218
1220
  margin-top: 4px;
1221
+ width: 100%;
1219
1222
  min-width: 0;
1220
1223
  }
1221
1224
 
1222
- #hd-wallet-ui-container .account-address-label {
1223
- flex: 0 0 auto;
1224
- }
1225
-
1226
- #hd-wallet-ui-container .account-address-select {
1227
- min-width: 90px;
1228
- max-width: 130px;
1229
- font-size: 12px;
1230
- padding: 4px 28px 4px 10px;
1231
- height: 28px;
1232
- background-position: right 6px center;
1233
- color: var(--white-90);
1234
- user-select: none;
1235
- -webkit-user-select: none;
1236
- }
1237
-
1238
- #hd-wallet-ui-container .account-address-display {
1239
- font-family: var(--font-mono, 'SF Mono', monospace);
1240
- font-size: 11px;
1241
- color: var(--white-50);
1242
- letter-spacing: 0.04em;
1243
- white-space: nowrap;
1244
- overflow: hidden;
1245
- text-overflow: ellipsis;
1225
+ #hd-wallet-ui-container .account-wallet-select.glass-input.compact {
1246
1226
  flex: 1 1 auto;
1247
- min-width: 12ch;
1227
+ min-width: 180px;
1248
1228
  width: 100%;
1229
+ height: 32px;
1230
+ font-size: 13px;
1231
+ padding: 4px 34px 4px 10px;
1232
+ color: var(--white-90);
1233
+ appearance: none;
1234
+ -webkit-appearance: none;
1235
+ -moz-appearance: none;
1236
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4 4.5-4' stroke='rgba(255,255,255,0.9)' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
1237
+ background-repeat: no-repeat;
1238
+ background-position: right 11px center;
1249
1239
  }
1250
1240
 
1251
- #hd-wallet-ui-container .account-address-copy {
1252
- background: none;
1253
- border: none;
1254
- color: var(--white-30);
1255
- cursor: pointer;
1256
- height: 24px;
1257
- padding: 2px;
1258
- width: 24px;
1259
- flex-shrink: 0;
1260
- display: flex;
1261
- align-items: center;
1262
- justify-content: center;
1263
- }
1264
- #hd-wallet-ui-container .account-address-copy:hover {
1265
- color: var(--white-70);
1241
+ #hd-wallet-ui-container #account-wallet-manage-btn {
1242
+ flex: 0 0 auto;
1266
1243
  }
1267
1244
 
1268
1245
  @media (max-width: 600px) {
1269
- #hd-wallet-ui-container .account-address-display {
1270
- min-width: 10ch;
1246
+ #hd-wallet-ui-container .account-wallet-row {
1247
+ gap: 8px;
1248
+ }
1249
+
1250
+ #hd-wallet-ui-container .account-wallet-select.glass-input.compact {
1251
+ min-width: 0;
1271
1252
  }
1272
1253
  }
1273
1254
 
@@ -1932,6 +1913,10 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
1932
1913
  ============================================================================= */
1933
1914
 
1934
1915
  /* Portfolio Hero */
1916
+ #hd-wallet-ui-container #wallet-main-view {
1917
+ position: relative;
1918
+ }
1919
+
1935
1920
  #hd-wallet-ui-container .ph-portfolio {
1936
1921
  text-align: center;
1937
1922
  padding: 24px 0 20px;
@@ -1958,12 +1943,21 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
1958
1943
  justify-content: center;
1959
1944
  gap: 6px;
1960
1945
  margin-top: 10px;
1946
+ width: 100%;
1947
+ max-width: 100%;
1961
1948
  }
1962
1949
 
1963
1950
  #hd-wallet-ui-container .ph-xpub-text {
1951
+ box-sizing: border-box;
1964
1952
  font-size: 11px;
1965
- color: var(--white-40);
1966
- max-width: 200px;
1953
+ color: var(--white-90);
1954
+ background: var(--white-05);
1955
+ border: 1px solid var(--glass-border);
1956
+ border-radius: 6px;
1957
+ padding: 2px 6px;
1958
+ flex: 1 1 auto;
1959
+ min-width: 0;
1960
+ width: 100%;
1967
1961
  overflow: hidden;
1968
1962
  text-overflow: ellipsis;
1969
1963
  white-space: nowrap;
@@ -2189,6 +2183,68 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
2189
2183
  opacity: 0.45;
2190
2184
  }
2191
2185
 
2186
+ #hd-wallet-ui-container .wallet-asset-action-overlay {
2187
+ position: absolute;
2188
+ inset: 0;
2189
+ z-index: 40;
2190
+ display: none;
2191
+ align-items: flex-end;
2192
+ justify-content: center;
2193
+ padding: 16px;
2194
+ background: rgba(0, 0, 0, 0.42);
2195
+ }
2196
+
2197
+ #hd-wallet-ui-container .wallet-asset-action-card {
2198
+ width: min(100%, 420px);
2199
+ border: 1px solid var(--glass-border);
2200
+ border-radius: 12px;
2201
+ background: rgba(28, 28, 31, 0.98);
2202
+ box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4);
2203
+ padding: 16px;
2204
+ }
2205
+
2206
+ #hd-wallet-ui-container .wallet-asset-action-header {
2207
+ display: flex;
2208
+ align-items: flex-start;
2209
+ justify-content: space-between;
2210
+ gap: 12px;
2211
+ margin-bottom: 12px;
2212
+ }
2213
+
2214
+ #hd-wallet-ui-container .wallet-asset-action-header h4 {
2215
+ margin: 0 0 4px;
2216
+ font-size: 16px;
2217
+ line-height: 1.2;
2218
+ }
2219
+
2220
+ #hd-wallet-ui-container .wallet-asset-action-path {
2221
+ font-size: 11px;
2222
+ color: var(--muted);
2223
+ font-family: var(--font-mono);
2224
+ }
2225
+
2226
+ #hd-wallet-ui-container .wallet-asset-action-address {
2227
+ display: block;
2228
+ box-sizing: border-box;
2229
+ width: 100%;
2230
+ padding: 8px 10px;
2231
+ border: 1px solid var(--glass-border);
2232
+ border-radius: 8px;
2233
+ background: var(--white-05);
2234
+ color: var(--white-90);
2235
+ font-size: 12px;
2236
+ overflow: hidden;
2237
+ text-overflow: ellipsis;
2238
+ white-space: nowrap;
2239
+ }
2240
+
2241
+ #hd-wallet-ui-container .wallet-asset-action-buttons {
2242
+ display: grid;
2243
+ grid-template-columns: 1fr 1fr;
2244
+ gap: 10px;
2245
+ margin-top: 14px;
2246
+ }
2247
+
2192
2248
  #hd-wallet-ui-container .ph-token-icon {
2193
2249
  width: 40px;
2194
2250
  height: 40px;
@@ -5203,6 +5259,63 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
5203
5259
  display: none;
5204
5260
  }
5205
5261
 
5262
+ #hd-wallet-ui-container .identity-wallet-keys {
5263
+ display: flex;
5264
+ flex-direction: column;
5265
+ gap: 8px;
5266
+ margin: 14px 0 4px;
5267
+ }
5268
+
5269
+ #hd-wallet-ui-container .identity-wallet-key-row {
5270
+ display: grid;
5271
+ grid-template-columns: 62px minmax(0, 1fr) 28px;
5272
+ align-items: center;
5273
+ gap: 8px;
5274
+ min-width: 0;
5275
+ }
5276
+
5277
+ #hd-wallet-ui-container .identity-wallet-key-label {
5278
+ color: var(--muted);
5279
+ font-family: var(--font-mono);
5280
+ font-size: 11px;
5281
+ text-transform: uppercase;
5282
+ }
5283
+
5284
+ #hd-wallet-ui-container .identity-wallet-key-value {
5285
+ box-sizing: border-box;
5286
+ min-width: 0;
5287
+ width: 100%;
5288
+ padding: 5px 8px;
5289
+ border: 1px solid var(--glass-border);
5290
+ border-radius: 7px;
5291
+ background: var(--white-05);
5292
+ color: var(--white-90);
5293
+ font-family: var(--font-mono);
5294
+ font-size: 12px;
5295
+ line-height: 1.3;
5296
+ overflow: hidden;
5297
+ text-overflow: ellipsis;
5298
+ white-space: nowrap;
5299
+ }
5300
+
5301
+ #hd-wallet-ui-container .identity-wallet-copy {
5302
+ width: 28px;
5303
+ height: 28px;
5304
+ padding: 0;
5305
+ border: 1px solid var(--glass-border);
5306
+ border-radius: 7px;
5307
+ background: var(--white-05);
5308
+ color: var(--white-50);
5309
+ display: inline-flex;
5310
+ align-items: center;
5311
+ justify-content: center;
5312
+ }
5313
+
5314
+ #hd-wallet-ui-container .identity-wallet-copy:hover {
5315
+ color: var(--white);
5316
+ background: var(--white-10);
5317
+ }
5318
+
5206
5319
  /* Identity edit button (pencil icon in card) */
5207
5320
  #hd-wallet-ui-container .identity-edit-btn {
5208
5321
  position: absolute;