add address fetching

This commit is contained in:
Paul Miller
2023-04-06 11:21:58 -05:00
parent d5c7f2a0d6
commit 3291885a5a
9 changed files with 98 additions and 39 deletions

View File

@@ -1,7 +1,9 @@
import { Motion, Presence } from "@motionone/solid";
import { MutinyBalance } from "@mutinywallet/node-manager";
import { createResource, Show } from "solid-js";
import { useNodeManager } from "~/state/nodeManagerState";
import { ButtonLink } from "./Button";
function prettyPrintAmount(n?: number | bigint): string {
if (!n || n.valueOf() === 0) {
@@ -15,7 +17,15 @@ function prettyPrintBalance(b: MutinyBalance): string {
}
export default function BalanceBox() {
const { balance, refetchBalance } = useNodeManager();
const { nodeManager } = useNodeManager();
const fetchBalance = async () => {
console.log("Refetching balance");
const balance = await nodeManager()?.get_balance();
return balance
};
const [balance, { refetch: refetchBalance }] = createResource(nodeManager, fetchBalance);
return (
<Presence>
@@ -31,12 +41,15 @@ export default function BalanceBox() {
</header>
<div onClick={refetchBalance}>
<h1 class='text-4xl font-light'>
{balance() && prettyPrintBalance(balance())} <span class='text-xl'>SAT</span>
<Show when={balance()}>
{/* TODO: no-non-null-asssertion but type narrowing just isn't working */}
{prettyPrintBalance(balance()!)} <span class='text-xl'>SAT</span>
</Show>
</h1>
</div>
<div class="flex gap-2 py-4">
<button class='bg-[#1EA67F] p-4 flex-1 rounded-xl text-xl font-semibold '><span class="drop-shadow-sm shadow-black">Send</span></button>
<button class='bg-[#3B6CCC] p-4 flex-1 rounded-xl text-xl font-semibold '><span class="drop-shadow-sm shadow-black">Receive</span></button>
<ButtonLink href="/scanner" intent="green">Send</ButtonLink>
<ButtonLink href="/receive" intent="blue">Receive</ButtonLink>
</div>
</div>
</Motion>

View File

@@ -1,5 +1,6 @@
import { cva, VariantProps } from "class-variance-authority";
import { children, JSX, ParentComponent, splitProps } from "solid-js";
import { A } from "solid-start";
const button = cva(["p-4", "rounded-xl", "text-xl", "font-semibold"], {
variants: {
@@ -7,7 +8,8 @@ const button = cva(["p-4", "rounded-xl", "text-xl", "font-semibold"], {
active: "bg-white text-black",
inactive: "bg-black text-white border border-white",
blue: "bg-[#3B6CCC] text-white",
red: "bg-[#F61D5B] text-white"
red: "bg-[#F61D5B] text-white",
green: "bg-[#1EA67F] text-white",
},
layout: {
flex: "flex-1",
@@ -43,4 +45,27 @@ export const Button: ParentComponent<ButtonProps> = props => {
{slot()}
</button>
)
}
interface ButtonLinkProps extends JSX.ButtonHTMLAttributes<HTMLAnchorElement>, StyleProps {
href: string
}
export const ButtonLink: ParentComponent<ButtonLinkProps> = props => {
const slot = children(() => props.children)
const [local, attrs] = splitProps(props, ['children', 'intent', 'layout', 'class', 'href'])
return (
<A
href={local.href}
{...attrs}
class={button({
class: local.class || "",
intent: local.intent,
layout: local.layout,
})}
>
{slot()}
</A>
)
}

View File

@@ -4,14 +4,16 @@ import settings from '~/assets/icons/settings.svg';
import { A } from "solid-start";
type ActiveTab = 'home' | 'scan' | 'settings';
type ActiveTab = 'home' | 'scan' | 'settings' | 'none';
export default function NavBar(props: { activeTab: ActiveTab }) {
const activeStyle = 'h-full border-t-2 border-b-2 border-b-black flex flex-col justify-center'
return (<nav class='bg-black fixed bottom-0 shadow-lg z-40 w-full safe-bottom'>
<ul class='h-16 flex justify-between px-16 items-center'>
<li class={props.activeTab === "home" ? activeStyle : ""}>
<img src={mutiny_m} alt="home" />
<A href="/">
<img src={mutiny_m} alt="home" />
</A>
</li>
<li class={props.activeTab === "scan" ? activeStyle : ""}>
<A href="/scanner">

View File

@@ -52,12 +52,12 @@ export async function checkForWasm() {
}
}
export async function setupNodeManager(settings?: NodeManagerSettingStrings): Promise<NodeManager> {
export async function setupNodeManager(): Promise<NodeManager> {
const _ = await init();
console.time("Setup");
console.log("Starting setup...")
const { network, proxy, esplora } = await setAndGetMutinySettings(settings)
const { network, proxy, esplora } = await setAndGetMutinySettings()
console.log("Initializing Node Manager")
console.log("Using network", network);
console.log("Using proxy", proxy);

View File

@@ -13,6 +13,7 @@ import {
Title,
} from "solid-start";
import "./root.css";
import { NodeManagerProvider } from "./state/nodeManagerState";
export default function Root() {
return (
@@ -34,9 +35,11 @@ export default function Root() {
<Body>
<Suspense>
<ErrorBoundary>
<Routes>
<FileRoutes />
</Routes>
<NodeManagerProvider>
<Routes>
<FileRoutes />
</Routes>
</NodeManagerProvider>
</ErrorBoundary>
</Suspense>
<Scripts />

31
src/routes/Receive.tsx Normal file
View File

@@ -0,0 +1,31 @@
import { createResource, Show } from "solid-js";
import { Button } from "~/components/Button";
import NavBar from "~/components/NavBar";
import SafeArea from "~/components/SafeArea";
import { useNodeManager } from "~/state/nodeManagerState";
export default function Receive() {
const { nodeManager } = useNodeManager();
// TODO: would be nice if this was just newest unused address
const getNewAddress = async () => {
console.log("Getting new address");
const address = await nodeManager()?.get_new_address();
return address
};
const [address, { refetch: refetchAddress }] = createResource(nodeManager, getNewAddress);
return (
<SafeArea>
<main class='flex flex-col gap-4 py-8 px-4'>
<Show when={address()}>
<h1>{address()}</h1>
<Button onClick={refetchAddress}>Get new address</Button>
</Show>
</main>
<NavBar activeTab="none" />
</SafeArea>
)
}

View File

@@ -35,9 +35,7 @@ export default function Home() {
<ReloadPrompt />
<Switch fallback={<>Loading...</>} >
<Match when={waitlistData() && waitlistData().approval_date}>
<NodeManagerProvider>
<App />
</NodeManagerProvider>
<App />
</Match>
<Match when={waitlistData() && waitlistData().date}>
<WaitlistAlreadyIn />

View File

@@ -1,10 +0,0 @@
import { Outlet } from "solid-start";
export default function UsersLayout() {
return (
<div>
<h1>Users</h1>
<Outlet />
</div>
);
}

View File

@@ -1,24 +1,14 @@
import { NodeManager } from "@mutinywallet/node-manager";
import { createContext, JSX, useContext, createResource } from "solid-js";
import { createContext, JSX, useContext, createResource, Resource } from "solid-js";
import { setupNodeManager } from "~/logic/nodeManagerSetup";
const NodeManagerContext = createContext();
const NodeManagerContext = createContext<{ nodeManager: Resource<NodeManager> }>();
export function NodeManagerProvider(props: { children: JSX.Element }) {
const [nodeManager] = createResource({}, setupNodeManager);
const fetchBalance = async (nm: NodeManager) => {
console.log("refetching balance");
const balance = await nm.get_balance();
return balance
};
const [balance, { refetch }] = createResource(nodeManager, fetchBalance);
const [nodeManager] = createResource(setupNodeManager);
const value = {
nodeManager,
balance,
refetchBalance: refetch
};
return (
@@ -28,4 +18,11 @@ export function NodeManagerProvider(props: { children: JSX.Element }) {
)
}
export function useNodeManager() { return useContext(NodeManagerContext); }
export function useNodeManager() {
// This is a trick to narrow the typescript types: https://docs.solidjs.com/references/api-reference/component-apis/createContext
const context = useContext(NodeManagerContext);
if (!context) {
throw new Error("useNodeManager: cannot find a NodeManagerContext")
}
return context;
}