Skip to main content
Glama
getArchitecture.tsโ€ข14.2 kB
import { Tool, ToolResult } from '../types/tool.js'; export const getArchitectureTool: Tool = { name: 'ldk_get_architecture', description: 'Get iOS Lightning wallet architecture patterns and best practices', inputSchema: { type: 'object', properties: { topic: { type: 'string', enum: [ 'project_structure', 'security_architecture', 'data_flow', 'testing_strategy', 'deployment', 'performance' ], description: 'Architecture topic to explore' } }, required: ['topic'] }, execute: async (args: any): Promise<ToolResult> => { const architectureGuides: Record<string, any> = { project_structure: { title: 'iOS Lightning Wallet Project Structure', overview: 'Modular architecture with clear separation of concerns', structure: ` LightningWallet/ โ”œโ”€โ”€ App/ โ”‚ โ”œโ”€โ”€ LightningWalletApp.swift โ”‚ โ”œโ”€โ”€ AppDelegate.swift โ”‚ โ””โ”€โ”€ Info.plist โ”œโ”€โ”€ Core/ โ”‚ โ”œโ”€โ”€ LDK/ โ”‚ โ”‚ โ”œโ”€โ”€ LDKManager.swift โ”‚ โ”‚ โ”œโ”€โ”€ ChannelManager+Extensions.swift โ”‚ โ”‚ โ”œโ”€โ”€ EventHandler.swift โ”‚ โ”‚ โ””โ”€โ”€ Persistence/ โ”‚ โ”œโ”€โ”€ Bitcoin/ โ”‚ โ”‚ โ”œโ”€โ”€ WalletManager.swift โ”‚ โ”‚ โ”œโ”€โ”€ AddressManager.swift โ”‚ โ”‚ โ””โ”€โ”€ TransactionBuilder.swift โ”‚ โ””โ”€โ”€ Networking/ โ”‚ โ”œโ”€โ”€ PeerConnection.swift โ”‚ โ”œโ”€โ”€ ElectrumClient.swift โ”‚ โ””โ”€โ”€ RapidGossipSync.swift โ”œโ”€โ”€ Features/ โ”‚ โ”œโ”€โ”€ Wallet/ โ”‚ โ”‚ โ”œโ”€โ”€ Views/ โ”‚ โ”‚ โ”œโ”€โ”€ ViewModels/ โ”‚ โ”‚ โ””โ”€โ”€ Models/ โ”‚ โ”œโ”€โ”€ Channels/ โ”‚ โ”‚ โ”œโ”€โ”€ Views/ โ”‚ โ”‚ โ”œโ”€โ”€ ViewModels/ โ”‚ โ”‚ โ””โ”€โ”€ Services/ โ”‚ โ”œโ”€โ”€ Payments/ โ”‚ โ”‚ โ”œโ”€โ”€ Send/ โ”‚ โ”‚ โ”œโ”€โ”€ Receive/ โ”‚ โ”‚ โ””โ”€โ”€ History/ โ”‚ โ””โ”€โ”€ Settings/ โ”‚ โ”œโ”€โ”€ Security/ โ”‚ โ”œโ”€โ”€ Network/ โ”‚ โ””โ”€โ”€ Backup/ โ”œโ”€โ”€ Shared/ โ”‚ โ”œโ”€โ”€ UI/ โ”‚ โ”‚ โ”œโ”€โ”€ Components/ โ”‚ โ”‚ โ”œโ”€โ”€ Styles/ โ”‚ โ”‚ โ””โ”€โ”€ Extensions/ โ”‚ โ”œโ”€โ”€ Utils/ โ”‚ โ”‚ โ”œโ”€โ”€ Crypto/ โ”‚ โ”‚ โ”œโ”€โ”€ Formatting/ โ”‚ โ”‚ โ””โ”€โ”€ Validation/ โ”‚ โ””โ”€โ”€ Services/ โ”‚ โ”œโ”€โ”€ KeychainService.swift โ”‚ โ”œโ”€โ”€ BiometricService.swift โ”‚ โ””โ”€โ”€ NotificationService.swift โ””โ”€โ”€ Resources/ โ”œโ”€โ”€ Assets.xcassets โ”œโ”€โ”€ Localizable.strings โ””โ”€โ”€ LaunchScreen.storyboard`, designPatterns: [ 'MVVM for UI architecture', 'Repository pattern for data access', 'Coordinator pattern for navigation', 'Factory pattern for LDK object creation', 'Observer pattern for Lightning events' ], dependencies: { 'LightningDevKit': 'Lightning protocol implementation', 'BitcoinDevKit': 'On-chain wallet functionality', 'SwiftUI': 'Modern declarative UI', 'Combine': 'Reactive programming', 'CryptoKit': 'Cryptographic operations' } }, security_architecture: { title: 'Security Architecture for iOS Lightning Wallet', layers: { 'Key Management': { description: 'Secure generation, storage, and usage of cryptographic keys', implementation: ` // Secure Key Management class SecureKeyManager { private let keychain: KeychainService private let secureEnclave: SecureEnclaveService // Key generation with Secure Enclave func generateNodeKey() throws -> SecKey { let access = SecAccessControlCreateWithFlags( nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage, .biometryCurrentSet], nil )! let attributes: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits as String: 256, kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: "com.app.lightning.nodekey", kSecAttrAccessControl as String: access ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } return privateKey } // Encrypted seed storage func storeSeed(_ seed: Data) throws { let encryptedSeed = try encryptWithHardwareKey(seed) try keychain.store( encryptedSeed, for: "lightning_seed", withBiometricProtection: true ) } }`, bestPractices: [ 'Use Secure Enclave for key generation when possible', 'Enable biometric protection for all sensitive operations', 'Implement key rotation strategies', 'Use hardware-backed encryption', 'Clear sensitive data from memory immediately after use' ] }, 'Network Security': { description: 'Secure communication with Lightning peers and Bitcoin nodes', implementation: ` // Tor Integration for Privacy class TorManager { private var torThread: TorThread? private var torConfiguration: TorConfiguration func startTor() async throws { torConfiguration = TorConfiguration() torConfiguration.cookieAuthentication = true torConfiguration.dataDirectory = getTorDataDirectory() torThread = TorThread(configuration: torConfiguration) try await torThread?.start() // Wait for Tor to be ready await waitForTorConnection() } func createTorSocket(to address: String, port: UInt16) -> TorSocket { return TorSocket( socksHost: "127.0.0.1", socksPort: torConfiguration.socksPort, destinationHost: address, destinationPort: port ) } }`, protocols: [ 'Use Tor for all Lightning peer connections', 'Certificate pinning for API endpoints', 'Noise protocol for peer communication', 'No plaintext storage of sensitive data', 'Regular security audits' ] }, 'Application Security': { description: 'App-level security measures', features: [ 'Jailbreak detection', 'Anti-debugging protection', 'Code obfuscation for critical paths', 'Runtime application self-protection (RASP)', 'Secure backup and restore' ] } } }, data_flow: { title: 'Lightning Wallet Data Flow Architecture', flows: { 'Payment Flow': { description: 'End-to-end payment processing', steps: [ '1. User initiates payment in UI', '2. ViewModel validates input and creates payment request', '3. LDKManager finds route via Router', '4. ChannelManager sends payment through Lightning network', '5. EventHandler processes payment events', '6. Persistence layer saves payment record', '7. UI updates with payment status' ], diagram: ` UI Layer Business Layer LDK Layer Network Layer โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€ Send Payment โ”€โ”€โ”€โ”€>โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€ Validate โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€ Find Route โ”€โ”€โ”€โ”€>โ”‚ โ”‚ โ”‚ โ”‚<โ”€โ”€โ”€ Route โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”œโ”€ Send HTLC โ”€โ”€โ”€โ”€โ”€>โ”‚ โ”‚ โ”‚<โ”€ Payment Event โ”€โ”ค โ”‚ โ”‚<โ”€ Update Status โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ โ”œโ”€ Save Record โ”€โ”€โ”€>โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚` }, 'Channel Management': { description: 'Channel lifecycle management', states: [ 'Pending -> Opening -> Open -> Active', 'Active -> Closing -> Closed', 'Any State -> Force Closing -> Closed' ] } } }, testing_strategy: { title: 'Comprehensive Testing Strategy', levels: { 'Unit Tests': { coverage: '80%+ for business logic', framework: 'XCTest', example: ` class ChannelManagerTests: XCTestCase { var sut: ChannelManager! var mockLDK: MockLDKManager! override func setUp() { super.setUp() mockLDK = MockLDKManager() sut = ChannelManager(ldkManager: mockLDK) } func testOpenChannel_WithValidInputs_CreatesChannel() async throws { // Given let expectedCapacity: UInt64 = 100000 let remotePubkey = TestData.validPubkey // When let channel = try await sut.openChannel( remotePubkey: remotePubkey, capacity: expectedCapacity ) // Then XCTAssertEqual(channel.capacity, expectedCapacity) XCTAssertEqual(channel.remotePubkey, remotePubkey) XCTAssertTrue(mockLDK.createChannelCalled) } }` }, 'Integration Tests': { coverage: 'Critical user flows', tools: ['XCUITest', 'Appium'], scenarios: [ 'Complete payment flow', 'Channel open/close cycle', 'Backup and restore', 'Network disruption handling' ] }, 'Lightning Network Tests': { description: 'Testing with real Lightning testnet', setup: 'Automated testnet node deployment', cases: [ 'Multi-hop payments', 'Channel force close', 'Payment timeout handling', 'Fee estimation accuracy' ] } } }, deployment: { title: 'Deployment Architecture', environments: { 'Development': { network: 'Regtest', features: ['Debug logging', 'Mock services', 'Test shortcuts'], backend: 'Local Bitcoin Core + CLN' }, 'Staging': { network: 'Testnet', features: ['Real Lightning connections', 'TestFlight distribution'], backend: 'Hosted testnet infrastructure' }, 'Production': { network: 'Mainnet', features: ['Full security', 'Analytics', 'Crash reporting'], backend: 'Redundant node infrastructure' } }, cicd: { pipeline: [ 'Code commit -> GitHub Actions', 'Run tests (unit, integration, UI)', 'Security scanning (SAST/DAST)', 'Build and sign IPA', 'Deploy to TestFlight/App Store' ], tools: { 'Fastlane': 'Automation and deployment', 'Bitrise': 'CI/CD platform', 'Firebase': 'Crash reporting and analytics', 'Sentry': 'Error tracking' } } }, performance: { title: 'Performance Optimization Architecture', strategies: { 'Memory Management': [ 'Lazy loading of channel data', 'Pagination for payment history', 'Efficient image caching for QR codes', 'Proper cleanup of LDK objects' ], 'Network Optimization': [ 'Connection pooling for peers', 'Batched gossip updates', 'Compressed data transmission', 'Smart retry mechanisms' ], 'UI Performance': [ 'SwiftUI view optimization', 'Async image loading', 'List virtualization', 'Smooth animations at 60fps' ], 'Battery Optimization': [ 'Intelligent background sync', 'Reduced network polling', 'Efficient cryptographic operations', 'Wake lock management' ] }, monitoring: ` // Performance Monitoring class PerformanceMonitor { static let shared = PerformanceMonitor() func trackLightningOperation<T>( _ operation: String, block: () async throws -> T ) async rethrows -> T { let startTime = CFAbsoluteTimeGetCurrent() let startMemory = getMemoryUsage() defer { let duration = CFAbsoluteTimeGetCurrent() - startTime let memoryDelta = getMemoryUsage() - startMemory Analytics.track("lightning_operation", [ "operation": operation, "duration_ms": duration * 1000, "memory_delta_mb": memoryDelta / 1024 / 1024 ]) } return try await block() } }` } }; try { const guide = architectureGuides[args.topic]; if (!guide) { throw new Error(`Unknown topic: ${args.topic}`); } return { content: [{ type: 'text', text: JSON.stringify({ success: true, topic: args.topic, content: guide }, 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