nostr_zap
Send Bitcoin Lightning payments through Nostr with optional comments and event attachments, automatically creating zap receipts when supported or using standard Lightning addresses.
Instructions
Send a Nostr zap (NIP-57 Lightning payment with optional Nostr event). If the recipient supports NIP-57, a proper zap receipt is created. Otherwise falls back to a regular Lightning address payment. REQUIRES AGENT KEY with Nostr identity set.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Lightning address to zap (user@domain.com) | |
| amount_sats | Yes | Amount in satoshis to zap | |
| recipient_pubkey | No | Nostr hex pubkey of recipient (for NIP-57 zap receipt) | |
| content | No | Optional zap comment/message | |
| event_id | No | Nostr event ID to attach zap to (hex format) | |
| relays | No | Nostr relay URLs for zap receipt |
Implementation Reference
- src/lightning-faucet.ts:1324-1360 (handler)The `nostrZap` method in the `LightningFaucetClient` class handles the core logic for the 'nostr_zap' tool, including preparing the API request parameters and executing it.
async nostrZap( address: string, amountSats: number, recipientPubkey?: string, content?: string, eventId?: string, relays?: string[] ): Promise<{ amountSats: number; feeSats: number; paymentHash: string; newBalance: number; zapType: 'nip57' | 'fallback'; rawResponse: ApiResponse; }> { const data: Record<string, unknown> = { address, amount_sats: amountSats, }; if (recipientPubkey) data.recipient_pubkey = recipientPubkey; if (content) data.content = content; if (eventId) data.event_id = eventId; if (relays) data.relays = relays; const result = await this.request<ApiResponse & { amount_sats?: number; fee_sats?: number; payment_hash?: string; new_balance?: number; zap_type?: 'nip57' | 'fallback'; }>('nostr_zap', data); return { amountSats: result.amount_sats || amountSats, feeSats: result.fee_sats || 0, paymentHash: result.payment_hash || '', newBalance: result.new_balance || 0, - src/index.ts:1549-1576 (registration)The tool 'nostr_zap' is handled in the `src/index.ts` file within the switch-case block of the CallToolRequestSchema handler, where it calls `session.requireClient().nostrZap(...)`.
case 'nostr_zap': { const parsed = NostrZapSchema.parse(args); const result = await session.requireClient().nostrZap( parsed.address, parsed.amount_sats, parsed.recipient_pubkey, parsed.content, parsed.event_id, parsed.relays ); return { content: [ { type: 'text', text: JSON.stringify({ success: true, message: `Zapped ${parsed.amount_sats} sats to ${parsed.address}` + (result.zapType === 'nip57' ? ' (NIP-57 zap receipt created)' : ' (regular payment, recipient does not support NIP-57)'), amount_sats: result.amountSats, fee_sats: result.feeSats, payment_hash: result.paymentHash, new_balance: result.newBalance, zap_type: result.zapType, }, null, 2), }, ], }; } - src/index.ts:239-249 (schema)The `NostrZapSchema` Zod object in `src/index.ts` defines the input parameters and validation rules for the 'nostr_zap' tool.
const NostrZapSchema = z.object({ address: z.string().regex(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, 'Invalid Lightning address format') .describe('Lightning address to zap (user@domain.com format)'), amount_sats: z.number().int().positive().describe('Amount in satoshis to zap'), recipient_pubkey: z.string().regex(/^[0-9a-f]{64}$/, 'Must be 64-character hex pubkey').optional() .describe('Nostr hex pubkey of the recipient (for NIP-57 zap receipt)'), content: z.string().max(500).optional().describe('Optional zap comment/message'), event_id: z.string().regex(/^[0-9a-f]{64}$/, 'Must be 64-character hex event ID').optional() .describe('Nostr event ID to attach the zap to (hex format)'), relays: z.array(z.string().url()).optional().describe('Nostr relay URLs for zap receipt publication'), });