Skip to content

Commit

Permalink
Add timeout to all wallet API calls
Browse files Browse the repository at this point in the history
  • Loading branch information
ekzyis committed Dec 14, 2024
1 parent bdd2413 commit 065459c
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 15 deletions.
9 changes: 7 additions & 2 deletions api/resolvers/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { SELECT, itemQueryWithMeta } from './item'
import { formatMsats, msatsToSats, msatsToSatsDecimal, satsToMsats } from '@/lib/format'
import {
USER_ID, INVOICE_RETENTION_DAYS,
PAID_ACTION_PAYMENT_METHODS
PAID_ACTION_PAYMENT_METHODS,
WALLET_CREATE_INVOICE_TIMEOUT_MS
} from '@/lib/constants'
import { amountSchema, validateSchema, withdrawlSchema, lnAddrSchema } from '@/lib/validate'
import assertGofacYourself from './ofac'
Expand All @@ -24,6 +25,7 @@ import validateWallet from '@/wallets/validate'
import { canReceive } from '@/wallets/common'
import performPaidAction from '../paidAction'
import performPayingAction from '../payingAction'
import { withTimeout } from '@/lib/time'

function injectResolvers (resolvers) {
console.group('injected GraphQL resolvers:')
Expand Down Expand Up @@ -65,7 +67,10 @@ function injectResolvers (resolvers) {
wallet,
testCreateInvoice:
walletDef.testCreateInvoice && validateLightning && canReceive({ def: walletDef, config: data })
? (data) => walletDef.testCreateInvoice(data, { logger, me, models })
? (data) => withTimeout(
// TODO: pass and use AbortSignal to also abort any pending requests
walletDef.testCreateInvoice(data, { logger, me, models }),
WALLET_CREATE_INVOICE_TIMEOUT_MS)
: null
}, {
settings,
Expand Down
3 changes: 3 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,6 @@ export const LONG_POLL_INTERVAL = Number(process.env.NEXT_PUBLIC_LONG_POLL_INTER
export const EXTRA_LONG_POLL_INTERVAL = Number(process.env.NEXT_PUBLIC_EXTRA_LONG_POLL_INTERVAL)

export const ZAP_UNDO_DELAY_MS = 5_000

export const WALLET_SEND_PAYMENT_TIMEOUT_MS = 15_000
export const WALLET_CREATE_INVOICE_TIMEOUT_MS = 15_000
4 changes: 1 addition & 3 deletions wallets/blink/server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { withTimeout } from '@/lib/time'
import { getScopes, SCOPE_READ, SCOPE_RECEIVE, SCOPE_WRITE, getWallet, request } from '@/wallets/blink/common'
import { msatsToSats } from '@/lib/format'
export * from '@/wallets/blink'
Expand All @@ -15,9 +14,8 @@ export async function testCreateInvoice ({ apiKeyRecv, currencyRecv }) {
throw new Error('missing RECEIVE scope')
}

const timeout = 15_000
currencyRecv = currencyRecv ? currencyRecv.toUpperCase() : 'BTC'
return await withTimeout(createInvoice({ msats: 1000, expiry: 1 }, { apiKeyRecv, currencyRecv }), timeout)
return await createInvoice({ msats: 1000, expiry: 1 }, { apiKeyRecv, currencyRecv })
}

export async function createInvoice (
Expand Down
8 changes: 7 additions & 1 deletion wallets/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { REMOVE_WALLET } from '@/fragments/wallet'
import { useWalletLogger } from '@/wallets/logger'
import { useWallets } from '.'
import validateWallet from './validate'
import { WALLET_SEND_PAYMENT_TIMEOUT_MS } from '@/lib/constants'
import { withTimeout } from '@/lib/time'

export function useWalletConfigurator (wallet) {
const { me } = useMe()
Expand Down Expand Up @@ -43,7 +45,11 @@ export function useWalletConfigurator (wallet) {
clientConfig = Object.assign(clientConfig, transformedConfig)
}
if (wallet.def.testSendPayment && validateLightning) {
transformedConfig = await wallet.def.testSendPayment(clientConfig, { me, logger })
transformedConfig = await withTimeout(
// TODO: pass and use AbortSignal to also abort any request
wallet.def.testSendPayment(clientConfig, { me, logger }),
WALLET_SEND_PAYMENT_TIMEOUT_MS
)
if (transformedConfig) {
clientConfig = Object.assign(clientConfig, transformedConfig)
}
Expand Down
7 changes: 2 additions & 5 deletions wallets/nwc/server.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { withTimeout } from '@/lib/time'
import { getNwc, supportedMethods, nwcTryRun } from '@/wallets/nwc'
export * from '@/wallets/nwc'

export async function testCreateInvoice ({ nwcUrlRecv }, { logger }) {
const timeout = 15_000

const supported = await supportedMethods(nwcUrlRecv, { logger, timeout })
const supported = await supportedMethods(nwcUrlRecv, { logger })

const supports = (method) => supported.includes(method)

Expand All @@ -20,7 +17,7 @@ export async function testCreateInvoice ({ nwcUrlRecv }, { logger }) {
}
}

return await withTimeout(createInvoice({ msats: 1000, expiry: 1 }, { nwcUrlRecv }, { logger }), timeout)
return await createInvoice({ msats: 1000, expiry: 1 }, { nwcUrlRecv }, { logger })
}

export async function createInvoice ({ msats, description, expiry }, { nwcUrlRecv }, { logger }) {
Expand Down
8 changes: 6 additions & 2 deletions wallets/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { useCallback } from 'react'
import { useSendWallets } from '@/wallets'
import { formatSats } from '@/lib/format'
import useInvoice from '@/components/use-invoice'
import { FAST_POLL_INTERVAL } from '@/lib/constants'
import { FAST_POLL_INTERVAL, WALLET_SEND_PAYMENT_TIMEOUT_MS } from '@/lib/constants'
import {
WalletsNotAvailableError, WalletSenderError, WalletAggregateError, WalletPaymentAggregateError,
WalletNotEnabledError, WalletSendNotConfiguredError, WalletPaymentError, WalletError, WalletReceiverError
} from '@/wallets/errors'
import { canSend } from './common'
import { useWalletLoggerFactory } from './logger'
import { withTimeout } from '@/lib/time'

export function useWalletPayment () {
const wallets = useSendWallets()
Expand Down Expand Up @@ -152,7 +153,10 @@ function useSendPayment () {

logger.info(`↗ sending payment: ${formatSats(satsRequested)}`, { bolt11 })
try {
const preimage = await wallet.def.sendPayment(bolt11, wallet.config, { logger })
const preimage = await withTimeout(
// TODO: pass and use AbortSignal to also abort any pending requests
wallet.def.sendPayment(bolt11, wallet.config, { logger }),
WALLET_SEND_PAYMENT_TIMEOUT_MS)
logger.ok(`↗ payment sent: ${formatSats(satsRequested)}`, { bolt11, preimage })
} catch (err) {
// we don't log the error here since we want to handle receiver errors separately
Expand Down
5 changes: 3 additions & 2 deletions wallets/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { walletLogger } from '@/api/resolvers/wallet'
import walletDefs from '@/wallets/server'
import { parsePaymentRequest } from 'ln-service'
import { toPositiveBigInt, toPositiveNumber, formatMsats, formatSats, msatsToSats } from '@/lib/format'
import { PAID_ACTION_TERMINAL_STATES } from '@/lib/constants'
import { PAID_ACTION_TERMINAL_STATES, WALLET_CREATE_INVOICE_TIMEOUT_MS } from '@/lib/constants'
import { withTimeout } from '@/lib/time'
import { canReceive } from './common'
import wrapInvoice from './wrap'
Expand Down Expand Up @@ -193,6 +193,7 @@ async function walletCreateInvoice ({ wallet, def }, {
}

return await withTimeout(
// TODO: pass and use AbortSignal to also abort any pending requests
def.createInvoice(
{
msats,
Expand All @@ -202,5 +203,5 @@ async function walletCreateInvoice ({ wallet, def }, {
},
wallet.wallet,
{ logger }
), 10_000)
), WALLET_CREATE_INVOICE_TIMEOUT_MS)
}

0 comments on commit 065459c

Please sign in to comment.