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
11 changes: 3 additions & 8 deletions apps/order-book/frontend/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { Deposit } from "./components/Deposit";
import { Header } from "./components/Header";
import { LiveBlocks } from "./components/LiveBlocks";
import { OrderBook } from "./components/OrderBook";
import { AccountProvider, useAccountContext } from "./contexts/AccountContext";
import { ManifestProvider } from "./contexts/ManifestContext";
import { useBalances } from "./hooks/useBalances";
import { useDemoSignUp } from "./hooks/useDemoSignUp";
import { useSignUp } from "./hooks/useSignUp";
import { useStoredAccount } from "./hooks/useStoredAccount";
import "./index.css";
import { RouterProvider, useMatch, useRoute } from "./lib/router";
import { AboutOrderBook } from "./pages/AboutOrderBook";
Expand Down Expand Up @@ -53,7 +52,7 @@ function Auth() {
}

function OrderBookRoute() {
const { account, loading } = useAccountContext();
const { data: account, isPending: loading } = useStoredAccount();
const balances = useBalances(account?.accountId);

if (loading) return <Shell compact />;
Expand Down Expand Up @@ -133,11 +132,7 @@ export function App() {
return (
<QueryClientProvider client={queryClient}>
<RouterProvider>
<ManifestProvider>
<AccountProvider>
<Routes />
</AccountProvider>
</ManifestProvider>
<Routes />
</RouterProvider>
</QueryClientProvider>
);
Expand Down
8 changes: 5 additions & 3 deletions apps/order-book/frontend/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { TokenAmount, USD } from "order-book-sdk";
import { useAccountContext } from "../contexts/AccountContext";
import { useAccount } from "../hooks/useAccount";
import { useBalances } from "../hooks/useBalances";
import { usePing } from "../hooks/usePing";
import { useSignOut } from "../hooks/useSignOut";
import { useStoredAccount } from "../hooks/useStoredAccount";
import { Link } from "../lib/router";

export function Header({ compact = false }: { compact?: boolean }) {
Expand Down Expand Up @@ -43,7 +44,8 @@ function Ping() {
}

function HeaderAccountControls() {
const { account, setAccount } = useAccountContext();
const { data: account } = useStoredAccount();
const signOut = useSignOut();
const { data } = useBalances(account?.accountId);
const accountQuery = useAccount(account?.accountId);

Expand All @@ -67,7 +69,7 @@ function HeaderAccountControls() {
) : null}
<button
type="button"
onClick={() => void setAccount(null)}
onClick={() => signOut.mutate()}
className="border border-black px-3 py-1 cursor-pointer hover:bg-zinc-50"
>
sign out
Expand Down
4 changes: 2 additions & 2 deletions apps/order-book/frontend/components/OrderBook.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { fromLots, INSTRUMENTS, q32ToPrice, TokenAmount } from "order-book-sdk";
import { useState } from "react";
import { useAccountContext } from "../contexts/AccountContext";
import { useBalances } from "../hooks/useBalances";
import { useDepth } from "../hooks/useDepth";
import { useMarketOrderMutation } from "../hooks/useMarketOrderMutation";
import { usePrice } from "../hooks/usePrice";
import { useStoredAccount } from "../hooks/useStoredAccount";

function lotAligned(raw: bigint, lotExp: number): bigint {
const e = BigInt(lotExp);
Expand Down Expand Up @@ -33,7 +33,7 @@ const instruments = Object.entries(INSTRUMENTS) as [
][];

export function OrderBook() {
const { account } = useAccountContext();
const { data: account } = useStoredAccount();
const { data: balancesData } = useBalances(account?.accountId);

return (
Expand Down
130 changes: 0 additions & 130 deletions apps/order-book/frontend/contexts/AccountContext.tsx

This file was deleted.

40 changes: 0 additions & 40 deletions apps/order-book/frontend/contexts/ManifestContext.tsx

This file was deleted.

38 changes: 28 additions & 10 deletions apps/order-book/frontend/hooks/useDemoSignUp.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { useMutation } from "@tanstack/react-query";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { DEFAULT_NON_ROOT_PERMISSIONS } from "order-book-sdk";
import { Secp256k1, Signature } from "ox";
import type * as HexNamespace from "ox/Hex";
import {
authorizeMutation,
deploymentKey,
deriveAccountID,
getAuthorizationPayload,
type TypedMutation,
} from "typewriter/client";
import { bytesToHex, encodeAbiParameters, type Hex } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { useAccountContext } from "../contexts/AccountContext";
import { useManifestContext } from "../contexts/ManifestContext";
import { saveStoredAccount } from "../lib/account-store";
import { request } from "../lib/api";
import { exportPublicKey, generateSessionKey } from "../lib/sessionKey";
import { useManifest } from "./useManifest";
import { toAccount } from "./useStoredAccount";

function signSecp256k1(privateKey: Hex, payload: Hex): Hex {
const signature = Secp256k1.sign({
Expand All @@ -27,12 +28,18 @@ function signSecp256k1(privateKey: Hex, payload: Hex): Hex {
}

export function useDemoSignUp() {
const { setAccount } = useAccountContext();
const { manifest } = useManifestContext();
const { data: manifest } = useManifest();
const storageKey =
manifest === undefined
? undefined
: deploymentKey(manifest.chainId, manifest.address);
const queryClient = useQueryClient();

return useMutation({
mutationFn: async () => {
if (manifest === null) throw new Error("Missing manifest");
if (manifest === undefined || storageKey === undefined) {
throw new Error("Missing manifest");
}
const rootPrivateKey = generatePrivateKey();
const rootAddress = privateKeyToAccount(rootPrivateKey).address;
const rootPublicKey = encodeAbiParameters(
Expand All @@ -58,8 +65,14 @@ export function useDemoSignUp() {
);
await request("/api", { method: "POST", body: create });

const sessionKey = await generateSessionKey();
const sessionPublicKey = await exportPublicKey(sessionKey);
const keyPair = await crypto.subtle.generateKey(
{ name: "ECDSA", namedCurve: "P-256" },
false,
["sign", "verify"],
);
const sessionPublicKey = bytesToHex(
new Uint8Array(await crypto.subtle.exportKey("raw", keyPair.publicKey)),
);
const addMutation = {
name: "AddCredential",
params: {
Expand All @@ -82,7 +95,12 @@ export function useDemoSignUp() {
),
);
await request("/api", { method: "POST", body: add });
await setAccount({ accountId, keyId: 1, sessionKey });
const stored = { accountId, keyPair };
await saveStoredAccount(storageKey, stored);
return toAccount(stored);
},
onSuccess: (account) => {
queryClient.setQueryData(["storedAccount", storageKey], account);
},
});
}
26 changes: 17 additions & 9 deletions apps/order-book/frontend/hooks/useDepositMutation.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { deploymentKey, incrementNonce } from "typewriter/client";
import type { Address } from "viem";
import { getNonce, useAccountContext } from "../contexts/AccountContext";
import { useManifestContext } from "../contexts/ManifestContext";
import { request } from "../lib/api";
import { useManifest } from "./useManifest";
import { signDeposit } from "./useSign";
import { useStoredAccount } from "./useStoredAccount";

type DepositParams = {
asset: Address;
amount: bigint;
};

export function useDepositMutation() {
const { account, incrementSeq } = useAccountContext();
const { manifest } = useManifestContext();
const { data: manifest } = useManifest();
const storageKey =
manifest === undefined
? undefined
: deploymentKey(manifest.chainId, manifest.address);
const { data: account } = useStoredAccount();
const queryClient = useQueryClient();

return useMutation({
mutationFn: async ({ asset, amount }: DepositParams) => {
if (!account) throw new Error("No account");
if (manifest === null) throw new Error("Missing manifest");
if (manifest === undefined) throw new Error("Missing manifest");

const signed = await signDeposit(account, manifest, getNonce(account), {
const signed = await signDeposit(account, manifest, account.nonce, {
asset,
amount,
});
Expand All @@ -34,10 +39,13 @@ export function useDepositMutation() {
`[tx-latency] deposit ${(performance.now() - start).toFixed(1)}ms`,
);

return result;
return {
id: result.id,
account: { ...account, nonce: incrementNonce(account.nonce) },
};
},
onSuccess: async () => {
incrementSeq();
onSuccess: async (result) => {
queryClient.setQueryData(["storedAccount", storageKey], result.account);
await queryClient.invalidateQueries({
queryKey: ["balances", account?.accountId],
});
Expand Down
Loading
Loading