hd-wallet-ui 1.2.3 → 1.2.5
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 +37 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hd-wallet-ui",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
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.5",
|
|
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
|
@@ -204,6 +204,9 @@ async function p384GenerateKeyPairAsync() {
|
|
|
204
204
|
// State
|
|
205
205
|
// =============================================================================
|
|
206
206
|
|
|
207
|
+
// Integration callback — set via options.onLogin in createWalletUI / init
|
|
208
|
+
let _onLoginCallback = null;
|
|
209
|
+
|
|
207
210
|
const state = {
|
|
208
211
|
initialized: false,
|
|
209
212
|
loggedIn: false,
|
|
@@ -2375,6 +2378,27 @@ function login(keys) {
|
|
|
2375
2378
|
state.addresses = deriveAllAddressesFromHD();
|
|
2376
2379
|
state.selectedCrypto = 'btc';
|
|
2377
2380
|
|
|
2381
|
+
// Fire onLogin callback with SDN identity (coin type 1957 — Sputnik)
|
|
2382
|
+
if (_onLoginCallback && state.hdRoot) {
|
|
2383
|
+
try {
|
|
2384
|
+
const sdnSigning = getSigningKey(state.hdRoot, 1957, 0, 0);
|
|
2385
|
+
const sdnPubKey = ed25519.getPublicKey(sdnSigning.privateKey);
|
|
2386
|
+
const xpub = state.hdRoot.toXpub();
|
|
2387
|
+
_onLoginCallback({
|
|
2388
|
+
xpub,
|
|
2389
|
+
signingPublicKey: sdnPubKey,
|
|
2390
|
+
async sign(message) {
|
|
2391
|
+
const msgBytes = typeof message === 'string'
|
|
2392
|
+
? new TextEncoder().encode(message)
|
|
2393
|
+
: message;
|
|
2394
|
+
return ed25519.sign(msgBytes, sdnSigning.privateKey);
|
|
2395
|
+
},
|
|
2396
|
+
});
|
|
2397
|
+
} catch (err) {
|
|
2398
|
+
console.error('onLogin callback error:', err);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2378
2402
|
// Close login modal if open
|
|
2379
2403
|
$('login-modal')?.classList.remove('active');
|
|
2380
2404
|
|
|
@@ -3347,11 +3371,16 @@ function parseAndDisplayVCF(vcfText) {
|
|
|
3347
3371
|
if (!resultEl || !fieldsEl) return;
|
|
3348
3372
|
|
|
3349
3373
|
if (photoEl) {
|
|
3350
|
-
|
|
3351
|
-
? `<img src="${photo}" alt="Contact photo">`
|
|
3352
|
-
: `<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">
|
|
3353
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"/>
|
|
3354
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
|
+
}
|
|
3355
3384
|
}
|
|
3356
3385
|
|
|
3357
3386
|
let html = '';
|
|
@@ -4163,6 +4192,7 @@ function setupMainAppHandlers() {
|
|
|
4163
4192
|
const img = document.createElement('img');
|
|
4164
4193
|
img.src = dataUrl;
|
|
4165
4194
|
img.alt = 'Photo';
|
|
4195
|
+
img.onerror = () => { img.remove(); resetPhotoPreview(); };
|
|
4166
4196
|
preview.appendChild(img);
|
|
4167
4197
|
const removeBtn = $('vcard-photo-remove');
|
|
4168
4198
|
if (removeBtn) removeBtn.style.display = '';
|
|
@@ -5224,9 +5254,10 @@ function setupHomepageHandlers() {
|
|
|
5224
5254
|
// =============================================================================
|
|
5225
5255
|
|
|
5226
5256
|
export async function init(rootElement, options = {}) {
|
|
5227
|
-
const { autoOpenWallet = false } = typeof rootElement === 'object' && !(rootElement instanceof Node)
|
|
5257
|
+
const { autoOpenWallet = false, onLogin = null } = typeof rootElement === 'object' && !(rootElement instanceof Node)
|
|
5228
5258
|
? (options = rootElement, {}) : options;
|
|
5229
5259
|
if (rootElement && rootElement instanceof Node) _root = rootElement;
|
|
5260
|
+
if (typeof onLogin === 'function') _onLoginCallback = onLogin;
|
|
5230
5261
|
|
|
5231
5262
|
// Inject modal HTML if not already present in the DOM
|
|
5232
5263
|
if (!document.getElementById('keys-modal')) {
|
|
@@ -5337,6 +5368,8 @@ export async function init(rootElement, options = {}) {
|
|
|
5337
5368
|
*
|
|
5338
5369
|
* @param {Node} [rootElement] - Optional root element for DOM queries
|
|
5339
5370
|
* @param {Object} [options] - Options passed to init()
|
|
5371
|
+
* @param {Function} [options.onLogin] - Callback fired after successful login with
|
|
5372
|
+
* `{ xpub, signingPublicKey, sign(message) }` for SDN identity (coin type 1957)
|
|
5340
5373
|
* @returns {Promise<{openLogin: Function, openAccount: Function, destroy: Function}>}
|
|
5341
5374
|
*/
|
|
5342
5375
|
export async function createWalletUI(rootElement, options = {}) {
|