Skip to content

Commit

Permalink
Merge pull request #44 from ChainSafe/willem/wasm-loading-bugfixes
Browse files Browse the repository at this point in the history
Add loading overlay and some quality of life improvements
  • Loading branch information
willemolding authored Oct 18, 2024
2 parents 78a63fa + a2448e6 commit 58431a6
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 173 deletions.
7 changes: 4 additions & 3 deletions packages/demo-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
"react": "^18.2.0",
"react-bootstrap": "^2.10.4",
"react-dom": "^18.2.0",
"react-loading-overlay": "^1.0.1",
"react-qr-code": "^2.0.15",
"react-toastify": "^10.0.5",
"usehooks-ts": "^3.1.0"
},
"devDependencies": {
"@parcel/core": "^2.12.0",
"@vitejs/plugin-react": "^4.3.2",
"parcel": "^2.12.0",
"typescript": "^5.6.2",
"vite": "^5.4.9",
"@parcel/core": "^2.12.0",
"parcel": "^2.12.0"
"vite": "^5.4.9"
}
}
51 changes: 28 additions & 23 deletions packages/demo-wallet/src/App/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export async function init(state: State, dispatch: React.Dispatch<Action>) {
type: "set-active-account",
payload: summary?.account_balances[0][0],
});
dispatch({
type: "set-loading",
payload: false,
});
}

