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 +2 -2
- package/src/app.js +25 -6
- package/src/template.js +1 -1
- package/styles/main.css +26 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hd-wallet-ui",
|
|
3
|
-
"version": "1.2.
|
|
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.
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
|
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;
|