Skip to content

Commit acf7bdc

Browse files
committed
get transaction sends working
1 parent 8ccc77c commit acf7bdc

File tree

9 files changed

+83
-42
lines changed

9 files changed

+83
-42
lines changed
Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import initWasm, { initThreadPool, WebWallet } from "@webzjs/webz-core";
22

3-
import { Action } from "./App";
3+
import { State, Action } from "./App";
44
import { MAINNET_LIGHTWALLETD_PROXY } from "./constants";
55

66
export async function init(dispatch: React.Dispatch<Action>) {
@@ -12,31 +12,54 @@ export async function init(dispatch: React.Dispatch<Action>) {
1212
});
1313
}
1414

15+
export async function addNewAccount(state: State, dispatch: React.Dispatch<Action>, seedPhrase: string, birthdayHeight: number) {
16+
await state.webWallet?.create_account(seedPhrase, 0, birthdayHeight);
17+
dispatch({ type: "append-account-seed", payload: seedPhrase });
18+
await syncStateWithWallet(state, dispatch);
19+
}
20+
1521
export async function syncStateWithWallet(
16-
webWallet: WebWallet | undefined,
22+
state: State,
1723
dispatch: React.Dispatch<Action>
1824
) {
19-
if (!webWallet) {
20-
return;
25+
if (!state.webWallet) {
26+
throw new Error("Wallet not initialized");
2127
}
22-
let summary = await webWallet?.get_wallet_summary();
28+
let summary = await state.webWallet?.get_wallet_summary();
2329
if (summary) {
2430
dispatch({ type: "set-summary", payload: summary });
2531
}
26-
let chainHeight = await webWallet?.get_latest_block();
32+
let chainHeight = await state.webWallet?.get_latest_block();
2733
if (chainHeight) {
2834
dispatch({ type: "set-chain-height", payload: chainHeight });
2935
}
3036
dispatch({ type: "set-active-account", payload: summary?.account_balances[0][0] });
3137
}
3238

3339
export async function triggerRescan(
34-
webWallet: WebWallet | undefined,
40+
state: State,
3541
dispatch: React.Dispatch<Action>
3642
) {
37-
if (!webWallet) {
38-
return;
43+
if (!state.webWallet) {
44+
throw new Error("Wallet not initialized");
45+
}
46+
await state.webWallet?.sync2();
47+
await syncStateWithWallet(state, dispatch);
48+
}
49+
50+
export async function triggerTransfer(
51+
state: State,
52+
dispatch: React.Dispatch<Action>,
53+
toAddress: string,
54+
amount: bigint
55+
) {
56+
if (!state.webWallet) {
57+
throw new Error("Wallet not initialized");
3958
}
40-
await webWallet?.sync2();
41-
await syncStateWithWallet(webWallet, dispatch);
59+
if (state.activeAccount == null) {
60+
throw new Error("No active account");
61+
}
62+
63+
await state.webWallet?.transfer(state.accountSeeds[state.activeAccount], state.activeAccount, toAddress, amount);
64+
await syncStateWithWallet(state, dispatch);
4265
}

packages/demo-wallet/src/App/App.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,24 @@ import { SendFunds } from "./components/SendFunds";
1818
import { ReceiveFunds } from "./components/ReceiveFunds";
1919
import { Summary } from "./components/Summary";
2020

21-
type State = {
21+
export type State = {
2222
webWallet?: WebWallet;
2323
activeAccount?: number;
2424
summary?: WalletSummary;
2525
chainHeight?: bigint;
26+
accountSeeds: string[];
2627
};
2728

2829
const initialState: State = {
2930
activeAccount: undefined,
3031
summary: undefined,
3132
chainHeight: undefined,
33+
accountSeeds: [],
3234
};
3335

3436
export type Action =
3537
| { type: "set-active-account"; payload: number }
38+
| { type: "append-account-seed"; payload: string }
3639
| { type: "set-web-wallet"; payload: WebWallet }
3740
| { type: "set-summary"; payload: WalletSummary }
3841
| { type: "set-chain-height"; payload: bigint };
@@ -42,6 +45,9 @@ const reducer = (state: State, action: Action): State => {
4245
case "set-active-account": {
4346
return { ...state, activeAccount: action.payload };
4447
}
48+
case "append-account-seed": {
49+
return { ...state, accountSeeds: [...state.accountSeeds, action.payload] };
50+
}
4551
case "set-web-wallet": {
4652
return { ...state, webWallet: action.payload };
4753
}
@@ -68,16 +74,6 @@ export function App() {
6874
init(dispatch);
6975
}, [dispatch]);
7076

71-
const triggerRescan = () => {
72-
if (!state.webWallet) {
73-
return;
74-
}
75-
console.log("rescanning");
76-
state.webWallet.sync2().then(() => {
77-
console.log("rescan complete");
78-
});
79-
};
80-
8177
return (
8278
<div>
8379
<WalletContext.Provider value={{ state, dispatch }}>

packages/demo-wallet/src/App/components/Header.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export function Header() {
1717
state.summary?.account_balances.find(
1818
([id]) => id === state.activeAccount
1919
);
20-
console.log(activeBalanceReport);
2120

2221
let totalBalance = activeBalanceReport ? activeBalanceReport[1].sapling_balance + activeBalanceReport[1].orchard_balance : 0
2322
return (
@@ -55,12 +54,12 @@ export function Header() {
5554
<Stack>
5655
<Button
5756
onClick={async () =>
58-
await syncStateWithWallet(state.webWallet, dispatch)
57+
await syncStateWithWallet(state, dispatch)
5958
}
6059
>
6160
Refresh
6261
</Button>
63-
<Button onClick={() => triggerRescan(state.webWallet, dispatch)}>
62+
<Button onClick={() => triggerRescan(state, dispatch)}>
6463
Sync
6564
</Button>
6665
</Stack>

packages/demo-wallet/src/App/components/ImportAccount.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,20 @@ import Form from "react-bootstrap/Form";
55
import { ToastContainer, toast } from "react-toastify";
66

77
import { WalletContext } from "../App";
8-
import { syncStateWithWallet } from "../Actions";
8+
import { addNewAccount } from "../Actions";
99

1010
export function ImportAccount() {
1111
let {state, dispatch} = useContext(WalletContext);
1212

1313
let [birthdayHeight, setBirthdayHeight] = useState(2657762);
1414
let [seedPhrase, setSeedPhrase] = useState("mix sample clay sweet planet lava giraffe hand fashion switch away pool rookie earth purity truly square trumpet goose move actor save jaguar volume");
1515

16-
const handleSubmit = async (event: FormEvent) => {
17-
event.preventDefault();
18-
await state.webWallet?.create_account(seedPhrase, 0, birthdayHeight);
16+
const handleSubmit = async (e: FormEvent) => {
17+
e.preventDefault();
18+
await addNewAccount(state, dispatch, seedPhrase, birthdayHeight);
1919
toast.success("Account imported successfully", {
2020
position: "top-center",
2121
});
22-
await syncStateWithWallet(state.webWallet, dispatch);
2322
setBirthdayHeight(0);
2423
setSeedPhrase("");
2524
};

packages/demo-wallet/src/App/components/SendFunds.tsx

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,44 @@
1-
import React from "react";
1+
import React, { FormEvent, useContext, useState } from "react";
22

33
import Button from "react-bootstrap/Button";
44
import Form from "react-bootstrap/Form";
55

6+
import { WalletContext } from "../App";
7+
import { triggerTransfer } from "../Actions";
8+
69
export function SendFunds() {
10+
let { state, dispatch } = useContext(WalletContext);
11+
12+
let [toAddress, setToAddress] = useState("");
13+
let [amount, setAmount] = useState<bigint>(BigInt(0));
14+
15+
const handleSubmit = async (e: FormEvent) => {
16+
e.preventDefault();
17+
console.log("Sending", amount, "to", toAddress);
18+
await triggerTransfer(state, dispatch, toAddress, amount);
19+
console.log("Send complete");
20+
};
21+
722
return (
8-
<Form>
23+
<Form onSubmit={handleSubmit}>
924
<Form.Group className="mb-3" controlId="formSend">
10-
<Form.Label>From Account:</Form.Label>
11-
<Form.Select>
12-
<option>Account 1</option>
13-
</Form.Select>
1425
<Form.Label>To:</Form.Label>
15-
<Form.Control type="text" placeholder="Zcash z-address"/>
26+
<Form.Control
27+
type="text"
28+
placeholder="Zcash z-address"
29+
value={toAddress}
30+
onChange={(e) => setToAddress(e.target.value)}
31+
/>
1632
<Form.Label>Amount:</Form.Label>
17-
<Form.Control type="number" placeholder="0.0" size="lg"/>
33+
<Form.Control
34+
type="number"
35+
placeholder="0.0"
36+
size="lg"
37+
value={"" + amount}
38+
onChange={(e) => setAmount(BigInt(e.target.value))}
39+
/>
1840
<Form.Label>Memo (optional):</Form.Label>
19-
<Form.Control type="text" placeholder="memo text (max 512 bytes)"/>
41+
<Form.Control type="text" placeholder="memo text (max 512 bytes)" />
2042
</Form.Group>
2143
<Button variant="primary" type="submit">
2244
Send

packages/demo-wallet/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="utf-8" />
55
<title>WebZjs Wallet Demo</title>
6-
<script src="enable-threads.js"></script>
6+
<!-- <script src="enable-threads.js"></script> -->
77
</head>
88
<body>
99
<div id="app"></div>

packages/demo-wallet/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
1212

1313
/* Language and Environment */
14-
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
14+
"target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
1515
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
1616
"jsx": "react", /* Specify what JSX code is generated. */
1717
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */

src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ pub enum Error {
5757
#[cfg(feature = "sqlite-db")]
5858
#[error("Sqlite error: {0}")]
5959
SqliteError(#[from] zcash_client_sqlite::error::SqliteClientError),
60+
#[error("Invalid seed phrase")]
61+
InvalidSeedPhrase,
6062
}
6163

6264
impl From<Error> for JsValue {

src/wallet.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ fn usk_from_seed_str(
515515
account_index: u32,
516516
network: &consensus::Network,
517517
) -> Result<UnifiedSpendingKey, Error> {
518-
let mnemonic = <Mnemonic<English>>::from_phrase(seed).unwrap();
518+
let mnemonic = <Mnemonic<English>>::from_phrase(seed).map_err(|_| Error::InvalidSeedPhrase)?;
519519
let seed = {
520520
let mut seed = mnemonic.to_seed("");
521521
let secret = seed.to_vec();

0 commit comments

Comments
 (0)