import * as moment from 'moment' import * as zbase32 from './zbase32' import * as LND from './lightning' import * as path from 'path' import * as mqtt from 'mqtt' import * as fetch from 'node-fetch' const env = process.env.NODE_ENV || 'development' const config = require(path.join(__dirname,'../../config/app.json'))[env] let client:any export async function connect(onMessage) { try{ const info = await LND.getInfo() async function reconnect(){ client = null const pwd = await genSignedTimestamp() console.log('[tribes] try to connect:',`tls://${config.tribes_host}:8883`) client = mqtt.connect(`tls://${config.tribes_host}:8883`,{ username:info.identity_pubkey, password:pwd, reconnectPeriod:0, // dont auto reconnect }) client.on('connect', function () { console.log("[tribes] connected!") client.subscribe(`${info.identity_pubkey}/#`) }) client.on('close', function (e) { setTimeout(()=> reconnect(), 2000) }) client.on('error', function (e) { console.log('[tribes] error: ',e.message||e) }) client.on('message', function(topic, message) { if(onMessage) onMessage(topic, message) }) } reconnect() } catch(e){ console.log("TRIBES ERROR",e) } } export function subscribe(topic){ if(client) client.subscribe(topic) } export function publish(topic,msg){ if(client) client.publish(topic,msg) } export async function declare({uuid,name,description,tags,img,groupKey,host,pricePerMessage,priceToJoin,ownerAlias,ownerPubkey}) { const r = await fetch('https://' + host + '/tribes', { method: 'POST' , body: JSON.stringify({ uuid, groupKey, name, description, tags, img:img||'', pricePerMessage:pricePerMessage||0, priceToJoin:priceToJoin||0, ownerAlias, ownerPubkey, }), headers: { 'Content-Type': 'application/json' } }) const j = await r.json() console.log(j) } export async function genSignedTimestamp(){ const now = moment().unix() const tsBytes = Buffer.from(now.toString(16), 'hex') const sig = await LND.signBuffer(tsBytes) const sigBytes = zbase32.decode(sig) const totalLength = tsBytes.length + sigBytes.length const buf = Buffer.concat([tsBytes, sigBytes], totalLength) return urlBase64(buf) } export async function verifySignedTimestamp(stsBase64){ const stsBuf = Buffer.from(stsBase64, 'base64') const sig = stsBuf.subarray(4,92) const sigZbase32 = zbase32.encode(sig) const r = await LND.verifyBytes(stsBuf.subarray(0,4), sigZbase32) // sig needs to be zbase32 :( if (r.valid) { return r.pubkey } else { return false } } export function getHost() { return config.tribes_host || '' } function urlBase64(buf){ return buf.toString('base64').replace(/\//g, '_').replace(/\+/g, '-') }