UNPKG

bot18

Version:

A high-frequency cryptocurrency trading bot by Zenbot creator @carlos8f

218 lines (217 loc) 7.36 kB
var fs = require('fs') , loadRecipients = require('../utils/loadRecipients') , crypto = require('crypto') , constants = require('../lib/constants') , makeNonce = require('../utils/makeNonce') , encrypt = require('../lib/encrypt') , printHeader = require('../utils/printHeader') , translateHeader = require('../utils/translateHeader') , Progress = require('progress') , loadWallet = require('../utils/loadWallet') , pempal = require('pempal') , through = require('through') , prompt = require('cli-prompt') , createGist = require('../utils/createGist') , tar = require('tar') , zlib = require('zlib') , fstream = require('fstream') , tmpDir = require('os').tmpdir() , path = require('path') , minimist = require('minimist') , headersFromArgs = require('../utils/headersFromArgs') , libPubkey = require('../lib/pubkey') module.exports = function (inFile, outFile, options) { options.headers = headersFromArgs() var walletDir = options.parent.wallet if (options.message || options.gist) options.armor = true if (!options.armor) { var stat = fs.statSync(inFile) if (!outFile) { outFile = crypto.randomBytes(4).toString('hex') + '.salty' } outFile = path.resolve(outFile) try { fs.statSync(outFile) if (!options.parent.force) { throw new Error('Refusing to overwrite ' + outFile + '. Use --force to ignore this.') } } catch (err) { if (err && err.code !== 'ENOENT') { throw err } } } if (inFile) inFile = path.resolve(inFile) if (outFile) outFile = path.resolve(outFile) var nonce = makeNonce() loadRecipients(walletDir, function (err, recipients) { if (err) throw err var recipient = recipients[options.to] if (!recipient) { if (options.to) { recipient = libPubkey.parse(options.to) } else { recipient = recipients.self } if (!recipient) { throw new Error('Recipient not found') } } if (options.sign) { loadWallet(walletDir, function (err, wallet) { if (err) throw err withWallet(wallet) }) } else withWallet() function withWallet (wallet) { if (options.message) { process.stderr.write('Compose message: (CTL-D when done)\n\n> ') var lines = [] process.stdin.once('end', function () { lines.push('') var m = Buffer.from(lines.join('\n')) withMessage(m) }) ;(function getLine () { prompt(null, function (line) { lines.push(line) getLine() }) })() function withMessage (m) { var mStream = through() var encryptor = encrypt(mStream, recipient, nonce, m.length, wallet, true, options.headers) withEncryptor(encryptor, m.length) mStream.end(m) } } else { var inStat = fs.statSync(inFile) var inStream, encryptor if (inStat.isDirectory()) { var tarStream = tar.Pack({fromBase: true}) var gzipStream = tarStream.pipe(zlib.createGzip()) var tmpFile = path.join(tmpDir, crypto.randomBytes(16).toString('hex')) var tmpStream = fs.createWriteStream(tmpFile, {mode: parseInt('0600', 8)}) process.on('uncaughtException', function (err) { try { fs.unlinkSync(tmpFile) } catch (e) {} throw err }) function onExit () { try { fs.unlinkSync(tmpFile) } catch (e) {} process.exit(1) } process.once('SIGINT', onExit) process.once('SIGTERM', onExit) tmpStream.once('finish', function () { inStat = fs.statSync(tmpFile) if (options.armor && inStat.size > constants.PEM_MAX_SIZE) { throw new Error('File is too big for ascii armor') } inStream = fs.createReadStream(tmpFile) inStream.once('end', function () { fs.unlinkSync(tmpFile) }) encryptor = encrypt(inStream, recipient, nonce, inStat.size, wallet, options.armor, options.headers) withEncryptor(encryptor, inStat.size) }) options.headers['content-type'] = 'application/x-tar' options.headers['content-encoding'] = 'x-gzip' var reader = fstream.Reader({ path: inFile, type: 'Directory', sort: 'alpha', mode: parseInt('0700', 8) }) var bar reader.once('entries', function (entries) { bar = new Progress(' packing [:bar] :percent ETA: :etas', { total: entries.length, width: 80 }) }) reader.on('entry', function (entry) { bar.tick() }) reader.on('end', function () { bar.terminate() }) gzipStream.pipe(tmpStream) reader.pipe(tarStream) } else { if (options.armor && inStat.size > constants.PEM_MAX_SIZE) { throw new Error('File is too big for ascii armor') } inStream = fs.createReadStream(inFile) encryptor = encrypt(inStream, recipient, nonce, inStat.size, wallet, options.armor, options.headers) withEncryptor(encryptor, inStat.size) } } var header, outStream function withEncryptor (encryptor, totalSize) { encryptor.once('header', function (h) { header = options.translate ? translateHeader(h, recipients) : h }) if (options.armor) { var chunks = [] outStream = through(function write (buf) { chunks.push(buf) }, function end () { var buf = Buffer.concat(chunks) var str = pempal.encode(buf, {tag: 'SALTY MESSAGE'}) if (options.gist) { createGist(str, function (err, gist) { if (err) throw err console.log(gist.html_url) }) } else console.log(str) }) } else { outStream = fs.createWriteStream(outFile, {mode: parseInt('0644', 8)}) outStream.once('finish', function () { bar.terminate() printHeader(header) console.log('Encrypted to', outFile) }) process.on('uncaughtException', function (err) { try { fs.unlinkSync(outFile) } catch (e) {} throw err }) function onExit () { try { fs.unlinkSync(outFile) } catch (e) {} process.exit(1) } process.once('SIGINT', onExit) process.once('SIGTERM', onExit) var bar = new Progress(' encrypting [:bar] :percent ETA: :etas', { total: totalSize, width: 80 }) var chunkCounter = 0 var tickCounter = 0 encryptor.on('data', function (chunk) { chunkCounter++ tickCounter += chunk.length if (chunkCounter % 100 === 0) { bar.tick(tickCounter) tickCounter = 0 } }) } encryptor.pipe(outStream) } } }) }