Fix QR code interaction with WebLN provider (#834)
* Fix passing of bolt11 for QR payments * Fix missing provider check * Only cancel invoice if hash and hmac were given * Fix duplicate toast on error * Fix relay might not be set yet when sendPayment is called
This commit is contained in:
parent
8727f95fd9
commit
afe096e516
|
@ -3,27 +3,24 @@ import { CopyInput, InputSkeleton } from './form'
|
||||||
import InvoiceStatus from './invoice-status'
|
import InvoiceStatus from './invoice-status'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useWebLN } from './webln'
|
import { useWebLN } from './webln'
|
||||||
import { useToast } from './toast'
|
|
||||||
|
|
||||||
export default function Qr ({ asIs, value, webLn, statusVariant, description, status }) {
|
export default function Qr ({ asIs, value, webLn, statusVariant, description, status }) {
|
||||||
const qrValue = asIs ? value : 'lightning:' + value.toUpperCase()
|
const qrValue = asIs ? value : 'lightning:' + value.toUpperCase()
|
||||||
|
|
||||||
const provider = useWebLN()
|
const provider = useWebLN()
|
||||||
const toaster = useToast()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function effect () {
|
async function effect () {
|
||||||
if (webLn) {
|
if (webLn && provider?.enabled) {
|
||||||
try {
|
try {
|
||||||
await provider.sendPayment(value)
|
await provider.sendPayment({ bolt11: value })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e?.message)
|
console.log(e?.message)
|
||||||
toaster.danger(`${provider.name}: ${e?.message}`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effect()
|
effect()
|
||||||
}, [])
|
}, [provider])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -87,7 +87,8 @@ function RawWebLNProvider ({ children }) {
|
||||||
autohide: false,
|
autohide: false,
|
||||||
onCancel: async () => {
|
onCancel: async () => {
|
||||||
try {
|
try {
|
||||||
await cancelInvoice({ variables: { hash, hmac } })
|
// hash and hmac are only passed for HODL invoices
|
||||||
|
if (hash && hmac) await cancelInvoice({ variables: { hash, hmac } })
|
||||||
canceled = true
|
canceled = true
|
||||||
toaster.warning('payment canceled')
|
toaster.warning('payment canceled')
|
||||||
removeToast = undefined
|
removeToast = undefined
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// https://github.com/getAlby/js-sdk/blob/master/src/webln/NostrWeblnProvider.ts
|
// https://github.com/getAlby/js-sdk/blob/master/src/webln/NostrWeblnProvider.ts
|
||||||
|
|
||||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'
|
||||||
import { Relay, finalizeEvent, nip04 } from 'nostr-tools'
|
import { Relay, finalizeEvent, nip04 } from 'nostr-tools'
|
||||||
import { parseNwcUrl } from '../../lib/url'
|
import { parseNwcUrl } from '../../lib/url'
|
||||||
|
|
||||||
|
@ -13,11 +13,21 @@ export function NWCProvider ({ children }) {
|
||||||
const [secret, setSecret] = useState()
|
const [secret, setSecret] = useState()
|
||||||
const [enabled, setEnabled] = useState()
|
const [enabled, setEnabled] = useState()
|
||||||
const [initialized, setInitialized] = useState(false)
|
const [initialized, setInitialized] = useState(false)
|
||||||
const [relay, setRelay] = useState()
|
|
||||||
|
const relayRef = useRef()
|
||||||
|
|
||||||
const name = 'NWC'
|
const name = 'NWC'
|
||||||
const storageKey = 'webln:provider:nwc'
|
const storageKey = 'webln:provider:nwc'
|
||||||
|
|
||||||
|
const updateRelay = async (relayUrl) => {
|
||||||
|
try {
|
||||||
|
relayRef.current?.close()
|
||||||
|
if (relayUrl) relayRef.current = await Relay.connect(relayUrl)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const loadConfig = useCallback(async () => {
|
const loadConfig = useCallback(async () => {
|
||||||
const configStr = window.localStorage.getItem(storageKey)
|
const configStr = window.localStorage.getItem(storageKey)
|
||||||
if (!configStr) {
|
if (!configStr) {
|
||||||
|
@ -39,6 +49,7 @@ export function NWCProvider ({ children }) {
|
||||||
try {
|
try {
|
||||||
const supported = await validateParams(params)
|
const supported = await validateParams(params)
|
||||||
setEnabled(supported.includes('pay_invoice'))
|
setEnabled(supported.includes('pay_invoice'))
|
||||||
|
await updateRelay(params.relayUrl)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('invalid NWC config:', err)
|
console.error('invalid NWC config:', err)
|
||||||
setEnabled(false)
|
setEnabled(false)
|
||||||
|
@ -69,6 +80,7 @@ export function NWCProvider ({ children }) {
|
||||||
try {
|
try {
|
||||||
const supported = await validateParams(params)
|
const supported = await validateParams(params)
|
||||||
setEnabled(supported.includes('pay_invoice'))
|
setEnabled(supported.includes('pay_invoice'))
|
||||||
|
await updateRelay(params.relayUrl)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('invalid NWC config:', err)
|
console.error('invalid NWC config:', err)
|
||||||
setEnabled(false)
|
setEnabled(false)
|
||||||
|
@ -85,25 +97,12 @@ export function NWCProvider ({ children }) {
|
||||||
setEnabled(undefined)
|
setEnabled(undefined)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let relay
|
|
||||||
(async function () {
|
|
||||||
if (relayUrl) {
|
|
||||||
relay = await Relay.connect(relayUrl)
|
|
||||||
setRelay(relay)
|
|
||||||
}
|
|
||||||
})().catch((err) => {
|
|
||||||
console.error(err)
|
|
||||||
setRelay(null)
|
|
||||||
})
|
|
||||||
return () => {
|
|
||||||
relay?.close()
|
|
||||||
setRelay(null)
|
|
||||||
}
|
|
||||||
}, [relayUrl])
|
|
||||||
|
|
||||||
const sendPayment = useCallback((bolt11) => {
|
const sendPayment = useCallback((bolt11) => {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
const relay = relayRef.current
|
||||||
|
if (!relay) {
|
||||||
|
return reject(new Error('not connected to relay'))
|
||||||
|
}
|
||||||
(async function () {
|
(async function () {
|
||||||
// XXX set this to mock NWC relays
|
// XXX set this to mock NWC relays
|
||||||
const MOCK_NWC_RELAY = false
|
const MOCK_NWC_RELAY = false
|
||||||
|
@ -168,9 +167,9 @@ export function NWCProvider ({ children }) {
|
||||||
})
|
})
|
||||||
})().catch(reject)
|
})().catch(reject)
|
||||||
})
|
})
|
||||||
}, [relay, walletPubkey, secret])
|
}, [walletPubkey, secret])
|
||||||
|
|
||||||
const getInfo = useCallback(() => getInfoWithRelay(relay, walletPubkey), [relay, walletPubkey])
|
const getInfo = useCallback(() => getInfoWithRelay(relayRef?.current, walletPubkey), [relayRef?.current, walletPubkey])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadConfig().catch(console.error)
|
loadConfig().catch(console.error)
|
||||||
|
|
Loading…
Reference in New Issue