ZapProvider.tsx raw
1 import lightningService from '@/services/lightning.service'
2 import storage, { dispatchSettingsChanged } from '@/services/local-storage.service'
3 import { onConnected, onDisconnected } from '@getalby/bitcoin-connect-react'
4 import { GetInfoResponse, WebLNProvider } from '@webbtc/webln-types'
5 import { createContext, useContext, useEffect, useState } from 'react'
6
7 type TZapContext = {
8 isWalletConnected: boolean
9 provider: WebLNProvider | null
10 walletInfo: GetInfoResponse | null
11 defaultZapSats: number
12 updateDefaultSats: (sats: number) => void
13 defaultZapComment: string
14 updateDefaultComment: (comment: string) => void
15 quickZap: boolean
16 updateQuickZap: (quickZap: boolean) => void
17 }
18
19 const ZapContext = createContext<TZapContext | undefined>(undefined)
20
21 export const useZap = () => {
22 const context = useContext(ZapContext)
23 if (!context) {
24 throw new Error('useZap must be used within a ZapProvider')
25 }
26 return context
27 }
28
29 export function ZapProvider({ children }: { children: React.ReactNode }) {
30 const [defaultZapSats, setDefaultZapSats] = useState<number>(storage.getDefaultZapSats())
31 const [defaultZapComment, setDefaultZapComment] = useState<string>(storage.getDefaultZapComment())
32 const [quickZap, setQuickZap] = useState<boolean>(storage.getQuickZap())
33 const [isWalletConnected, setIsWalletConnected] = useState(false)
34 const [provider, setProvider] = useState<WebLNProvider | null>(null)
35 const [walletInfo, setWalletInfo] = useState<GetInfoResponse | null>(null)
36
37 useEffect(() => {
38 // Set up listeners FIRST
39 const unSubOnConnected = onConnected((provider) => {
40 setIsWalletConnected(true)
41 setWalletInfo(null)
42 setProvider(provider)
43 lightningService.provider = provider
44 provider.getInfo().then(setWalletInfo)
45 })
46 const unSubOnDisconnected = onDisconnected(() => {
47 setIsWalletConnected(false)
48 setProvider(null)
49 lightningService.provider = null
50 })
51
52 // THEN initialize bitcoin-connect (this triggers auto-reconnect which fires onConnected)
53 lightningService.initBitcoinConnect()
54
55 return () => {
56 unSubOnConnected()
57 unSubOnDisconnected()
58 }
59 }, [])
60
61 const updateDefaultSats = (sats: number) => {
62 storage.setDefaultZapSats(sats)
63 setDefaultZapSats(sats)
64 dispatchSettingsChanged()
65 }
66
67 const updateDefaultComment = (comment: string) => {
68 storage.setDefaultZapComment(comment)
69 setDefaultZapComment(comment)
70 dispatchSettingsChanged()
71 }
72
73 const updateQuickZap = (quickZap: boolean) => {
74 storage.setQuickZap(quickZap)
75 setQuickZap(quickZap)
76 dispatchSettingsChanged()
77 }
78
79 return (
80 <ZapContext.Provider
81 value={{
82 isWalletConnected,
83 provider,
84 walletInfo,
85 defaultZapSats,
86 updateDefaultSats,
87 defaultZapComment,
88 updateDefaultComment,
89 quickZap,
90 updateQuickZap
91 }}
92 >
93 {children}
94 </ZapContext.Provider>
95 )
96 }
97