Add periodic auto-sync with backend push events, remove refresh button

This commit is contained in:
2026-05-22 12:53:18 +08:00
parent cb55a6fc6b
commit c87e166468
5 changed files with 93 additions and 14 deletions
+53 -4
View File
@@ -195,6 +195,10 @@ type RPC = {
params: {} params: {}
response: void response: void
} }
setAutoSync: {
params: { address: string; chainid: string } | null
response: void
}
fetchTokenBalances: { fetchTokenBalances: {
params: { params: {
address: string address: string
@@ -316,7 +320,13 @@ type RPC = {
}> }>
webview: RPCSchema<{ webview: RPCSchema<{
requests: {} requests: {}
messages: {} messages: {
transfersUpdate: {
count: number
chainid: string
address: string
}
}
}> }>
} }
@@ -419,6 +429,9 @@ function mapTransfer(t: any): TxEntry {
let moneroManager: MoneroWalletManager | null = null let moneroManager: MoneroWalletManager | null = null
let moneroDownloading = false let moneroDownloading = false
let autoSyncTarget: { address: string; chainid: string } | null = null
let autoSyncTimer: ReturnType<typeof setInterval> | null = null
const rpc = BrowserView.defineRPC<RPC>({ const rpc = BrowserView.defineRPC<RPC>({
maxRequestTime: 120000, maxRequestTime: 120000,
handlers: { handlers: {
@@ -614,9 +627,45 @@ const rpc = BrowserView.defineRPC<RPC>({
name: 'alchemy_key', name: 'alchemy_key',
}) })
if (!key) return if (!key) return
syncTransactionHistory(key, chainid, address).catch((e) => try {
console.error('[sync] error:', e), const count = await syncTransactionHistory(
) key,
chainid,
address,
)
rpc.send.transfersUpdate({ count, chainid, address })
} catch (e) {
console.error('[sync] error:', e)
}
},
setAutoSync: async (target) => {
if (autoSyncTimer) clearInterval(autoSyncTimer)
autoSyncTimer = null
autoSyncTarget = null
if (!target) return
autoSyncTarget = target
autoSyncTimer = setInterval(async () => {
if (!autoSyncTarget) return
const key = await Bun.secrets.get({
service: 'koins',
name: 'alchemy_key',
})
if (!key) return
try {
const count = await syncTransactionHistory(
key,
autoSyncTarget.chainid,
autoSyncTarget.address,
)
rpc.send.transfersUpdate({
count,
chainid: autoSyncTarget.chainid,
address: autoSyncTarget.address,
})
} catch (e) {
console.error('[auto-sync] error:', e)
}
}, 30000)
}, },
flushTxCache: async () => { flushTxCache: async () => {
sqlite.run('DELETE FROM tx_history') sqlite.run('DELETE FROM tx_history')
@@ -11,7 +11,7 @@ export const syncTransactionHistory = async (
key: string, key: string,
chainid: string, chainid: string,
address: string, address: string,
) => { ): Promise<number> => {
const addrLower = address.toLowerCase() const addrLower = address.toLowerCase()
const existing = db const existing = db
@@ -39,7 +39,7 @@ export const syncTransactionHistory = async (
}, },
) )
if (!transfers || transfers.length === 0) return if (!transfers || transfers.length === 0) return 0
const prepared: Array<typeof txHistory.$inferInsert> = [] const prepared: Array<typeof txHistory.$inferInsert> = []
let latestBlock = Number(existing?.lastSyncBlock ?? '0') let latestBlock = Number(existing?.lastSyncBlock ?? '0')
@@ -91,6 +91,8 @@ export const syncTransactionHistory = async (
console.log( console.log(
`[sync] ${chainid}/${addrLower}: synced ${prepared.length} transfers up to block ${latestBlock}`, `[sync] ${chainid}/${addrLower}: synced ${prepared.length} transfers up to block ${latestBlock}`,
) )
return prepared.length
} }
function flush(prepared: Array<typeof txHistory.$inferInsert>) { function flush(prepared: Array<typeof txHistory.$inferInsert>) {
@@ -367,12 +367,6 @@
{/if} {/if}
<div class="flex gap-2 flex-wrap"> <div class="flex gap-2 flex-wrap">
<Button onclick={() => w.refresh()} disabled={w.loading}>
{#if w.loading}
<Loader />
{/if}
Refresh
</Button>
<Button <Button
variant="outline" variant="outline"
onclick={() => navigate('/settings')}> onclick={() => navigate('/settings')}>
+12 -2
View File
@@ -98,7 +98,7 @@ export type EvmWalletInfo = {
} }
type RPC = { type RPC = {
bun: { bun: {
requests: { requests: {
resetApp: { resetApp: {
params: {} params: {}
@@ -149,6 +149,10 @@ type RPC = {
params: {} params: {}
response: void response: void
} }
setAutoSync: {
params: { address: string; chainid: string } | null
response: void
}
fetchTokenBalances: { fetchTokenBalances: {
params: { params: {
address: string address: string
@@ -260,7 +264,13 @@ type RPC = {
} }
webview: { webview: {
requests: {} requests: {}
messages: {} messages: {
transfersUpdate: {
count: number
chainid: string
address: string
}
}
} }
} }
@@ -111,6 +111,18 @@ export const EvmWallet = () => {
const init = async () => { const init = async () => {
if (!electrobun.rpc) return if (!electrobun.rpc) return
electrobun.rpc.addMessageListener(
'transfersUpdate',
(payload: { chainid: string; address: string; count: number }) => {
if (
payload.address === address &&
payload.chainid === net().chainid
) {
fetchTxHistory()
}
},
)
const [walletList] = await tryCatch( const [walletList] = await tryCatch(
electrobun.rpc.request.evmListWallets({}), electrobun.rpc.request.evmListWallets({}),
) )
@@ -166,6 +178,7 @@ export const EvmWallet = () => {
transactions = [] transactions = []
error = '' error = ''
currentPasswordHash = null currentPasswordHash = null
electrobun.rpc?.request.setAutoSync(null)
} }
const unlockWallet = async (walletId: string) => { const unlockWallet = async (walletId: string) => {
@@ -181,6 +194,7 @@ export const EvmWallet = () => {
if (!vaultSeed) return false if (!vaultSeed) return false
seed = vaultSeed seed = vaultSeed
await refresh() await refresh()
await setAutoSync()
return true return true
} }
@@ -221,6 +235,7 @@ export const EvmWallet = () => {
if (!vaultSeed) return false if (!vaultSeed) return false
seed = vaultSeed seed = vaultSeed
await refresh() await refresh()
await setAutoSync()
return true return true
} }
@@ -360,6 +375,14 @@ export const EvmWallet = () => {
}) })
} }
const setAutoSync = async () => {
if (!address || !electrobun.rpc) return
electrobun.rpc.request.setAutoSync({
address,
chainid: net().chainid,
})
}
const flushTxCache = async () => { const flushTxCache = async () => {
await electrobun.rpc?.request.flushTxCache({}) await electrobun.rpc?.request.flushTxCache({})
await fetchTxHistory() await fetchTxHistory()
@@ -513,6 +536,7 @@ export const EvmWallet = () => {
deleteWallet, deleteWallet,
clearSelection, clearSelection,
syncTxHistory, syncTxHistory,
setAutoSync,
flushTxCache, flushTxCache,
} }
} }