Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 15 additions & 1 deletion gaztec/src/aztecEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { BBWASMLazyPrivateKernelProver } from "@aztec/bb-prover/wasm/lazy";
import { WASMSimulator } from "@aztec/simulator/client";
import { debug } from "debug";
import { createContext } from "react";
import { WalletDB } from "./utils/storage";
import { NetworkDB, WalletDB } from "./utils/storage";
import { ContractFunctionInteractionTx } from "./utils/txs";

process.env = Object.keys(import.meta.env).reduce((acc, key) => {
Expand Down Expand Up @@ -143,6 +143,20 @@ export const AztecContext = createContext<{
});

export class AztecEnv {
static isNetworkStoreInitialized = false;

static async initNetworkStore() {
if (!AztecEnv.isNetworkStoreInitialized) {
AztecEnv.isNetworkStoreInitialized = true;
const networkStore = await createStore(`network`, {
dataDirectory: "network",
dataStoreMapSizeKB: 1e6,
});
const networkDB = NetworkDB.getInstance();
networkDB.init(networkStore);
}
}

static async connectToNode(nodeURL: string): Promise<AztecNode> {
const aztecNode = await createAztecNodeClient(nodeURL);
return aztecNode;
Expand Down
37 changes: 22 additions & 15 deletions gaztec/src/components/home/home.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { css } from "@emotion/react";
import { ContractComponent } from "../contract/contract";
import { SidebarComponent } from "../sidebar/sidebar";
import { useState } from "react";
import { AztecContext } from "../../aztecEnv";
import { useEffect, useState } from "react";
import { AztecContext, AztecEnv } from "../../aztecEnv";
import NoSleep from "nosleep.js";
import { LogPanel } from "../logPanel/logPanel";
import logoURL from "../../assets/Aztec_logo.png";
import { Box, Drawer } from "@mui/material";
import { CircularProgress, Drawer, LinearProgress } from "@mui/material";

const layout = css({
display: "flex",
Expand All @@ -26,17 +26,6 @@ const collapsedDrawer = css({
overflow: "hidden",
});

const noSleep = new NoSleep();

function enableNoSleep() {
noSleep.enable();
document.removeEventListener("touchstart", enableNoSleep, false);
}

// Enable wake lock.
// (must be wrapped in a user input event handler e.g. a mouse or touch handler)
document.addEventListener("touchstart", enableNoSleep, false);

export default function Home() {
const [pxe, setPXE] = useState(null);
const [wallet, setWallet] = useState(null);
Expand All @@ -52,6 +41,17 @@ export default function Home() {
const [logsOpen, setLogsOpen] = useState(false);
const [drawerOpen, setDrawerOpen] = useState(false);

const [isNetworkStoreInitialized, setIsNetworkStoreInitialized] =
useState(false);

useEffect(() => {
const initNetworkStore = async () => {
await AztecEnv.initNetworkStore();
setIsNetworkStoreInitialized(true);
};
initNetworkStore();
}, []);

const AztecContextInitialValue = {
pxe,
nodeURL,
Expand Down Expand Up @@ -94,11 +94,18 @@ export default function Home() {
width: "340px",
},
}}
ModalProps={{
keepMounted: true,
}}
onClose={() => setDrawerOpen(false)}
variant="temporary"
open={drawerOpen}
>
<SidebarComponent />
{isNetworkStoreInitialized ? (
<SidebarComponent />
) : (
<LinearProgress />
)}
</Drawer>
<LogPanel />
<ContractComponent />
Expand Down
64 changes: 64 additions & 0 deletions gaztec/src/components/sidebar/components/addNetworkDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import DialogTitle from "@mui/material/DialogTitle";
import Dialog from "@mui/material/Dialog";
import { Button, TextField, css } from "@mui/material";
import { useState } from "react";
import { AztecAddress } from "@aztec/aztec.js";

const creationForm = css({
display: "flex",
flexDirection: "column",
gap: "1rem",
padding: "1rem",
alignItems: "center",
});

export function AddNetworksDialog({
open,
onClose,
}: {
open: boolean;
onClose: (network?: string, alias?: string) => void;
}) {
const [alias, setAlias] = useState("");
const [network, setNetwork] = useState("");

const addNetwork = async () => {
setAlias("");
setNetwork("");
onClose(network, alias);
};

const handleClose = () => {
setAlias("");
setNetwork("");
onClose();
};

return (
<Dialog onClose={handleClose} open={open}>
<DialogTitle>Add network</DialogTitle>
<div css={creationForm}>
<TextField
value={network}
label="Network"
onChange={(event) => {
setNetwork(event.target.value);
}}
/>
<TextField
value={alias}
label="Alias"
onChange={(event) => {
setAlias(event.target.value);
}}
/>
<Button disabled={alias === "" || network === ""} onClick={addNetwork}>
Add
</Button>
<Button color="error" onClick={handleClose}>
Cancel
</Button>
</div>
</Dialog>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ export function CreateAccountDialog({
const [alias, setAlias] = useState("");
const [secretKey] = useState(Fr.random());
const [deployingAccount, setDeployingAccount] = useState(false);
const { pxe } = useContext(AztecContext);
const { pxe, setDrawerOpen, setLogsOpen } = useContext(AztecContext);

const createAccount = async () => {
setDeployingAccount(true);
setDrawerOpen(false);
setLogsOpen(true);
const salt = Fr.random();
const account = await getSchnorrAccount(
pxe,
Expand Down
58 changes: 53 additions & 5 deletions gaztec/src/components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Select, { SelectChangeEvent } from "@mui/material/Select";
import { AztecEnv, AztecContext, WebLogger } from "../../aztecEnv";
import { createStore } from "@aztec/kv-store/indexeddb";
import { AccountWalletWithSecretKey, Fr, AztecAddress } from "@aztec/aztec.js";
import { WalletDB } from "../../utils/storage";
import { NetworkDB, WalletDB } from "../../utils/storage";
import { useContext, useEffect, useState } from "react";
import { CreateAccountDialog } from "./components/createAccountDialog";
import { getSchnorrAccount } from "@aztec/accounts/schnorr";
Expand All @@ -21,6 +21,7 @@ import { CopyToClipboardButton } from "../common/copyToClipboardButton";
import { AddSendersDialog } from "./components/addSenderDialog";
import { deriveSigningKey } from "@aztec/circuits.js/keys";
import { TxsPanel } from "./components/txsPanel";
import { AddNetworksDialog } from "./components/addNetworkDialog";

const container = css({
display: "flex",
Expand Down Expand Up @@ -49,13 +50,13 @@ const header = css({
marginBottom: "1rem",
});

const NETWORKS = [
type Network = { nodeURL: string; name: string };

const NETWORKS: Network[] = [
{
nodeURL: "http://localhost:8080",
name: "Local",
},
{ nodeURL: "http://34.145.98.34:8080", name: "Devnet" },
{ nodeURL: "http://35.197.121.62:8080", name: "Masternet" },
];

export function SidebarComponent() {
Expand All @@ -78,6 +79,8 @@ export function SidebarComponent() {
const [changingNetworks, setChangingNetworks] = useState(false);
const [accounts, setAccounts] = useState([]);
const [contracts, setContracts] = useState([]);
const [networks, setNetworks] = useState(NETWORKS);
const [openAddNetworksDialog, setOpenAddNetworksDialog] = useState(false);
const [openCreateAccountDialog, setOpenCreateAccountDialog] = useState(false);
const [openAddSendersDialog, setOpenAddSendersDialog] = useState(false);

Expand All @@ -101,6 +104,22 @@ export function SidebarComponent() {
return { ourAccounts, senders };
};

useEffect(() => {
const refreshNetworks = async () => {
const aliasedBuffers = await NetworkDB.getInstance().listNetworks();
const aliasedNetworks = parseAliasedBuffersAsString(aliasedBuffers);
const networks = [
...NETWORKS,
...aliasedNetworks.map((network) => ({
nodeURL: network.value,
name: network.key,
})),
];
setNetworks(networks);
};
refreshNetworks();
}, []);

const handleNetworkChange = async (event: SelectChangeEvent) => {
setChangingNetworks(true);
setPXEInitialized(false);
Expand Down Expand Up @@ -203,6 +222,23 @@ export function SidebarComponent() {
setOpenAddSendersDialog(false);
};

const handleNetworkAdded = async (network?: string, alias?: string) => {
if (network && alias) {
await NetworkDB.getInstance().storeNetwork(alias, network);
const aliasedBuffers = await NetworkDB.getInstance().listNetworks();
const aliasedNetworks = parseAliasedBuffersAsString(aliasedBuffers);
const networks = [
...NETWORKS,
...aliasedNetworks.map((network) => ({
nodeURL: network.value,
name: network.key,
})),
];
setNetworks(networks);
}
setOpenAddNetworksDialog(false);
};

return (
<div css={container}>
<div css={header}>
Expand All @@ -223,13 +259,25 @@ export function SidebarComponent() {
disabled={changingNetworks}
onChange={handleNetworkChange}
>
{NETWORKS.map((network) => (
{networks.map((network) => (
<MenuItem key={network.name} value={network.nodeURL}>
{network.name} ({network.nodeURL})
</MenuItem>
))}
<MenuItem
key="create"
value=""
onClick={() => setOpenAddNetworksDialog(true)}
>
<AddIcon />
&nbsp;Create
</MenuItem>
</Select>
</FormControl>
<AddNetworksDialog
open={openAddNetworksDialog}
onClose={handleNetworkAdded}
/>
{pxe && isPXEInitialized ? (
<>
<FormControl css={select}>
Expand Down
38 changes: 38 additions & 0 deletions gaztec/src/utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,41 @@ export class WalletDB {
log(`Data stored in database with alias ${type}:${key}`);
}
}

export class NetworkDB {
#networks!: AztecAsyncMap<string, Buffer>;

private static instance: NetworkDB;

static getInstance() {
if (!NetworkDB.instance) {
NetworkDB.instance = new NetworkDB();
}

return NetworkDB.instance;
}

init(store: AztecAsyncKVStore) {
this.#networks = store.openMap("networks");
}

async storeNetwork(network: string, alias: string) {
await this.#networks.set(network, Buffer.from(alias));
}

async retrieveNetwork(network: string) {
const result = await this.#networks.getAsync(network);
if (!result) {
throw new Error(`Could not find network with alias ${network}`);
}
return result.toString();
}

async listNetworks() {
const result = [];
for await (const [key, value] of this.#networks.entriesAsync()) {
result.push({ key, value: value.toString() });
}
return result;
}
}