Skip to content

Commit

Permalink
add ability to fetch chain tip by forwarding lightwalletd calls
Browse files Browse the repository at this point in the history
  • Loading branch information
willemolding committed Sep 25, 2024
1 parent aff28fc commit f406298
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 112 deletions.
87 changes: 61 additions & 26 deletions packages/demo-wallet/src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,24 @@ import Tab from "react-bootstrap/Tab";
import Tabs from "react-bootstrap/Tabs";
import Stack from "react-bootstrap/Stack";


import initWasm, { initThreadPool, start, WebWallet } from "@webzjs/webz-core";
import initWasm, {
initThreadPool,
start,
WebWallet,
WalletSummary,
} from "@webzjs/webz-core";

import { Header } from "./components/Header";
import { ImportAccount } from "./components/ImportAccount";
import { SendFunds } from "./components/SendFunds";
import { ReceiveFunds } from "./components/ReceiveFunds";
import { Balance } from "./components/Balance";


const SAPLING_ACTIVATION = 419200;
const ORCHARD_ACTIVATION = 1687104;
const TIP = 2442739;
import { Summary } from "./components/Summary";

const MAINNET_LIGHTWALLETD_PROXY = "https://zcash-mainnet.chainsafe.dev";
const TESTNET_LIGHTWALLETD_PROXY = "https://zcash-testnet.chainsafe.dev";

export const WalletContext = createContext<WebWallet | null>(null);

