From adfeb835b9d5ece4f116c82b19b76e9ae4c75017 Mon Sep 17 00:00:00 2001 From: huyny-de Date: Tue, 2 Apr 2024 22:20:48 +0700 Subject: [PATCH 1/5] feat: saving last block query for next fetching --- .../src/background/keyring/handler.ts | 19 +++++++++--- apps/extension/src/background/keyring/init.ts | 2 ++ .../src/background/keyring/keyring.ts | 10 ++++++ .../src/background/keyring/service.ts | 22 +++++++++---- apps/extension/src/provider/InjectedNamada.ts | 14 +++++++-- apps/extension/src/provider/Namada.ts | 16 ++++++++-- apps/extension/src/provider/messages.ts | 26 +++++++++++++++- .../DerivedAccounts/DerivedAccounts.tsx | 2 +- .../src/App/Token/TokenSend/TokenSend.tsx | 4 +-- apps/namada-interface/src/slices/accounts.ts | 10 +++++- packages/integrations/src/Namada.ts | 10 ++++-- .../integrations/src/types/Integration.ts | 2 +- packages/shared/lib/src/query.rs | 31 ++++++++++++++++--- packages/types/src/namada.ts | 8 ++++- 14 files changed, 148 insertions(+), 28 deletions(-) diff --git a/apps/extension/src/background/keyring/handler.ts b/apps/extension/src/background/keyring/handler.ts index 48c53b8dae..6776713e20 100644 --- a/apps/extension/src/background/keyring/handler.ts +++ b/apps/extension/src/background/keyring/handler.ts @@ -5,6 +5,7 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, + QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "provider/messages"; @@ -63,6 +64,8 @@ export const getHandler: (service: KeyRingService) => Handler = (service) => { return handleQueryBalancesMsg(service)(env, msg as QueryBalancesMsg); case ShieldedSyncMsg: return handleShieldedSyncMsg(service)(env, msg as ShieldedSyncMsg); + case QueryLastBlocksMsg: + return handleRequestLastBlock(service)(env, msg as QueryLastBlocksMsg); case SetActiveAccountMsg: return handleSetActiveAccountMsg(service)( env, @@ -209,9 +212,9 @@ const handleQueryAccountsMsg: ( const { query } = msg; const output = - query && query.accountId - ? await service.queryAccountById(query.accountId) - : await service.queryAccounts(); + query && query.accountId ? + await service.queryAccountById(query.accountId) + : await service.queryAccounts(); return output; }; @@ -236,8 +239,16 @@ const handleQueryBalancesMsg: ( const handleShieldedSyncMsg: ( service: KeyRingService ) => InternalHandler = (service) => { + return async (_, { startHeight, lastHeight }) => { + return await service.shieldedSync(startHeight, lastHeight); + }; +}; + +const handleRequestLastBlock: ( + service: KeyRingService +) => InternalHandler = (service) => { return async () => { - return await service.shieldedSync(); + return await service.queryLastBlock(); }; }; diff --git a/apps/extension/src/background/keyring/init.ts b/apps/extension/src/background/keyring/init.ts index d36e14013f..838d307180 100644 --- a/apps/extension/src/background/keyring/init.ts +++ b/apps/extension/src/background/keyring/init.ts @@ -5,6 +5,7 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, + QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "provider/messages"; @@ -40,6 +41,7 @@ export function init(router: Router, service: KeyRingService): void { router.registerMessage(QueryDefaultAccountMsg); router.registerMessage(QueryBalancesMsg); router.registerMessage(ShieldedSyncMsg); + router.registerMessage(QueryLastBlocksMsg); router.registerMessage(QueryParentAccountsMsg); router.registerMessage(SaveAccountSecretMsg); router.registerMessage(ScanAccountsMsg); diff --git a/apps/extension/src/background/keyring/keyring.ts b/apps/extension/src/background/keyring/keyring.ts index d4b1321666..ab4a02dc6f 100644 --- a/apps/extension/src/background/keyring/keyring.ts +++ b/apps/extension/src/background/keyring/keyring.ts @@ -907,6 +907,16 @@ export class KeyRing { return Result.ok(null); } + async queryLastBlock() { + try { + const query = await this.sdkService.getQuery(); + const bigInitLastBlock = await query.query_last_block(); + return Number(bigInitLastBlock); + } catch (e) { + console.warn(e); + } + } + async queryBalances( owner: string, tokens: string[] diff --git a/apps/extension/src/background/keyring/service.ts b/apps/extension/src/background/keyring/service.ts index 9c37c1ce61..abde3cbc48 100644 --- a/apps/extension/src/background/keyring/service.ts +++ b/apps/extension/src/background/keyring/service.ts @@ -482,13 +482,23 @@ export class KeyRingService { return Sdk.has_masp_params(); } - async shieldedSync(): Promise { - const vks = (await this.vaultStorage.findAll(KeyStore)) - .filter((a) => a.public.type === AccountType.ShieldedKeys) - .map((a) => a.public.owner); + async shieldedSync(startHeight?: number, lastHeight?: number): Promise { + try { + const vks = (await this.vaultStorage.findAll(KeyStore)) + .filter((a) => a.public.type === AccountType.ShieldedKeys) + .map((a) => a.public.owner); + const start_height = startHeight ? BigInt(startHeight) : undefined; + const last_height = lastHeight ? BigInt(lastHeight) : undefined; + + const query = await this.sdkService.getQuery(); + await query.shielded_sync(vks, start_height, last_height); + } catch (error) { + console.warn(error); + } + } - const query = await this.sdkService.getQuery(); - await query.shielded_sync(vks); + async queryLastBlock(): Promise { + return await this._keyRing.queryLastBlock(); } async queryBalances( diff --git a/apps/extension/src/provider/InjectedNamada.ts b/apps/extension/src/provider/InjectedNamada.ts index b3cc900734..c4de1d61ae 100644 --- a/apps/extension/src/provider/InjectedNamada.ts +++ b/apps/extension/src/provider/InjectedNamada.ts @@ -4,6 +4,7 @@ import { DerivedAccount, Namada as INamada, Signer as ISigner, + ShieldedSyncProps, SignArbitraryProps, SignatureResponse, TxMsgProps, @@ -60,8 +61,17 @@ export class InjectedNamada implements INamada { >("balances", props); } - public async shieldedSync(): Promise { - return await InjectedProxy.requestMethod("shieldedSync"); + public async shieldedSync(props: ShieldedSyncProps): Promise { + return await InjectedProxy.requestMethod( + "shieldedSync", + props + ); + } + + public async queryLastBlock(): Promise { + return await InjectedProxy.requestMethod( + "queryLastBlock" + ); } public async getChain(): Promise { diff --git a/apps/extension/src/provider/Namada.ts b/apps/extension/src/provider/Namada.ts index 7344ee527e..12e4ec0fdb 100644 --- a/apps/extension/src/provider/Namada.ts +++ b/apps/extension/src/provider/Namada.ts @@ -3,6 +3,7 @@ import { Chain, DerivedAccount, Namada as INamada, + ShieldedSyncProps, SignArbitraryProps, SignatureResponse, TxMsgProps, @@ -22,6 +23,7 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, + QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "./messages"; @@ -126,10 +128,20 @@ export class Namada implements INamada { ); } - public async shieldedSync(): Promise { + public async shieldedSync({ + startHeight, + lastHeight, + }: ShieldedSyncProps): Promise { return await this.requester?.sendMessage( Ports.Background, - new ShieldedSyncMsg() + new ShieldedSyncMsg(startHeight, lastHeight) + ); + } + + public async queryLastBlock(): Promise { + return await this.requester?.sendMessage( + Ports.Background, + new QueryLastBlocksMsg() ); } diff --git a/apps/extension/src/provider/messages.ts b/apps/extension/src/provider/messages.ts index f43f15d527..728006ada7 100644 --- a/apps/extension/src/provider/messages.ts +++ b/apps/extension/src/provider/messages.ts @@ -39,6 +39,7 @@ enum MessageType { CheckDurability = "check-durability", ApproveSignArbitrary = "approve-sign-arbitrary", VerifyArbitrary = "verify-arbitrary", + QueryLastBlock = "query-last-block", } /** @@ -173,7 +174,10 @@ export class ShieldedSyncMsg extends Message { return MessageType.ShieldedSync; } - constructor() { + constructor( + public readonly startHeight?: number, + public readonly lastHeight?: number + ) { super(); } @@ -188,6 +192,26 @@ export class ShieldedSyncMsg extends Message { } } +export class QueryLastBlocksMsg extends Message { + public static type(): MessageType { + return MessageType.QueryLastBlock; + } + + constructor() { + super(); + } + + validate(): void {} + + route(): string { + return Route.KeyRing; + } + + type(): string { + return QueryLastBlocksMsg.type(); + } +} + export class QueryDefaultAccountMsg extends Message< DerivedAccount | undefined > { diff --git a/apps/namada-interface/src/App/AccountOverview/DerivedAccounts/DerivedAccounts.tsx b/apps/namada-interface/src/App/AccountOverview/DerivedAccounts/DerivedAccounts.tsx index c9ef6a52bc..9c2c3ac5de 100644 --- a/apps/namada-interface/src/App/AccountOverview/DerivedAccounts/DerivedAccounts.tsx +++ b/apps/namada-interface/src/App/AccountOverview/DerivedAccounts/DerivedAccounts.tsx @@ -142,7 +142,7 @@ const DerivedAccounts = (): JSX.Element => { // Show native token first return tokenType === chain.currency.token ? 1 : -1; }) - .filter(([_, amount]) => amount.isGreaterThan(0)) + .filter(([_, amount]) => amount?.isGreaterThan(0)) .map(([token, amount]) => { return ( diff --git a/apps/namada-interface/src/App/Token/TokenSend/TokenSend.tsx b/apps/namada-interface/src/App/Token/TokenSend/TokenSend.tsx index 94301a50c7..d9fe5a8088 100644 --- a/apps/namada-interface/src/App/Token/TokenSend/TokenSend.tsx +++ b/apps/namada-interface/src/App/Token/TokenSend/TokenSend.tsx @@ -70,11 +70,11 @@ const TokenSend = (): JSX.Element => { const shieldedAccountsWithBalance = accounts.filter( ({ details }) => details.isShielded - ).filter(({ balance }) => Object.values(balance).some((amount) => amount.isGreaterThan(0))); + ).filter(({ balance }) => Object.values(balance).some((amount) => amount?.isGreaterThan(0))); const transparentAccountsWithBalance = accounts.filter( ({ details }) => !details.isShielded - ).filter(({ balance }) => Object.values(balance).some((amount) => amount.isGreaterThan(0))); + ).filter(({ balance }) => Object.values(balance).some((amount) => amount?.isGreaterThan(0))); const shieldedTokenData = accountsWithBalanceIntoSelectData( shieldedAccountsWithBalance diff --git a/apps/namada-interface/src/slices/accounts.ts b/apps/namada-interface/src/slices/accounts.ts index 34d8cc6c7a..a47c477bd5 100644 --- a/apps/namada-interface/src/slices/accounts.ts +++ b/apps/namada-interface/src/slices/accounts.ts @@ -185,6 +185,8 @@ const accountsAtom = (() => { ); })(); +const LATEST_SYNCED_HEIGHT_STORAGE = "latest-synced-height" + const balancesAtom = (() => { const base = atom<{ [address: Address]: TokenBalances }>({}); @@ -223,7 +225,13 @@ const balancesAtom = (() => { set(base, { ...get(base), [address]: balance }); }); - await namada.sync(); + const lastHeight = await namada.queryLastBlock(); + const startHeightStorage = Number(localStorage.getItem(LATEST_SYNCED_HEIGHT_STORAGE)); + const startHeight = startHeightStorage ? startHeightStorage : undefined; + await namada.sync(startHeight,lastHeight); + if(lastHeight){ + localStorage.setItem(LATEST_SYNCED_HEIGHT_STORAGE, lastHeight.toString()) + } const shieldedBalances = await Promise.all( queryBalance(namada, shieldedAccounts, token) diff --git a/packages/integrations/src/Namada.ts b/packages/integrations/src/Namada.ts index a1c10b1663..5e5f075a20 100644 --- a/packages/integrations/src/Namada.ts +++ b/packages/integrations/src/Namada.ts @@ -90,11 +90,15 @@ export default class Namada implements Integration { // TODO: fix this return { - NAM: mapUndefined((amount) => new BigNumber(amount), balances[0].amount), + NAM: mapUndefined((amount) => new BigNumber(amount), balances[0]?.amount), }; } - public async sync(): Promise { - await this._namada?.shieldedSync(); + public async sync(startHeight?: number, lastHeight?: number): Promise { + await this._namada?.shieldedSync({ startHeight, lastHeight }); + } + + public async queryLastBlock(): Promise { + return await this._namada?.queryLastBlock(); } } diff --git a/packages/integrations/src/types/Integration.ts b/packages/integrations/src/types/Integration.ts index a2ef751119..6cf9b02dfe 100644 --- a/packages/integrations/src/types/Integration.ts +++ b/packages/integrations/src/types/Integration.ts @@ -28,5 +28,5 @@ export interface Integration { owner: string, tokens?: string[] ) => Promise>; - sync: (owners: string[]) => Promise; + sync: (startHeight?: number, lastHeight?: number) => Promise; } diff --git a/packages/shared/lib/src/query.rs b/packages/shared/lib/src/query.rs index 7ea23be96f..e97fcd55c8 100644 --- a/packages/shared/lib/src/query.rs +++ b/packages/shared/lib/src/query.rs @@ -18,8 +18,9 @@ use namada::sdk::masp_primitives::zip32::ExtendedFullViewingKey; use namada::sdk::rpc::{ format_denominated_amount, get_public_key_at, get_token_balance, get_total_staked_tokens, query_epoch, query_native_token, query_proposal_by_id, query_proposal_votes, - query_storage_value, + query_storage_value, query_block }; +use namada::storage::BlockHeight; use namada::token; use namada::uint::I256; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -255,7 +256,19 @@ impl Query { Ok(result) } - pub async fn shielded_sync(&self, owners: Box<[JsValue]>) -> Result<(), JsError> { + pub async fn query_last_block(&self) -> u64 { + let last_block_height_opt = query_block(&self.client).await.unwrap(); + let last_block_height = + last_block_height_opt.map_or_else(BlockHeight::first, |block| block.height); + last_block_height.0 + } + + pub async fn shielded_sync( + &self, + owners: Box<[JsValue]>, + start_height: Option, + last_height: Option, + ) -> Result<(), JsError> { let owners: Vec = owners .into_iter() .filter_map(|owner| owner.as_string()) @@ -278,12 +291,22 @@ impl Query { let _ = shielded.save().await?; + let start_query_height = match start_height { + Some(x) => Some(BlockHeight(x)), + None => None + }; + + let last_query_height = match last_height { + Some(x) => Some(BlockHeight(x)), + None => None + }; + shielded .fetch( &self.client, &DefaultLogger::new(&WebIo), - None, - None, + start_query_height, + last_query_height, 1, &[], &owners, diff --git a/packages/types/src/namada.ts b/packages/types/src/namada.ts index 3c23bad47c..5bbe63a8d9 100644 --- a/packages/types/src/namada.ts +++ b/packages/types/src/namada.ts @@ -22,6 +22,11 @@ export type VerifyArbitraryProps = { signature: string; }; +export type ShieldedSyncProps = { + startHeight?: number; + lastHeight?: number; +}; + export type BalancesProps = { owner: string; tokens: string[]; @@ -32,7 +37,8 @@ export interface Namada { balances( props: BalancesProps ): Promise<{ token: string; amount: string }[] | undefined>; - shieldedSync(): Promise; + shieldedSync(props: ShieldedSyncProps): Promise; + queryLastBlock(): Promise; connect(chainId?: string): Promise; isConnected(): Promise; defaultAccount(chainId?: string): Promise; From 1ddfa65668e5e2999cd1447c07f3eab7c1517d90 Mon Sep 17 00:00:00 2001 From: huyny-de Date: Mon, 8 Apr 2024 19:55:52 +0700 Subject: [PATCH 2/5] fix: change save latest block from browser to extension local storage --- apps/extension/src/background/index.ts | 2 + .../src/background/keyring/handler.ts | 4 +- .../src/background/keyring/keyring.ts | 5 +-- .../src/background/keyring/service.ts | 26 ++++++++----- apps/extension/src/extension/utils.ts | 9 +++++ apps/extension/src/provider/InjectedNamada.ts | 8 +--- apps/extension/src/provider/Namada.ts | 8 +--- apps/extension/src/provider/messages.ts | 5 +-- apps/extension/src/storage/LocalStorage.ts | 37 ++++++++++++++++++- apps/namada-interface/src/slices/accounts.ts | 8 +--- packages/integrations/src/Namada.ts | 4 +- packages/sdk/src/rpc/rpc.ts | 17 ++++++--- packages/shared/lib/src/query.rs | 15 +------- packages/types/src/namada.ts | 7 +--- 14 files changed, 89 insertions(+), 66 deletions(-) diff --git a/apps/extension/src/background/index.ts b/apps/extension/src/background/index.ts index a1418bbd65..531b45d86e 100644 --- a/apps/extension/src/background/index.ts +++ b/apps/extension/src/background/index.ts @@ -14,6 +14,7 @@ import { ExtensionRequester, ExtensionRouter, getNamadaRouterId, + initNamadaLatestSyncBlock, } from "extension"; import { KVPrefix, Ports } from "router"; import { LocalStorage, RevealedPKStorage, VaultStorage } from "storage"; @@ -56,6 +57,7 @@ const init = new Promise(async (resolve) => { const requester = new ExtensionRequester(messenger, routerId); const broadcaster = new ExtensionBroadcaster(localStorage, requester); const sdkService = await SdkService.init(localStorage); + await initNamadaLatestSyncBlock(localStorage); const { cryptoMemory } = sdkService.getSdk(); diff --git a/apps/extension/src/background/keyring/handler.ts b/apps/extension/src/background/keyring/handler.ts index 6776713e20..9bbb5603df 100644 --- a/apps/extension/src/background/keyring/handler.ts +++ b/apps/extension/src/background/keyring/handler.ts @@ -239,8 +239,8 @@ const handleQueryBalancesMsg: ( const handleShieldedSyncMsg: ( service: KeyRingService ) => InternalHandler = (service) => { - return async (_, { startHeight, lastHeight }) => { - return await service.shieldedSync(startHeight, lastHeight); + return async (_, {}) => { + return await service.shieldedSync(); }; }; diff --git a/apps/extension/src/background/keyring/keyring.ts b/apps/extension/src/background/keyring/keyring.ts index d02c69651c..df9c989d3c 100644 --- a/apps/extension/src/background/keyring/keyring.ts +++ b/apps/extension/src/background/keyring/keyring.ts @@ -818,9 +818,8 @@ export class KeyRing { async queryLastBlock() { try { - const query = await this.sdkService.getQuery(); - const bigInitLastBlock = await query.query_last_block(); - return Number(bigInitLastBlock); + const query = this.sdkService.getSdk().rpc; + return await query.queryLastBlock(); } catch (e) { console.warn(e); } diff --git a/apps/extension/src/background/keyring/service.ts b/apps/extension/src/background/keyring/service.ts index 56c686d676..d3d92ab1f6 100644 --- a/apps/extension/src/background/keyring/service.ts +++ b/apps/extension/src/background/keyring/service.ts @@ -538,19 +538,27 @@ export class KeyRingService { return await this.sdkService.getSdk().masp.hasMaspParams(); } - async shieldedSync(startHeight?: number, lastHeight?: number): Promise { + async queryLastBlock(): Promise { + return await this._keyRing.queryLastBlock(); + } + + async shieldedSync(): Promise { const vks = (await this.vaultStorage.findAll(KeyStore)) .filter((a) => a.public.type === AccountType.ShieldedKeys) .map((a) => a.public.owner); - const start_height = startHeight ? BigInt(startHeight) : undefined; - const last_height = lastHeight ? BigInt(lastHeight) : undefined; - await this.sdkService - .getSdk() - .rpc.shieldedSync(vks, start_height, last_height); - } - async queryLastBlock(): Promise { - return await this._keyRing.queryLastBlock(); + const startHeight = (await this.localStorage.getLatestSyncBlock()) + ?.lastestSyncBlock; + const lastHeight = await this.queryLastBlock(); + + if (startHeight !== undefined && lastHeight) { + await this.localStorage.setLatestSyncBlock({ + lastestSyncBlock: lastHeight, + }); + } + + const start_height = startHeight ? BigInt(startHeight) : undefined; + await this.sdkService.getSdk().rpc.shieldedSync(vks, start_height); } async queryBalances( diff --git a/apps/extension/src/extension/utils.ts b/apps/extension/src/extension/utils.ts index a79d4a3f70..60968d2080 100644 --- a/apps/extension/src/extension/utils.ts +++ b/apps/extension/src/extension/utils.ts @@ -17,6 +17,15 @@ export const getNamadaRouterId = async ( return storedId; }; +export const initNamadaLatestSyncBlock = async ( + store: LocalStorage +): Promise => { + const latestBlock = await store.getLatestSyncBlock(); + if (!latestBlock) { + await store.setLatestSyncBlock({ lastestSyncBlock: 0 }); + } +}; + // Determine if content-scripts can be executed in this environment export class ContentScriptEnv { static readonly produceEnv = (sender: MessageSender): Env => { diff --git a/apps/extension/src/provider/InjectedNamada.ts b/apps/extension/src/provider/InjectedNamada.ts index c4de1d61ae..cd028c6627 100644 --- a/apps/extension/src/provider/InjectedNamada.ts +++ b/apps/extension/src/provider/InjectedNamada.ts @@ -4,7 +4,6 @@ import { DerivedAccount, Namada as INamada, Signer as ISigner, - ShieldedSyncProps, SignArbitraryProps, SignatureResponse, TxMsgProps, @@ -61,11 +60,8 @@ export class InjectedNamada implements INamada { >("balances", props); } - public async shieldedSync(props: ShieldedSyncProps): Promise { - return await InjectedProxy.requestMethod( - "shieldedSync", - props - ); + public async shieldedSync(): Promise { + return await InjectedProxy.requestMethod("shieldedSync"); } public async queryLastBlock(): Promise { diff --git a/apps/extension/src/provider/Namada.ts b/apps/extension/src/provider/Namada.ts index 12e4ec0fdb..2d99238992 100644 --- a/apps/extension/src/provider/Namada.ts +++ b/apps/extension/src/provider/Namada.ts @@ -3,7 +3,6 @@ import { Chain, DerivedAccount, Namada as INamada, - ShieldedSyncProps, SignArbitraryProps, SignatureResponse, TxMsgProps, @@ -128,13 +127,10 @@ export class Namada implements INamada { ); } - public async shieldedSync({ - startHeight, - lastHeight, - }: ShieldedSyncProps): Promise { + public async shieldedSync(): Promise { return await this.requester?.sendMessage( Ports.Background, - new ShieldedSyncMsg(startHeight, lastHeight) + new ShieldedSyncMsg() ); } diff --git a/apps/extension/src/provider/messages.ts b/apps/extension/src/provider/messages.ts index a653e1cff0..c69bd03e95 100644 --- a/apps/extension/src/provider/messages.ts +++ b/apps/extension/src/provider/messages.ts @@ -174,10 +174,7 @@ export class ShieldedSyncMsg extends Message { return MessageType.ShieldedSync; } - constructor( - public readonly startHeight?: number, - public readonly lastHeight?: number - ) { + constructor() { super(); } diff --git a/apps/extension/src/storage/LocalStorage.ts b/apps/extension/src/storage/LocalStorage.ts index 6227574a38..96abb7993a 100644 --- a/apps/extension/src/storage/LocalStorage.ts +++ b/apps/extension/src/storage/LocalStorage.ts @@ -61,26 +61,35 @@ type NamadaExtensionApprovedOriginsType = t.TypeOf< const NamadaExtensionRouterId = t.number; type NamadaExtensionRouterIdType = t.TypeOf; +const NamadaExtensionLatestSyncBlock = t.type({ lastestSyncBlock: t.number }); +type NamadaExtensionLatestBlockType = t.TypeOf< + typeof NamadaExtensionLatestSyncBlock +>; + type LocalStorageTypes = | ChainType | NamadaExtensionApprovedOriginsType - | NamadaExtensionRouterIdType; + | NamadaExtensionRouterIdType + | NamadaExtensionLatestBlockType; type LocalStorageSchemas = | typeof Chain | typeof NamadaExtensionApprovedOrigins - | typeof NamadaExtensionRouterId; + | typeof NamadaExtensionRouterId + | typeof NamadaExtensionLatestSyncBlock; export type LocalStorageKeys = | "chains" | "namadaExtensionApprovedOrigins" | "namadaExtensionRouterId" + | "namadaExtensionLatestSyncBlock" | "tabs"; const schemasMap = new Map([ [Chain, "chains"], [NamadaExtensionApprovedOrigins, "namadaExtensionApprovedOrigins"], [NamadaExtensionRouterId, "namadaExtensionRouterId"], + [NamadaExtensionLatestSyncBlock, "namadaExtensionLatestSyncBlock"], ]); export class LocalStorage extends ExtStorage { @@ -132,6 +141,30 @@ export class LocalStorage extends ExtStorage { ); } + async getLatestSyncBlock(): Promise< + NamadaExtensionLatestBlockType | undefined + > { + const data = await this.getRaw(this.getKey(NamadaExtensionLatestSyncBlock)); + + const Schema = t.union([NamadaExtensionLatestSyncBlock, t.undefined]); + const decodedData = Schema.decode(data); + + if (E.isLeft(decodedData)) { + throw new Error("Latest block is not valid"); + } + + return decodedData.right; + } + + async setLatestSyncBlock( + namadaExtensionLatestSyncBlock: NamadaExtensionLatestBlockType + ): Promise { + await this.setRaw( + this.getKey(NamadaExtensionLatestSyncBlock), + namadaExtensionLatestSyncBlock + ); + } + async getRouterId(): Promise { const data = await this.getRaw(this.getKey(NamadaExtensionRouterId)); diff --git a/apps/namada-interface/src/slices/accounts.ts b/apps/namada-interface/src/slices/accounts.ts index a47c477bd5..b7119e791c 100644 --- a/apps/namada-interface/src/slices/accounts.ts +++ b/apps/namada-interface/src/slices/accounts.ts @@ -185,7 +185,6 @@ const accountsAtom = (() => { ); })(); -const LATEST_SYNCED_HEIGHT_STORAGE = "latest-synced-height" const balancesAtom = (() => { const base = atom<{ [address: Address]: TokenBalances }>({}); @@ -226,12 +225,7 @@ const balancesAtom = (() => { }); const lastHeight = await namada.queryLastBlock(); - const startHeightStorage = Number(localStorage.getItem(LATEST_SYNCED_HEIGHT_STORAGE)); - const startHeight = startHeightStorage ? startHeightStorage : undefined; - await namada.sync(startHeight,lastHeight); - if(lastHeight){ - localStorage.setItem(LATEST_SYNCED_HEIGHT_STORAGE, lastHeight.toString()) - } + await namada.sync(); const shieldedBalances = await Promise.all( queryBalance(namada, shieldedAccounts, token) diff --git a/packages/integrations/src/Namada.ts b/packages/integrations/src/Namada.ts index d1dc5990af..e251622b69 100644 --- a/packages/integrations/src/Namada.ts +++ b/packages/integrations/src/Namada.ts @@ -97,8 +97,8 @@ export default class Namada implements Integration { }; } - public async sync(startHeight?: number, lastHeight?: number): Promise { - await this._namada?.shieldedSync({ startHeight, lastHeight }); + public async sync(): Promise { + await this._namada?.shieldedSync(); } public async queryLastBlock(): Promise { diff --git a/packages/sdk/src/rpc/rpc.ts b/packages/sdk/src/rpc/rpc.ts index 1084337dd9..3a50b497ca 100644 --- a/packages/sdk/src/rpc/rpc.ts +++ b/packages/sdk/src/rpc/rpc.ts @@ -218,11 +218,16 @@ export class Rpc { * @param vks - Array of viewing keys * @returns */ - async shieldedSync( - vks: string[], - start_height?: bigint, - last_height?: bigint - ): Promise { - await this.query.shielded_sync(vks, start_height, last_height); + async shieldedSync(vks: string[], start_height?: bigint): Promise { + await this.query.shielded_sync(vks, start_height); + } + + /** + * Get the latest block + * @async + * @returns latest block + */ + async queryLastBlock(): Promise { + return Number(await this.query.query_last_block()); } } diff --git a/packages/shared/lib/src/query.rs b/packages/shared/lib/src/query.rs index d726d239c4..34c868bc47 100644 --- a/packages/shared/lib/src/query.rs +++ b/packages/shared/lib/src/query.rs @@ -267,7 +267,6 @@ impl Query { &self, owners: Box<[JsValue]>, start_height: Option, - last_height: Option, ) -> Result<(), JsError> { let owners: Vec = owners .into_iter() @@ -291,22 +290,12 @@ impl Query { let _ = shielded.save().await?; - let start_query_height = match start_height { - Some(x) => Some(BlockHeight(x)), - None => None - }; - - let last_query_height = match last_height { - Some(x) => Some(BlockHeight(x)), - None => None - }; - shielded .fetch( &self.client, &DefaultLogger::new(&WebIo), - start_query_height, - last_query_height, + start_height.map(BlockHeight), + None, 1, &[], &owners, diff --git a/packages/types/src/namada.ts b/packages/types/src/namada.ts index 5bbe63a8d9..90af195a9e 100644 --- a/packages/types/src/namada.ts +++ b/packages/types/src/namada.ts @@ -22,11 +22,6 @@ export type VerifyArbitraryProps = { signature: string; }; -export type ShieldedSyncProps = { - startHeight?: number; - lastHeight?: number; -}; - export type BalancesProps = { owner: string; tokens: string[]; @@ -37,7 +32,7 @@ export interface Namada { balances( props: BalancesProps ): Promise<{ token: string; amount: string }[] | undefined>; - shieldedSync(props: ShieldedSyncProps): Promise; + shieldedSync(): Promise; queryLastBlock(): Promise; connect(chainId?: string): Promise; isConnected(): Promise; From b7c5c33c5de21ac9f516a72463c86ea53f2695f3 Mon Sep 17 00:00:00 2001 From: huyny-de Date: Mon, 8 Apr 2024 20:03:58 +0700 Subject: [PATCH 3/5] fix: clean code --- .../src/background/keyring/handler.ts | 11 ---------- apps/extension/src/background/keyring/init.ts | 2 -- apps/extension/src/provider/InjectedNamada.ts | 6 ------ apps/extension/src/provider/Namada.ts | 8 ------- apps/extension/src/provider/messages.ts | 21 ------------------- apps/namada-interface/src/slices/accounts.ts | 1 - packages/integrations/src/Namada.ts | 4 ---- packages/types/src/namada.ts | 1 - 8 files changed, 54 deletions(-) diff --git a/apps/extension/src/background/keyring/handler.ts b/apps/extension/src/background/keyring/handler.ts index 9bbb5603df..2edffcc8f0 100644 --- a/apps/extension/src/background/keyring/handler.ts +++ b/apps/extension/src/background/keyring/handler.ts @@ -5,7 +5,6 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, - QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "provider/messages"; @@ -64,8 +63,6 @@ export const getHandler: (service: KeyRingService) => Handler = (service) => { return handleQueryBalancesMsg(service)(env, msg as QueryBalancesMsg); case ShieldedSyncMsg: return handleShieldedSyncMsg(service)(env, msg as ShieldedSyncMsg); - case QueryLastBlocksMsg: - return handleRequestLastBlock(service)(env, msg as QueryLastBlocksMsg); case SetActiveAccountMsg: return handleSetActiveAccountMsg(service)( env, @@ -244,14 +241,6 @@ const handleShieldedSyncMsg: ( }; }; -const handleRequestLastBlock: ( - service: KeyRingService -) => InternalHandler = (service) => { - return async () => { - return await service.queryLastBlock(); - }; -}; - const handleQueryParentAccountsMsg: ( service: KeyRingService ) => InternalHandler = (service) => { diff --git a/apps/extension/src/background/keyring/init.ts b/apps/extension/src/background/keyring/init.ts index 838d307180..d36e14013f 100644 --- a/apps/extension/src/background/keyring/init.ts +++ b/apps/extension/src/background/keyring/init.ts @@ -5,7 +5,6 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, - QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "provider/messages"; @@ -41,7 +40,6 @@ export function init(router: Router, service: KeyRingService): void { router.registerMessage(QueryDefaultAccountMsg); router.registerMessage(QueryBalancesMsg); router.registerMessage(ShieldedSyncMsg); - router.registerMessage(QueryLastBlocksMsg); router.registerMessage(QueryParentAccountsMsg); router.registerMessage(SaveAccountSecretMsg); router.registerMessage(ScanAccountsMsg); diff --git a/apps/extension/src/provider/InjectedNamada.ts b/apps/extension/src/provider/InjectedNamada.ts index cd028c6627..b3cc900734 100644 --- a/apps/extension/src/provider/InjectedNamada.ts +++ b/apps/extension/src/provider/InjectedNamada.ts @@ -64,12 +64,6 @@ export class InjectedNamada implements INamada { return await InjectedProxy.requestMethod("shieldedSync"); } - public async queryLastBlock(): Promise { - return await InjectedProxy.requestMethod( - "queryLastBlock" - ); - } - public async getChain(): Promise { return await InjectedProxy.requestMethod("getChain"); } diff --git a/apps/extension/src/provider/Namada.ts b/apps/extension/src/provider/Namada.ts index 2d99238992..7344ee527e 100644 --- a/apps/extension/src/provider/Namada.ts +++ b/apps/extension/src/provider/Namada.ts @@ -22,7 +22,6 @@ import { QueryAccountsMsg, QueryBalancesMsg, QueryDefaultAccountMsg, - QueryLastBlocksMsg, ShieldedSyncMsg, VerifyArbitraryMsg, } from "./messages"; @@ -134,13 +133,6 @@ export class Namada implements INamada { ); } - public async queryLastBlock(): Promise { - return await this.requester?.sendMessage( - Ports.Background, - new QueryLastBlocksMsg() - ); - } - public async submitTx(props: TxMsgProps): Promise { return await this.requester?.sendMessage( Ports.Background, diff --git a/apps/extension/src/provider/messages.ts b/apps/extension/src/provider/messages.ts index c69bd03e95..6476c77527 100644 --- a/apps/extension/src/provider/messages.ts +++ b/apps/extension/src/provider/messages.ts @@ -39,7 +39,6 @@ enum MessageType { CheckDurability = "check-durability", ApproveSignArbitrary = "approve-sign-arbitrary", VerifyArbitrary = "verify-arbitrary", - QueryLastBlock = "query-last-block", } /** @@ -189,26 +188,6 @@ export class ShieldedSyncMsg extends Message { } } -export class QueryLastBlocksMsg extends Message { - public static type(): MessageType { - return MessageType.QueryLastBlock; - } - - constructor() { - super(); - } - - validate(): void {} - - route(): string { - return Route.KeyRing; - } - - type(): string { - return QueryLastBlocksMsg.type(); - } -} - export class QueryDefaultAccountMsg extends Message< DerivedAccount | undefined > { diff --git a/apps/namada-interface/src/slices/accounts.ts b/apps/namada-interface/src/slices/accounts.ts index b7119e791c..d9c25cb16f 100644 --- a/apps/namada-interface/src/slices/accounts.ts +++ b/apps/namada-interface/src/slices/accounts.ts @@ -224,7 +224,6 @@ const balancesAtom = (() => { set(base, { ...get(base), [address]: balance }); }); - const lastHeight = await namada.queryLastBlock(); await namada.sync(); const shieldedBalances = await Promise.all( diff --git a/packages/integrations/src/Namada.ts b/packages/integrations/src/Namada.ts index e251622b69..ea1ba1563f 100644 --- a/packages/integrations/src/Namada.ts +++ b/packages/integrations/src/Namada.ts @@ -100,8 +100,4 @@ export default class Namada implements Integration { public async sync(): Promise { await this._namada?.shieldedSync(); } - - public async queryLastBlock(): Promise { - return await this._namada?.queryLastBlock(); - } } diff --git a/packages/types/src/namada.ts b/packages/types/src/namada.ts index 90af195a9e..3c23bad47c 100644 --- a/packages/types/src/namada.ts +++ b/packages/types/src/namada.ts @@ -33,7 +33,6 @@ export interface Namada { props: BalancesProps ): Promise<{ token: string; amount: string }[] | undefined>; shieldedSync(): Promise; - queryLastBlock(): Promise; connect(chainId?: string): Promise; isConnected(): Promise; defaultAccount(chainId?: string): Promise; From 14970844a6549b91ca022c0eb08539ed32df78c4 Mon Sep 17 00:00:00 2001 From: huyny-de Date: Mon, 8 Apr 2024 20:06:34 +0700 Subject: [PATCH 4/5] fix: remove redundant code --- apps/extension/src/background/keyring/handler.ts | 2 +- apps/namada-interface/src/slices/accounts.ts | 1 - packages/integrations/src/types/Integration.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/extension/src/background/keyring/handler.ts b/apps/extension/src/background/keyring/handler.ts index 2edffcc8f0..08898e3237 100644 --- a/apps/extension/src/background/keyring/handler.ts +++ b/apps/extension/src/background/keyring/handler.ts @@ -236,7 +236,7 @@ const handleQueryBalancesMsg: ( const handleShieldedSyncMsg: ( service: KeyRingService ) => InternalHandler = (service) => { - return async (_, {}) => { + return async () => { return await service.shieldedSync(); }; }; diff --git a/apps/namada-interface/src/slices/accounts.ts b/apps/namada-interface/src/slices/accounts.ts index d9c25cb16f..34d8cc6c7a 100644 --- a/apps/namada-interface/src/slices/accounts.ts +++ b/apps/namada-interface/src/slices/accounts.ts @@ -185,7 +185,6 @@ const accountsAtom = (() => { ); })(); - const balancesAtom = (() => { const base = atom<{ [address: Address]: TokenBalances }>({}); diff --git a/packages/integrations/src/types/Integration.ts b/packages/integrations/src/types/Integration.ts index 6cf9b02dfe..2694d0e7f9 100644 --- a/packages/integrations/src/types/Integration.ts +++ b/packages/integrations/src/types/Integration.ts @@ -28,5 +28,5 @@ export interface Integration { owner: string, tokens?: string[] ) => Promise>; - sync: (startHeight?: number, lastHeight?: number) => Promise; + sync: () => Promise; } From 6569356a5f85c465673ab0906f27e11aa522e3c2 Mon Sep 17 00:00:00 2001 From: huyny-de Date: Tue, 9 Apr 2024 16:21:52 +0700 Subject: [PATCH 5/5] fix: fix lint and logic save latest block --- apps/extension/src/background/keyring/keyring.ts | 3 ++- apps/extension/src/background/keyring/service.ts | 7 +++---- packages/sdk/src/rpc/rpc.ts | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/extension/src/background/keyring/keyring.ts b/apps/extension/src/background/keyring/keyring.ts index df9c989d3c..9eb73c7786 100644 --- a/apps/extension/src/background/keyring/keyring.ts +++ b/apps/extension/src/background/keyring/keyring.ts @@ -816,12 +816,13 @@ export class KeyRing { return Result.ok(null); } - async queryLastBlock() { + async queryLastBlock(): Promise { try { const query = this.sdkService.getSdk().rpc; return await query.queryLastBlock(); } catch (e) { console.warn(e); + return NaN; } } diff --git a/apps/extension/src/background/keyring/service.ts b/apps/extension/src/background/keyring/service.ts index d3d92ab1f6..fe7a095678 100644 --- a/apps/extension/src/background/keyring/service.ts +++ b/apps/extension/src/background/keyring/service.ts @@ -538,7 +538,7 @@ export class KeyRingService { return await this.sdkService.getSdk().masp.hasMaspParams(); } - async queryLastBlock(): Promise { + async queryLastBlock(): Promise { return await this._keyRing.queryLastBlock(); } @@ -550,15 +550,14 @@ export class KeyRingService { const startHeight = (await this.localStorage.getLatestSyncBlock()) ?.lastestSyncBlock; const lastHeight = await this.queryLastBlock(); + const start_height = startHeight ? BigInt(startHeight) : undefined; + await this.sdkService.getSdk().rpc.shieldedSync(vks, start_height); if (startHeight !== undefined && lastHeight) { await this.localStorage.setLatestSyncBlock({ lastestSyncBlock: lastHeight, }); } - - const start_height = startHeight ? BigInt(startHeight) : undefined; - await this.sdkService.getSdk().rpc.shieldedSync(vks, start_height); } async queryBalances( diff --git a/packages/sdk/src/rpc/rpc.ts b/packages/sdk/src/rpc/rpc.ts index 3a50b497ca..535ebebdb9 100644 --- a/packages/sdk/src/rpc/rpc.ts +++ b/packages/sdk/src/rpc/rpc.ts @@ -216,6 +216,7 @@ export class Rpc { * Sync the shielded context * @async * @param vks - Array of viewing keys + * @param start_height - Bigint epoch height to start syncing from * @returns */ async shieldedSync(vks: string[], start_height?: bigint): Promise {