Save payment tokens in localStorage
This commit is contained in:
		
							parent
							
								
									4d725272e3
								
							
						
					
					
						commit
						f0bc1baed2
					
				@ -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)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										40
									
								
								components/payment-tokens.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								components/payment-tokens.js
									
									
									
									
									
										Normal 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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>
 | 
				
			||||||
 | 
					                    <PaymentTokenProvider>
 | 
				
			||||||
                      <ShowModalProvider>
 | 
					                      <ShowModalProvider>
 | 
				
			||||||
                        <Component ssrData={ssrData} {...otherProps} />
 | 
					                        <Component ssrData={ssrData} {...otherProps} />
 | 
				
			||||||
                      </ShowModalProvider>
 | 
					                      </ShowModalProvider>
 | 
				
			||||||
 | 
					                    </PaymentTokenProvider>
 | 
				
			||||||
                  </LightningProvider>
 | 
					                  </LightningProvider>
 | 
				
			||||||
                </PriceProvider>
 | 
					                </PriceProvider>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              </ServiceWorkerProvider>
 | 
					              </ServiceWorkerProvider>
 | 
				
			||||||
            </MeProvider>
 | 
					            </MeProvider>
 | 
				
			||||||
          </ApolloProvider>
 | 
					          </ApolloProvider>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user