Commit graph

3440 commits

Author SHA1 Message Date
Patrick Mulligan
aa58f88670 feat(extensions): add split payments extension
Some checks failed
Docker Compose Actions Workflow / test (push) Has been cancelled
Automatically distributes a percentage of every incoming payment to
one or more recipients. Supports Nostr pubkeys, LNURL, and Lightning
Addresses as targets.

Dual-layer architecture:
- NIP-57 zap tags (preferred): Nostr wallets split at sender side
- Internal splits (fallback): onPaymentReceived for non-Nostr payments
- Recursion guard (metadata.splitted) prevents double-splitting

RPC methods:
- splitpay.setTargets: configure split recipients and percentages
- splitpay.getTargets: list current configuration
- splitpay.clearTargets: remove all targets
- splitpay.getHistory: view split payment audit trail

Closes #13

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:20:50 -04:00
Patrick Mulligan
68c71599f8 fix(lnd): allow self-payments for LNURL-withdraw
Some checks failed
Docker Compose Actions Workflow / test (push) Has been cancelled
When the user's wallet (e.g. Zeus) is connected to the same LND node
that LP uses, LNURL-withdraw fails because LND rejects the payment
with "no self-payments allowed". This is safe because LP always
decrements the user's balance before paying and refunds on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
5aaa3bcc23 feat(extensions): pay from caller's balance via PayAppUserInvoice
When userPubkey is provided, resolve the ApplicationUser and call
applicationManager.PayAppUserInvoice instead of paymentManager.PayInvoice
directly. This ensures notifyAppUserPayment fires, sending
LiveUserOperation events via Nostr for real-time balance updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
cb9fb78eb8 feat(withdraw): track creator pubkey on withdraw links
Store the Nostr pubkey of the user who creates a withdraw link so the
LNURL callback debits the correct user's balance instead of the app
owner's. Pass userPubkey through from RPC handler to WithdrawManager.

- Add creator_pubkey column (migration v4)
- Store creatorPubkey on link creation
- Pass creator_pubkey to payInvoice on LNURL callback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
1273da9020 feat: route Nostr RPC to extension methods
Initialize extension system before nostrMiddleware so registered
RPC methods are available. Extension methods (e.g. withdraw.createLink)
are intercepted and routed to the extension loader before falling
through to the standard nostrTransport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
3ee8b6b010 feat(withdraw): add HTTP API for creating withdraw links
Add POST /api/v1/withdraw/create endpoint to allow external apps (ATM,
web clients) to create LNURL-withdraw links via HTTP instead of RPC.

Changes:
- Add handleCreateWithdrawLink HTTP handler
- Fix route ordering: callback routes before wildcard :unique_hash
- Extract app_id from Authorization header (Bearer app_<id>)
- Use is_unique=false for simple single-use ATM links

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
f06d50f227 feat(server): add CORS support for extension HTTP routes
Enable CORS on the extension HTTP server to allow cross-origin requests
from ATM apps and other web-based clients.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
e998762ca7 feat: integrate extension system with withdraw extension support
- Add extension loader initialization to startup
- Create mainHandlerAdapter to bridge mainHandler with extension context
- Mount extension HTTP routes on separate port (main port + 1)
- Configure EXTENSION_SERVICE_URL for LNURL link generation

The withdraw extension provides LUD-03 LNURL-withdraw support for
creating withdraw links that allow users to pull funds.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
Patrick Mulligan
8de5e4fd3a feat(extensions): add LNURL-withdraw extension
Implements LUD-03 (LNURL-withdraw) for creating withdraw links
that allow anyone to pull funds from a Lightning wallet.

Features:
- Create withdraw links with min/max amounts
- Quick vouchers: batch creation of single-use codes
- Multi-use links with wait time between uses
- Unique QR codes per use (prevents sharing exploits)
- Webhook notifications on successful withdrawals
- Full LNURL protocol compliance for wallet compatibility

