hd-wallet-ui 1.6.0 → 2.0.1
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 +77 -3
- package/src/template.js +4 -0
- package/styles/main.css +98 -0
- package/styles/widget.css +98 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hd-wallet-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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.15",
|
|
43
|
-
"hd-wallet-wasm": "^
|
|
43
|
+
"hd-wallet-wasm": "^2.0.1",
|
|
44
44
|
"qrcode": "^1.5.3",
|
|
45
45
|
"spacedatastandards.org": "^23.3.3-0.3.4",
|
|
46
46
|
"vcard-cryptoperson": "^1.1.11"
|
package/src/app.js
CHANGED
|
@@ -3498,11 +3498,49 @@ function verifyVCardSignature(vcardText) {
|
|
|
3498
3498
|
}
|
|
3499
3499
|
}
|
|
3500
3500
|
|
|
3501
|
+
function hideImportedVcardPreview() {
|
|
3502
|
+
state.importedVcardPreview = null;
|
|
3503
|
+
const resultEl = $('vcf-import-result');
|
|
3504
|
+
const fieldsEl = $('vcf-import-fields');
|
|
3505
|
+
const sigStatus = $('vcf-import-sig-status');
|
|
3506
|
+
if (fieldsEl) fieldsEl.innerHTML = '';
|
|
3507
|
+
if (sigStatus) {
|
|
3508
|
+
sigStatus.innerHTML = '';
|
|
3509
|
+
sigStatus.style.display = 'none';
|
|
3510
|
+
}
|
|
3511
|
+
if (resultEl) resultEl.style.display = 'none';
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
function applyImportedVcardPreview() {
|
|
3515
|
+
const imported = state.importedVcardPreview;
|
|
3516
|
+
if (!imported) return;
|
|
3517
|
+
|
|
3518
|
+
for (const id of vcardFieldIds) {
|
|
3519
|
+
const el = $(id);
|
|
3520
|
+
if (el) el.value = imported.formValues[id] || '';
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
state.vcardPhoto = imported.photo || null;
|
|
3524
|
+
if (imported.photo) {
|
|
3525
|
+
showPhotoPreview(imported.photo);
|
|
3526
|
+
} else {
|
|
3527
|
+
resetPhotoPreview();
|
|
3528
|
+
}
|
|
3529
|
+
|
|
3530
|
+
saveVcardIdentity();
|
|
3531
|
+
updateIdentityCardSummary();
|
|
3532
|
+
setPhotoActionsVisible(false);
|
|
3533
|
+
$('vcard-edit-view').style.display = 'none';
|
|
3534
|
+
$('vcard-form-view').style.display = '';
|
|
3535
|
+
hideImportedVcardPreview();
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3501
3538
|
function parseAndDisplayVCF(vcfText) {
|
|
3502
3539
|
const lines = vcfText.replace(/\r?\n /g, '').split(/\r?\n/);
|
|
3503
3540
|
const fields = {};
|
|
3504
3541
|
const keys = [];
|
|
3505
3542
|
let photo = null;
|
|
3543
|
+
const formValues = Object.fromEntries(vcardFieldIds.map(id => [id, '']));
|
|
3506
3544
|
|
|
3507
3545
|
for (const line of lines) {
|
|
3508
3546
|
const colonIdx = line.indexOf(':');
|
|
@@ -3512,19 +3550,38 @@ function parseAndDisplayVCF(vcfText) {
|
|
|
3512
3550
|
|
|
3513
3551
|
if (prop === 'FN') {
|
|
3514
3552
|
fields.name = value;
|
|
3515
|
-
} else if (prop
|
|
3553
|
+
} else if (prop === 'N') {
|
|
3554
|
+
const parts = value.split(';');
|
|
3555
|
+
formValues['vcard-lastname'] = parts[0] || '';
|
|
3556
|
+
formValues['vcard-firstname'] = parts[1] || '';
|
|
3557
|
+
formValues['vcard-middlename'] = parts[2] || '';
|
|
3558
|
+
formValues['vcard-prefix'] = parts[3] || '';
|
|
3559
|
+
formValues['vcard-suffix'] = parts[4] || '';
|
|
3516
3560
|
if (!fields.name) {
|
|
3517
|
-
const parts = value.split(';');
|
|
3518
3561
|
fields.name = [parts[3], parts[1], parts[2], parts[0], parts[4]].filter(Boolean).join(' ');
|
|
3519
3562
|
}
|
|
3563
|
+
} else if (prop === 'NICKNAME') {
|
|
3564
|
+
formValues['vcard-nickname'] = value;
|
|
3520
3565
|
} else if (prop.startsWith('EMAIL')) {
|
|
3566
|
+
formValues['vcard-email'] ||= value;
|
|
3521
3567
|
fields.email = value;
|
|
3522
3568
|
} else if (prop.startsWith('ORG')) {
|
|
3523
|
-
|
|
3569
|
+
const normalized = value.replace(/;/g, ', ');
|
|
3570
|
+
formValues['vcard-org'] ||= normalized;
|
|
3571
|
+
fields.org = normalized;
|
|
3524
3572
|
} else if (prop.startsWith('TITLE')) {
|
|
3573
|
+
formValues['vcard-title'] ||= value;
|
|
3525
3574
|
fields.title = value;
|
|
3526
3575
|
} else if (prop.startsWith('TEL')) {
|
|
3576
|
+
formValues['vcard-phone'] ||= value;
|
|
3527
3577
|
fields.tel = value;
|
|
3578
|
+
} else if (prop.startsWith('ADR')) {
|
|
3579
|
+
const parts = value.split(';');
|
|
3580
|
+
formValues['vcard-street'] ||= [parts[1], parts[2]].filter(Boolean).join(' ');
|
|
3581
|
+
formValues['vcard-city'] ||= parts[3] || '';
|
|
3582
|
+
formValues['vcard-region'] ||= parts[4] || '';
|
|
3583
|
+
formValues['vcard-postal'] ||= parts[5] || '';
|
|
3584
|
+
formValues['vcard-country'] ||= parts[6] || '';
|
|
3528
3585
|
} else if (prop.startsWith('PHOTO')) {
|
|
3529
3586
|
if (prop.includes('VALUE=URI') || value.startsWith('data:') || value.startsWith('http')) {
|
|
3530
3587
|
photo = value;
|
|
@@ -3541,6 +3598,10 @@ function parseAndDisplayVCF(vcfText) {
|
|
|
3541
3598
|
}
|
|
3542
3599
|
}
|
|
3543
3600
|
|
|
3601
|
+
if (!formValues['vcard-firstname'] && !formValues['vcard-lastname'] && fields.name) {
|
|
3602
|
+
formValues['vcard-firstname'] = fields.name;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3544
3605
|
const resultEl = $('vcf-import-result');
|
|
3545
3606
|
const photoEl = $('vcf-import-photo');
|
|
3546
3607
|
const fieldsEl = $('vcf-import-fields');
|
|
@@ -3601,6 +3662,11 @@ function parseAndDisplayVCF(vcfText) {
|
|
|
3601
3662
|
sigStatus.style.display = 'flex';
|
|
3602
3663
|
}
|
|
3603
3664
|
|
|
3665
|
+
state.importedVcardPreview = {
|
|
3666
|
+
formValues,
|
|
3667
|
+
photo,
|
|
3668
|
+
};
|
|
3669
|
+
|
|
3604
3670
|
fieldsEl.innerHTML = html;
|
|
3605
3671
|
resultEl.style.display = 'block';
|
|
3606
3672
|
}
|
|
@@ -4534,6 +4600,14 @@ function setupMainAppHandlers() {
|
|
|
4534
4600
|
e.target.value = '';
|
|
4535
4601
|
});
|
|
4536
4602
|
|
|
4603
|
+
$('vcf-import-apply')?.addEventListener('click', () => {
|
|
4604
|
+
applyImportedVcardPreview();
|
|
4605
|
+
});
|
|
4606
|
+
|
|
4607
|
+
$('vcf-import-close')?.addEventListener('click', () => {
|
|
4608
|
+
hideImportedVcardPreview();
|
|
4609
|
+
});
|
|
4610
|
+
|
|
4537
4611
|
// Reveal sensitive key buttons
|
|
4538
4612
|
$qa('.reveal-key-btn').forEach(btn => {
|
|
4539
4613
|
btn.addEventListener('click', () => {
|
package/src/template.js
CHANGED
|
@@ -256,6 +256,10 @@ export function getModalHTML() {
|
|
|
256
256
|
<div class="vcf-import-fields" id="vcf-import-fields"></div>
|
|
257
257
|
</div>
|
|
258
258
|
<div id="vcf-import-sig-status" class="vcard-sig-badge" style="display:none;"></div>
|
|
259
|
+
<div class="vcf-import-actions">
|
|
260
|
+
<button id="vcf-import-apply" class="glass-btn primary">Replace Identity</button>
|
|
261
|
+
<button id="vcf-import-close" class="glass-btn">Dismiss</button>
|
|
262
|
+
</div>
|
|
259
263
|
</div>
|
|
260
264
|
</div>
|
|
261
265
|
|
package/styles/main.css
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
padding: 0;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/* Button reset — counteract host-page normalize/tachyons leaking into the widget */
|
|
14
|
+
button {
|
|
15
|
+
-webkit-appearance: none;
|
|
16
|
+
appearance: none;
|
|
17
|
+
line-height: inherit;
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
/* Prevent dragging on headings, headers, and links */
|
|
14
21
|
h1, h2, h3, h4, h5, h6,
|
|
15
22
|
a, button, nav, nav * {
|
|
@@ -4937,6 +4944,13 @@ body:has(.modal.active) .nav-bar {
|
|
|
4937
4944
|
color: rgba(255, 255, 255, 0.9) !important;
|
|
4938
4945
|
}
|
|
4939
4946
|
|
|
4947
|
+
.vcf-import-actions {
|
|
4948
|
+
display: flex;
|
|
4949
|
+
gap: 10px;
|
|
4950
|
+
justify-content: flex-end;
|
|
4951
|
+
margin-top: 14px;
|
|
4952
|
+
}
|
|
4953
|
+
|
|
4940
4954
|
/* Readonly badge */
|
|
4941
4955
|
.readonly-badge {
|
|
4942
4956
|
font-size: 0.6875rem;
|
|
@@ -4968,6 +4982,10 @@ body:has(.modal.active) .nav-bar {
|
|
|
4968
4982
|
.vcard-form-row.address-row {
|
|
4969
4983
|
grid-template-columns: 1fr;
|
|
4970
4984
|
}
|
|
4985
|
+
|
|
4986
|
+
.vcf-import-actions {
|
|
4987
|
+
flex-direction: column;
|
|
4988
|
+
}
|
|
4971
4989
|
|
|
4972
4990
|
.photo-upload-section {
|
|
4973
4991
|
flex-direction: column;
|
|
@@ -5861,6 +5879,76 @@ a.chain-card:hover {
|
|
|
5861
5879
|
display: block;
|
|
5862
5880
|
}
|
|
5863
5881
|
|
|
5882
|
+
.x509-overview {
|
|
5883
|
+
display: grid;
|
|
5884
|
+
grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
|
|
5885
|
+
gap: 24px;
|
|
5886
|
+
padding: 32px;
|
|
5887
|
+
margin-bottom: 24px;
|
|
5888
|
+
align-items: start;
|
|
5889
|
+
}
|
|
5890
|
+
|
|
5891
|
+
.x509-copy {
|
|
5892
|
+
min-width: 0;
|
|
5893
|
+
}
|
|
5894
|
+
|
|
5895
|
+
.x509-eyebrow {
|
|
5896
|
+
display: inline-flex;
|
|
5897
|
+
align-items: center;
|
|
5898
|
+
gap: 8px;
|
|
5899
|
+
padding: 6px 10px;
|
|
5900
|
+
margin-bottom: 14px;
|
|
5901
|
+
border-radius: 999px;
|
|
5902
|
+
background: rgba(96, 165, 250, 0.12);
|
|
5903
|
+
color: #93c5fd;
|
|
5904
|
+
font-size: 0.72rem;
|
|
5905
|
+
font-weight: 600;
|
|
5906
|
+
letter-spacing: 0.08em;
|
|
5907
|
+
text-transform: uppercase;
|
|
5908
|
+
}
|
|
5909
|
+
|
|
5910
|
+
.x509-copy h3 {
|
|
5911
|
+
font-size: 1.35rem;
|
|
5912
|
+
font-weight: 600;
|
|
5913
|
+
line-height: 1.25;
|
|
5914
|
+
margin-bottom: 12px;
|
|
5915
|
+
}
|
|
5916
|
+
|
|
5917
|
+
.x509-copy p {
|
|
5918
|
+
color: var(--white-60);
|
|
5919
|
+
font-size: 0.95rem;
|
|
5920
|
+
line-height: 1.75;
|
|
5921
|
+
margin-bottom: 14px;
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5924
|
+
.x509-tag-row {
|
|
5925
|
+
display: flex;
|
|
5926
|
+
flex-wrap: wrap;
|
|
5927
|
+
gap: 10px;
|
|
5928
|
+
margin-top: 18px;
|
|
5929
|
+
}
|
|
5930
|
+
|
|
5931
|
+
.x509-tag {
|
|
5932
|
+
display: inline-flex;
|
|
5933
|
+
align-items: center;
|
|
5934
|
+
padding: 7px 12px;
|
|
5935
|
+
border-radius: 999px;
|
|
5936
|
+
background: rgba(255, 255, 255, 0.06);
|
|
5937
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
5938
|
+
color: var(--white-80);
|
|
5939
|
+
font-size: 0.78rem;
|
|
5940
|
+
font-family: var(--font-mono);
|
|
5941
|
+
}
|
|
5942
|
+
|
|
5943
|
+
.x509-flow {
|
|
5944
|
+
margin-bottom: 24px;
|
|
5945
|
+
padding: 28px 24px;
|
|
5946
|
+
}
|
|
5947
|
+
|
|
5948
|
+
.x509-grid {
|
|
5949
|
+
grid-template-columns: repeat(2, 1fr);
|
|
5950
|
+
}
|
|
5951
|
+
|
|
5864
5952
|
@media (max-width: 600px) {
|
|
5865
5953
|
.code-block pre {
|
|
5866
5954
|
padding: 14px;
|
|
@@ -5875,6 +5963,16 @@ a.chain-card:hover {
|
|
|
5875
5963
|
padding-left: 8px;
|
|
5876
5964
|
padding-right: 8px;
|
|
5877
5965
|
}
|
|
5966
|
+
.x509-overview {
|
|
5967
|
+
grid-template-columns: 1fr;
|
|
5968
|
+
padding: 20px;
|
|
5969
|
+
}
|
|
5970
|
+
.x509-copy h3 {
|
|
5971
|
+
font-size: 1.1rem;
|
|
5972
|
+
}
|
|
5973
|
+
.x509-copy p {
|
|
5974
|
+
font-size: 0.88rem;
|
|
5975
|
+
}
|
|
5878
5976
|
}
|
|
5879
5977
|
|
|
5880
5978
|
/* =============================================================================
|
package/styles/widget.css
CHANGED
|
@@ -20,6 +20,13 @@
|
|
|
20
20
|
padding: 0;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/* Button reset — counteract host-page normalize/tachyons leaking into the widget */
|
|
24
|
+
#hd-wallet-ui-container button {
|
|
25
|
+
-webkit-appearance: none;
|
|
26
|
+
appearance: none;
|
|
27
|
+
line-height: inherit;
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
/* Prevent dragging on headings, headers, and links */
|
|
24
31
|
#hd-wallet-ui-container h1, #hd-wallet-ui-container h2, #hd-wallet-ui-container h3, #hd-wallet-ui-container h4, #hd-wallet-ui-container h5, #hd-wallet-ui-container h6, #hd-wallet-ui-container a, #hd-wallet-ui-container button, #hd-wallet-ui-container nav, #hd-wallet-ui-container nav * {
|
|
25
32
|
-webkit-user-drag: none;
|
|
@@ -4930,6 +4937,13 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
|
|
|
4930
4937
|
color: rgba(255, 255, 255, 0.9) !important;
|
|
4931
4938
|
}
|
|
4932
4939
|
|
|
4940
|
+
#hd-wallet-ui-container .vcf-import-actions {
|
|
4941
|
+
display: flex;
|
|
4942
|
+
gap: 10px;
|
|
4943
|
+
justify-content: flex-end;
|
|
4944
|
+
margin-top: 14px;
|
|
4945
|
+
}
|
|
4946
|
+
|
|
4933
4947
|
/* Readonly badge */
|
|
4934
4948
|
#hd-wallet-ui-container .readonly-badge {
|
|
4935
4949
|
font-size: 0.6875rem;
|
|
@@ -4961,6 +4975,10 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
|
|
|
4961
4975
|
#hd-wallet-ui-container .vcard-form-row.address-row {
|
|
4962
4976
|
grid-template-columns: 1fr;
|
|
4963
4977
|
}
|
|
4978
|
+
|
|
4979
|
+
#hd-wallet-ui-container .vcf-import-actions {
|
|
4980
|
+
flex-direction: column;
|
|
4981
|
+
}
|
|
4964
4982
|
|
|
4965
4983
|
#hd-wallet-ui-container .photo-upload-section {
|
|
4966
4984
|
flex-direction: column;
|
|
@@ -5853,6 +5871,76 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
|
|
|
5853
5871
|
display: block;
|
|
5854
5872
|
}
|
|
5855
5873
|
|
|
5874
|
+
#hd-wallet-ui-container .x509-overview {
|
|
5875
|
+
display: grid;
|
|
5876
|
+
grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
|
|
5877
|
+
gap: 24px;
|
|
5878
|
+
padding: 32px;
|
|
5879
|
+
margin-bottom: 24px;
|
|
5880
|
+
align-items: start;
|
|
5881
|
+
}
|
|
5882
|
+
|
|
5883
|
+
#hd-wallet-ui-container .x509-copy {
|
|
5884
|
+
min-width: 0;
|
|
5885
|
+
}
|
|
5886
|
+
|
|
5887
|
+
#hd-wallet-ui-container .x509-eyebrow {
|
|
5888
|
+
display: inline-flex;
|
|
5889
|
+
align-items: center;
|
|
5890
|
+
gap: 8px;
|
|
5891
|
+
padding: 6px 10px;
|
|
5892
|
+
margin-bottom: 14px;
|
|
5893
|
+
border-radius: 999px;
|
|
5894
|
+
background: rgba(96, 165, 250, 0.12);
|
|
5895
|
+
color: #93c5fd;
|
|
5896
|
+
font-size: 0.72rem;
|
|
5897
|
+
font-weight: 600;
|
|
5898
|
+
letter-spacing: 0.08em;
|
|
5899
|
+
text-transform: uppercase;
|
|
5900
|
+
}
|
|
5901
|
+
|
|
5902
|
+
#hd-wallet-ui-container .x509-copy h3 {
|
|
5903
|
+
font-size: 1.35rem;
|
|
5904
|
+
font-weight: 600;
|
|
5905
|
+
line-height: 1.25;
|
|
5906
|
+
margin-bottom: 12px;
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5909
|
+
#hd-wallet-ui-container .x509-copy p {
|
|
5910
|
+
color: var(--white-60);
|
|
5911
|
+
font-size: 0.95rem;
|
|
5912
|
+
line-height: 1.75;
|
|
5913
|
+
margin-bottom: 14px;
|
|
5914
|
+
}
|
|
5915
|
+
|
|
5916
|
+
#hd-wallet-ui-container .x509-tag-row {
|
|
5917
|
+
display: flex;
|
|
5918
|
+
flex-wrap: wrap;
|
|
5919
|
+
gap: 10px;
|
|
5920
|
+
margin-top: 18px;
|
|
5921
|
+
}
|
|
5922
|
+
|
|
5923
|
+
#hd-wallet-ui-container .x509-tag {
|
|
5924
|
+
display: inline-flex;
|
|
5925
|
+
align-items: center;
|
|
5926
|
+
padding: 7px 12px;
|
|
5927
|
+
border-radius: 999px;
|
|
5928
|
+
background: rgba(255, 255, 255, 0.06);
|
|
5929
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
5930
|
+
color: var(--white-80);
|
|
5931
|
+
font-size: 0.78rem;
|
|
5932
|
+
font-family: var(--font-mono);
|
|
5933
|
+
}
|
|
5934
|
+
|
|
5935
|
+
#hd-wallet-ui-container .x509-flow {
|
|
5936
|
+
margin-bottom: 24px;
|
|
5937
|
+
padding: 28px 24px;
|
|
5938
|
+
}
|
|
5939
|
+
|
|
5940
|
+
#hd-wallet-ui-container .x509-grid {
|
|
5941
|
+
grid-template-columns: repeat(2, 1fr);
|
|
5942
|
+
}
|
|
5943
|
+
|
|
5856
5944
|
@media (max-width: 600px) {
|
|
5857
5945
|
#hd-wallet-ui-container .code-block pre {
|
|
5858
5946
|
padding: 14px;
|
|
@@ -5867,6 +5955,16 @@ body:has(#hd-wallet-ui-container .modal.active) #hd-wallet-ui-container .nav-bar
|
|
|
5867
5955
|
padding-left: 8px;
|
|
5868
5956
|
padding-right: 8px;
|
|
5869
5957
|
}
|
|
5958
|
+
#hd-wallet-ui-container .x509-overview {
|
|
5959
|
+
grid-template-columns: 1fr;
|
|
5960
|
+
padding: 20px;
|
|
5961
|
+
}
|
|
5962
|
+
#hd-wallet-ui-container .x509-copy h3 {
|
|
5963
|
+
font-size: 1.1rem;
|
|
5964
|
+
}
|
|
5965
|
+
#hd-wallet-ui-container .x509-copy p {
|
|
5966
|
+
font-size: 0.88rem;
|
|
5967
|
+
}
|
|
5870
5968
|
}
|
|
5871
5969
|
|
|
5872
5970
|
/* =============================================================================
|