mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2025-12-19 07:14:22 +01:00
add address fetching
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
31
src/routes/Receive.tsx
Normal 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>
|
||||
|
||||
)
|
||||
}
|
||||
@@ -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 />
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Outlet } from "solid-start";
|
||||
|
||||
export default function UsersLayout() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Users</h1>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user