Use cases:
- Faucets
- Gift cards / prepaid cards
- Tips / donations
- User onboarding

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-02 14:48:55 -04:00
77e5772afd feat(extensions): add extension loader infrastructure (#3)
Some checks are pending
Docker Compose Actions Workflow / test (push) Waiting to run
## Summary

- Adds a modular extension system for Lightning.Pub enabling third-party plugins
- Provides isolated SQLite databases per extension for data safety
- Implements ExtensionContext API for accessing Lightning.Pub services (payments, Nostr, storage)
- Supports RPC method registration with automatic namespacing
- Includes HTTP route handling for protocols like LNURL
- Event routing for payment receipts and Nostr events
- Comprehensive documentation with architecture overview and working examples

## Key Components

- `src/extensions/types.ts` - Core extension interfaces
- `src/extensions/loader.ts` - Extension discovery, loading, and lifecycle management
- `src/extensions/context.ts` - Bridge between extensions and Lightning.Pub services
- `src/extensions/database.ts` - SQLite isolation with WAL mode
- `src/extensions/README.md` - Full documentation with examples

## ExtensionContext API

| Method | Description |
|--------|-------------|
| `getApplication()` | Get application info |
| `createInvoice()` | Create Lightning invoice |
| `payInvoice()` | Pay Lightning invoice |
| `getLnurlPayInfo()` | Get LNURL-pay info for a user (enables Lightning Address/zaps) |
| `sendEncryptedDM()` | Send Nostr DM (NIP-44) |
| `publishNostrEvent()` | Publish Nostr event |
| `registerMethod()` | Register RPC method |
| `onPaymentReceived()` | Subscribe to payment callbacks |
| `onNostrEvent()` | Subscribe to Nostr events |

## Test plan

- [x] Review extension loader code for correctness
- [x] Verify TypeScript compilation succeeds
- [x] Test extension discovery from `src/extensions/` directory
- [x] Test RPC method registration and routing
- [x] Test database isolation between extensions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: boufni95 <boufni95@gmail.com>
Co-authored-by: Patrick Mulligan <patjmulligan@protonmail.com>
Reviewed-on: #3
2026-04-02 18:47:55 +00:00
Patrick Mulligan
72c9872b23 fix(watchdog): handle LND restarts without locking outgoing operations
Some checks failed
Docker Compose Actions Workflow / test (push) Has been cancelled
When the payment index advances (e.g. after an LND restart or external
payment), update the cached offset instead of immediately locking.
Only lock if both a history mismatch AND a balance discrepancy are
detected — indicating a real security concern rather than a benign
LND restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:19:20 -05:00
Patrick Mulligan
5e5e30c7a2 fix(lnd): wait for chain/graph sync before marking LND ready
Warmup() previously only checked that LND responded to GetInfo(), but
did not verify syncedToChain/syncedToGraph. This caused LP to accept
requests while LND was still syncing, leading to "not synced" errors
on every Health() check. Now waits for full sync with a 10min timeout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:18:06 -05:00
Patrick Mulligan
611eb4fc04 fix(nostr): close SimplePool after publishing to prevent connection leak
Each sendEvent() call created a new SimplePool() but never closed it,
causing relay WebSocket connections to accumulate indefinitely (~20/min).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:16:28 -05:00
Patrick Mulligan
6512e10f08 fix(handlers): await NostrSend calls throughout codebase
Update all NostrSend call sites to properly handle the async nature
of the function now that it returns Promise<void>.

Changes:
- handler.ts: Add async to sendResponse, await nostrSend calls
- debitManager.ts: Add logging for Kind 21002 response sending
- nostrMiddleware.ts: Update nostrSend signature
- tlvFilesStorageProcessor.ts: Update nostrSend signature
- webRTC/index.ts: Add async/await for nostrSend calls

This ensures Kind 21002 (ndebit) responses are properly sent to
wallet clients, fixing the "Debit request failed" issue in ShockWallet.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-04 15:16:28 -05:00
Patrick Mulligan
e9b5dacb3b fix(nostr): update NostrSend type to Promise<void> with error handling
The NostrSend type was incorrectly typed as returning void when it actually
returns Promise<void>. This caused async errors to be silently swallowed.

Changes:
- Update NostrSend type signature to return Promise<void>
- Make NostrSender._nostrSend default to async function
- Add .catch() error handling in NostrSender.Send() to log failures
- Add logging to track event publishing status

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-04 15:16:28 -05:00
Justin (shocknet)
a2b7ac1673
Merge pull request #903 from shocknet/bump-fee-api
bimp fee
2026-03-04 13:27:32 -05:00
boufni95
70544bd551
rate fix 2026-03-04 18:26:21 +00:00
boufni95
74513a1412
bimp fee 2026-03-04 17:57:50 +00:00
Justin (shocknet)
266f526453
Merge pull request #901 from shocknet/bump-fee
bump fee api
2026-03-04 12:38:46 -05:00
boufni95
169284021f
bump fee api 2026-03-04 17:19:42 +00:00
Justin (shocknet)
67f9dfde8b
Merge pull request #900 from shocknet/refund-filed-swps
refund failed swaps
2026-03-03 21:04:18 -05:00
boufni95
7c8cca0a55
refund failed swaps 2026-03-03 19:49:54 +00:00
Justin (shocknet)
0a30cf537f
Merge pull request #899 from shocknet/activate-users-cleanup
fk fix
2026-03-02 15:21:42 -05:00
shocknet-justin
595e5bb257
fk fix 2026-03-02 15:16:08 -05:00
Justin (shocknet)
8576a1d138
Merge pull request #898 from shocknet/activate-users-cleanup
cleanup fix
2026-03-02 15:13:23 -05:00
shocknet-justin
c18b79dc50
use number 2026-03-02 15:10:24 -05:00
shocknet-justin
bfa71f7439
cleanup fix 2026-03-02 15:08:56 -05:00
Justin (shocknet)
a0b77ec1ca
Merge pull request #897 from shocknet/activate-users-cleanup
clean users table
2026-03-02 15:05:45 -05:00
shocknet-justin
cfb7dd1e6e
serial id 2026-03-02 15:01:12 -05:00
shocknet-justin
be6f48427f
clean users table 2026-03-02 14:56:48 -05:00
Justin (shocknet)
21cb960c2e
Merge pull request #896 from shocknet/activate-users-cleanup
cleanup db fix
2026-03-02 14:46:53 -05:00
shocknet-justin
7af841c330
cleanup db fix 2026-03-02 14:44:32 -05:00
Justin (shocknet)
71b55c06d4
Merge pull request #894 from shocknet/activate-users-cleanup
activte cleanup
2026-03-02 14:34:37 -05:00
shocknet-justin
432f9d0b42
bump never active to 90 2026-03-02 14:33:53 -05:00
boufni95
574f229cee
activte cleanup 2026-03-02 18:49:22 +00:00
Justin (shocknet)
f0418fb389
Merge pull request #891 from shocknet/assets_liabilities
assets and liabilities
2026-02-27 00:42:29 -05:00
Justin (shocknet)
dcfa9250fe
Merge pull request #889 from shocknet/tx-swaps
tx swaps polish
2026-02-27 00:42:02 -05:00
boufni95
ef14ec9ddf
assets and liabilities 2026-02-26 21:54:28 +00:00
boufni95
2c8d57dd6e
address amt validation 2026-02-25 18:14:56 +00:00
boufni95
f8fe946b40
tx swaps polish 2026-02-24 18:36:03 +00:00
Justin (shocknet)
e411b7aa7f
Merge pull request #887 from shocknet/test
notification types and topic id
2026-02-20 14:51:58 -05:00
Justin (shocknet)
d949addb16
Merge pull request #886 from shocknet/lnd-log-level
use debug log level,  no level = ERROR
2026-02-20 14:39:17 -05:00
boufni95
9e66f7d72e
use debug log level, no level = ERROR 2026-02-20 19:37:11 +00:00
Justin (shocknet)
ae3b39ee04
Merge pull request #885 from shocknet/fix-pending-tx
fetch each pending tx to validate
2026-02-20 13:46:48 -05:00
boufni95
c83028c419
fetch each pending tx to validate 2026-02-20 18:40:40 +00:00
Mothana
c146d46c59 notification types and topic id 2026-02-20 17:08:38 +04:00
Justin (shocknet)
6aa90d63ba
Merge pull request #884 from shocknet/new-block-logs
new block handler logs
2026-02-19 17:25:13 -05:00
boufni95
8ada2ac165
new block handler logs 2026-02-19 21:45:31 +00:00
Justin (shocknet)
6e8a181d34
Merge pull request #883 from shocknet/missed-tx-process
await tx added to db
2026-02-19 16:38:51 -05:00
boufni95
875d1274de
await tx added to db 2026-02-19 21:24:24 +00:00