hide the rescan control on a source that cannot rescan
the card keyed off `sync.rescan` being null, which is what esplora reports — and equally what nbxplorer reports before its first scan. so the guard could not tell "unsupported" from "not yet run" and resolved it the wrong way: every esplora wallet got a button that 501s. canRescan carries the distinction explicitly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -313,6 +313,7 @@ export class OnchainBackend extends BaseBackend {
|
|||||||
syncedAt: this.current?.at ?? null,
|
syncedAt: this.current?.at ?? null,
|
||||||
stale: this.current !== null && Date.now() - this.current.at >= SCAN_TTL_MS,
|
stale: this.current !== null && Date.now() - this.current.at >= SCAN_TTL_MS,
|
||||||
lastError: this.lastError,
|
lastError: this.lastError,
|
||||||
|
canRescan: this.chain.startRescan !== undefined,
|
||||||
rescan: this.chain.rescanState?.() ?? null,
|
rescan: this.chain.rescanState?.() ?? null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,6 +321,14 @@ export type SyncState = {
|
|||||||
stale: boolean;
|
stale: boolean;
|
||||||
/** The last refresh failure, still reported while the previous good data is being served. */
|
/** The last refresh failure, still reported while the previous good data is being served. */
|
||||||
lastError: string | null;
|
lastError: string | null;
|
||||||
|
/**
|
||||||
|
* Whether this chain source can search the chain from scratch at all. False for Esplora, which asks
|
||||||
|
* about every address on every refresh and so has nothing to catch up on.
|
||||||
|
*
|
||||||
|
* Distinct from `rescan === null`, which is ALSO what a source that simply hasn't run one yet reports
|
||||||
|
* — conflating the two put a button that 501s in front of every Esplora wallet.
|
||||||
|
*/
|
||||||
|
canRescan: boolean;
|
||||||
/** A deep rescan in flight, or the outcome of the last one. Null from a source that cannot rescan. */
|
/** A deep rescan in flight, or the outcome of the last one. Null from a source that cannot rescan. */
|
||||||
rescan: RescanState | null;
|
rescan: RescanState | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ export const RescanCard = ({ walletId }: RescanCardProps) => {
|
|||||||
const { sync } = useBalances(walletId);
|
const { sync } = useBalances(walletId);
|
||||||
const { rescan } = useWalletOperations(walletId);
|
const { rescan } = useWalletOperations(walletId);
|
||||||
|
|
||||||
// `sync.rescan` is null from a source with no rescan endpoint AND from one that has simply never run
|
// `sync` null is a node backend, which owns its own coins and has nothing to look for. `canRescan`
|
||||||
// one, so the card has to stay visible in the second case. `sync` itself being null is a node backend,
|
// false is Esplora. Note this cannot key off `sync.rescan` being null — that is equally what NBXplorer
|
||||||
// which owns its own coins and has nothing to look for.
|
// reports before its first scan, which is exactly when the card is most needed.
|
||||||
if (!sync) return null;
|
if (!sync?.canRescan) return null;
|
||||||
|
|
||||||
const state = sync.rescan;
|
const state = sync.rescan;
|
||||||
const running = state?.running === true;
|
const running = state?.running === true;
|
||||||
|
|||||||
@@ -123,6 +123,12 @@ export type SyncState = {
|
|||||||
syncedAt: number | null;
|
syncedAt: number | null;
|
||||||
stale: boolean;
|
stale: boolean;
|
||||||
lastError: string | null;
|
lastError: string | null;
|
||||||
|
/**
|
||||||
|
* Whether the chain source can search the chain from scratch at all — false for Esplora, which reads
|
||||||
|
* every address on every refresh and has nothing to catch up on. Gate the control on this, NOT on
|
||||||
|
* `rescan === null`: that is also what a source reports before its first scan.
|
||||||
|
*/
|
||||||
|
canRescan: boolean;
|
||||||
/** A deep rescan in flight, or the last one's outcome. Null from a chain source that cannot rescan. */
|
/** A deep rescan in flight, or the last one's outcome. Null from a chain source that cannot rescan. */
|
||||||
rescan: RescanState | null;
|
rescan: RescanState | null;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user