ldk_get_architecture
Retrieve iOS Lightning wallet architecture patterns and best practices for topics like project structure, security, data flow, and deployment to streamline development workflows.
Instructions
Get iOS Lightning wallet architecture patterns and best practices
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes | Architecture topic to explore |
Input Schema (JSON Schema)
{
"properties": {
"topic": {
"description": "Architecture topic to explore",
"enum": [
"project_structure",
"security_architecture",
"data_flow",
"testing_strategy",
"deployment",
"performance"
],
"type": "string"
}
},
"required": [
"topic"
],
"type": "object"
}
Implementation Reference
- src/tools/getArchitecture.ts:24-423 (handler)The core handler function that processes the tool request, selects the appropriate architecture guide based on the input 'topic', and returns it as formatted JSON or an error.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 }; } }
- src/tools/getArchitecture.ts:6-23 (schema)Input schema defining the expected parameters for the tool, specifically requiring a 'topic' string from a predefined enum of architecture areas.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'] },
- src/index.ts:38-62 (registration)The getArchitectureTool is included in the central tools array that is registered with the MCP server for tool discovery and execution.const tools = [ generateInvoiceTool, payInvoiceTool, getChannelStatusTool, getNodeInfoTool, backupStateTool, keychainTestTool, backgroundTestTool, pushNotificationTool, biometricAuthTool, createChannelTool, closeChannelTool, getBalanceTool, decodeInvoiceTool, listPaymentsTool, estimateFeeTool, generateMnemonicTool, deriveAddressTool, getSwiftCodeTool, getArchitectureTool, testScenarioTool, networkGraphTool, eventHandlingTool, chainSyncTool, ];
- src/index.ts:31-31 (registration)Import statement that brings the tool definition into the main server file for registration.import { getArchitectureTool } from './tools/getArchitecture.js';