export async function addNewAccount(
Expand All @@ -50,6 +54,7 @@ export async function addNewAccount(
let account_id =
(await state.webWallet?.create_account(seedPhrase, 0, birthdayHeight)) || 0;
dispatch({ type: "add-account-seed", payload: [account_id, seedPhrase] });
dispatch({ type: "set-active-account", payload: account_id });
await syncStateWithWallet(state, dispatch);
}

Expand All @@ -58,7 +63,8 @@ export async function syncStateWithWallet(
dispatch: React.Dispatch<Action>
) {
if (!state.webWallet) {
throw new Error("Wallet not initialized");
console.error("Wallet not initialized");
return;
}
let summary = await state.webWallet?.get_wallet_summary();
if (summary) {
Expand All @@ -74,8 +80,21 @@ export async function triggerRescan(
state: State,
dispatch: React.Dispatch<Action>
) {
if (state.loading) {
console.error("App not yet loaded");
return;
}
if (!state.webWallet) {
throw new Error("Wallet not initialized");
console.error("Wallet not initialized");
return;
}
if (state.activeAccount == undefined) {
console.error("No active account");
return;
}
if (state.syncInProgress) {
console.error("Sync already in progress");
return;
}
dispatch({
type: "set-sync-in-progress",
Expand All @@ -99,10 +118,12 @@ export async function triggerTransfer(
amount: bigint
) {
if (!state.webWallet) {
throw new Error("Wallet not initialized");
console.error("Wallet not initialized");
return;
}
if (state.activeAccount == null) {
throw new Error("No active account");
console.error("No active account");
return;
}

let activeAccountSeedPhrase =
Expand Down Expand Up @@ -132,7 +153,8 @@ export async function flushDbToStore(
dispatch: React.Dispatch<Action>
) {
if (!state.webWallet) {
throw new Error("Wallet not initialized");
console.error("Wallet not initialized");
return;
}
console.info("Serializing wallet and dumpling to IndexDb store");
let bytes = await state.webWallet.db_to_bytes();
Expand All @@ -150,22 +172,5 @@ export async function clearStore(
await set("wallet", undefined);
console.info("Wallet cleared from storage");

let wallet = new WebWallet("main", MAINNET_LIGHTWALLETD_PROXY, 1);
dispatch({
type: "set-web-wallet",
payload: wallet,
});

let summary = await wallet.get_wallet_summary();
if (summary) {
dispatch({ type: "set-summary", payload: summary });
}
let chainHeight = await wallet.get_latest_block();
if (chainHeight) {
dispatch({ type: "set-chain-height", payload: chainHeight });
}
dispatch({
type: "set-active-account",
payload: summary?.account_balances[0][0],
});
location.reload();
}
80 changes: 46 additions & 34 deletions packages/demo-wallet/src/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import "./App.css";

import React, { useEffect, createContext, useReducer } from "react";
import { useInterval } from 'usehooks-ts'
import { useInterval } from "usehooks-ts";

import Tab from "react-bootstrap/Tab";
import Tabs from "react-bootstrap/Tabs";
import Stack from "react-bootstrap/Stack";
import Container from "react-bootstrap/Container";
import LoadingOverlay from "react-loading-overlay";

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

import { init, triggerRescan } from "./Actions";
import { Header } from "./components/Header";
Expand All @@ -29,6 +27,7 @@ export type State = {
chainHeight?: bigint;
accountSeeds: Map<number, string>;
syncInProgress: boolean;
loading: boolean;
};

const initialState: State = {
Expand All @@ -37,6 +36,7 @@ const initialState: State = {
chainHeight: undefined,
accountSeeds: new Map<number, string>(),
syncInProgress: false,
loading: true,
};

export type Action =
Expand All @@ -46,15 +46,22 @@ export type Action =
| { type: "set-summary"; payload: WalletSummary }
| { type: "set-chain-height"; payload: bigint }
| { type: "set-account-seeds"; payload: Map<number, string> }
| { type: "set-sync-in-progress"; payload: boolean };
| { type: "set-sync-in-progress"; payload: boolean }
| { type: "set-loading"; payload: boolean };

const reducer = (state: State, action: Action): State => {
switch (action.type) {
case "set-active-account": {
return { ...state, activeAccount: action.payload };
}
case "add-account-seed": {
return { ...state, accountSeeds: state.accountSeeds.set(action.payload[0], action.payload[1]) };
return {
...state,
accountSeeds: state.accountSeeds.set(
action.payload[0],
action.payload[1]
),
};
}
case "set-web-wallet": {
return { ...state, webWallet: action.payload };
Expand All @@ -71,6 +78,9 @@ const reducer = (state: State, action: Action): State => {
case "set-sync-in-progress": {
return { ...state, syncInProgress: action.payload };
}
case "set-loading": {
return { ...state, loading: action.payload };
}
default:
return state;
}
Expand All @@ -96,33 +106,35 @@ export function App() {
return (
<div>
<WalletContext.Provider value={{ state, dispatch }}>
<Container>
<Stack>
<h1>WebZjs Wallet Demo</h1>
<Header />
<Tabs
defaultActiveKey="import"
id="base-wallet-tabs"
className="mb-3"
>
<Tab eventKey="import" title="Import Account">
<AddAccount />
</Tab>
<Tab eventKey="summary" title="Summary">
<Summary summary={state.summary}/>
</Tab>
<Tab eventKey="send" title="Send">
<SendFunds />
</Tab>
<Tab eventKey="receive" title="Receive">
<ReceiveFunds />
</Tab>
<Tab eventKey="settings" title="Settings">
<Settings />
</Tab>
</Tabs>
</Stack>
</Container>
<LoadingOverlay active={state.loading} spinner text="Loading. This may take up to 1 minute...">
<Container>
<Stack>
<h1>WebZjs Wallet Demo</h1>
<Header />
<Tabs
defaultActiveKey="import"
id="base-wallet-tabs"
className="mb-3"
>
<Tab eventKey="import" title="Import Account">
<AddAccount />
</Tab>
<Tab eventKey="summary" title="Summary">
<Summary summary={state.summary} />
</Tab>
<Tab eventKey="send" title="Send">
<SendFunds />
</Tab>
<Tab eventKey="receive" title="Receive">
<ReceiveFunds />
</Tab>
<Tab eventKey="settings" title="Settings">
<Settings />
</Tab>
</Tabs>
</Stack>
</Container>
</LoadingOverlay>
</WalletContext.Provider>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/demo-wallet/src/App/Constants.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const MAINNET_LIGHTWALLETD_PROXY = "https://zcash-mainnet.chainsafe.dev";
export const ZATOSHI_PER_ZEC = 1e8;
export const RESCAN_INTERVAL = 20000;
export const RESCAN_INTERVAL = 20000;
export const NU5_ACTIVATION = 1687104;
20 changes: 14 additions & 6 deletions packages/demo-wallet/src/App/components/AddAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FormEvent, useContext, useState } from "react";
import React, { FormEvent, useContext, useEffect, useState } from "react";

import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";
Expand All @@ -7,23 +7,30 @@ import { generate_seed_phrase } from "@webzjs/webz-core";

import { WalletContext } from "../App";
import { addNewAccount, flushDbToStore } from "../Actions";

const NU5_ACTIVATION = 1687104;
import { NU5_ACTIVATION } from "../Constants";

export function AddAccount() {
let { state, dispatch } = useContext(WalletContext);

let [birthdayHeight, setBirthdayHeight] = useState(NU5_ACTIVATION);
let [birthdayHeight, setBirthdayHeight] = useState(0);
let [seedPhrase, setSeedPhrase] = useState("");

useEffect(() => {
const fetchBirthday = async () => {
let birthday = await state.webWallet?.get_latest_block();
setBirthdayHeight(Number(birthday) || 0);
}
fetchBirthday();
}, [state]);

const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
await addNewAccount(state, dispatch, seedPhrase, birthdayHeight);
toast.success("Account imported successfully", {
position: "top-center",
autoClose: 2000,
});
setBirthdayHeight(NU5_ACTIVATION);
setBirthdayHeight(0);
setSeedPhrase("");
flushDbToStore(state, dispatch);
};
Expand All @@ -32,7 +39,7 @@ export function AddAccount() {
const newSeedPhrase = generate_seed_phrase();
let birthday = await state.webWallet?.get_latest_block();
setSeedPhrase(newSeedPhrase);
setBirthdayHeight(Number(birthday) || NU5_ACTIVATION);
setBirthdayHeight(Number(birthday) || 0);
};

return (
Expand Down Expand Up @@ -68,6 +75,7 @@ export function AddAccount() {
onChange={({ target: { value } }) =>
setBirthdayHeight(parseInt(value))
}
min={NU5_ACTIVATION}
/>
</Form.Group>
<Button variant="primary" type="submit">
Expand Down
Loading

1 comment on commit 58431a6

@github-actions
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.