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
| Name | Required | Description | Default |
|---|---|---|---|
| strength | No | Mnemonic strength (128 = 12 words, 256 = 24 words) | |
| wordCount | No | Number of words in mnemonic (12 or 24) |
Implementation Reference
- src/tools/generateMnemonic.ts:26-293 (handler)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 }; } }
- src/tools/generateMnemonic.ts:9-25 (schema)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 } } },
- src/tools/generateMnemonic.ts:6-7 (registration)Tool registration defining the name 'ldk_generate_mnemonic', description, schema, and handler.export const generateMnemonicTool: Tool = { name: 'ldk_generate_mnemonic',
- src/services/walletService.ts:19-21 (helper)WalletService helper method that generates the BIP39 mnemonic string using the bip39 library.generateMnemonic(strength: 128 | 256 = 256): string { return bip39.generateMnemonic(strength); }
- src/services/walletService.ts:23-28 (helper)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); }