Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
19 changes: 15 additions & 4 deletions apps/extension/src/background/keyring/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
QueryAccountsMsg,
QueryBalancesMsg,
QueryDefaultAccountMsg,
QueryLastBlocksMsg,
ShieldedSyncMsg,
VerifyArbitraryMsg,
} from "provider/messages";
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
};
Expand All @@ -236,8 +239,16 @@ const handleQueryBalancesMsg: (
const handleShieldedSyncMsg: (
service: KeyRingService
) => InternalHandler<ShieldedSyncMsg> = (service) => {
return async (_, { startHeight, lastHeight }) => {
return await service.shieldedSync(startHeight, lastHeight);
};
};

const handleRequestLastBlock: (
service: KeyRingService
) => InternalHandler<QueryLastBlocksMsg> = (service) => {
return async () => {
return await service.shieldedSync();
return await service.queryLastBlock();
};
};

Expand Down
2 changes: 2 additions & 0 deletions apps/extension/src/background/keyring/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
QueryAccountsMsg,
QueryBalancesMsg,
QueryDefaultAccountMsg,
QueryLastBlocksMsg,
ShieldedSyncMsg,
VerifyArbitraryMsg,
} from "provider/messages";
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions apps/extension/src/background/keyring/keyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
Expand Down
22 changes: 16 additions & 6 deletions apps/extension/src/background/keyring/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,13 +482,23 @@ export class KeyRingService {
return Sdk.has_masp_params();
}

async shieldedSync(): Promise<void> {
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<void> {
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<number | undefined> {
return await this._keyRing.queryLastBlock();
}

async queryBalances(
Expand Down
14 changes: 12 additions & 2 deletions apps/extension/src/provider/InjectedNamada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DerivedAccount,
Namada as INamada,
Signer as ISigner,
ShieldedSyncProps,
SignArbitraryProps,
SignatureResponse,
TxMsgProps,
Expand Down Expand Up @@ -60,8 +61,17 @@ export class InjectedNamada implements INamada {
>("balances", props);
}

public async shieldedSync(): Promise<void> {
return await InjectedProxy.requestMethod<void, void>("shieldedSync");
public async shieldedSync(props: ShieldedSyncProps): Promise<void> {
return await InjectedProxy.requestMethod<ShieldedSyncProps, void>(
"shieldedSync",
props
);
}

public async queryLastBlock(): Promise<number | undefined> {
return await InjectedProxy.requestMethod<void, number | undefined>(
"queryLastBlock"
);
}

public async getChain(): Promise<Chain | undefined> {
Expand Down
16 changes: 14 additions & 2 deletions apps/extension/src/provider/Namada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Chain,
DerivedAccount,
Namada as INamada,
ShieldedSyncProps,
SignArbitraryProps,
SignatureResponse,
TxMsgProps,
Expand All @@ -22,6 +23,7 @@ import {
QueryAccountsMsg,
QueryBalancesMsg,
QueryDefaultAccountMsg,
QueryLastBlocksMsg,
ShieldedSyncMsg,
VerifyArbitraryMsg,
} from "./messages";
Expand Down Expand Up @@ -126,10 +128,20 @@ export class Namada implements INamada {
);
}

public async shieldedSync(): Promise<void> {
public async shieldedSync({
startHeight,
lastHeight,
}: ShieldedSyncProps): Promise<void> {
return await this.requester?.sendMessage(
Ports.Background,
new ShieldedSyncMsg()
new ShieldedSyncMsg(startHeight, lastHeight)
);
}

public async queryLastBlock(): Promise<number | undefined> {
return await this.requester?.sendMessage(
Ports.Background,
new QueryLastBlocksMsg()
);
}

Expand Down
26 changes: 25 additions & 1 deletion apps/extension/src/provider/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum MessageType {
CheckDurability = "check-durability",
ApproveSignArbitrary = "approve-sign-arbitrary",
VerifyArbitrary = "verify-arbitrary",
QueryLastBlock = "query-last-block",
}

/**
Expand Down Expand Up @@ -173,7 +174,10 @@ export class ShieldedSyncMsg extends Message<void> {
return MessageType.ShieldedSync;
}

constructor() {
constructor(
public readonly startHeight?: number,
public readonly lastHeight?: number
) {
super();
}

Expand All @@ -188,6 +192,26 @@ export class ShieldedSyncMsg extends Message<void> {
}
}

export class QueryLastBlocksMsg extends Message<number | undefined> {
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
> {
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
10 changes: 9 additions & 1 deletion apps/namada-interface/src/slices/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ const accountsAtom = (() => {
);
})();

const LATEST_SYNCED_HEIGHT_STORAGE = "latest-synced-height"
Copy link
Collaborator

Choose a reason for hiding this comment

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


const balancesAtom = (() => {
const base = atom<{ [address: Address]: TokenBalances }>({});

Expand Down Expand Up @@ -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){
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like formatting is a bit off. Please run yarn prepare in the root of monorepo to setup husky.

localStorage.setItem(LATEST_SYNCED_HEIGHT_STORAGE, lastHeight.toString())
}

const shieldedBalances = await Promise.all(
queryBalance(namada, shieldedAccounts, token)
Expand Down
10 changes: 7 additions & 3 deletions packages/integrations/src/Namada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,15 @@ export default class Namada implements Integration<Account, Signer> {

// 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<void> {
await this._namada?.shieldedSync();
public async sync(startHeight?: number, lastHeight?: number): Promise<void> {
await this._namada?.shieldedSync({ startHeight, lastHeight });
}

public async queryLastBlock(): Promise<number | undefined> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Once you use extension local storage this function is not needed anymore :)

return await this._namada?.queryLastBlock();
}
}
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: (startHeight?: number, lastHeight?: number) => Promise<void>;
}
31 changes: 27 additions & 4 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,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<u64>,
last_height: Option<u64>,
) -> Result<(), JsError> {
let owners: Vec<ViewingKey> = owners
.into_iter()
.filter_map(|owner| owner.as_string())
Expand All @@ -278,12 +291,22 @@ impl Query {

let _ = shielded.save().await?;

let start_query_height = match start_height {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can also just start_height.map(BlockHeight) - should work :)

Copy link
Author

Choose a reason for hiding this comment

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

Haha. Thanks for your suggestion. I'm a newbie on Rust

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,
Copy link
Collaborator

@mateuszjasiuk mateuszjasiuk Apr 4, 2024

Choose a reason for hiding this comment

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

I'm pretty sure Namada will fetch up to last block if you pass None.

1,
&[],
&owners,
Expand Down
8 changes: 7 additions & 1 deletion packages/types/src/namada.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export type VerifyArbitraryProps = {
signature: string;
};

export type ShieldedSyncProps = {
startHeight?: number;
lastHeight?: number;
};

export type BalancesProps = {
owner: string;
tokens: string[];
Expand All @@ -32,7 +37,8 @@ export interface Namada {
balances(
props: BalancesProps
): Promise<{ token: string; amount: string }[] | undefined>;
shieldedSync(): Promise<void>;
shieldedSync(props: ShieldedSyncProps): Promise<void>;
queryLastBlock(): Promise<number | undefined>;
connect(chainId?: string): Promise<void>;
isConnected(): Promise<boolean | undefined>;
defaultAccount(chainId?: string): Promise<DerivedAccount | undefined>;
Expand Down