Skip to main content
Glama
generateInvoice.tsโ€ข5.79 kB
import { Tool, ToolResult } from '../types/tool.js'; import { LightningService } from '../services/lightningService.js'; const lightningService = new LightningService(); export const generateInvoiceTool: Tool = { name: 'ldk_generate_invoice', description: 'Generate a Lightning invoice with real payment hash for testing', inputSchema: { type: 'object', properties: { amountSats: { type: 'number', description: 'Amount in satoshis', minimum: 1 }, description: { type: 'string', description: 'Invoice description' }, expirySeconds: { type: 'number', description: 'Invoice expiry time in seconds (default: 3600)', default: 3600 } }, required: ['amountSats'] }, execute: async (args: any): Promise<ToolResult> => { try { const amountMsat = args.amountSats * 1000; const invoice = await lightningService.generateInvoice( amountMsat, args.description, args.expirySeconds || 3600 ); return { content: [{ type: 'text', text: JSON.stringify({ success: true, invoice: invoice.bolt11, paymentHash: invoice.paymentHash, amountSats: args.amountSats, expiryTime: invoice.expiryTime, description: invoice.description, swiftExample: ` // Swift code to generate and display Lightning invoice using LDK import SwiftUI import LightningDevKit import CoreImage.CIFilterBuiltins class InvoiceGenerator { let channelManager: Bindings.ChannelManager let logger: Bindings.Logger let keys: Bindings.KeysManager init(channelManager: Bindings.ChannelManager, logger: Bindings.Logger, keys: Bindings.KeysManager) { self.channelManager = channelManager self.logger = logger self.keys = keys } func createInvoice(amountMsat: UInt64?, description: String, expirySecs: UInt32 = 3600) -> Result<Bindings.Bolt11Invoice, Error> { let invoiceParams = Bindings.InvoiceBuilder.newInvoiceBuilder() if let amount = amountMsat { invoiceParams.amountMsat(amount) } invoiceParams.description(description.asLdkStr()) invoiceParams.expiryTime(expirySecs) do { let invoice = try invoiceParams.build() return .success(invoice) } catch { return .failure(error) } } } struct InvoiceView: View { let invoice = "${invoice.bolt11}" let amountSats = ${args.amountSats} @State private var isCopied = false var body: some View { VStack(spacing: 20) { Text("Lightning Invoice") .font(.title) // QR Code Image(uiImage: generateQRCode(from: invoice)) .interpolation(.none) .resizable() .scaledToFit() .frame(width: 250, height: 250) .overlay( RoundedRectangle(cornerRadius: 16) .stroke(Color.secondary.opacity(0.3), lineWidth: 1) ) // Amount VStack(spacing: 4) { Text("\\(amountSats)") .font(.system(size: 36, weight: .bold, design: .rounded)) Text("sats") .font(.subheadline) .foregroundColor(.secondary) } // Invoice details Text("${args.description || 'Lightning Payment'}") .font(.subheadline) .foregroundColor(.secondary) .multilineTextAlignment(.center) // Copy button with feedback Button(action: { UIPasteboard.general.string = invoice withAnimation(.easeInOut(duration: 0.2)) { isCopied = true } DispatchQueue.main.asyncAfter(deadline: .now() + 2) { withAnimation(.easeInOut(duration: 0.2)) { isCopied = false } } }) { Label( isCopied ? "Copied!" : "Copy Invoice", systemImage: isCopied ? "checkmark.circle.fill" : "doc.on.doc" ) .frame(minWidth: 150) } .buttonStyle(.borderedProminent) .tint(isCopied ? .green : .accentColor) // Share button ShareLink(item: invoice) { Label("Share", systemImage: "square.and.arrow.up") } .buttonStyle(.bordered) } .padding() } func generateQRCode(from string: String) -> UIImage { let context = CIContext() let filter = CIFilter.qrCodeGenerator() filter.message = Data(string.utf8) if let outputImage = filter.outputImage { let transform = CGAffineTransform(scaleX: 10, y: 10) let scaledImage = outputImage.transformed(by: transform) if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) { return UIImage(cgImage: cgImage) } } return UIImage(systemName: "xmark.circle") ?? UIImage() } }`.trim() }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : 'Unknown error' }, null, 2) }], isError: true }; } } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/StevenGeller/ldk-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server