diff --git a/components/invoice.js b/components/invoice.js index 8d2a5606..172f9630 100644 --- a/components/invoice.js +++ b/components/invoice.js @@ -12,6 +12,7 @@ import { useMe } from './me' import { useShowModal } from './modal' import { sleep } from '../lib/time' import FundError, { isInsufficientFundsError } from './fund-error' +import { usePaymentTokens } from './payment-tokens' export function Invoice ({ invoice, onConfirmation, successVerb }) { let variant = 'default' @@ -161,15 +162,20 @@ export const useInvoiceable = (fn, options = defaultOptions) => { }`) const showModal = useShowModal() const [fnArgs, setFnArgs] = useState() + const { addPaymentToken, removePaymentToken } = usePaymentTokens() // fix for bug where `showModal` runs the code for two modals and thus executes `onConfirmation` twice let errorCount = 0 const onConfirmation = useCallback( (onClose, hmac) => { return async ({ id, satsReceived, hash }) => { + addPaymentToken(hash, hmac, satsReceived) await sleep(500) const repeat = () => fn(satsReceived, ...fnArgs, hash, hmac) + .then(() => { + removePaymentToken(hash, hmac) + }) .then(onClose) .catch((error) => { console.error(error) diff --git a/components/payment-tokens.js b/components/payment-tokens.js new file mode 100644 index 00000000..3ac8a63d --- /dev/null +++ b/components/payment-tokens.js @@ -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 ( + + {children} + + ) +} + +export function usePaymentTokens () { + return useContext(PaymentTokenContext) +} diff --git a/pages/_app.js b/pages/_app.js index af7b4fcd..c7f2f186 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -14,6 +14,7 @@ import { ServiceWorkerProvider } from '../components/serviceworker' import { SSR } from '../lib/constants' import NProgress from 'nprogress' import 'nprogress/nprogress.css' +import { PaymentTokenProvider } from '../components/payment-tokens' NProgress.configure({ showSpinner: false @@ -89,11 +90,14 @@ function MyApp ({ Component, pageProps: { ...props } }) { - - - + + + + + +