1- import { useState , useEffect } from "react"
1+ import { useState , useEffect , useCallback } from "react"
22import { initCashuManager , getCashuManager } from "@/lib/cashu/manager"
33import type { Manager } from "@/lib/cashu/core/index"
44import type { HistoryEntry , SendHistoryEntry } from "@/lib/cashu/core/models/History"
@@ -48,8 +48,16 @@ const ensureMeltQuoteReposInit = async () => {
4848const DEFAULT_MINT = "https://mint.coinos.io"
4949
5050export default function CashuWallet ( ) {
51- const { expandHistory, activeTab, toggleExpandHistory, setActiveTab} =
52- useCashuWalletStore ( )
51+ const {
52+ expandHistory,
53+ activeTab,
54+ activeMint,
55+ toggleExpandHistory,
56+ setActiveTab,
57+ setActiveMint,
58+ setCachedMintInfo,
59+ getCachedMintInfo,
60+ } = useCashuWalletStore ( )
5361 const { activeProviderType} = useWalletProviderStore ( )
5462 const navigate = useNavigate ( )
5563 const location = useLocation ( )
@@ -69,6 +77,7 @@ export default function CashuWallet() {
6977 )
7078 const [ sendDialogInitialInvoice , setSendDialogInitialInvoice ] = useState < string > ( "" )
7179 const [ receiveDialogInitialToken , setReceiveDialogInitialToken ] = useState < string > ( "" )
80+ const [ receiveDialogInitialInvoice , setReceiveDialogInitialInvoice ] = useState < string > ( "" )
7281 const [ refreshing , setRefreshing ] = useState ( false )
7382 const [ qrError , setQrError ] = useState < string > ( "" )
7483 const [ isOffline , setIsOffline ] = useState ( ! navigator . onLine )
@@ -186,10 +195,18 @@ export default function CashuWallet() {
186195 }
187196 }
188197
189- const handleSendEntryClick = ( entry : SendHistoryEntry ) => {
198+ const handleSendEntryClick = useCallback ( ( entry : SendHistoryEntry ) => {
190199 setSendDialogInitialToken ( entry . token )
191200 setShowSendDialog ( true )
192- }
201+ } , [ ] )
202+
203+ const handleMintEntryClick = useCallback ( ( entry : HistoryEntry ) => {
204+ if ( entry . type === "mint" && entry . state === "UNPAID" ) {
205+ // Show receive dialog with the pending invoice
206+ setReceiveDialogInitialInvoice ( entry . paymentRequest )
207+ setShowReceiveDialog ( true )
208+ }
209+ } , [ ] )
193210
194211 const handleCloseSendDialog = ( ) => {
195212 setShowSendDialog ( false )
@@ -200,6 +217,7 @@ export default function CashuWallet() {
200217 const handleCloseReceiveDialog = ( ) => {
201218 setShowReceiveDialog ( false )
202219 setReceiveDialogInitialToken ( "" )
220+ setReceiveDialogInitialInvoice ( "" )
203221 }
204222
205223 const handleRefresh = async ( ) => {
@@ -330,11 +348,17 @@ export default function CashuWallet() {
330348
331349 // Handle receiveToken from navigation state
332350 useEffect ( ( ) => {
333- const state = location . state as { receiveToken ?: string } | undefined
351+ const state = location . state as { receiveToken ?: string ; lightningInvoice ?: string } | undefined
334352 if ( state ?. receiveToken && manager ) {
335353 setReceiveDialogInitialToken ( state . receiveToken )
336354 setShowReceiveDialog ( true )
337355 }
356+ if ( state ?. lightningInvoice && manager ) {
357+ setSendDialogInitialInvoice ( state . lightningInvoice )
358+ setShowSendDialog ( true )
359+ // Clear state after handling
360+ window . history . replaceState ( { } , "" , "/wallet" )
361+ }
338362 } , [ location . state , manager ] )
339363
340364 // Handle paymentRequest from URL params
@@ -392,6 +416,28 @@ export default function CashuWallet() {
392416 const bal = await mgr . wallet . getBalances ( )
393417 setBalance ( bal )
394418
419+ // Load all mints and cache their info
420+ const mints = await mgr . mint . getAllMints ( )
421+ for ( const { mintUrl} of mints ) {
422+ // Skip if already cached
423+ if ( getCachedMintInfo ( mintUrl ) ) continue
424+
425+ // Fetch and cache mint info
426+ try {
427+ const { CashuMint} = await import ( "@cashu/cashu-ts" )
428+ const mint = new CashuMint ( mintUrl )
429+ const info = await mint . getInfo ( )
430+ setCachedMintInfo ( mintUrl , info )
431+ } catch ( err ) {
432+ console . warn ( `Failed to fetch info for ${ mintUrl } :` , err )
433+ }
434+ }
435+
436+ // Set active mint if not already set
437+ if ( ! activeMint && bal && Object . keys ( bal ) . length > 0 ) {
438+ setActiveMint ( Object . keys ( bal ) [ 0 ] )
439+ }
440+
395441 // Load history
396442 const hist = await mgr . history . getPaginatedHistory ( 0 , 1000 )
397443 const enrichedHist = await enrichHistoryWithMetadata ( hist )
@@ -552,12 +598,15 @@ export default function CashuWallet() {
552598 </ div >
553599
554600 { /* Mint Info */ }
555- { balance && Object . keys ( balance ) . length > 0 && (
601+ { activeMint && (
556602 < div className = "text-sm text-base-content/60 mt-4" >
557603 Mint:{ " " }
558- < span className = "font-medium" >
559- { Object . keys ( balance ) [ 0 ] . replace ( / ^ h t t p s ? : \/ \/ / , "" ) }
560- </ span >
604+ < button
605+ onClick = { ( ) => setActiveTab ( "mints" ) }
606+ className = "font-medium hover:underline cursor-pointer"
607+ >
608+ { activeMint . replace ( / ^ h t t p s ? : \/ \/ / , "" ) }
609+ </ button >
561610 </ div >
562611 ) }
563612 </ div >
@@ -654,6 +703,7 @@ export default function CashuWallet() {
654703 history = { history }
655704 usdRate = { usdRate }
656705 onSendEntryClick = { handleSendEntryClick }
706+ onMintEntryClick = { handleMintEntryClick }
657707 />
658708 </ div >
659709 ) }
@@ -665,6 +715,8 @@ export default function CashuWallet() {
665715 balance = { balance }
666716 manager = { manager }
667717 onBalanceUpdate = { refreshData }
718+ activeMint = { activeMint }
719+ onMintClick = { setActiveMint }
668720 />
669721 </ div >
670722 ) }
@@ -676,7 +728,7 @@ export default function CashuWallet() {
676728 isOpen = { showSendDialog }
677729 onClose = { handleCloseSendDialog }
678730 manager = { manager }
679- mintUrl = { balance ? Object . keys ( balance ) [ 0 ] : DEFAULT_MINT }
731+ mintUrl = { activeMint || DEFAULT_MINT }
680732 onSuccess = { refreshData }
681733 initialToken = { sendDialogInitialToken }
682734 initialInvoice = { sendDialogInitialInvoice }
@@ -687,9 +739,10 @@ export default function CashuWallet() {
687739 isOpen = { showReceiveDialog }
688740 onClose = { handleCloseReceiveDialog }
689741 manager = { manager }
690- mintUrl = { balance ? Object . keys ( balance ) [ 0 ] : DEFAULT_MINT }
742+ mintUrl = { activeMint || DEFAULT_MINT }
691743 onSuccess = { refreshData }
692744 initialToken = { receiveDialogInitialToken }
745+ initialInvoice = { receiveDialogInitialInvoice }
693746 balance = { totalBalance }
694747 onScanRequest = { ( ) => setShowQRScanner ( true ) }
695748 />
0 commit comments