export function App() {

useEffect(() => {
async function init() {
await initWasm();
Expand All @@ -37,27 +34,65 @@ export function App() {
}, []);

let [webWallet, setWebWallet] = useState<WebWallet | null>(null);
let [summary, setSummary] = useState<WalletSummary | null>(null);
let [chainHeight, setChainHeight] = useState<bigint | null>(null);
let [activeAccoumt, setActiveAccount] = useState<number>(0);

const refreshSummary = async () => {
if (!webWallet) {
return;
}
let summary = await webWallet?.get_wallet_summary();
if (summary) {
setSummary(summary);
}
let chainHeight = await webWallet?.get_latest_block();
if (chainHeight) {
setChainHeight(chainHeight);
}
};

const triggerRescan = () => {
if (!webWallet) {
return;
}
console.log("rescanning");
webWallet.sync2().then(() => {
console.log("rescan complete");
});
};

return (
<div>
<WalletContext.Provider value={webWallet}>
<Stack>
<h1>WebZjs Wallet Demo</h1>
<Header />
<Tabs defaultActiveKey="import" id="base-wallet-tabs" className="mb-3">
<Tab eventKey="import" title="Import Account">
<ImportAccount />
</Tab>
<Tab eventKey="balance" title="Balance">
<Balance />
</Tab>
<Tab eventKey="send" title="Send">
<SendFunds />
</Tab>
<Tab eventKey="receive" title="Receive">
<ReceiveFunds />
</Tab>
</Tabs>
<h1>WebZjs Wallet Demo</h1>
<Header
walletSummary={summary}
refreshSummary={refreshSummary}
activeAccount={activeAccoumt}
setActiveAccount={setActiveAccount}
triggerRescan={triggerRescan}
chainHeight={chainHeight}
/>
<Tabs
defaultActiveKey="import"
id="base-wallet-tabs"
className="mb-3"
>
<Tab eventKey="import" title="Import Account">
<ImportAccount refreshSummary={refreshSummary} />
</Tab>
<Tab eventKey="summary" title="Summary">
<Summary walletSummary={summary} />
</Tab>
<Tab eventKey="send" title="Send">
<SendFunds />
</Tab>
<Tab eventKey="receive" title="Receive">
<ReceiveFunds />
</Tab>
</Tabs>
</Stack>
</WalletContext.Provider>
</div>
Expand Down
60 changes: 0 additions & 60 deletions packages/demo-wallet/src/App/components/Balance.tsx

This file was deleted.

62 changes: 42 additions & 20 deletions packages/demo-wallet/src/App/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
import React, { useContext, useEffect, useState } from "react";

import Form from "react-bootstrap/Form";
import Card from "react-bootstrap/Card";
import Stack from "react-bootstrap/Stack";

import { WalletContext } from "../App";
import { WalletSummary, AccountBalance } from "@webzjs/webz-core";
import { WalletSummary } from "@webzjs/webz-core";
import { Button } from "react-bootstrap";

export function Header() {
let webWallet = useContext(WalletContext);
let [summary, setSummary] = useState<WalletSummary | null>();

let resyncSummary = async () => {
if (!webWallet) {
return;
}
console.log("fetching balance");
let summary = await webWallet?.get_wallet_summary();
console.log("summary", summary);
console.log("balances");

setSummary(summary);
};

export function Header({
walletSummary,
refreshSummary,
activeAccount,
setActiveAccount,
triggerRescan,
chainHeight,
}: {
walletSummary: WalletSummary | null;
refreshSummary: () => Promise<void>;
activeAccount: number;
setActiveAccount: (account: number) => void;
triggerRescan: () => void;
chainHeight: bigint | null;
}) {
return (
<div className="p-2">
<span className="me-2">Balance: </span>
</div>
<Stack direction="horizontal" gap={3}>
<Form.Select
value={activeAccount}
onChange={(e) => setActiveAccount(parseInt(e.target.value))}
>
{walletSummary?.account_balances.map(([id]) => (
<option key={id} value={id}>
Account {id}
</option>
))}
</Form.Select>
<Card style={{ width: "30rem" }}>
<Card.Title>Balance: {0} ZEC</Card.Title>
<Card.Text>Available Balance: {0} ZEC</Card.Text>
</Card>
<Card style={{ width: "30rem" }}>
<Card.Text>Chain Height: {chainHeight ? ""+chainHeight : '?'}</Card.Text>
<Card.Text>Synced Height: {walletSummary?.fully_scanned_height ? walletSummary?.fully_scanned_height : '?'}</Card.Text>
</Card>
<Stack>
<Button onClick={async () => await refreshSummary()}>Refresh</Button>
<Button onClick={() => triggerRescan()}>Sync</Button>
</Stack>
</Stack>
);
}
3 changes: 2 additions & 1 deletion packages/demo-wallet/src/App/components/ImportAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ToastContainer, toast } from "react-toastify";

import { WalletContext } from "../App";

export function ImportAccount() {
export function ImportAccount({refreshSummary}: {refreshSummary: () => Promise<void>}) {
let webWallet = useContext(WalletContext);

let [birthdayHeight, setBirthdayHeight] = useState(2657762);
Expand All @@ -18,6 +18,7 @@ export function ImportAccount() {
toast.success("Account imported successfully", {
position: "top-center",
});
await refreshSummary();
setBirthdayHeight(0);
setSeedPhrase("");
};
Expand Down
26 changes: 26 additions & 0 deletions packages/demo-wallet/src/App/components/Summary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useContext, useEffect, useState } from "react";

import Form from "react-bootstrap/Form";

import { WalletContext } from "../App";
import { WalletSummary, AccountBalance } from "@webzjs/webz-core";
import { Button } from "react-bootstrap";

export function Summary({
walletSummary,
}: {
walletSummary: WalletSummary | null;
}) {
return (
<div>
<pre>
{JSON.stringify(
walletSummary?.toJSON(),
(key, value) =>
typeof value === "bigint" ? value.toString() : value,
2
)}
</pre>
</div>
);
}
20 changes: 15 additions & 5 deletions src/bindgen/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::num::NonZeroU32;

use serde::{Deserialize, Serialize};
Expand All @@ -10,7 +9,10 @@ use crate::error::Error;
use crate::{BlockRange, MemoryWallet, Wallet, PRUNING_DEPTH};
use wasm_thread as thread;
use zcash_address::ZcashAddress;
use zcash_client_backend::proto::service::compact_tx_streamer_client::CompactTxStreamerClient;
use zcash_client_backend::proto::service::{
ChainSpec,
compact_tx_streamer_client::CompactTxStreamerClient
};
use zcash_client_memory::MemoryWalletDb;
use zcash_keys::keys::UnifiedFullViewingKey;
use zcash_primitives::consensus::{self, BlockHeight};
Expand Down Expand Up @@ -174,12 +176,21 @@ impl WebWallet {
.transfer(seed_phrase, from_account_index, to_address, value)
.await
}

/// Forwards a call to lightwalletd to retrieve the height of the latest block in the chain
pub async fn get_latest_block(
&self,
) -> Result<u64, Error> {
self.client().get_latest_block(ChainSpec{}).await.map(|response| {
response.into_inner().height
}).map_err(Error::from)
}
}

#[wasm_bindgen]
#[derive(Debug, Serialize, Deserialize)]
#[wasm_bindgen(inspectable)]
pub struct WalletSummary {
account_balances: HashMap<u32, AccountBalance>,
account_balances: Vec<(u32, AccountBalance)>,
pub chain_tip_height: u32,
pub fully_scanned_height: u32,
// scan_progress: Option<Ratio<u64>>,
Expand All @@ -195,7 +206,6 @@ impl WalletSummary {
}
}


#[derive(Debug, Serialize, Deserialize)]
pub struct AccountBalance {
pub sapling_balance: u64,
Expand Down

0 comments on commit f406298

Please sign in to comment.