From 2c06dc68340f33ef8b4f8176367979bd6e42dfa7 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 17:16:55 +0200 Subject: [PATCH 01/12] Display discounted amount --- src/generated/client/types.gen.ts | 18 ++++++++++++++++-- src/pages/quotes/QuotePage.tsx | 13 +++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index 5e0a1be..1772032 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -135,9 +135,21 @@ export type InfoReply = { } | { bill: BillInfo; id: string; - signatures: Array; + status: 'Cancelled'; + tstamp: string; +} | { + bill: BillInfo; + id: string; + keyset_id: string; status: 'Offered'; + discounted: number; ttl: string; +} | { + bill: BillInfo; + id: string; + status: 'OfferExpired'; + discounted: number; + tstamp: string; } | { bill: BillInfo; id: string; @@ -145,12 +157,14 @@ export type InfoReply = { } | { bill: BillInfo; id: string; - signatures: Array; + keyset_id: string; + discounted: number; status: 'Accepted'; } | { bill: BillInfo; id: string; status: 'Rejected'; + discounted: number; tstamp: string; }; diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 59f30b1..922f8a5 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -579,6 +579,7 @@ function PayeePublicDataCard({ value }: { value?: PayeePublicData }) { } function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) { + console.log("Quote Page", value) return (
@@ -601,6 +602,18 @@ function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) Sum: {formatNumber("en", value.bill?.sum)} sat + {(value.status === "Offered" || + value.status === "Accepted" || + value.status === "Rejected" || + value.status === "OfferExpired") && + "discounted" in value ? ( + + Discounted: + {formatNumber("en", value.discounted)} crsat + + ) : ( + <> + )} Maturity date: From 45703d165b514d4a603a75a3cd6449884fea0252 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 17:25:10 +0200 Subject: [PATCH 02/12] Add american english canceled page and offer expired --- src/components/AppSidebar.tsx | 8 ++++++++ src/generated/client/types.gen.ts | 2 +- src/main.tsx | 3 ++- src/pages/quotes/StatusQuotePage.tsx | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/AppSidebar.tsx b/src/components/AppSidebar.tsx index c141a88..0f3183e 100644 --- a/src/components/AppSidebar.tsx +++ b/src/components/AppSidebar.tsx @@ -29,6 +29,10 @@ const data = { title: "Offered", url: "/quotes/offered", }, + { + title: "Offer Expired", + url: "/quotes/offerexpired", + }, { title: "Accepted", url: "/quotes/accepted", @@ -41,6 +45,10 @@ const data = { title: "Rejected", url: "/quotes/rejected", }, + { + title: "Canceled", + url: "/quotes/canceled", + }, ], }, ], diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index 1772032..4f47db9 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -135,7 +135,7 @@ export type InfoReply = { } | { bill: BillInfo; id: string; - status: 'Cancelled'; + status: 'Canceled'; tstamp: string; } | { bill: BillInfo; diff --git a/src/main.tsx b/src/main.tsx index c145461..1e99f55 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -39,10 +39,11 @@ function App() { } /> } /> } /> + } /> } /> + } /> } /> } /> - {/* } /> */} } /> } /> } /> diff --git a/src/pages/quotes/StatusQuotePage.tsx b/src/pages/quotes/StatusQuotePage.tsx index 2465c42..c74ff73 100644 --- a/src/pages/quotes/StatusQuotePage.tsx +++ b/src/pages/quotes/StatusQuotePage.tsx @@ -16,7 +16,7 @@ import { formatNumber, truncateString } from "@/utils/strings" import { Badge } from "@/components/ui/badge" import { cn } from "@/lib/utils" -type QuoteStatus = "Accepted" | "Denied" | "Expired" | "Offered" | "Pending" | "Rejected" | "Cancelled" +type QuoteStatus = "Accepted" | "Denied" | "OfferExpired" | "Offered" | "Pending" | "Rejected" | "Canceled" interface StatusQuotePageProps { status?: QuoteStatus From ab24e928b475558026923f51d08377b6d85a769a Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 19:17:41 +0200 Subject: [PATCH 03/12] Display keyset id --- src/pages/quotes/QuotePage.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 922f8a5..82904c3 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -590,6 +590,14 @@ function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) {value.id} + {(value.status === "Offered" || value.status === "Accepted") && "keyset_id" in value ? ( + + Keyset ID: + {value.keyset_id} + + ) : ( + <> + )} Status: From c76e058562df802cc94285400486cedfa8a2bab9 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 20:34:09 +0200 Subject: [PATCH 04/12] Display keyset status --- src/generated/client/sdk.gen.ts | 14 ++- src/generated/client/types.gen.ts | 26 +++++ src/pages/quotes/QuotePage.tsx | 169 ++++++++++++++++++++---------- 3 files changed, 150 insertions(+), 59 deletions(-) diff --git a/src/generated/client/sdk.gen.ts b/src/generated/client/sdk.gen.ts index e4d1df7..ca92b25 100644 --- a/src/generated/client/sdk.gen.ts +++ b/src/generated/client/sdk.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch'; -import type { ListQuotesData, ListQuotesResponse, ListPendingQuotesData, ListPendingQuotesResponse, AdminLookupQuoteData, AdminLookupQuoteResponse, AdminUpdateQuoteData, AdminUpdateQuoteResponse, ResolveOfferData, EnquireQuoteData, EnquireQuoteResponse, LookupQuoteData, LookupQuoteResponse, ActivateKeysetData, ActivateKeysetResponse, DebitData, CreditData, ECashBalance, OnChainBalanceData, OnChainData} from './types.gen'; +import type { ListQuotesData, ListQuotesResponse, ListPendingQuotesData, ListPendingQuotesResponse, AdminLookupQuoteData, AdminLookupQuoteResponse, AdminUpdateQuoteData, AdminUpdateQuoteResponse, ResolveOfferData, EnquireQuoteData, EnquireQuoteResponse, LookupQuoteData, LookupQuoteResponse, ActivateKeysetData, ActivateKeysetResponse, DebitData, CreditData, ECashBalance, OnChainBalanceData, OnChainData, KeysetInfoData, KeySetInfo} from './types.gen'; import { client as _heyApiClient } from './client.gen'; export type Options = ClientOptions & { @@ -125,3 +125,15 @@ export const onchainBalance = (options: Op ...options }); }; + +/** + * --------------------------- KeySetInfo +*/ + + +export const keysetInfo = (options: Options) => { + return (options.client ?? _heyApiClient).get({ + url: '/v1/admin/keysets/{keyset_id}', + ...options + }); +}; diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index 4f47db9..e084318 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -476,3 +476,29 @@ export type OnChainData = { query?: never; url: '/v1/admin/onchain/balance'; }; + + +// {"id":"0095980cf97298e4","unit":"crsat","active":true,"input_fee_ppk":0} +// KeysetResponse +// cashu::nuts::nut02 +// pub struct KeySetInfo { +// pub id: Id, +// pub unit: CurrencyUnit, +// pub active: bool, +// pub input_fee_ppk: u64, +// } + +export type KeySetInfo = { + id: string; + unit: CurrencyUnit; + active: boolean; + input_fee_ppk: number; +}; + + +export type KeysetInfoData = { + body?: never; + path?: never; + query?: never; + url: '/v1/admin/keysets/{keyset_id}'; +}; diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 82904c3..407c0e4 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -6,18 +6,18 @@ import { Button } from "@/components/ui/button" import { Skeleton } from "@/components/ui/skeleton" import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" -import { IdentityPublicData, PayeePublicData, InfoReply, AnonPublicData } from "@/generated/client" +import { IdentityPublicData, PayeePublicData, InfoReply, AnonPublicData, KeySetInfo } from "@/generated/client" import { adminLookupQuoteOptions, adminLookupQuoteQueryKey, adminUpdateQuoteMutation, } from "@/generated/client/@tanstack/react-query.gen" -import { activateKeyset } from "@/generated/client/sdk.gen" +import { activateKeyset, keysetInfo } from "@/generated/client/sdk.gen" import { cn, getInitials } from "@/lib/utils" import { formatDate, humanReadableDuration } from "@/utils/dates" import { formatNumber, truncateString } from "@/utils/strings" -import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query" +import { useMutation, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query" import { getDeterministicColor } from "@/utils/dev" import { LoaderIcon } from "lucide-react" @@ -211,7 +211,15 @@ function DenyConfirmDrawer({ children, onSubmit, ...drawerProps }: DenyConfirmDr ) } -function QuoteActions({ value, isFetching }: { value: InfoReply; isFetching: boolean }) { +function QuoteActions({ + value, + isFetching, + keysetActive, +}: { + value: InfoReply + isFetching: boolean + keysetActive: boolean +}) { const [offerFormData, setOfferFormData] = useState() const [offerFormDrawerOpen, setOfferFormDrawerOpen] = useState(false) const [offerConfirmDrawerOpen, setOfferConfirmDrawerOpen] = useState(false) @@ -334,39 +342,48 @@ function QuoteActions({ value, isFetching }: { value: InfoReply; isFetching: boo return (
- { - onDenyQuote() - setDenyConfirmDrawerOpen(false) - }} - > - - - { - setOfferFormData(data) - setOfferConfirmDrawerOpen(true) - setOfferFormDrawerOpen(false) - }} - > - - + + + ) : ( + <> + )} + {value.status === "Pending" ? ( + { + setOfferFormData(data) + setOfferConfirmDrawerOpen(true) + setOfferFormDrawerOpen(false) + }} + > + + + ) : ( + <> + )} + - { - onActivateKeyset() - setActivateKeysetConfirmDrawerOpen(false) - }} - submitButtonText="Yes, activate keyset" - trigger={ - - } - /> + {(value.status === "Accepted" || value.status === "Offered") && "keyset_id" in value ? ( + { + onActivateKeyset() + setActivateKeysetConfirmDrawerOpen(false) + }} + submitButtonText="Yes, activate keyset" + trigger={ + + } + /> + ) : ( + <> + )}
) } @@ -580,6 +601,27 @@ function PayeePublicDataCard({ value }: { value?: PayeePublicData }) { function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) { console.log("Quote Page", value) + + const shouldFetchKeyset = (value.status === "Offered" || value.status === "Accepted") && "keyset_id" in value + + const keysetId = "keyset_id" in value ? value.keyset_id : "" + + const { data: keysetData } = useQuery({ + queryKey: ["keyset", keysetId], + queryFn: () => + keysetInfo({ + path: { keyset_id: keysetId }, + }), + enabled: shouldFetchKeyset, + }) + + let keysetActive = false + if (keysetData) { + console.log("Keyset Info:", keysetData) + if ("data" in keysetData && keysetData.data !== undefined) { + keysetActive = keysetData.data.active + } + } return (
@@ -593,7 +635,18 @@ function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) {(value.status === "Offered" || value.status === "Accepted") && "keyset_id" in value ? ( Keyset ID: - {value.keyset_id} + + {keysetId.length > 0 ? ( + + {keysetId} + + ) : ( + <> + )} + ) : ( <> @@ -667,7 +720,7 @@ function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean })
- +
) } From 1ea629e33d1b4b6b54657fea2b741bb9b9125dc7 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 20:42:23 +0200 Subject: [PATCH 05/12] Set path for keyset lookup --- src/generated/client/sdk.gen.ts | 1 - src/generated/client/types.gen.ts | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/generated/client/sdk.gen.ts b/src/generated/client/sdk.gen.ts index ca92b25..032dc66 100644 --- a/src/generated/client/sdk.gen.ts +++ b/src/generated/client/sdk.gen.ts @@ -130,7 +130,6 @@ export const onchainBalance = (options: Op * --------------------------- KeySetInfo */ - export const keysetInfo = (options: Options) => { return (options.client ?? _heyApiClient).get({ url: '/v1/admin/keysets/{keyset_id}', diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index e084318..d3d32f1 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -498,7 +498,9 @@ export type KeySetInfo = { export type KeysetInfoData = { body?: never; - path?: never; + path: { + keyset_id: string; + }; query?: never; url: '/v1/admin/keysets/{keyset_id}'; }; From 9bdea336c4ccbec52c9b8b3db7af9b208f0bc4d3 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 21:11:51 +0200 Subject: [PATCH 06/12] Clean up comments --- src/pages/quotes/QuotePage.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 407c0e4..27ba2ee 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button" import { Skeleton } from "@/components/ui/skeleton" import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" -import { IdentityPublicData, PayeePublicData, InfoReply, AnonPublicData, KeySetInfo } from "@/generated/client" +import { IdentityPublicData, PayeePublicData, InfoReply, AnonPublicData } from "@/generated/client" import { adminLookupQuoteOptions, adminLookupQuoteQueryKey, @@ -339,7 +339,6 @@ function QuoteActions({ const onActivateKeyset = () => { activateKeysetMutation.mutate() } - return (
{value.status === "Pending" ? ( @@ -416,7 +415,7 @@ function QuoteActions({
- {(value.status === "Accepted" || value.status === "Offered") && "keyset_id" in value ? ( + {value.status === "Accepted" && "keyset_id" in value ? ( { onActivateKeyset() setActivateKeysetConfirmDrawerOpen(false) + keysetActive = true }} submitButtonText="Yes, activate keyset" trigger={ @@ -586,8 +586,6 @@ function AnonPublicDataCard({ value }: { value?: AnonPublicData }) { function PayeePublicDataCard({ value }: { value?: PayeePublicData }) { if (!value) return null - console.log("Payee public data", value) - if ("Ident" in value) { const identData = (value as { Ident: IdentityPublicData }).Ident return IdentityPublicDataCard({ value: identData }) @@ -600,8 +598,6 @@ function PayeePublicDataCard({ value }: { value?: PayeePublicData }) { } function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) { - console.log("Quote Page", value) - const shouldFetchKeyset = (value.status === "Offered" || value.status === "Accepted") && "keyset_id" in value const keysetId = "keyset_id" in value ? value.keyset_id : "" @@ -617,7 +613,6 @@ function Quote({ value, isFetching }: { value: InfoReply; isFetching: boolean }) let keysetActive = false if (keysetData) { - console.log("Keyset Info:", keysetData) if ("data" in keysetData && keysetData.data !== undefined) { keysetActive = keysetData.data.active } From 09bde213f36825236b58ac4f5b6ba78c5fc57cda Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Mon, 2 Jun 2025 21:15:09 +0200 Subject: [PATCH 07/12] Add keyset info --- src/generated/client/types.gen.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index d3d32f1..16363da 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -469,7 +469,6 @@ export type OnChainBalanceData = { confirmed: number; }; - export type OnChainData = { body?: never; path?: never; @@ -477,16 +476,9 @@ export type OnChainData = { url: '/v1/admin/onchain/balance'; }; - -// {"id":"0095980cf97298e4","unit":"crsat","active":true,"input_fee_ppk":0} -// KeysetResponse -// cashu::nuts::nut02 -// pub struct KeySetInfo { -// pub id: Id, -// pub unit: CurrencyUnit, -// pub active: bool, -// pub input_fee_ppk: u64, -// } +/** + * Keyset information + */ export type KeySetInfo = { id: string; From 09826c64d12f09e15623d004f72b419d85b102a1 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Tue, 3 Jun 2025 08:49:18 +0200 Subject: [PATCH 08/12] Remove comments --- src/main.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index 1e99f55..c047c76 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -20,10 +20,6 @@ const queryClient = new QueryClient() const prepare = async () => { await initKeycloak() - // if (meta.apiMocksEnabled) { - // const { worker } = await import("./mocks/browser") - // await worker.start() - // } } function App() { From c3ab14a5a2d859a962b437e55fc0e92db46726e6 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Tue, 3 Jun 2025 09:17:21 +0200 Subject: [PATCH 09/12] Don't set keysetActive to true manually --- src/pages/quotes/QuotePage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 27ba2ee..760affe 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -424,7 +424,6 @@ function QuoteActions({ onSubmit={() => { onActivateKeyset() setActivateKeysetConfirmDrawerOpen(false) - keysetActive = true }} submitButtonText="Yes, activate keyset" trigger={ From 1c5ea240dd312833763247a380ff0ed57d78f45b Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Tue, 3 Jun 2025 09:23:12 +0200 Subject: [PATCH 10/12] Force refresh when activating a keyset --- src/pages/quotes/QuotePage.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index 760affe..ee4eca3 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -297,13 +297,7 @@ function QuoteActions({ }, onSuccess: () => { toast.success("Keyset has been activated.") - void queryClient.invalidateQueries({ - queryKey: adminLookupQuoteQueryKey({ - path: { - id: value.id, - }, - }), - }) + void queryClient.invalidateQueries() }, }) From e5ddcb44ccf830ba06b740ef1b4c2e831aeeb390 Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Tue, 3 Jun 2025 17:52:18 +0200 Subject: [PATCH 11/12] Use new enable endpoint --- src/generated/client/sdk.gen.ts | 2 +- src/generated/client/types.gen.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generated/client/sdk.gen.ts b/src/generated/client/sdk.gen.ts index 032dc66..2b547a4 100644 --- a/src/generated/client/sdk.gen.ts +++ b/src/generated/client/sdk.gen.ts @@ -91,7 +91,7 @@ export const lookupQuote = (options: Optio */ export const activateKeyset = (options: Options) => { return (options.client ?? _heyApiClient).post({ - url: '/v1/admin/keys/activate', + url: '/v1/admin/keys/enable', ...options, headers: { 'Content-Type': 'application/json', diff --git a/src/generated/client/types.gen.ts b/src/generated/client/types.gen.ts index 16363da..4515483 100644 --- a/src/generated/client/types.gen.ts +++ b/src/generated/client/types.gen.ts @@ -416,7 +416,7 @@ export type ActivateKeysetData = { body: ActivateKeysetRequest; path?: never; query?: never; - url: '/v1/admin/keys/activate'; + url: '/v1/admin/keys/enable'; }; export type ActivateKeysetErrors = { From 76a6883ca5aba460f59c5729abd202ef8bc4ca9a Mon Sep 17 00:00:00 2001 From: stefanbitcr Date: Tue, 3 Jun 2025 17:52:43 +0200 Subject: [PATCH 12/12] Show whether ebill is paid --- src/pages/quotes/QuotePage.tsx | 46 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/src/pages/quotes/QuotePage.tsx b/src/pages/quotes/QuotePage.tsx index ee4eca3..daff027 100644 --- a/src/pages/quotes/QuotePage.tsx +++ b/src/pages/quotes/QuotePage.tsx @@ -211,15 +211,7 @@ function DenyConfirmDrawer({ children, onSubmit, ...drawerProps }: DenyConfirmDr ) } -function QuoteActions({ - value, - isFetching, - keysetActive, -}: { - value: InfoReply - isFetching: boolean - keysetActive: boolean -}) { +function QuoteActions({ value, isFetching, newKeyset }: { value: InfoReply; isFetching: boolean; newKeyset: boolean }) { const [offerFormData, setOfferFormData] = useState() const [offerFormDrawerOpen, setOfferFormDrawerOpen] = useState(false) const [offerConfirmDrawerOpen, setOfferConfirmDrawerOpen] = useState(false) @@ -423,7 +415,7 @@ function QuoteActions({ trigger={