hd-wallet-ui 1.1.1 → 1.1.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.1.1",
3
+ "version": "1.1.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",
@@ -34,7 +34,7 @@
34
34
  "bip39": "^3.1.0",
35
35
  "buffer": "^6.0.3",
36
36
  "flatbuffers": "^25.9.23",
37
- "hd-wallet-wasm": "^1.1.1",
37
+ "hd-wallet-wasm": "^1.1.3",
38
38
  "qrcode": "^1.5.3",
39
39
  "vcard-cryptoperson": "^1.1.10"
40
40
  },
package/src/app.js CHANGED
@@ -38,6 +38,7 @@ import {
38
38
  coinTypeToConfig,
39
39
  buildSigningPath,
40
40
  buildEncryptionPath,
41
+ PKI_STORAGE_KEY,
41
42
  } from './constants.js';
42
43
 
43
44
  import {
@@ -1630,7 +1631,7 @@ async function updateAdversarialSecurity() {
1630
1631
  // Update account header total value
1631
1632
  const accountTotalEl = $('account-total-value');
1632
1633
  if (accountTotalEl) {
1633
- accountTotalEl.textContent = 'Security Level: ' + formatCurrencyValue(totalConverted, currency);
1634
+ accountTotalEl.textContent = 'Bond: ' + formatCurrencyValue(totalConverted, currency);
1634
1635
  }
1635
1636
 
1636
1637
  // Update account address dropdown values
@@ -2585,6 +2586,7 @@ function setupMainAppHandlers() {
2585
2586
  if (video) {
2586
2587
  video.srcObject = cameraStream;
2587
2588
  video.style.display = '';
2589
+ await video.play();
2588
2590
  }
2589
2591
  const preview = $('vcard-photo-preview');
2590
2592
  if (preview) {
@@ -3161,7 +3163,7 @@ function setupTrustHandlers() {
3161
3163
  }
3162
3164
 
3163
3165
  // Update encryption tab when it becomes active or HD controls change
3164
- $qa('.modal-tab[data-modal-tab="encryption-tab-content"]').forEach(tab => {
3166
+ $qa('.modal-tab[data-modal-tab="encrypt-tab-content"]').forEach(tab => {
3165
3167
  tab.addEventListener('click', () => {
3166
3168
  if (state.hdRoot) updateEncryptionTab();
3167
3169
  });
@@ -3274,8 +3276,6 @@ function setupTrustHandlers() {
3274
3276
  $('encrypt-out-iv').textContent = toHexCompact(iv);
3275
3277
  $('encrypt-out-salt').textContent = toHexCompact(salt);
3276
3278
  $('encrypt-out-sender-pub').textContent = toHexCompact(senderPub);
3277
- $('encrypt-output-section').style.display = 'block';
3278
-
3279
3279
  // Build EME (Encrypted Message Envelope) standard object
3280
3280
  currentEME = new EMET(
3281
3281
  Array.from(ciphertext), // ENCRYPTED_BLOB
@@ -3293,8 +3293,9 @@ function setupTrustHandlers() {
3293
3293
 
3294
3294
  updateBundleDisplay();
3295
3295
 
3296
- // Clear any previous decrypt result
3297
- $('decrypt-result').style.display = 'none';
3296
+ // Switch to result step
3297
+ $('encrypt-step-compose').style.display = 'none';
3298
+ $('encrypt-step-result').style.display = 'block';
3298
3299
  } catch (err) {
3299
3300
  console.error('Encryption failed:', err);
3300
3301
  alert('Encryption failed: ' + err.message);
@@ -3391,7 +3392,10 @@ function setupTrustHandlers() {
3391
3392
  const decStr = new TextDecoder().decode(decrypted);
3392
3393
 
3393
3394
  $('decrypt-result-value').textContent = decStr;
3394
- $('decrypt-result').style.display = 'block';
3395
+
3396
+ // Switch to result step
3397
+ $('decrypt-step-input').style.display = 'none';
3398
+ $('decrypt-step-result').style.display = 'block';
3395
3399
  } catch (err) {
3396
3400
  console.error('Decryption failed:', err);
3397
3401
  alert('Decryption failed: ' + err.message);
@@ -3404,15 +3408,16 @@ function setupTrustHandlers() {
3404
3408
  if (btn) btn.disabled = !$('decrypt-payload')?.value?.trim();
3405
3409
  });
3406
3410
 
3407
- // Clear button
3408
- $('encrypt-clear-btn')?.addEventListener('click', () => {
3409
- $('encrypt-plaintext').value = '';
3410
- $('encrypt-recipient-pubkey').value = '';
3411
- $('encrypt-output-section').style.display = 'none';
3412
- $('decrypt-payload').value = '';
3413
- $('decrypt-result').style.display = 'none';
3414
- $('encrypt-btn').disabled = !state.hdRoot;
3415
- $('decrypt-btn').disabled = true;
3411
+ // Back button: encrypt result -> compose
3412
+ $('encrypt-back-btn')?.addEventListener('click', () => {
3413
+ $('encrypt-step-result').style.display = 'none';
3414
+ $('encrypt-step-compose').style.display = 'block';
3415
+ });
3416
+
3417
+ // Back button: decrypt result -> input
3418
+ $('decrypt-back-btn')?.addEventListener('click', () => {
3419
+ $('decrypt-step-result').style.display = 'none';
3420
+ $('decrypt-step-input').style.display = 'block';
3416
3421
  });
3417
3422
  }
3418
3423
 
package/src/template.js CHANGED
@@ -8,8 +8,9 @@ export function getModalHTML() {
8
8
  <button class="modal-tab active" data-modal-tab="vcard-tab-content">Identity</button>
9
9
  <button class="modal-tab" data-modal-tab="keys-tab-content">Keys</button>
10
10
  <button class="modal-tab" data-modal-tab="trust-tab-content">Trust Map</button>
11
- <button class="modal-tab" data-modal-tab="bond-tab-content">Security Bond</button>
12
- <button class="modal-tab" data-modal-tab="encryption-tab-content">Encrypt</button>
11
+ <button class="modal-tab" data-modal-tab="bond-tab-content">Bond</button>
12
+ <button class="modal-tab" data-modal-tab="encrypt-tab-content">Encrypt</button>
13
+ <button class="modal-tab" data-modal-tab="decrypt-tab-content">Decrypt</button>
13
14
  </div>
14
15
  <div class="modal-body">
15
16
  <div id="keys-tab-content" class="modal-tab-content">
@@ -272,57 +273,62 @@ export function getModalHTML() {
272
273
  </div>
273
274
  </div>
274
275
 
275
- <!-- Encryption Tab -->
276
- <div id="encryption-tab-content" class="modal-tab-content">
277
- <div class="encrypt-tab-intro">
278
- <h4 class="section-label">ECIES Encrypt / Decrypt</h4>
279
- <p>End-to-end encryption using your HD wallet keys. Uses ECDH key agreement + HKDF + AES-256-GCM (ECIES).</p>
280
- </div>
276
+ <!-- Encrypt Tab -->
277
+ <div id="encrypt-tab-content" class="modal-tab-content">
278
+ <!-- Step 1: Compose -->
279
+ <div id="encrypt-step-compose" class="encrypt-step">
280
+ <div class="encrypt-tab-intro">
281
+ <h4 class="section-label">Encrypt a Message</h4>
282
+ <p>ECDH key agreement + HKDF + AES-256-GCM (ECIES)</p>
283
+ </div>
281
284
 
282
- <div class="encrypt-keys-section">
283
- <div class="encrypt-key-row">
284
- <div class="encrypt-key-card glass-card">
285
- <div class="encrypt-key-header">
286
- <span class="encrypt-role-badge sender">Sender (You)</span>
287
- </div>
288
- <div class="encrypt-key-detail">
289
- <label>Encryption Public Key</label>
290
- <code id="encrypt-sender-pubkey" class="truncate">--</code>
291
- </div>
292
- <div class="encrypt-key-detail">
293
- <label>Derivation Path</label>
294
- <code id="encrypt-sender-path">--</code>
295
- </div>
296
- </div>
297
- <div class="encrypt-key-card glass-card">
298
- <div class="encrypt-key-header">
299
- <span class="encrypt-role-badge recipient">Recipient</span>
285
+ <div class="encrypt-keys-section">
286
+ <div class="encrypt-key-row">
287
+ <div class="encrypt-key-card glass-card">
288
+ <div class="encrypt-key-header">
289
+ <span class="encrypt-role-badge sender">Sender (You)</span>
290
+ </div>
291
+ <div class="encrypt-key-detail">
292
+ <label>Encryption Public Key</label>
293
+ <code id="encrypt-sender-pubkey" class="truncate">--</code>
294
+ </div>
295
+ <div class="encrypt-key-detail">
296
+ <label>Derivation Path</label>
297
+ <code id="encrypt-sender-path">--</code>
298
+ </div>
300
299
  </div>
301
- <div class="encrypt-key-detail">
302
- <label>Recipient Public Key (hex)</label>
303
- <div class="encrypt-recipient-input-row">
304
- <input type="text" id="encrypt-recipient-pubkey" class="glass-input compact" placeholder="Paste recipient's secp256k1 public key (hex)">
305
- <button id="encrypt-use-self" class="glass-btn small" title="Use your own key (for testing)">Self</button>
300
+ <div class="encrypt-key-card glass-card">
301
+ <div class="encrypt-key-header">
302
+ <span class="encrypt-role-badge recipient">Recipient</span>
303
+ </div>
304
+ <div class="encrypt-key-detail">
305
+ <label>Recipient Public Key (hex)</label>
306
+ <div class="encrypt-recipient-input-row">
307
+ <input type="text" id="encrypt-recipient-pubkey" class="glass-input compact" placeholder="Paste recipient's secp256k1 public key (hex)">
308
+ <button id="encrypt-use-self" class="glass-btn small" title="Use your own key (for testing)">Self</button>
309
+ </div>
306
310
  </div>
307
311
  </div>
308
312
  </div>
309
313
  </div>
310
- </div>
311
314
 
312
- <div class="encrypt-message-section">
313
- <div class="encrypt-input-group">
314
- <label class="section-label">Message</label>
315
- <textarea id="encrypt-plaintext" class="glass-input glass-textarea" rows="3" placeholder="Enter a message to encrypt..."></textarea>
316
- </div>
317
- <div class="encrypt-actions">
318
- <button id="encrypt-btn" class="glass-btn primary" disabled>Encrypt</button>
319
- <button id="decrypt-btn" class="glass-btn" disabled>Decrypt</button>
320
- <button id="encrypt-clear-btn" class="glass-btn small">Clear</button>
315
+ <div class="encrypt-message-section">
316
+ <div class="encrypt-input-group">
317
+ <label class="section-label">Message</label>
318
+ <textarea id="encrypt-plaintext" class="glass-input glass-textarea" rows="3" placeholder="Enter a message to encrypt..."></textarea>
319
+ </div>
320
+ <div class="encrypt-actions">
321
+ <button id="encrypt-btn" class="glass-btn primary" disabled>Encrypt</button>
322
+ </div>
321
323
  </div>
322
324
  </div>
323
325
 
324
- <div id="encrypt-output-section" class="encrypt-output-section" style="display:none;">
325
- <h4 class="section-label">Encrypted Payload</h4>
326
+ <!-- Step 2: Result (replaces compose) -->
327
+ <div id="encrypt-step-result" class="encrypt-step" style="display:none;">
328
+ <div class="encrypt-step-header">
329
+ <button id="encrypt-back-btn" class="glass-btn small encrypt-back-btn"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg> Back</button>
330
+ <h4 class="section-label">Encrypted Payload</h4>
331
+ </div>
326
332
  <div class="encrypt-output-fields">
327
333
  <div class="encrypt-field"><label>Ciphertext</label><code id="encrypt-out-ciphertext" class="encrypt-out-value truncate"></code><button class="copy-btn" data-copy="encrypt-out-ciphertext" title="Copy"><svg width="14" height="14" 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"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button></div>
328
334
  <div class="encrypt-field"><label>Auth Tag</label><code id="encrypt-out-tag" class="encrypt-out-value truncate"></code></div>
@@ -348,13 +354,29 @@ export function getModalHTML() {
348
354
  </div>
349
355
  </div>
350
356
  </div>
357
+ </div>
351
358
 
352
- <div class="encrypt-decrypt-section">
353
- <h4 class="section-label">Decrypt a Message</h4>
354
- <p class="encrypt-decrypt-info">Paste an EME payload (JSON or base64 FlatBuffer) to decrypt with your key.</p>
355
- <textarea id="decrypt-payload" class="glass-input glass-textarea" rows="4" placeholder='Paste EME JSON or base64 FlatBuffer here...'></textarea>
356
- <div id="decrypt-result" class="decrypt-result" style="display:none;">
357
- <label>Decrypted Message</label>
359
+ <!-- Decrypt Tab -->
360
+ <div id="decrypt-tab-content" class="modal-tab-content">
361
+ <!-- Step 1: Input -->
362
+ <div id="decrypt-step-input" class="encrypt-step">
363
+ <div class="encrypt-tab-intro">
364
+ <h4 class="section-label">Decrypt a Message</h4>
365
+ <p>Paste an EME payload (JSON or base64 FlatBuffer) to decrypt with your key.</p>
366
+ </div>
367
+ <textarea id="decrypt-payload" class="glass-input glass-textarea" rows="6" placeholder='Paste EME JSON or base64 FlatBuffer here...'></textarea>
368
+ <div class="encrypt-actions">
369
+ <button id="decrypt-btn" class="glass-btn primary" disabled>Decrypt</button>
370
+ </div>
371
+ </div>
372
+
373
+ <!-- Step 2: Result (replaces input) -->
374
+ <div id="decrypt-step-result" class="encrypt-step" style="display:none;">
375
+ <div class="encrypt-step-header">
376
+ <button id="decrypt-back-btn" class="glass-btn small encrypt-back-btn"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg> Back</button>
377
+ <h4 class="section-label">Decrypted Message</h4>
378
+ </div>
379
+ <div class="decrypt-result">
358
380
  <div class="decrypt-result-value" id="decrypt-result-value"></div>
359
381
  </div>
360
382
  </div>
package/styles/main.css CHANGED
@@ -142,6 +142,10 @@ body {
142
142
  border-bottom: 1px solid var(--glass-border);
143
143
  }
144
144
 
145
+ body:has(.modal.active) {
146
+ overflow: hidden;
147
+ }
148
+
145
149
  body:has(.modal.active) .nav-bar {
146
150
  z-index: 1;
147
151
  }
@@ -4628,6 +4632,24 @@ a.chain-card:hover {
4628
4632
  margin-top: 10px;
4629
4633
  }
4630
4634
 
4635
+ .encrypt-step-header {
4636
+ display: flex;
4637
+ align-items: center;
4638
+ gap: 12px;
4639
+ margin-bottom: 16px;
4640
+ }
4641
+
4642
+ .encrypt-step-header .section-label {
4643
+ margin: 0;
4644
+ }
4645
+
4646
+ .encrypt-back-btn {
4647
+ display: inline-flex;
4648
+ align-items: center;
4649
+ gap: 4px;
4650
+ flex-shrink: 0;
4651
+ }
4652
+
4631
4653
  .encrypt-output-section {
4632
4654
  margin-bottom: 24px;
4633
4655
  padding: 16px;
@@ -4663,6 +4685,18 @@ a.chain-card:hover {
4663
4685
  flex: 1;
4664
4686
  min-width: 0;
4665
4687
  }
4688
+ .encrypt-field .copy-btn {
4689
+ background: none;
4690
+ border: none;
4691
+ padding: 4px;
4692
+ cursor: pointer;
4693
+ color: var(--white-30);
4694
+ flex-shrink: 0;
4695
+ transition: color 0.2s;
4696
+ }
4697
+ .encrypt-field .copy-btn:hover {
4698
+ color: var(--white);
4699
+ }
4666
4700
  .encrypt-bundle-group {
4667
4701
  margin-top: 12px;
4668
4702
  }