/* eslint no-console: 0 */ // --> OFF // import grpc from 'grpc' import * as invoicesController from './invoicesController' import * as channelController from './channelController' import * as walletController from './walletController' import * as peersController from './peersController' import * as paymentsController from './paymentsController' import * as networkController from './networkController' // TODO - GetChanInfo // TODO - GetTransactions // TODO - GetNodeInfo // TODO - DescribeGraph // TODO - GetNetworkInfo // TODO - QueryRoutes // TODO - DecodePayReq // TODO - SendPayment // TODO - DeleteAllPayments export default function (lnd, log, event, msg, data) { switch (msg) { case 'info': networkController .getInfo(lnd) .then((infoData) => { event.sender.send('receiveInfo', infoData) event.sender.send('receiveCryptocurrency', infoData.chains[0]) return infoData }) .catch(() => event.sender.send('infoFailed')) break case 'describeNetwork': networkController .describeGraph(lnd) .then(networkData => event.sender.send('receiveDescribeNetwork', networkData)) .catch(error => log.error('describeGraph:', error)) break case 'queryRoutes': // Data looks like { pubkey: String, amount: Number } networkController .queryRoutes(lnd, data) .then(routes => event.sender.send('receiveQueryRoutes', routes)) .catch(error => log.error('queryRoutes:', error)) break case 'getInvoiceAndQueryRoutes': // Data looks like { pubkey: String, amount: Number } invoicesController .getInvoice(lnd, { pay_req: data.payreq }) .then(invoiceData => networkController.queryRoutes(lnd, { pubkey: invoiceData.destination, amount: invoiceData.num_satoshis })) .then(routes => event.sender.send('receiveInvoiceAndQueryRoutes', routes)) .catch(error => log.error('getInvoiceAndQueryRoutes invoice:', error)) break case 'newaddress': // Data looks like { address: '' } walletController .newAddress(lnd, data.type) .then(({ address }) => event.sender.send('receiveAddress', address)) .catch(error => log.error('newaddress:', error)) break case 'setAlias': // Data looks like { new_alias: '' } walletController .setAlias(lnd, data) .then(() => event.sender.send('aliasSet')) .catch(error => log.error('setAlias:', error)) break case 'peers': // Data looks like { peers: [] } peersController .listPeers(lnd) .then(peersData => event.sender.send('receivePeers', peersData)) .catch(error => log.error('peers:', error)) break case 'channels': // Data looks like // [ { channels: [] }, { total_limbo_balance: 0, pending_open_channels: [], pending_closing_channels: [], pending_force_closing_channels: [] } ] Promise.all([channelController.listChannels, channelController.pendingChannels].map(func => func(lnd))) .then(channelsData => event.sender.send('receiveChannels', { channels: channelsData[0].channels, pendingChannels: channelsData[1] })) .catch(error => log.error('channels:', error)) break case 'transactions': // Data looks like { transactions: [] } walletController .getTransactions(lnd) .then(transactionsData => event.sender.send('receiveTransactions', transactionsData)) .catch(error => log.error('transactions:', error)) break case 'payments': // Data looks like { payments: [] } paymentsController .listPayments(lnd) .then(paymentsData => event.sender.send('receivePayments', paymentsData)) .catch(error => log.error('payments:', error)) break case 'invoices': // Data looks like { invoices: [] } invoicesController .listInvoices(lnd) .then(invoicesData => event.sender.send('receiveInvoices', invoicesData)) .catch(error => log.error('invoices:', error)) break case 'invoice': // Data looks like { invoices: [] } invoicesController .getInvoice(lnd, { pay_req: data.payreq }) .then(invoiceData => event.sender.send('receiveInvoice', invoiceData)) .catch(error => log.error('invoice:', error)) break case 'balance': // Balance looks like [ { balance: '129477456' }, { balance: '243914' } ] Promise.all([walletController.walletBalance, channelController.channelBalance].map(func => func(lnd))) .then((balance) => { event.sender.send('receiveBalance', { walletBalance: balance[0].total_balance, channelBalance: balance[1].balance }) return balance }) .catch(error => log.error('balance:', error)) break case 'createInvoice': // Invoice looks like { r_hash: Buffer, payment_request: '' } // { memo, value } = data invoicesController .addInvoice(lnd, data) .then(newinvoice => invoicesController .getInvoice(lnd, { pay_req: newinvoice.payment_request }) .then(decodedInvoice => event.sender.send( 'createdInvoice', Object.assign(decodedInvoice, { memo: data.memo, value: data.value, r_hash: Buffer.from(newinvoice.r_hash, 'hex').toString('hex'), payment_request: newinvoice.payment_request, creation_date: Date.now() / 1000 }) )) .catch((error) => { log.error('decodedInvoice:', error) event.sender.send('invoiceFailed', { error: error.toString() }) })) .catch((error) => { log.error('addInvoice:', error) event.sender.send('invoiceFailed', { error: error.toString() }) }) break case 'sendPayment': // Payment looks like { payment_preimage: Buffer, payment_route: Object } // { paymentRequest } = data paymentsController .sendPaymentSync(lnd, data) .then((payment) => { log.info('payment:', payment) const { payment_route } = payment log.error('payinvoice success:', payment_route) event.sender.send('paymentSuccessful', Object.assign(data, { payment_route })) return payment }) .catch(({ error }) => { log.error('error: ', error) event.sender.send('paymentFailed', { error: error.toString() }) }) break case 'sendCoins': // Transaction looks like { txid: String } // { amount, addr } = data walletController .sendCoins(lnd, data) .then(({ txid }) => event.sender.send('transactionSuccessful', { amount: data.amount, addr: data.addr, txid })) .catch((error) => { log.error('error: ', error) event.sender.send('transactionError', { error: error.toString() }) }) break case 'openChannel': // Response is empty. Streaming updates on channel status and updates // { pubkey, localamt, pushamt } = data channelController .openChannel(lnd, event, data) .then((channel) => { log.error('CHANNEL: ', channel) event.sender.send('channelSuccessful', { channel }) return channel }) .catch(error => log.error('openChannel:', error)) break case 'closeChannel': // Response is empty. Streaming updates on channel status and updates // { channel_point, force } = data channelController .closeChannel(lnd, event, data) .then((result) => { log.error('CLOSE CHANNEL: ', result) event.sender.send('closeChannelSuccessful') return result }) .catch(error => log.error('closeChannel:', error)) break case 'connectPeer': // Returns a peer_id. Pass the pubkey, host and peer_id so we can add a new peer to the list // { pubkey, host } = data peersController .connectPeer(lnd, data) .then((peer) => { const { peer_id } = peer log.error('peer_id: ', peer_id) event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id }) return peer }) .catch((error) => { event.sender.send('connectFailure', { error: error.toString() }) log.error('connectPeer:', error) }) break case 'disconnectPeer': // Empty response. Pass back pubkey on success to remove it from the peers list // { pubkey } = data peersController .disconnectPeer(lnd, data) .then(() => { log.error('pubkey: ', data.pubkey) event.sender.send('disconnectSuccess', { pubkey: data.pubkey }) return null }) .catch(error => log.error('disconnectPeer:', error)) break case 'connectAndOpen': // Connects to a peer if we aren't connected already and then attempt to open a channel // {} = data channelController .connectAndOpen(lnd, event, data) .then((channelData) => { log.error('connectAndOpen data: ', channelData) // event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id }) return channelData }) .catch((error) => { // event.sender.send('connectFailure', { error: error.toString() }) log.error('connectAndOpen:', error) }) break default: } }