Skip to content

Commit f72af08

Browse files
Soxasoraekzyishuumn
authored
fix: WebLN QR fallback for anon users (#1858)
* fix: WebLN QR fallback for anon users * wip: clear zap color on payment fail * reverse clearItemMeAnonSats * webln-specific retry bypass * cleanup * send WebLN payment when user is Anon AND on QR * skip wallet checking on anon * Use WalletError for all errors in webln.sendPayment --------- Co-authored-by: ekzyis <ek@stacker.news> Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
1 parent 5e7fd69 commit f72af08

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed

components/use-qr-payment.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { useCallback } from 'react'
22
import Invoice from '@/components/invoice'
3-
import { InvoiceCanceledError, InvoiceExpiredError } from '@/wallets/errors'
3+
import { InvoiceCanceledError, InvoiceExpiredError, AnonWalletError } from '@/wallets/errors'
44
import { useShowModal } from '@/components/modal'
55
import useInvoice from '@/components/use-invoice'
6+
import { sendPayment } from '@/wallets/webln/client'
67

78
export default function useQrPayment () {
89
const invoice = useInvoice()
@@ -16,6 +17,10 @@ export default function useQrPayment () {
1617
waitFor = inv => inv?.satsReceived > 0
1718
} = {}
1819
) => {
20+
// if anon user and webln is available, try to pay with webln
21+
if (typeof window.webln !== 'undefined' && (walletError instanceof AnonWalletError)) {
22+
sendPayment(inv.bolt11).catch(e => { console.error('WebLN payment failed:', e) })
23+
}
1924
return await new Promise((resolve, reject) => {
2025
let paid
2126
const cancelAndReject = async (onClose) => {

wallets/errors.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ export class WalletsNotAvailableError extends WalletConfigurationError {
6262
}
6363
}
6464

65+
export class AnonWalletError extends WalletConfigurationError {
66+
constructor () {
67+
super('anon cannot pay with wallets')
68+
this.name = 'AnonWalletError'
69+
}
70+
}
71+
6572
export class WalletAggregateError extends WalletError {
6673
constructor (errors, invoice) {
6774
super('WalletAggregateError')

wallets/payment.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,30 @@ import { formatSats } from '@/lib/format'
44
import useInvoice from '@/components/use-invoice'
55
import { FAST_POLL_INTERVAL, WALLET_SEND_PAYMENT_TIMEOUT_MS } from '@/lib/constants'
66
import {
7-
WalletsNotAvailableError, WalletSenderError, WalletAggregateError, WalletPaymentAggregateError,
7+
AnonWalletError, WalletsNotAvailableError, WalletSenderError, WalletAggregateError, WalletPaymentAggregateError,
88
WalletNotEnabledError, WalletSendNotConfiguredError, WalletPaymentError, WalletError, WalletReceiverError
99
} from '@/wallets/errors'
1010
import { canSend } from './common'
1111
import { useWalletLoggerFactory } from './logger'
1212
import { timeoutSignal, withTimeout } from '@/lib/time'
13+
import { useMe } from '@/components/me'
1314

1415
export function useWalletPayment () {
1516
const wallets = useSendWallets()
1617
const sendPayment = useSendPayment()
1718
const loggerFactory = useWalletLoggerFactory()
1819
const invoiceHelper = useInvoice()
20+
const { me } = useMe()
1921

2022
return useCallback(async (invoice, { waitFor, updateOnFallback } = {}) => {
2123
let aggregateError = new WalletAggregateError([])
2224
let latestInvoice = invoice
2325

26+
// anon user cannot pay with wallets
27+
if (!me) {
28+
throw new AnonWalletError()
29+
}
30+
2431
// throw a special error that caller can handle separately if no payment was attempted
2532
if (wallets.length === 0) {
2633
throw new WalletsNotAvailableError()

wallets/webln/client.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
import { useEffect } from 'react'
22
import { SSR } from '@/lib/constants'
3+
import { WalletError } from '../errors'
34
export * from '@/wallets/webln'
45

56
export const sendPayment = async (bolt11) => {
67
if (typeof window.webln === 'undefined') {
7-
throw new Error('WebLN provider not found')
8+
throw new WalletError('WebLN provider not found')
89
}
910

1011
// this will prompt the user to unlock the wallet if it's locked
11-
await window.webln.enable()
12+
try {
13+
await window.webln.enable()
14+
} catch (err) {
15+
throw new WalletError(err.message)
16+
}
1217

1318
// this will prompt for payment if no budget is set
1419
const response = await window.webln.sendPayment(bolt11)
1520
if (!response) {
1621
// sendPayment returns nothing if WebLN was enabled
1722
// but browser extension that provides WebLN was then disabled
1823
// without reloading the page
19-
throw new Error('sendPayment returned no response')
24+
throw new WalletError('sendPayment returned no response')
2025
}
2126

2227
return response.preimage

0 commit comments

Comments
 (0)