Skip to main content
Glama
StevenGeller

LDK MCP Server

by StevenGeller

ldk_generate_mnemonic

Generate BIP39 mnemonic phrases for wallet initialization, supporting 12 or 24 word configurations to create secure seed phrases for Lightning wallet development.

Instructions

Generate BIP39 mnemonic for wallet initialization

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
strengthNoMnemonic strength (128 = 12 words, 256 = 24 words)
wordCountNoNumber of words in mnemonic (12 or 24)

Implementation Reference

  • The main tool handler (execute function) that processes input args, generates BIP39 mnemonic and seed using WalletService, formats response with JSON including mnemonic, seed hex, word count, and embedded SwiftUI example code for secure mnemonic handling.
      execute: async (args: any): Promise<ToolResult> => {
        try {
          // Convert wordCount to strength if provided
          let strength = args.strength;
          if (args.wordCount) {
            strength = args.wordCount === 12 ? 128 : 256;
          }
          
          const mnemonic = walletService.generateMnemonic(strength || 256);
          const seedBuffer = walletService.mnemonicToSeed(mnemonic);
          const wordCount = mnemonic.split(' ').length;
    
          return {
            content: [{
              type: 'text',
              text: JSON.stringify({
                success: true,
                mnemonic,
                wordCount,
                seed: seedBuffer.toString('hex'),
                swiftExample: `
    // Swift code for secure mnemonic generation in your iOS app
    import SwiftUI
    import CryptoKit
    import LightningDevKit
    
    class MnemonicGenerator {
        enum MnemonicLength: Int {
            case words12 = 128
            case words24 = 256
            
            var wordCount: Int {
                switch self {
                case .words12: return 12
                case .words24: return 24
                }
            }
        }
        
        static func generateMnemonic(length: MnemonicLength = .words24) throws -> [String] {
            // Generate entropy
            let entropyBytes = length.rawValue / 8
            var entropy = Data(count: entropyBytes)
            let result = entropy.withUnsafeMutableBytes { bytes in
                SecRandomCopyBytes(kSecRandomDefault, entropyBytes, bytes.baseAddress!)
            }
            
            guard result == errSecSuccess else {
                throw WalletError.entropyGenerationFailed
            }
            
            // Convert to mnemonic
            let mnemonic = Mnemonic.toMnemonic(entropy: [UInt8](entropy))
            guard let words = mnemonic else {
                throw WalletError.mnemonicGenerationFailed
            }
            
            return words.components(separatedBy: " ")
        }
        
        static func mnemonicToSeed(words: [String], passphrase: String = "") -> Data {
            let mnemonic = words.joined(separator: " ")
            let seed = Mnemonic.toSeed(phrase: mnemonic, password: passphrase)
            return Data(seed)
        }
    }
    
    // SwiftUI view for secure mnemonic display
    struct MnemonicSetupView: View {
        @State private var mnemonicWords: [String] = []
        @State private var currentStep: SetupStep = .generate
        @State private var verificationWords: Set<Int> = []
        @State private var verificationInput: [Int: String] = [:]
        @State private var showError = false
        
        enum SetupStep {
            case generate
            case display
            case verify
            case complete
        }
        
        var body: some View {
            VStack(spacing: 0) {
                // Progress indicator
                ProgressBar(currentStep: currentStep)
                    .padding()
                
                // Content
                Group {
                    switch currentStep {
                    case .generate:
                        GenerateView(onGenerate: generateMnemonic)
                        
                    case .display:
                        DisplayView(words: mnemonicWords, onContinue: {
                            setupVerification()
                            currentStep = .verify
                        })
                        
                    case .verify:
                        VerifyView(
                            words: mnemonicWords,
                            verificationIndices: Array(verificationWords),
                            verificationInput: $verificationInput,
                            onVerify: verifyMnemonic
                        )
                        
                    case .complete:
                        CompleteView()
                    }
                }
                .padding()
                
                Spacer()
            }
            .navigationTitle("Wallet Setup")
            .navigationBarBackButtonHidden(currentStep != .generate)
            .alert("Verification Failed", isPresented: $showError) {
                Button("Try Again") { }
            } message: {
                Text("Please check the words and try again.")
            }
        }
        
        func generateMnemonic() {
            do {
                mnemonicWords = try MnemonicGenerator.generateMnemonic()
                currentStep = .display
            } catch {
                // Handle error
            }
        }
        
        func setupVerification() {
            // Select random words to verify
            verificationWords = Set((0..<mnemonicWords.count).shuffled().prefix(3))
            verificationInput = [:]
        }
        
        func verifyMnemonic() {
            var allCorrect = true
            
            for index in verificationWords {
                let expectedWord = mnemonicWords[index]
                let inputWord = verificationInput[index]?.lowercased().trimmingCharacters(in: .whitespacesAndNewlines)
                
                if inputWord != expectedWord {
                    allCorrect = false
                    break
                }
            }
            
            if allCorrect {
                saveMnemonicSecurely()
                currentStep = .complete
            } else {
                showError = true
            }
        }
        
        func saveMnemonicSecurely() {
            // Save to keychain with biometric protection
            Task {
                do {
                    let seed = MnemonicGenerator.mnemonicToSeed(words: mnemonicWords)
                    _ = try await BiometricLightningAuth.protectSeedWithBiometrics(seed: seed)
                    
                    // Clear mnemonic from memory
                    mnemonicWords = []
                    verificationInput = [:]
                } catch {
                    // Handle error
                }
            }
        }
    }
    
    struct DisplayView: View {
        let words: [String]
        let onContinue: () -> Void
        @State private var hasScreenshot = false
        
        var body: some View {
            VStack(spacing: 24) {
                // Warning
                VStack(spacing: 12) {
                    Image(systemName: "exclamationmark.triangle.fill")
                        .font(.largeTitle)
                        .foregroundColor(.orange)
                    
                    Text("Write Down Your Recovery Phrase")
                        .font(.title2)
                        .fontWeight(.semibold)
                    
                    Text("Write these words on paper. Never share them with anyone.")
                        .font(.callout)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.center)
                }
                
                // Mnemonic grid
                LazyVGrid(columns: [
                    GridItem(.flexible()),
                    GridItem(.flexible()),
                    GridItem(.flexible())
                ], spacing: 12) {
                    ForEach(Array(words.enumerated()), id: \\.offset) { index, word in
                        WordCell(number: index + 1, word: word)
                    }
                }
                .padding()
                .background(Color(UIColor.secondarySystemBackground))
                .cornerRadius(12)
                
                // Screenshot warning
                Toggle("I have written down all words", isOn: $hasScreenshot)
                    .toggleStyle(CheckboxToggleStyle())
                
                Button(action: onContinue) {
                    Text("Continue to Verification")
                        .frame(maxWidth: .infinity)
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
                .disabled(!hasScreenshot)
            }
        }
    }
    
    struct WordCell: View {
        let number: Int
        let word: String
        
        var body: some View {
            HStack(spacing: 8) {
                Text("\\(number).")
                    .font(.caption)
                    .foregroundColor(.secondary)
                    .frame(width: 20, alignment: .trailing)
                
                Text(word)
                    .font(.system(.body, design: .monospaced))
                    .fontWeight(.medium)
            }
            .padding(.vertical, 8)
            .padding(.horizontal, 12)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(Color(UIColor.tertiarySystemBackground))
            .cornerRadius(8)
        }
    }`.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
          };
        }
      }
  • Input schema defining optional parameters for mnemonic strength (128/256 bits) or word count (12/24 words).
    inputSchema: {
      type: 'object',
      properties: {
        strength: {
          type: 'number',
          enum: [128, 256],
          description: 'Mnemonic strength (128 = 12 words, 256 = 24 words)',
          default: 256
        },
        wordCount: {
          type: 'number',
          enum: [12, 24],
          description: 'Number of words in mnemonic (12 or 24)',
          default: 24
        }
      }
    },
  • Tool registration defining the name 'ldk_generate_mnemonic', description, schema, and handler.
    export const generateMnemonicTool: Tool = {
      name: 'ldk_generate_mnemonic',
  • WalletService helper method that generates the BIP39 mnemonic string using the bip39 library.
    generateMnemonic(strength: 128 | 256 = 256): string {
      return bip39.generateMnemonic(strength);
    }
  • WalletService helper method that converts mnemonic to seed buffer using bip39, with validation.
    mnemonicToSeed(mnemonic: string, passphrase: string = ''): Buffer {
      if (!bip39.validateMnemonic(mnemonic)) {
        throw new Error('Invalid mnemonic');
      }
      return bip39.mnemonicToSeedSync(mnemonic, passphrase);
    }

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