diff --git a/packages/demo-wallet/package.json b/packages/demo-wallet/package.json index 572bbb4..d28d252 100644 --- a/packages/demo-wallet/package.json +++ b/packages/demo-wallet/package.json @@ -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" } } diff --git a/packages/demo-wallet/src/App/Actions.tsx b/packages/demo-wallet/src/App/Actions.tsx index 7316de0..13a68fc 100644 --- a/packages/demo-wallet/src/App/Actions.tsx +++ b/packages/demo-wallet/src/App/Actions.tsx @@ -39,6 +39,10 @@ export async function init(state: State, dispatch: React.Dispatch) { type: "set-active-account", payload: summary?.account_balances[0][0], }); + dispatch({ + type: "set-loading", + payload: false, + }); } export async function addNewAccount( @@ -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); } @@ -58,7 +63,8 @@ export async function syncStateWithWallet( dispatch: React.Dispatch ) { 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) { @@ -74,8 +80,21 @@ export async function triggerRescan( state: State, dispatch: React.Dispatch ) { + 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", @@ -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 = @@ -132,7 +153,8 @@ export async function flushDbToStore( dispatch: React.Dispatch ) { 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(); @@ -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(); } diff --git a/packages/demo-wallet/src/App/App.tsx b/packages/demo-wallet/src/App/App.tsx index 91ee004..ddac3c4 100644 --- a/packages/demo-wallet/src/App/App.tsx +++ b/packages/demo-wallet/src/App/App.tsx @@ -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"; @@ -29,6 +27,7 @@ export type State = { chainHeight?: bigint; accountSeeds: Map; syncInProgress: boolean; + loading: boolean; }; const initialState: State = { @@ -37,6 +36,7 @@ const initialState: State = { chainHeight: undefined, accountSeeds: new Map(), syncInProgress: false, + loading: true, }; export type Action = @@ -46,7 +46,8 @@ export type Action = | { type: "set-summary"; payload: WalletSummary } | { type: "set-chain-height"; payload: bigint } | { type: "set-account-seeds"; payload: Map } - | { 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) { @@ -54,7 +55,13 @@ const reducer = (state: State, action: Action): State => { 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 }; @@ -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; } @@ -96,33 +106,35 @@ export function App() { return (
- - -

WebZjs Wallet Demo

-
- - - - - - - - - - - - - - - - - - - + + + +

WebZjs Wallet Demo

+
+ + + + + + + + + + + + + + + + + + + +
); diff --git a/packages/demo-wallet/src/App/Constants.tsx b/packages/demo-wallet/src/App/Constants.tsx index 286f51f..e615a0f 100644 --- a/packages/demo-wallet/src/App/Constants.tsx +++ b/packages/demo-wallet/src/App/Constants.tsx @@ -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; \ No newline at end of file +export const RESCAN_INTERVAL = 20000; +export const NU5_ACTIVATION = 1687104; diff --git a/packages/demo-wallet/src/App/components/AddAccount.tsx b/packages/demo-wallet/src/App/components/AddAccount.tsx index 4f10a30..da1f7cf 100644 --- a/packages/demo-wallet/src/App/components/AddAccount.tsx +++ b/packages/demo-wallet/src/App/components/AddAccount.tsx @@ -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"; @@ -7,15 +7,22 @@ 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); @@ -23,7 +30,7 @@ export function AddAccount() { position: "top-center", autoClose: 2000, }); - setBirthdayHeight(NU5_ACTIVATION); + setBirthdayHeight(0); setSeedPhrase(""); flushDbToStore(state, dispatch); }; @@ -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 ( @@ -68,6 +75,7 @@ export function AddAccount() { onChange={({ target: { value } }) => setBirthdayHeight(parseInt(value)) } + min={NU5_ACTIVATION} />