Wallet receive: external transaction table and checks#3121
Conversation
b204a0c to
bdd5c6b
Compare
b03fca8 to
6a4c970
Compare
|
The fixups I pushed are back ported from work on #3125:
|
92c45c3 to
5059ca8
Compare
|
Apologies for more churn. I backported some fixups from #3125. The important stuff:
|
9cc6e5b to
8f08ff8
Compare
|
Force pushed (should be last time):
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8f08ff8. Configure here.
| invoiceExpiresAt | ||
| unknownReason | ||
| } | ||
| ` |
There was a problem hiding this comment.
Receive diagnostic missing direction
Medium Severity
EXTERNAL_TRANSACTION_FIELDS never requests direction, but externalTransactionDiagnosticMessage only emits the receive-specific STATUS_UNAVAILABLE copy when direction === 'RECEIVE'. On this receive-only path that check always fails, so users get the generic reconciliation message instead of the intended expired-invoice guidance on the activity table and transaction page.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 8f08ff8. Configure here.
| msats: walletAmountToMsatsOrUndefined({ sat: payment.receivedSat }), | ||
| actualFeeMsats: payment.fees, | ||
| settledAt: { milliseconds: payment.completedAt } | ||
| } |
There was a problem hiding this comment.
Phoenixd fee unit mismatch
Low Severity
checkInvoice wraps receivedSat with { sat: ... } before normalization, but passes payment.fees as a bare number. walletAmountToMsats treats bare numbers as msats, so phoenixd’s sat-denominated fee is stored about 1000× too small whenever a non-zero liquidity fee is present.
Reviewed by Cursor Bugbot for commit 8f08ff8. Configure here.


I'm happy with the shape of this now.
This contains the core logic/relations for external transactions (ie payments that SN is not party to) + the receive side of external txs. Send side will be its own PR.
Vaguely:
/satisticsand/wallets/[id]/activity/wallets/[wid]/transactions/[id]for viewing external txs, sharing components/design with payins/transactions/[id]make invoicewe navigate to this transaction page (we'll do this for send too)checkInvoiceto all wallets that have some means of checking invoice statuscheckInvoice, or if an invoice expires and we don't have a definite settled/failed reported by the wallet, external tx statuses are marked asunknownand we attempt to report why it's unknownPunted to other PRs:
Note
High Risk
Touches payment-adjacent persistence, background reconciliation, and wallet provider integrations; incorrect status or timeline ordering could mislead users about funds, though checks are largely read-only verification paths.
Overview
Introduces external wallet transactions (starting with receive) as first-class records with reconciliation scheduling, GraphQL types, and a dedicated
/wallets/transactions/[id]page that polls status and shows QR, diagnostics, and logs.createWalletInvoicenow persists a receive row (returns transaction id), enforces a cap on recent unpaid receives, and redirects the receive flow off the inline QR page. Wallet protocols gain optionalcheckInvoice(plus LNURL verify context where available); a minute cron/worker claims due rows and records SETTLED / FAILED / EXPIRED / UNKNOWN outcomes with structured unknown reasons.Satistics and wallet activity no longer return only PayIns: a merged SQL timeline pages lightweight keys across PayIn send/receive branches and ExternalTransaction, hydrates both shapes, and exposes
txs: [WalletActivityItem!]!. The activity table and PayIn detail pages are refactored to shared transaction UI, centralized viewer amount math, and stricterisSendcaching (ApollokeyFields: ['id','isSend']).Supporting changes include
ExternalTransactionPrisma migration and wallet log linkage, shared wallet amount/preimage/error helpers, fetch timeout behavior, and assorted wallet-client hardening (NWC ambiguous failures, WebLN enable probe, CLN rune/docs forlistinvoices).Reviewed by Cursor Bugbot for commit 8f08ff8. Bugbot is set up for automated code reviews on this repo. Configure here.