hd-wallet-ui 1.1.1 → 1.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hd-wallet-ui",
3
- "version": "1.1.1",
3
+ "version": "1.1.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,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.2",
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
@@ -3161,7 +3162,7 @@ function setupTrustHandlers() {
3161
3162
  }
3162
3163
 
3163
3164
  // Update encryption tab when it becomes active or HD controls change
3164
- $qa('.modal-tab[data-modal-tab="encryption-tab-content"]').forEach(tab => {
3165
+ $qa('.modal-tab[data-modal-tab="encrypt-tab-content"]').forEach(tab => {
3165
3166
  tab.addEventListener('click', () => {
3166
3167
  if (state.hdRoot) updateEncryptionTab();
3167
3168
  });
@@ -3274,8 +3275,6 @@ function setupTrustHandlers() {
3274
3275
  $('encrypt-out-iv').textContent = toHexCompact(iv);
3275
3276
  $('encrypt-out-salt').textContent = toHexCompact(salt);
3276
3277
  $('encrypt-out-sender-pub').textContent = toHexCompact(senderPub);
3277
- $('encrypt-output-section').style.display = 'block';
3278
-
3279
3278
  // Build EME (Encrypted Message Envelope) standard object
3280
3279
  currentEME = new EMET(
3281
3280
  Array.from(ciphertext), // ENCRYPTED_BLOB
@@ -3293,8 +3292,9 @@ function setupTrustHandlers() {
3293
3292
 
3294
3293
  updateBundleDisplay();
3295
3294
 
3296
- // Clear any previous decrypt result
3297
- $('decrypt-result').style.display = 'none';
3295
+ // Switch to result step
3296
+ $('encrypt-step-compose').style.display = 'none';
3297
+ $('encrypt-step-result').style.display = 'block';
3298
3298
  } catch (err) {
3299
3299
  console.error('Encryption failed:', err);
3300
3300
  alert('Encryption failed: ' + err.message);
@@ -3391,7 +3391,10 @@ function setupTrustHandlers() {
3391
3391
  const decStr = new TextDecoder().decode(decrypted);
3392
3392
 
3393
3393
  $('decrypt-result-value').textContent = decStr;
3394
- $('decrypt-result').style.display = 'block';
3394
+
3395
+ // Switch to result step
3396
+ $('decrypt-step-input').style.display = 'none';
3397
+ $('decrypt-step-result').style.display = 'block';
3395
3398
  } catch (err) {
3396
3399
  console.error('Decryption failed:', err);
3397
3400
  alert('Decryption failed: ' + err.message);
@@ -3404,15 +3407,16 @@ function setupTrustHandlers() {
3404
3407
  if (btn) btn.disabled = !$('decrypt-payload')?.value?.trim();
3405
3408
  });
3406
3409
 
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;
3410
+ // Back button: encrypt result -> compose
3411
+ $('encrypt-back-btn')?.addEventListener('click', () => {
3412
+ $('encrypt-step-result').style.display = 'none';
3413
+ $('encrypt-step-compose').style.display = 'block';
3414
+ });
3415
+
3416
+ // Back button: decrypt result -> input
3417
+ $('decrypt-back-btn')?.addEventListener('click', () => {
3418
+ $('decrypt-step-result').style.display = 'none';
3419
+ $('decrypt-step-input').style.display = 'block';
3416
3420
  });
3417
3421
  }
3418
3422
 
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
@@ -4628,6 +4628,24 @@ a.chain-card:hover {
4628
4628
  margin-top: 10px;
4629
4629
  }
4630
4630
 
4631
+ .encrypt-step-header {
4632
+ display: flex;
4633
+ align-items: center;
4634
+ gap: 12px;
4635
+ margin-bottom: 16px;
4636
+ }
4637
+
4638
+ .encrypt-step-header .section-label {
4639
+ margin: 0;
4640
+ }
4641
+
4642
+ .encrypt-back-btn {
4643
+ display: inline-flex;
4644
+ align-items: center;
4645
+ gap: 4px;
4646
+ flex-shrink: 0;
4647
+ }
4648
+
4631
4649
  .encrypt-output-section {
4632
4650
  margin-bottom: 24px;
4633
4651
  padding: 16px;
@@ -4663,6 +4681,18 @@ a.chain-card:hover {
4663
4681
  flex: 1;
4664
4682
  min-width: 0;
4665
4683
  }
4684
+ .encrypt-field .copy-btn {
4685
+ background: none;
4686
+ border: none;
4687
+ padding: 4px;
4688
+ cursor: pointer;
4689
+ color: var(--white-30);
4690
+ flex-shrink: 0;
4691
+ transition: color 0.2s;
4692
+ }
4693
+ .encrypt-field .copy-btn:hover {
4694
+ color: var(--white);
4695
+ }
4666
4696
  .encrypt-bundle-group {
4667
4697
  margin-top: 12px;
4668
4698
  }