import * as Sphinx from 'sphinx-bot' import { finalAction } from '../controllers/actions' import fetch from 'node-fetch' import validate from 'bitcoin-address-validation'; const msg_types = Sphinx.MSG_TYPE let initted = false const baseurl = 'https://localhost:8080' export function init() { if (initted) return initted = true const client = new Sphinx.Client() client.login('_', finalAction) client.on(msg_types.MESSAGE, async (message: Sphinx.Message) => { const arr = message.content.split(' ') if (arr.length < 2) return if (arr[0] !== '/loopout') return if (arr.length === 3) { // loop const addy = arr[1] if (!validate(addy)) { const embed = new Sphinx.MessageEmbed() .setAuthor('LoopBot') .setDescription('Invalid BTC address') message.channel.send({ embed }) return } const amt = arr[2] if (!validateAmount(amt)) { const embed = new Sphinx.MessageEmbed() .setAuthor('LoopBot') .setDescription('Invalid amount') message.channel.send({ embed }) return } try { const j = await doRequest(baseurl + '/v1/loop/out/quote/'+amt) console.log("=> LOOP QUOTE RES", j) if(!(j&&(j.swap_fee||j.swap_fee_sat))){ return } const j2 = await doRequest(baseurl + '/v1/loop/out', { method:'POST', body: JSON.stringify({ amt: amt, dest: addy, }), }) console.log("=> LOOP RESPONSE", j2) if(!(j2&&j2.server_message)) { return } const embed = new Sphinx.MessageEmbed() .setAuthor('LoopBot') .setTitle('Loop Initialized!') .setDescription(j2.server_message) message.channel.send({ embed }) } catch (e) { console.log('LoopBot error', e) } } const cmd = arr[1] switch (cmd) { case 'help': const embed = new Sphinx.MessageEmbed() .setAuthor('LoopBot') .setTitle('LoopBot Commands:') .addFields([ { name: 'Send to your on-chain address', value: '/loopout {ADDRESS} {AMOUNT}' }, { name: 'Help', value: '/loopout help' } ]) .setThumbnail(botSVG) message.channel.send({ embed }) return default: const embed2 = new Sphinx.MessageEmbed() .setAuthor('LoopBot') .setDescription('Command not recognized') message.channel.send({ embed: embed2 }) return } }) } const botSVG = ` ` function validateAmount(amtString: string) { const amt = parseInt(amtString) const ok = amt > 0 return ok } const fs = require('fs') const https = require("https"); const homedir = require('os').homedir(); const agent = new https.Agent({ rejectUnauthorized: false }) var filepath = homedir + '/.lnd/data/chain/bitcoin/mainnet/admin.macaroon' async function doRequest(theurl:string, params?:Object) { const ps = params || {} try { var macaroonString = fs.readFileSync(filepath); var mac = Buffer.from(macaroonString, 'utf8').toString('hex'); const theParams = { agent, headers: { 'Grpc-Metadata-macaroon': mac }, ...ps } const r = await fetch(theurl, theParams) const j = await r.json() return j } catch (e) { throw e } }