hd-wallet-ui 1.2.4 → 1.2.6

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.4",
3
+ "version": "1.2.6",
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.4",
38
+ "hd-wallet-wasm": "^1.2.6",
39
39
  "qrcode": "^1.5.3",
40
40
  "spacedatastandards.org": "^23.3.3-0.3.4",
41
41
  "vcard-cryptoperson": "^1.1.11"
package/src/app.js CHANGED
@@ -2378,10 +2378,10 @@ function login(keys) {
2378
2378
  state.addresses = deriveAllAddressesFromHD();
2379
2379
  state.selectedCrypto = 'btc';
2380
2380
 
2381
- // Fire onLogin callback with SDN identity (coin type 9999)
2381
+ // Fire onLogin callback with SDN identity (coin type 1957 — Sputnik)
2382
2382
  if (_onLoginCallback && state.hdRoot) {
2383
2383
  try {
2384
- const sdnSigning = getSigningKey(state.hdRoot, 9999, 0, 0);
2384
+ const sdnSigning = getSigningKey(state.hdRoot, 1957, 0, 0);
2385
2385
  const sdnPubKey = ed25519.getPublicKey(sdnSigning.privateKey);
2386
2386
  const xpub = state.hdRoot.toXpub();
2387
2387
  _onLoginCallback({
@@ -3371,11 +3371,16 @@ function parseAndDisplayVCF(vcfText) {
3371
3371
  if (!resultEl || !fieldsEl) return;
3372
3372
 
3373
3373
  if (photoEl) {
3374
- photoEl.innerHTML = photo
3375
- ? `<img src="${photo}" alt="Contact photo">`
3376
- : `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" style="width:32px;height:32px;opacity:0.3">
3374
+ const fallbackSvg = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" style="width:32px;height:32px;opacity:0.3">
3377
3375
  <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
3378
3376
  </svg>`;
3377
+ if (photo) {
3378
+ photoEl.innerHTML = `<img src="${photo}" alt="Contact photo">`;
3379
+ const img = photoEl.querySelector('img');
3380
+ if (img) img.onerror = () => { photoEl.innerHTML = fallbackSvg; };
3381
+ } else {
3382
+ photoEl.innerHTML = fallbackSvg;
3383
+ }
3379
3384
  }
3380
3385
 
3381
3386
  let html = '';
@@ -3638,6 +3643,19 @@ function setupLoginHandlers() {
3638
3643
  updatePasswordStrength(e.target.value);
3639
3644
  });
3640
3645
 
3646
+ // Password show/hide toggle
3647
+ $('toggle-password-vis')?.addEventListener('click', () => {
3648
+ const pw = $('wallet-password');
3649
+ const btn = $('toggle-password-vis');
3650
+ if (!pw || !btn) return;
3651
+ const showing = pw.type === 'text';
3652
+ pw.type = showing ? 'password' : 'text';
3653
+ btn.querySelector('.eye-open').style.display = showing ? '' : 'none';
3654
+ btn.querySelector('.eye-closed').style.display = showing ? 'none' : '';
3655
+ btn.title = showing ? 'Show password' : 'Hide password';
3656
+ pw.focus();
3657
+ });
3658
+
3641
3659
  $('wallet-username')?.addEventListener('input', () => {
3642
3660
  const pw = $('wallet-password');
3643
3661
  if (pw) updatePasswordStrength(pw.value);
@@ -4187,6 +4205,7 @@ function setupMainAppHandlers() {
4187
4205
  const img = document.createElement('img');
4188
4206
  img.src = dataUrl;
4189
4207
  img.alt = 'Photo';
4208
+ img.onerror = () => { img.remove(); resetPhotoPreview(); };
4190
4209
  preview.appendChild(img);
4191
4210
  const removeBtn = $('vcard-photo-remove');
4192
4211
  if (removeBtn) removeBtn.style.display = '';
@@ -5363,7 +5382,7 @@ export async function init(rootElement, options = {}) {
5363
5382
  * @param {Node} [rootElement] - Optional root element for DOM queries
5364
5383
  * @param {Object} [options] - Options passed to init()
5365
5384
  * @param {Function} [options.onLogin] - Callback fired after successful login with
5366
- * `{ xpub, signingPublicKey, sign(message) }` for SDN identity (coin type 9999)
5385
+ * `{ xpub, signingPublicKey, sign(message) }` for SDN identity (coin type 1957)
5367
5386
  * @returns {Promise<{openLogin: Function, openAccount: Function, destroy: Function}>}
5368
5387
  */
5369
5388
  export async function createWalletUI(rootElement, options = {}) {
package/src/template.js CHANGED
@@ -538,7 +538,7 @@ export function getModalHTML() {
538
538
  <form id="password-method" class="method-content active" onsubmit="return false;">
539
539
  <div class="glass-input-group"><input type="text" id="wallet-username" class="glass-input" placeholder="Username" autocomplete="username"></div>
540
540
  <div class="glass-input-group">
541
- <input type="password" id="wallet-password" class="glass-input" placeholder="Password (24+ chars)" autocomplete="new-password">
541
+ <div class="password-input-wrap"><input type="password" id="wallet-password" class="glass-input" placeholder="Password (24+ chars)" autocomplete="new-password"><button type="button" id="toggle-password-vis" class="password-toggle" title="Show password"><svg class="eye-open" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg><svg class="eye-closed" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg></button></div>
542
542
  <div class="entropy-bar"><div class="entropy-fill" id="strength-fill"></div><div class="entropy-threshold"></div></div>
543
543
  <span class="entropy-label"><span id="entropy-bits">0</span> bits entropy</span>
544
544
  </div>
package/styles/main.css CHANGED
@@ -450,6 +450,32 @@ body:has(.modal.active) .nav-bar {
450
450
  background: var(--white-10);
451
451
  }
452
452
 
453
+ .password-input-wrap {
454
+ position: relative;
455
+ }
456
+ .password-input-wrap .glass-input {
457
+ padding-right: 48px;
458
+ }
459
+ .password-toggle {
460
+ position: absolute;
461
+ right: 8px;
462
+ top: 50%;
463
+ transform: translateY(-50%);
464
+ background: none;
465
+ border: none;
466
+ color: var(--white-40);
467
+ cursor: pointer;
468
+ padding: 6px;
469
+ display: flex;
470
+ align-items: center;
471
+ justify-content: center;
472
+ border-radius: 6px;
473
+ transition: color 0.15s;
474
+ }
475
+ .password-toggle:hover {
476
+ color: var(--white-80);
477
+ }
478
+
453
479
  .glass-textarea {
454
480
  resize: vertical;
455
481
  min-height: 80px;