aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.js12
-rw-r--r--src/wallet.js13
2 files changed, 18 insertions, 7 deletions
diff --git a/src/app.js b/src/app.js
index ce8ee13..9c79ac4 100644
--- a/src/app.js
+++ b/src/app.js
@@ -542,7 +542,7 @@ function createPane() {
),
h(
'button',
- { class: 'btn-block', onClick: () => openWallet(ui.draftMnemonic) },
+ { class: 'btn-block', onClick: () => openWallet(ui.draftMnemonic, { generated: true }) },
t('skipVerification')
)
);
@@ -595,11 +595,11 @@ function createPane() {
if (hasPass && ui.confirmPass !== ui.passphrase) {
ui.unlockError = t('passphraseMismatch'); render(); return;
}
- openWallet(ui.draftMnemonic);
+ openWallet(ui.draftMnemonic, { generated: true });
},
}, t('openWallet'))
),
- h('button', { class: 'btn-block', onClick: () => openWallet(ui.draftMnemonic) }, t('skipVerification'))
+ h('button', { class: 'btn-block', onClick: () => openWallet(ui.draftMnemonic, { generated: true }) }, t('skipVerification'))
);
}
@@ -657,11 +657,11 @@ function optionsPanel() {
// Import accepts a recovery phrase, an xpub/zpub (watch-only), or an xprv/zprv
// (full spending). Classify the pasted text and open the right kind of wallet.
-async function openWallet(input) {
+async function openWallet(input, opts = {}) {
ui.unlockError = '';
const raw = (input || '').trim();
const m = raw.replace(/\s+/g, ' ');
- if (isValidMnemonic(m)) { await enterWallet(m, ui.passphrase); return; }
+ if (isValidMnemonic(m)) { await enterWallet(m, ui.passphrase, { generated: opts.generated }); return; }
let pk;
try { pk = parseExtendedKey(raw); } catch { ui.unlockError = t('invalidImport'); render(); return; }
const acc = pk.kind === 'xpub'
@@ -693,7 +693,7 @@ async function activateAccount(acc, opts = {}) {
const netName = getNetwork();
if (acc.type === 'watch') wallet.load({ xpub: acc.xpub, netName, offline: false });
else if (acc.xprv) wallet.load({ xprv: acc.xprv, netName, offline: false });
- else wallet.load({ mnemonic: acc.mnemonic, passphrase: acc.passphrase || '', netName, offline: false });
+ else wallet.load({ mnemonic: acc.mnemonic, passphrase: acc.passphrase || '', netName, offline: false, spFresh: !!opts.generated });
// Record the account-level xpub so this wallet survives a session wipe as a
// watch-only entry (see the durable account directory) — you keep seeing your
// balance/history and re-enter the seed to spend again.
diff --git a/src/wallet.js b/src/wallet.js
index 2f9cca5..497b60b 100644
--- a/src/wallet.js
+++ b/src/wallet.js
@@ -158,8 +158,11 @@ export class Wallet {
}
// --- setup --------------------------------------------------------------
- load({ mnemonic = '', passphrase = '', xpub = '', xprv = '', netName = 'mainnet', offline = false }) {
+ load({ mnemonic = '', passphrase = '', xpub = '', xprv = '', netName = 'mainnet', offline = false, spFresh = false }) {
this.stopRealtime();
+ // A freshly-generated wallet can't have received silent payments before it
+ // existed, so we start its SP watermark at the current tip (no history scan).
+ this._spFresh = spFresh;
this.mnemonic = (mnemonic || '').trim().replace(/\s+/g, ' ');
this.passphrase = passphrase;
this.xpub = xpub || '';
@@ -377,6 +380,14 @@ export class Wallet {
const indexer = spIndexerUrl(this.netName);
if (!keys || !indexer || this.offline) return { unavailable: true };
if (this._spScanBusy) return { busy: true };
+ // Fresh wallet, never scanned: set the watermark to the current tip instead of
+ // scanning all history (nothing predates the wallet). New blocks + mempool
+ // arrive via the live push from here on.
+ if (this._spFresh && !this.lastSpScan && !rescan) {
+ this._spFresh = false;
+ try { this.lastSpScan = (await (await fetch(`${indexer}/height`)).json()).height || 0; this.saveCache(); } catch {}
+ return { fresh: true };
+ }
this._spScanBusy = true;
// Only a manual scan shows the visible "Scanning…" state; auto-scans are
// invisible (setting spScanning for them left the card stuck on "Scanning…").