Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/extension/src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ExtensionRequester,
ExtensionRouter,
getNamadaRouterId,
initNamadaLatestSyncBlock,
} from "extension";
import { KVPrefix, Ports } from "router";
import { LocalStorage, RevealedPKStorage, VaultStorage } from "storage";
Expand Down Expand Up @@ -56,6 +57,7 @@ const init = new Promise<void>(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();

Expand Down
6 changes: 3 additions & 3 deletions apps/extension/src/background/keyring/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,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;
};
Expand Down
9 changes: 9 additions & 0 deletions apps/extension/src/background/keyring/keyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,15 @@ export class KeyRing {
return Result.ok(null);
}

async queryLastBlock() {
try {
const query = this.sdkService.getSdk().rpc;
return await query.queryLastBlock();
} catch (e) {
console.warn(e);
}
}

async queryBalances(
owner: string,
tokens: string[]
Expand Down
17 changes: 16 additions & 1 deletion apps/extension/src/background/keyring/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,12 +538,27 @@ export class KeyRingService {
return await this.sdkService.getSdk().masp.hasMaspParams();
}

async queryLastBlock(): Promise<number | undefined> {
return await this._keyRing.queryLastBlock();
}

async shieldedSync(): Promise<void> {
const vks = (await this.vaultStorage.findAll(KeyStore))
.filter((a) => a.public.type === AccountType.ShieldedKeys)
.map((a) => a.public.owner);

await this.sdkService.getSdk().rpc.shieldedSync(vks);
const startHeight = (await this.localStorage.getLatestSyncBlock())
?.lastestSyncBlock;
const lastHeight = await this.queryLastBlock();

if (startHeight !== undefined && lastHeight) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this "if" after the shieldedSync call. This way you can be sure that we completed the sync before saving lastBlock info

await this.localStorage.setLatestSyncBlock({
lastestSyncBlock: lastHeight,
});
}

const start_height = startHeight ? BigInt(startHeight) : undefined;
await this.sdkService.getSdk().rpc.shieldedSync(vks, start_height);
}

async queryBalances(
Expand Down
9 changes: 9 additions & 0 deletions apps/extension/src/extension/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ export const getNamadaRouterId = async (
return storedId;
};

export const initNamadaLatestSyncBlock = async (
store: LocalStorage
): Promise<void> => {
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 => {
Expand Down
37 changes: 35 additions & 2 deletions apps/extension/src/storage/LocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,35 @@ type NamadaExtensionApprovedOriginsType = t.TypeOf<
const NamadaExtensionRouterId = t.number;
type NamadaExtensionRouterIdType = t.TypeOf<typeof NamadaExtensionRouterId>;

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<LocalStorageSchemas, LocalStorageKeys>([
[Chain, "chains"],
[NamadaExtensionApprovedOrigins, "namadaExtensionApprovedOrigins"],
[NamadaExtensionRouterId, "namadaExtensionRouterId"],
[NamadaExtensionLatestSyncBlock, "namadaExtensionLatestSyncBlock"],
]);

export class LocalStorage extends ExtStorage {
Expand Down Expand Up @@ -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<void> {
await this.setRaw(
this.getKey(NamadaExtensionLatestSyncBlock),
namadaExtensionLatestSyncBlock
);
}

async getRouterId(): Promise<NamadaExtensionRouterIdType | undefined> {
const data = await this.getRaw(this.getKey(NamadaExtensionRouterId));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<TokenBalance key={`${address}-${token}`}>
Expand Down
4 changes: 2 additions & 2 deletions apps/namada-interface/src/App/Token/TokenSend/TokenSend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/integrations/src/types/Integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ export interface Integration<T, S, U extends string = TokenType> {
owner: string,
tokens?: string[]
) => Promise<TokenBalances<U>>;
sync: (owners: string[]) => Promise<void>;
sync: () => Promise<void>;
}
13 changes: 11 additions & 2 deletions packages/sdk/src/rpc/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,16 @@ export class Rpc {
* @param vks - Array of viewing keys
* @returns
*/
async shieldedSync(vks: string[]): Promise<void> {
await this.query.shielded_sync(vks);
async shieldedSync(vks: string[], start_height?: bigint): Promise<void> {
await this.query.shielded_sync(vks, start_height);
}

/**
* Get the latest block
* @async
* @returns latest block
*/
async queryLastBlock(): Promise<number> {
return Number(await this.query.query_last_block());
}
}
18 changes: 15 additions & 3 deletions packages/shared/lib/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -255,7 +256,18 @@ 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<u64>,
) -> Result<(), JsError> {
let owners: Vec<ViewingKey> = owners
.into_iter()
.filter_map(|owner| owner.as_string())
Expand All @@ -282,7 +294,7 @@ impl Query {
.fetch(
&self.client,
&DefaultLogger::new(&WebIo),
None,
start_height.map(BlockHeight),
None,
1,
&[],
Expand Down