Created
          June 22, 2025 02:44 
        
      - 
      
- 
        Save rossigee/7390b12269a21dc5afd4b1ae56607c85 to your computer and use it in GitHub Desktop. 
    LND wallet unlocker triggered from AMQP message
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // package.json: | |
| // { | |
| // "dependencies": { | |
| // "@grpc/grpc-js": "^1.12.6", | |
| // "@grpc/proto-loader": "^0.7.13", | |
| // "amqplib": "^0.10.5" | |
| // } | |
| //} | |
| const fs = require('fs'); | |
| const grpc = require('@grpc/grpc-js'); | |
| const protoLoader = require('@grpc/proto-loader'); | |
| const amqp = require('amqplib'); | |
| // Configuration | |
| const LND_HOST = 'lnd.your.lan:10009'; | |
| const TLS_CERT_PATH = '/etc/ssl/certs/ca-certificates.crt'; | |
| const AMQP_HOST = process.env.AMQP_HOST; | |
| const AMQP_PASSWORD = process.env.AMQP_PASSWORD; | |
| const QUEUE_NAME = process.env.QUEUE_NAME; | |
| // Load the proto file | |
| const loaderOptions = { | |
| keepCase: true, | |
| longs: String, | |
| enums: String, | |
| defaults: true, | |
| oneofs: true, | |
| }; | |
| const packageDefinition = protoLoader.loadSync('/usr/local/src/lnd/lnrpc/walletunlocker.proto', loaderOptions); | |
| const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc; | |
| // Set up SSL credentials | |
| process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'; // Required for LND's ECDSA cert | |
| const lndCert = fs.readFileSync(TLS_CERT_PATH); | |
| const sslCreds = grpc.credentials.createSsl(lndCert); | |
| // Create the gRPC client | |
| const walletUnlocker = new lnrpc.WalletUnlocker(LND_HOST, sslCreds); | |
| // Unlock wallet function | |
| function unlockWallet(password) { | |
| return new Promise((resolve, reject) => { | |
| const request = { | |
| wallet_password: Buffer.from(process.env.WALLET_PASSWORD, 'utf-8'), // Password must be a Buffer | |
| }; | |
| walletUnlocker.unlockWallet(request, (err, response) => { | |
| if (err) { | |
| reject(err); | |
| return; | |
| } | |
| resolve(response); | |
| }); | |
| }); | |
| } | |
| // Function to consume messages from the AMQP queue | |
| async function consumeMessages() { | |
| try { | |
| const url = `amqp://unlocker:${AMQP_PASSWORD}@${AMQP_HOST}/unlockers`; | |
| console.log(`Connecting to message queue...`); | |
| const connection = await amqp.connect(url); | |
| const channel = await connection.createChannel(); | |
| await channel.assertQueue(QUEUE_NAME, { durable: true }); | |
| console.log('Waiting for messages in %s. To exit press CTRL+C', QUEUE_NAME); | |
| channel.consume(QUEUE_NAME, async (msg) => { | |
| if (msg !== null) { | |
| const messageContent = msg.content.toString(); | |
| console.log('Received message:', messageContent); | |
| try { | |
| const jsonMessage = JSON.parse(messageContent); | |
| console.log(jsonMessage); | |
| const response = await unlockWallet(jsonMessage.password); | |
| console.log('Wallet unlocked successfully:', response); | |
| } catch (error) { | |
| console.error('Error processing message:', error); | |
| } | |
| channel.ack(msg); | |
| } | |
| }); | |
| } catch (error) { | |
| console.error('Error connecting to RabbitMQ:', error); | |
| } | |
| } | |
| async function main() { | |
| consumeMessages(); | |
| } | |
| main(); | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment