Save payment tokens in localStorage

This commit is contained in:
ekzyis 2023-08-12 03:18:56 +02:00
parent 4d725272e3
commit f0bc1baed2
3 changed files with 53 additions and 3 deletions

View File

@ -12,6 +12,7 @@ import { useMe } from './me'
import { useShowModal } from './modal' import { useShowModal } from './modal'
import { sleep } from '../lib/time' import { sleep } from '../lib/time'
import FundError, { isInsufficientFundsError } from './fund-error' import FundError, { isInsufficientFundsError } from './fund-error'
import { usePaymentTokens } from './payment-tokens'
export function Invoice ({ invoice, onConfirmation, successVerb }) { export function Invoice ({ invoice, onConfirmation, successVerb }) {
let variant = 'default' let variant = 'default'
@ -161,15 +162,20 @@ export const useInvoiceable = (fn, options = defaultOptions) => {
}`) }`)
const showModal = useShowModal() const showModal = useShowModal()
const [fnArgs, setFnArgs] = useState() const [fnArgs, setFnArgs] = useState()
const { addPaymentToken, removePaymentToken } = usePaymentTokens()
// fix for bug where `showModal` runs the code for two modals and thus executes `onConfirmation` twice // fix for bug where `showModal` runs the code for two modals and thus executes `onConfirmation` twice
let errorCount = 0 let errorCount = 0
const onConfirmation = useCallback( const onConfirmation = useCallback(
(onClose, hmac) => { (onClose, hmac) => {
return async ({ id, satsReceived, hash }) => { return async ({ id, satsReceived, hash }) => {
addPaymentToken(hash, hmac, satsReceived)
await sleep(500) await sleep(500)
const repeat = () => const repeat = () =>
fn(satsReceived, ...fnArgs, hash, hmac) fn(satsReceived, ...fnArgs, hash, hmac)
.then(() => {
removePaymentToken(hash, hmac)
})
.then(onClose) .then(onClose)
.catch((error) => { .catch((error) => {
console.error(error) console.error(error)

View File

@ -0,0 +1,40 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'
export const PaymentTokenContext = React.createContext()
const fetchTokensFromLocalStorage = () => {
const tokens = JSON.parse(window.localStorage.getItem('payment-tokens') || '[]')
return tokens
}
export function PaymentTokenProvider ({ children }) {
const [tokens, setTokens] = useState([])
useEffect(() => {
setTokens(fetchTokensFromLocalStorage())
}, [])
const addPaymentToken = useCallback((hash, hmac, amount) => {
const token = hash + '|' + hmac
const newTokens = [...tokens, { token, amount }]
window.localStorage.setItem('payment-tokens', JSON.stringify(newTokens))
setTokens(newTokens)
}, [tokens])
const removePaymentToken = useCallback((hash, hmac) => {
const token = hash + '|' + hmac
const newTokens = tokens.filter(({ token: t }) => t !== token)
window.localStorage.setItem('payment-tokens', JSON.stringify(newTokens))
setTokens(newTokens)
}, [tokens])
return (
<PaymentTokenContext.Provider value={{ tokens, addPaymentToken, removePaymentToken }}>
{children}
</PaymentTokenContext.Provider>
)
}
export function usePaymentTokens () {
return useContext(PaymentTokenContext)
}

View File

@ -14,6 +14,7 @@ import { ServiceWorkerProvider } from '../components/serviceworker'
import { SSR } from '../lib/constants' import { SSR } from '../lib/constants'
import NProgress from 'nprogress' import NProgress from 'nprogress'
import 'nprogress/nprogress.css' import 'nprogress/nprogress.css'
import { PaymentTokenProvider } from '../components/payment-tokens'
NProgress.configure({ NProgress.configure({
showSpinner: false showSpinner: false
@ -89,11 +90,14 @@ function MyApp ({ Component, pageProps: { ...props } }) {
<ServiceWorkerProvider> <ServiceWorkerProvider>
<PriceProvider price={price}> <PriceProvider price={price}>
<LightningProvider> <LightningProvider>
<ShowModalProvider> <PaymentTokenProvider>
<Component ssrData={ssrData} {...otherProps} /> <ShowModalProvider>
</ShowModalProvider> <Component ssrData={ssrData} {...otherProps} />
</ShowModalProvider>
</PaymentTokenProvider>
</LightningProvider> </LightningProvider>
</PriceProvider> </PriceProvider>
</ServiceWorkerProvider> </ServiceWorkerProvider>
</MeProvider> </MeProvider>
</ApolloProvider> </ApolloProvider>