add blockchain install scripts
This commit is contained in:
parent
0e9e27b97b
commit
178f576cfb
39 changed files with 3938 additions and 750 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -33,3 +33,6 @@ scratch/
|
|||
seeds/
|
||||
certs/
|
||||
lamassu.json
|
||||
|
||||
terraform.*
|
||||
.terraform
|
||||
|
|
|
|||
8
Vagrantfile
vendored
8
Vagrantfile
vendored
|
|
@ -11,7 +11,7 @@ Vagrant.configure(2) do |config|
|
|||
# vagrantup.com
|
||||
|
||||
# Every Vagrant virtual environment requires a box to build off of.
|
||||
config.vm.box = "ubuntu/trusty64"
|
||||
config.vm.box = "ubuntu/xenial64"
|
||||
|
||||
# Disable automatic box update checking. If you disable this, then
|
||||
# boxes will only be checked for updates when the user runs
|
||||
|
|
@ -46,13 +46,13 @@ Vagrant.configure(2) do |config|
|
|||
# backing providers for Vagrant. These expose provider-specific options.
|
||||
# Example for VirtualBox:
|
||||
#
|
||||
# config.vm.provider "virtualbox" do |vb|
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
# # Don't boot with headless mode
|
||||
# vb.gui = true
|
||||
#
|
||||
# # Use VBoxManage to customize the VM. For example to change memory:
|
||||
# vb.customize ["modifyvm", :id, "--memory", "1024"]
|
||||
# end
|
||||
vb.customize ["modifyvm", :id, "--memory", "4096"]
|
||||
end
|
||||
#
|
||||
# View the documentation for the provider you're using for more
|
||||
# information on available options.
|
||||
|
|
|
|||
54
blockchain/blockchain.tf
Normal file
54
blockchain/blockchain.tf
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
variable "name" {}
|
||||
variable "blockchain_cmd" {}
|
||||
variable "blockchain_conf" {}
|
||||
variable "ssh_key" {}
|
||||
|
||||
variable "size" {
|
||||
default = "2gb"
|
||||
}
|
||||
|
||||
variable "blockchain_dir" {
|
||||
default = "./scratch/blockchains"
|
||||
}
|
||||
|
||||
data "template_file" "supervisor_conf" {
|
||||
template = "${file("./blockchains/supervisor.conf")}"
|
||||
|
||||
vars {
|
||||
blockchain = "${var.name}"
|
||||
blockchain_cmd = "${var.blockchain_cmd}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "digitalocean_droplet" "blockchain_server" {
|
||||
image = "debian-9-x64"
|
||||
name = "${var.name}"
|
||||
region = "ams2"
|
||||
size = "${var.size}"
|
||||
ssh_keys = ["${var.ssh_key}"]
|
||||
|
||||
connection {
|
||||
type = "ssh"
|
||||
user = "root"
|
||||
private_key = "${file("${pathexpand("~/.ssh/id_rsa")}")}"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
content = "${data.template_file.supervisor_conf.rendered}"
|
||||
destination = "/tmp/supervisor-${var.name}.conf"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "${var.blockchain_dir}/${var.blockchain_conf}"
|
||||
destination = "/tmp/${var.blockchain_conf}"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
script = "./blockchains/${var.name}/install.sh"
|
||||
}
|
||||
}
|
||||
|
||||
output "ip_address" {
|
||||
value = "${digitalocean_droplet.blockchain_server.ipv4_address}"
|
||||
}
|
||||
|
||||
18
blockchains/bitcoin/install.sh
Normal file
18
blockchains/bitcoin/install.sh
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
LOG_FILE=/tmp/install.log
|
||||
|
||||
apt-get update -y >> $LOG_FILE 2>&1
|
||||
apt-get install -y ufw supervisor >> $LOG_FILE 2>&1
|
||||
ufw allow 8332 >> $LOG_FILE 2>&1
|
||||
ufw allow 22 >> $LOG_FILE 2>&1
|
||||
ufw --force enable >> $LOG_FILE 2>&1
|
||||
ufw status >> $LOG_FILE 2>&1
|
||||
wget -q https://bitcoin.org/bin/bitcoin-core-0.14.2/bitcoin-0.14.2-x86_64-linux-gnu.tar.gz >> $LOG_FILE 2>&1
|
||||
tar -xzf bitcoin-0.14.2-x86_64-linux-gnu.tar.gz >> $LOG_FILE 2>&1
|
||||
cp bitcoin-0.14.2/bin/* /usr/local/bin >> $LOG_FILE 2>&1
|
||||
mkdir ~/.bitcoin >> $LOG_FILE 2>&1
|
||||
mv /tmp/bitcoin.conf ~/.bitcoin
|
||||
mv /tmp/supervisor-bitcoin.conf /etc/supervisor/conf.d/bitcoin.conf >> $LOG_FILE 2>&1
|
||||
service supervisor restart >> $LOG_FILE 2>&1
|
||||
18
blockchains/dash/install.sh
Normal file
18
blockchains/dash/install.sh
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
LOG_FILE=/tmp/install.log
|
||||
|
||||
apt-get update -y >> $LOG_FILE 2>&1
|
||||
apt-get install -y ufw supervisor >> $LOG_FILE 2>&1
|
||||
ufw allow 8332 >> $LOG_FILE 2>&1
|
||||
ufw allow 22 >> $LOG_FILE 2>&1
|
||||
ufw --force enable >> $LOG_FILE 2>&1
|
||||
ufw status >> $LOG_FILE 2>&1
|
||||
wget -q https://www.dash.org/binaries/dashcore-0.12.1.5-linux64.tar.gz >> $LOG_FILE 2>&1
|
||||
tar -xzf dashcore-0.12.1.5-linux64.tar.gz >> $LOG_FILE 2>&1
|
||||
cp dashcore-0.12.1/bin/* /usr/local/bin >> $LOG_FILE 2>&1
|
||||
mkdir ~/.dash >> $LOG_FILE 2>&1
|
||||
mv /tmp/dash.conf ~/.bitocoin
|
||||
mv /tmp/supervisor-dash.conf /etc/supervisor/conf.d/dash.conf >> $LOG_FILE 2>&1
|
||||
service supervisor restart >> $LOG_FILE 2>&1
|
||||
18
blockchains/litecoin/install.sh
Normal file
18
blockchains/litecoin/install.sh
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
LOG_FILE=/tmp/install.log
|
||||
|
||||
apt-get update -y >> $LOG_FILE 2>&1
|
||||
apt-get install -y ufw supervisor >> $LOG_FILE 2>&1
|
||||
ufw allow 8332 >> $LOG_FILE 2>&1
|
||||
ufw allow 22 >> $LOG_FILE 2>&1
|
||||
ufw --force enable >> $LOG_FILE 2>&1
|
||||
ufw status >> $LOG_FILE 2>&1
|
||||
wget -q https://download.litecoin.org/litecoin-0.13.2/linux/litecoin-0.13.2-x86_64-linux-gnu.tar.gz >> $LOG_FILE 2>&1
|
||||
tar -xzf litecoin-0.13.2-x86_64-linux-gnu.tar.gz >> $LOG_FILE 2>&1
|
||||
cp litecoin-0.13.2/bin/* /usr/local/bin >> $LOG_FILE 2>&1
|
||||
mkdir ~/.litecoin >> $LOG_FILE 2>&1
|
||||
mv /tmp/litecoin.conf ~/.litecoin
|
||||
mv /tmp/supervisor-litecoin.conf /etc/supervisor/conf.d/litecoin.conf >> $LOG_FILE 2>&1
|
||||
service supervisor restart >> $LOG_FILE 2>&1
|
||||
7
blockchains/supervisor.conf
Normal file
7
blockchains/supervisor.conf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[program:${blockchain}]
|
||||
command=/usr/local/bin/${blockchain_cmd} -datadir=/mnt/blockchain/${blockchain}
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/var/log/supervisor/${blockchain}.err.log
|
||||
stdout_logfile=/var/log/supervisor/${blockchain}.out.log
|
||||
environment=HOME="/root"
|
||||
7
blockchains/tunnel.conf
Normal file
7
blockchains/tunnel.conf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[program:${blockchain}-tunnel]
|
||||
command=autossh -L 8232:localhost:8232 -o "ExitOnForwardFailure yes" -fN -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" root@188.226.149.173
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/var/log/supervisor/${blockchain}-tunnel.err.log
|
||||
stdout_logfile=/var/log/supervisor/${blockchain}-tunnel.out.log
|
||||
environment="AUTOSSH_GATETIME=0"
|
||||
19
blockchains/zcash/install.sh
Normal file
19
blockchains/zcash/install.sh
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
LOG_FILE=/tmp/install.log
|
||||
|
||||
apt-get update -y >> $LOG_FILE 2>&1
|
||||
apt-get install -y ufw supervisor libgomp1 >> $LOG_FILE 2>&1
|
||||
ufw allow 8233 >> $LOG_FILE 2>&1
|
||||
ufw allow 22 >> $LOG_FILE 2>&1
|
||||
ufw --force enable >> $LOG_FILE 2>&1
|
||||
ufw status >> $LOG_FILE 2>&1
|
||||
wget -q https://z.cash/downloads/zcash-1.0.10-1-linux64.tar.gz >> $LOG_FILE 2>&1
|
||||
tar -xzf zcash-1.0.10-1-linux64.tar.gz >> $LOG_FILE 2>&1
|
||||
cp zcash-1.0.10-1/bin/* /usr/local/bin >> $LOG_FILE 2>&1
|
||||
zcash-fetch-params >> $LOG_FILE 2>&1
|
||||
mkdir ~/.zcash >> $LOG_FILE 2>&1
|
||||
mv /tmp/zcash.conf ~/.zcash
|
||||
mv /tmp/supervisor-zcash.conf /etc/supervisor/conf.d/zcash.conf >> $LOG_FILE 2>&1
|
||||
service supervisor restart >> $LOG_FILE 2>&1
|
||||
0
blockchains/zcash/local-post-install
Normal file
0
blockchains/zcash/local-post-install
Normal file
20
blockchains/zcash/local-pre-install
Normal file
20
blockchains/zcash/local-pre-install
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path')
|
||||
const crypto = require('crypto')
|
||||
const fs = require('fs')
|
||||
|
||||
const options = require('../../lib/options')
|
||||
|
||||
const blockchainDir = options.blockchainDir
|
||||
const confPath = path.resolve(blockchainDir, 'zcash.conf')
|
||||
const password = crypto.randomBytes(32).toString('hex')
|
||||
|
||||
const conf = `rpcuser=username
|
||||
rpcpassword=${password}
|
||||
mainnet=1
|
||||
addnode=mainnet.z.cash
|
||||
dbcache=500
|
||||
`
|
||||
|
||||
fs.writeFileSync(confPath, conf)
|
||||
11
blockchains/zcash/upgrade.sh
Normal file
11
blockchains/zcash/upgrade.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
LOG_FILE=/tmp/install.log
|
||||
|
||||
wget -q $UPGRADE_URL >> $LOG_FILE 2>&1
|
||||
tar -xzf $UPGRADE_PACKAGE >> $LOG_FILE 2>&1
|
||||
supervisorctl stop zcash >> $LOG_FILE 2>&1
|
||||
cp $UPGRADE_PACKAGE/bin/* /usr/local/bin/ >> $LOG_FILE 2>&1
|
||||
supervisorctl start zcash >> $LOG_FILE 2>&1
|
||||
|
||||
4
blockchains/zcash/zcash.conf
Normal file
4
blockchains/zcash/zcash.conf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
rpcuser=username
|
||||
mainnet=1
|
||||
addnode=mainnet.z.cash
|
||||
dbcache=500
|
||||
|
|
@ -1,12 +1,44 @@
|
|||
const _ = require('lodash/fp')
|
||||
const BN = require('../bn')
|
||||
const settingsLoader = require('../settings-loader')
|
||||
const configManager = require('../config-manager')
|
||||
const wallet = require('../wallet')
|
||||
const ticker = require('../ticker')
|
||||
const coinUtils = require('../coin-utils')
|
||||
const machineLoader = require('../machine-loader')
|
||||
|
||||
module.exports = {getFunding}
|
||||
|
||||
function allScopes (cryptoScopes, machineScopes) {
|
||||
const scopes = []
|
||||
cryptoScopes.forEach(c => {
|
||||
machineScopes.forEach(m => scopes.push([c, m]))
|
||||
})
|
||||
|
||||
return scopes
|
||||
}
|
||||
|
||||
function allMachineScopes (machineList, machineScope) {
|
||||
const machineScopes = []
|
||||
|
||||
if (machineScope === 'global' || machineScope === 'both') machineScopes.push('global')
|
||||
if (machineScope === 'specific' || machineScope === 'both') machineList.forEach(r => machineScopes.push(r))
|
||||
|
||||
return machineScopes
|
||||
}
|
||||
|
||||
function getCryptos (config, machineList) {
|
||||
const scopes = allScopes(['global'], allMachineScopes(machineList, 'both'))
|
||||
const scoped = scope => configManager.scopedValue(scope[0], scope[1], 'cryptoCurrencies', config)
|
||||
|
||||
return _.uniq(_.flatten(_.map(scoped, scopes)))
|
||||
}
|
||||
|
||||
function fetchMachines () {
|
||||
return machineLoader.getMachines()
|
||||
.then(machineList => machineList.map(r => r.deviceId))
|
||||
}
|
||||
|
||||
function computeCrypto (cryptoCode, _balance) {
|
||||
const unitScale = coinUtils.coins[cryptoCode].unitScale
|
||||
|
||||
|
|
@ -19,15 +51,17 @@ function computeFiat (rate, cryptoCode, _balance) {
|
|||
return BN(_balance).shift(-unitScale).mul(rate).round(5)
|
||||
}
|
||||
|
||||
function getFunding (cryptoCode) {
|
||||
cryptoCode = cryptoCode || 'BTC'
|
||||
const cryptoDisplays = coinUtils.cryptoDisplays
|
||||
|
||||
if (!coinUtils.coins[cryptoCode]) throw new Error(`Unsupported coin: ${cryptoCode}`)
|
||||
return settingsLoader.loadLatest()
|
||||
.then(settings => {
|
||||
function getFunding (_cryptoCode) {
|
||||
return Promise.all([settingsLoader.loadLatest(), fetchMachines()])
|
||||
.then(([settings, machineList]) => {
|
||||
const config = configManager.unscoped(settings.config)
|
||||
const cryptoCodes = getCryptos(settings.config, machineList)
|
||||
const cryptoCode = _cryptoCode || cryptoCodes[0]
|
||||
const fiatCode = config.fiatCurrency
|
||||
const pareCoins = c => _.includes(c.cryptoCode, cryptoCodes)
|
||||
const cryptoDisplays = _.filter(pareCoins, coinUtils.cryptoDisplays)
|
||||
|
||||
if (!coinUtils.coins[cryptoCode]) throw new Error(`Unsupported coin: ${cryptoCode}`)
|
||||
|
||||
const promises = [
|
||||
wallet.newFunding(settings, cryptoCode),
|
||||
|
|
|
|||
33
lib/blockchain/bitcoin.js
Normal file
33
lib/blockchain/bitcoin.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('BTC')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500
|
||||
server=1
|
||||
connections=40
|
||||
keypool=10000
|
||||
prune=4000
|
||||
daemon=0`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/bitcoind -- -datadir=${dataDir}`)
|
||||
}
|
||||
61
lib/blockchain/common.js
Normal file
61
lib/blockchain/common.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
const crypto = require('crypto')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const cp = require('child_process')
|
||||
const logger = require('console-log-level')({level: 'info'})
|
||||
|
||||
module.exports = {es, firewall, randomPass, fetchAndInstall, logger}
|
||||
|
||||
const BINARIES = {
|
||||
BTC: {
|
||||
url: 'https://bitcoin.org/bin/bitcoin-core-0.14.2/bitcoin-0.14.2-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'bitcoin-0.14.2/bin'
|
||||
},
|
||||
ETH: {
|
||||
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.6.6-10a45cb5.tar.gz',
|
||||
dir: 'geth-linux-amd64-1.6.6-10a45cb5'
|
||||
},
|
||||
ZEC: {
|
||||
url: 'https://z.cash/downloads/zcash-1.0.10-1-linux64.tar.gz',
|
||||
dir: 'zcash-1.0.10-1/bin'
|
||||
},
|
||||
DASH: {
|
||||
url: 'https://www.dash.org/binaries/dashcore-0.12.1.5-linux64.tar.gz',
|
||||
dir: 'dashcore-0.12.1/bin'
|
||||
},
|
||||
LTC: {
|
||||
url: 'https://download.litecoin.org/litecoin-0.13.2/linux/litecoin-0.13.2-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'litecoin-0.13.2/bin'
|
||||
}
|
||||
}
|
||||
|
||||
function firewall (ports) {
|
||||
if (!ports || ports.length === 0) throw new Error('No ports supplied')
|
||||
const portsString = ports.join(',')
|
||||
es(`sudo ufw allow ${portsString}`)
|
||||
}
|
||||
|
||||
function randomPass () {
|
||||
return crypto.randomBytes(32).toString('hex')
|
||||
}
|
||||
|
||||
function es (cmd) {
|
||||
const env = {HOME: os.userInfo().homedir}
|
||||
const options = {encoding: 'utf8', env}
|
||||
const res = cp.execSync(cmd, options)
|
||||
logger.debug(res)
|
||||
return res.toString()
|
||||
}
|
||||
|
||||
function fetchAndInstall (crypto) {
|
||||
const binaries = BINARIES[crypto.cryptoCode]
|
||||
if (!binaries) throw new Error(`No such coin: ${crypto.code}`)
|
||||
|
||||
const url = binaries.url
|
||||
const downloadFile = path.basename(url)
|
||||
const binDir = binaries.dir
|
||||
|
||||
es(`wget -q ${url}`)
|
||||
es(`tar -xzf ${downloadFile}`)
|
||||
es(`sudo cp ${binDir}/* /usr/local/bin`)
|
||||
}
|
||||
28
lib/blockchain/dash.js
Normal file
28
lib/blockchain/dash.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('DASH')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/dashd -- -datadir=${dataDir}`)
|
||||
}
|
||||
0
lib/blockchain/dashd.js
Normal file
0
lib/blockchain/dashd.js
Normal file
67
lib/blockchain/do-volume.js
Normal file
67
lib/blockchain/do-volume.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
const fs = require('fs')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
const MOUNT_POINT = '/mnt/blockchains'
|
||||
|
||||
module.exports = {prepareVolume}
|
||||
|
||||
const logger = common.logger
|
||||
|
||||
function isMounted () {
|
||||
return fs.existsSync(MOUNT_POINT)
|
||||
}
|
||||
|
||||
function isFormatted (volumePath) {
|
||||
const res = common.es(`file --dereference -s ${volumePath}`)
|
||||
return res !== `${volumePath}: data`
|
||||
}
|
||||
|
||||
function formatVolume (volumePath) {
|
||||
if (isFormatted(volumePath)) {
|
||||
logger.info('Volume is already formatted.')
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Formatting...')
|
||||
common.es(`sudo mkfs.ext4 ${volumePath}`)
|
||||
}
|
||||
|
||||
function mountVolume (volumePath) {
|
||||
if (isMounted()) {
|
||||
logger.info('Volume is already mounted.')
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Mounting...')
|
||||
common.es(`sudo mkdir -p ${MOUNT_POINT}`)
|
||||
common.es(`sudo mount -o discard,defaults ${volumePath} ${MOUNT_POINT}`)
|
||||
common.es(`echo ${volumePath} ${MOUNT_POINT} ext4 defaults,nofail,discard 0 0 | sudo tee -a /etc/fstab`)
|
||||
}
|
||||
|
||||
function locateVolume () {
|
||||
const res = common.es('ls /dev/disk/by-id/*')
|
||||
const lines = res.trim().split('\n')
|
||||
|
||||
if (lines.length > 1) {
|
||||
logger.error('More than one volume present, cannot prepare.')
|
||||
return null
|
||||
}
|
||||
|
||||
if (lines.length === 0) {
|
||||
logger.error('No available volumes. You might need to attach one.')
|
||||
return null
|
||||
}
|
||||
|
||||
return lines[0].trim()
|
||||
}
|
||||
|
||||
function prepareVolume () {
|
||||
const volumePath = locateVolume()
|
||||
if (!volumePath) return false
|
||||
|
||||
formatVolume(volumePath)
|
||||
mountVolume(volumePath)
|
||||
|
||||
return true
|
||||
}
|
||||
17
lib/blockchain/ethereum.js
Normal file
17
lib/blockchain/ethereum.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('ETH')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/geth -- --datadir "${dataDir}" --cache 500`)
|
||||
}
|
||||
95
lib/blockchain/install.js
Normal file
95
lib/blockchain/install.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const process = require('process')
|
||||
|
||||
const makeDir = require('make-dir')
|
||||
const inquirer = require('inquirer')
|
||||
const _ = require('lodash/fp')
|
||||
|
||||
const options = require('../options')
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
const doVolume = require('./do-volume')
|
||||
|
||||
const cryptos = coinUtils.cryptoCurrencies()
|
||||
|
||||
const logger = common.logger
|
||||
|
||||
const PLUGINS = {
|
||||
BTC: require('./bitcoin.js'),
|
||||
LTC: require('./litecoin.js'),
|
||||
ETH: require('./ethereum.js'),
|
||||
DASH: require('./dash.js'),
|
||||
ZEC: require('./zcash.js')
|
||||
}
|
||||
|
||||
function installedFilePath (crypto) {
|
||||
return path.resolve(options.blockchainDir, crypto.code, '.installed')
|
||||
}
|
||||
|
||||
function isInstalled (crypto) {
|
||||
return fs.existsSync(installedFilePath(crypto))
|
||||
}
|
||||
|
||||
const choices = _.map(c => {
|
||||
const checked = isInstalled(c)
|
||||
return {
|
||||
name: c.display,
|
||||
value: c.code,
|
||||
checked,
|
||||
disabled: checked && 'Installed'
|
||||
}
|
||||
}, cryptos)
|
||||
|
||||
const questions = []
|
||||
|
||||
questions.push({
|
||||
type: 'checkbox',
|
||||
name: 'crypto',
|
||||
message: 'Which cryptocurrencies would you like to install?',
|
||||
choices
|
||||
})
|
||||
|
||||
function processCryptos (codes) {
|
||||
if (_.isEmpty(codes)) {
|
||||
logger.info('No cryptos selected. Exiting.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
doVolume.prepareVolume()
|
||||
|
||||
logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))
|
||||
|
||||
const selectedCryptos = _.map(code => _.find(['code', code], cryptos), codes)
|
||||
_.forEach(setupCrypto, selectedCryptos)
|
||||
common.es('pm2 save')
|
||||
logger.info('Installation complete.')
|
||||
}
|
||||
|
||||
inquirer.prompt(questions)
|
||||
.then(answers => processCryptos(answers.crypto))
|
||||
|
||||
function plugin (crypto) {
|
||||
const plugin = PLUGINS[crypto.cryptoCode]
|
||||
if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
|
||||
return plugin
|
||||
}
|
||||
|
||||
function setupCrypto (crypto) {
|
||||
logger.info(`Installing ${crypto.display}...`)
|
||||
const cryptoDir = path.resolve(options.blockchainDir, crypto.code)
|
||||
makeDir.sync(cryptoDir)
|
||||
const cryptoPlugin = plugin(crypto)
|
||||
const oldDir = process.cwd()
|
||||
const tmpDir = '/tmp/blockchain-install'
|
||||
|
||||
makeDir.sync(tmpDir)
|
||||
process.chdir(tmpDir)
|
||||
common.es('rm -rf *')
|
||||
common.fetchAndInstall(crypto)
|
||||
cryptoPlugin.setup(cryptoDir)
|
||||
fs.writeFileSync(installedFilePath(crypto), '')
|
||||
process.chdir(oldDir)
|
||||
}
|
||||
|
||||
33
lib/blockchain/litecoin.js
Normal file
33
lib/blockchain/litecoin.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
|
||||
function setup (dataDir) {
|
||||
const coinRec = coinUtils.getCryptoCurrency('LTC')
|
||||
common.firewall([coinRec.defaultPort])
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500
|
||||
server=1
|
||||
connections=40
|
||||
keypool=10000
|
||||
prune=4000
|
||||
daemon=0`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/litecoind -- -datadir=${dataDir}`)
|
||||
}
|
||||
37
lib/blockchain/zcash.js
Normal file
37
lib/blockchain/zcash.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const coinUtils = require('../coin-utils')
|
||||
|
||||
const common = require('./common')
|
||||
|
||||
module.exports = {setup}
|
||||
|
||||
const es = common.es
|
||||
const logger = common.logger
|
||||
|
||||
function setup (dataDir) {
|
||||
es('sudo apt-get update')
|
||||
es('sudo apt-get install libgomp1 -y')
|
||||
const coinRec = coinUtils.getCryptoCurrency('ZEC')
|
||||
|
||||
common.firewall([coinRec.defaultPort])
|
||||
logger.info('Fetching Zcash proofs, will take a while...')
|
||||
es('zcash-fetch-params 2>&1')
|
||||
logger.info('Finished fetching proofs.')
|
||||
const config = buildConfig()
|
||||
fs.writeFileSync(path.resolve(dataDir, 'zcash.conf'), config)
|
||||
setupPm2(dataDir)
|
||||
}
|
||||
|
||||
function buildConfig () {
|
||||
return `mainnet=1
|
||||
addnode=mainnet.z.cash
|
||||
rpcuser=lamassuserver
|
||||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500`
|
||||
}
|
||||
|
||||
function setupPm2 (dataDir) {
|
||||
es(`pm2 start /usr/local/bin/zcashd -- -datadir=${dataDir}`)
|
||||
}
|
||||
0
lib/blockchain/zcashd.js
Normal file
0
lib/blockchain/zcashd.js
Normal file
|
|
@ -1,22 +1,64 @@
|
|||
const _ = require('lodash/fp')
|
||||
|
||||
const coins = {
|
||||
BTC: {unitScale: 8},
|
||||
ETH: {unitScale: 18},
|
||||
ZEC: {unitScale: 8},
|
||||
LTC: {unitScale: 8},
|
||||
DASH: {unitScale: 8}
|
||||
}
|
||||
|
||||
const cryptoDisplays = [
|
||||
{cryptoCode: 'BTC', display: 'Bitcoin'},
|
||||
{cryptoCode: 'ETH', display: 'Ethereum'},
|
||||
{cryptoCode: 'ZEC', display: 'Zcash'},
|
||||
{cryptoCode: 'LTC', display: 'Litecoin'},
|
||||
{cryptoCode: 'DASH', display: 'Dash'}
|
||||
const CRYPTO_CURRENCIES = [
|
||||
{
|
||||
cryptoCode: 'BTC',
|
||||
display: 'Bitcoin',
|
||||
code: 'bitcoin',
|
||||
configFile: 'bitcoin.conf',
|
||||
daemon: 'bitcoind',
|
||||
defaultPort: 8332,
|
||||
unitScale: 8
|
||||
},
|
||||
{
|
||||
cryptoCode: 'ETH',
|
||||
display: 'Ethereum',
|
||||
code: 'ethereum',
|
||||
configFile: 'geth.conf',
|
||||
daemon: 'geth',
|
||||
defaultPort: 8545,
|
||||
unitScale: 18
|
||||
},
|
||||
{
|
||||
cryptoCode: 'LTC',
|
||||
display: 'Litecoin',
|
||||
code: 'litecoin',
|
||||
configFile: 'litecoin.conf',
|
||||
daemon: 'litecoind',
|
||||
defaultPort: 9332,
|
||||
unitScale: 8
|
||||
},
|
||||
{
|
||||
cryptoCode: 'DASH',
|
||||
display: 'Dash',
|
||||
code: 'dash',
|
||||
configFile: 'dash.conf',
|
||||
daemon: 'dashd',
|
||||
defaultPort: 9998,
|
||||
unitScale: 8
|
||||
},
|
||||
{
|
||||
cryptoCode: 'ZEC',
|
||||
display: 'Zcash',
|
||||
code: 'zcash',
|
||||
configFile: 'zcash.conf',
|
||||
daemon: 'zcashd',
|
||||
defaultPort: 8232,
|
||||
unitScale: 8
|
||||
}
|
||||
]
|
||||
|
||||
module.exports = {coins, cryptoDisplays, buildUrl, unitScale, display}
|
||||
module.exports = {buildUrl, cryptoCurrencies, getCryptoCurrency}
|
||||
|
||||
function getCryptoCurrency (cryptoCode) {
|
||||
const cryptoCurrency = _.find(['cryptoCode', cryptoCode], CRYPTO_CURRENCIES)
|
||||
if (!cryptoCurrency) throw new Error(`Unsupported crypto: ${cryptoCode}`)
|
||||
return cryptoCurrency
|
||||
}
|
||||
|
||||
function cryptoCurrencies () {
|
||||
return CRYPTO_CURRENCIES
|
||||
}
|
||||
|
||||
function buildUrl (cryptoCode, address) {
|
||||
switch (cryptoCode) {
|
||||
|
|
@ -28,15 +70,3 @@ function buildUrl (cryptoCode, address) {
|
|||
default: throw new Error(`Unsupported crypto: ${cryptoCode}`)
|
||||
}
|
||||
}
|
||||
|
||||
function display (cryptoCode) {
|
||||
const rec = _.find(['cryptoCode', cryptoCode], cryptoDisplays)
|
||||
if (!rec) throw new Error(`Unsupported crypto: ${cryptoCode}`)
|
||||
return rec.display
|
||||
}
|
||||
|
||||
function unitScale (cryptoCode) {
|
||||
const scaleRec = coins[cryptoCode]
|
||||
if (!scaleRec) throw new Error(`Unsupported crypto: ${cryptoCode}`)
|
||||
return scaleRec.unitScale
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ const argv = require('minimist')(process.argv.slice(2))
|
|||
let serverConfig
|
||||
|
||||
try {
|
||||
const homeConfigPath = path.resolve(os.homedir(), '.lamassu', 'lamassu.json')
|
||||
serverConfig = JSON.parse(fs.readFileSync(homeConfigPath))
|
||||
const globalConfigPath = path.resolve('/etc', 'lamassu', 'lamassu.json')
|
||||
serverConfig = JSON.parse(fs.readFileSync(globalConfigPath))
|
||||
} catch (_) {
|
||||
try {
|
||||
const globalConfigPath = path.resolve('/etc', 'lamassu', 'lamassu.json')
|
||||
serverConfig = JSON.parse(fs.readFileSync(globalConfigPath))
|
||||
const homeConfigPath = path.resolve(os.homedir(), '.lamassu', 'lamassu.json')
|
||||
serverConfig = JSON.parse(fs.readFileSync(homeConfigPath))
|
||||
} catch (_) {
|
||||
console.error("Couldn't open lamassu.json config file.")
|
||||
process.exit(1)
|
||||
|
|
|
|||
|
|
@ -171,7 +171,9 @@ function plugins (settings, deviceId) {
|
|||
.then(row => row.id)
|
||||
}
|
||||
|
||||
function mapCoinSettings (coin) {
|
||||
function mapCoinSettings (coinParams) {
|
||||
const coin = coinParams[0]
|
||||
const cryptoNetwork = coinParams[1]
|
||||
const config = configManager.scoped(coin, deviceId, settings.config)
|
||||
const minimumTx = BN(config.minimumTx)
|
||||
const cashInFee = BN(config.cashInFee)
|
||||
|
|
@ -180,7 +182,8 @@ function plugins (settings, deviceId) {
|
|||
cryptoCode: coin,
|
||||
display: coinUtils.display(coin),
|
||||
minimumTx: BN.max(minimumTx, cashInFee),
|
||||
cashInFee: cashInFee
|
||||
cashInFee: cashInFee,
|
||||
cryptoNetwork
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +194,7 @@ function plugins (settings, deviceId) {
|
|||
|
||||
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
|
||||
const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
||||
const testnetPromises = cryptoCodes.map(c => wallet.cryptoNetwork(settings, c))
|
||||
const pingPromise = recordPing(serialNumber, deviceTime, deviceRec)
|
||||
const currentConfigVersionPromise = fetchCurrentConfigVersion()
|
||||
|
||||
|
|
@ -198,20 +202,25 @@ function plugins (settings, deviceId) {
|
|||
buildAvailableCassettes(),
|
||||
pingPromise,
|
||||
currentConfigVersionPromise
|
||||
].concat(tickerPromises, balancePromises)
|
||||
].concat(tickerPromises, balancePromises, testnetPromises)
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(arr => {
|
||||
const cassettes = arr[0]
|
||||
const configVersion = arr[2]
|
||||
const tickers = arr.slice(3, cryptoCodes.length + 3)
|
||||
const balances = arr.slice(cryptoCodes.length + 3)
|
||||
const cryptoCodesCount = cryptoCodes.length
|
||||
const tickers = arr.slice(3, cryptoCodesCount + 3)
|
||||
const balances = arr.slice(cryptoCodesCount + 3, 2 * cryptoCodesCount + 3)
|
||||
const testNets = arr.slice(2 * cryptoCodesCount + 3)
|
||||
const coinParams = _.zip(cryptoCodes, testNets)
|
||||
|
||||
console.log('DEBUG200: %j', cryptoCodes)
|
||||
console.log('DEBUG201: %j', coinParams)
|
||||
return {
|
||||
cassettes,
|
||||
rates: buildRates(tickers),
|
||||
balances: buildBalances(balances),
|
||||
coins: _.map(mapCoinSettings, cryptoCodes),
|
||||
coins: _.map(mapCoinSettings, coinParams),
|
||||
configVersion
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -23,18 +23,27 @@ function fetch (account, method, params) {
|
|||
return r.data.result
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err.response.data.error)
|
||||
console.log(err.message)
|
||||
try {
|
||||
console.log(err.response.data.error)
|
||||
} catch (__) {}
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
function split (str) {
|
||||
const i = str.indexOf('=')
|
||||
if (i === -1) return []
|
||||
return [str.slice(0, i), str.slice(i + 1)]
|
||||
}
|
||||
|
||||
function parseConf (confPath) {
|
||||
const conf = fs.readFileSync(confPath)
|
||||
const lines = conf.toString().split('\n', 2)
|
||||
const lines = conf.toString().split('\n')
|
||||
|
||||
const res = {}
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const keyVal = lines[i].split('=')
|
||||
const keyVal = split(lines[i])
|
||||
|
||||
// skip when value is empty
|
||||
if (!keyVal[1]) continue
|
||||
|
|
|
|||
|
|
@ -39,11 +39,10 @@ function balance (account, cryptoCode) {
|
|||
}
|
||||
|
||||
function sendCoins (account, address, cryptoAtoms, cryptoCode) {
|
||||
const confirmations = 1
|
||||
const bitcoins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
const coins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
|
||||
return checkCryptoCode(cryptoCode)
|
||||
.then(() => fetch('sendfrom', [address, bitcoins, confirmations]))
|
||||
.then(() => fetch('sendtoaddress', [address, coins]))
|
||||
.catch(err => {
|
||||
if (err.code === -6) throw new E.InsufficientFundsError()
|
||||
throw err
|
||||
|
|
@ -103,10 +102,16 @@ function newFunding (account, cryptoCode) {
|
|||
}))
|
||||
}
|
||||
|
||||
function cryptoNetwork (account, cryptoCode) {
|
||||
return checkCryptoCode(cryptoCode)
|
||||
.then(() => parseInt(rpcConfig.port, 10) === 18332 ? 'test' : 'main')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
balance,
|
||||
sendCoins,
|
||||
newAddress,
|
||||
getStatus,
|
||||
newFunding
|
||||
newFunding,
|
||||
cryptoNetwork
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,11 +103,17 @@ function newFunding (account, cryptoCode) {
|
|||
})
|
||||
}
|
||||
|
||||
function cryptoNetwork (account, cryptoCode) {
|
||||
return checkCryptoCode(cryptoCode)
|
||||
.then(() => account.environment === 'test' ? 'test' : 'main')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
NAME,
|
||||
balance,
|
||||
sendCoins,
|
||||
newAddress,
|
||||
getStatus,
|
||||
newFunding
|
||||
newFunding,
|
||||
cryptoNetwork
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ module.exports = {
|
|||
sweep,
|
||||
defaultAddress,
|
||||
supportsHd: true,
|
||||
newFunding
|
||||
newFunding,
|
||||
privateKey
|
||||
}
|
||||
|
||||
if (!web3.isConnected()) {
|
||||
|
|
@ -31,6 +32,10 @@ if (!web3.isConnected()) {
|
|||
|
||||
const hex = bigNum => '0x' + bigNum.truncated().toString(16)
|
||||
|
||||
function privateKey (account) {
|
||||
return defaultWallet(account).getPrivateKey()
|
||||
}
|
||||
|
||||
function sendCoins (account, toAddress, cryptoAtoms, cryptoCode) {
|
||||
return generateTx(toAddress, defaultWallet(account), cryptoAtoms, false)
|
||||
.then(_.tap(r => console.log('DEBUG113: %s', r)))
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ const rpcConfig = {
|
|||
port: config.rpcport || DEFAULT_PORT
|
||||
}
|
||||
|
||||
console.log('DEBUG101: %j', configPath)
|
||||
console.log('DEBUG100: %j', rpcConfig)
|
||||
|
||||
function fetch (method, params) {
|
||||
return jsonRpc.fetch(rpcConfig, method, params)
|
||||
}
|
||||
|
|
@ -40,11 +43,10 @@ function balance (account, cryptoCode) {
|
|||
}
|
||||
|
||||
function sendCoins (account, address, cryptoAtoms, cryptoCode) {
|
||||
const confirmations = 1
|
||||
const bitcoins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
const coins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
|
||||
return checkCryptoCode(cryptoCode)
|
||||
.then(() => fetch('sendfrom', [address, bitcoins, confirmations]))
|
||||
.then(() => fetch('sendtoaddress', [address, coins]))
|
||||
.catch(err => {
|
||||
if (err.code === -6) throw new E.InsufficientFundsError()
|
||||
throw err
|
||||
|
|
|
|||
|
|
@ -40,11 +40,10 @@ function balance (account, cryptoCode) {
|
|||
}
|
||||
|
||||
function sendCoins (account, address, cryptoAtoms, cryptoCode) {
|
||||
const confirmations = 1
|
||||
const bitcoins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
const coins = cryptoAtoms.shift(-SATOSHI_SHIFT).toFixed(8)
|
||||
|
||||
return checkCryptoCode(cryptoCode)
|
||||
.then(() => fetch('sendfrom', [address, bitcoins, confirmations]))
|
||||
.then(() => fetch('sendtoaddress', [address, coins]))
|
||||
.catch(err => {
|
||||
if (err.code === -6) throw new E.InsufficientFundsError()
|
||||
throw err
|
||||
|
|
|
|||
|
|
@ -139,6 +139,15 @@ function isHd (settings, cryptoCode) {
|
|||
.then(r => r.wallet.supportsHd)
|
||||
}
|
||||
|
||||
function cryptoNetwork (settings, cryptoCode) {
|
||||
const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet
|
||||
const wallet = ph.load(ph.WALLET, plugin)
|
||||
const account = settings.accounts[plugin]
|
||||
|
||||
if (!wallet.cryptoNetwork) return Promise.resolve(false)
|
||||
return wallet.cryptoNetwork(account, cryptoCode)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
balance: mem(balance, {maxAge: FETCH_INTERVAL}),
|
||||
sendCoins,
|
||||
|
|
@ -146,5 +155,6 @@ module.exports = {
|
|||
getStatus,
|
||||
sweep,
|
||||
isHd,
|
||||
newFunding
|
||||
newFunding,
|
||||
cryptoNetwork
|
||||
}
|
||||
|
|
|
|||
37
main.tf
Normal file
37
main.tf
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
module "zcash" {
|
||||
source = "./blockchain"
|
||||
name = "zcash"
|
||||
blockchain_cmd = "zcashd"
|
||||
blockchain_conf = "zcash.conf"
|
||||
ssh_key = "${digitalocean_ssh_key.default.id}"
|
||||
}
|
||||
|
||||
module "litecoin" {
|
||||
source = "./blockchain"
|
||||
name = "litecoin"
|
||||
blockchain_cmd = "litecoind"
|
||||
blockchain_conf = "litecoin.conf"
|
||||
ssh_key = "${digitalocean_ssh_key.default.id}"
|
||||
}
|
||||
|
||||
module "dash" {
|
||||
source = "./blockchain"
|
||||
name = "dash"
|
||||
blockchain_cmd = "dashd"
|
||||
blockchain_conf = "dash.conf"
|
||||
ssh_key = "${digitalocean_ssh_key.default.id}"
|
||||
}
|
||||
|
||||
module "bitcoin" {
|
||||
source = "./blockchain"
|
||||
name = "bitcoin"
|
||||
blockchain_cmd = "bitcoind"
|
||||
blockchain_conf = "bitcoin.conf"
|
||||
ssh_key = "${digitalocean_ssh_key.default.id}"
|
||||
}
|
||||
|
||||
resource "digitalocean_ssh_key" "default" {
|
||||
name = "Lamassu Server"
|
||||
public_key = "${file("${pathexpand("~/.ssh/id_rsa.pub")}")}"
|
||||
}
|
||||
|
||||
3733
package-lock.json
generated
3733
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,7 @@
|
|||
"bitcoind-rpc": "^0.7.0",
|
||||
"bitgo": "^3.4.0",
|
||||
"body-parser": "^1.15.1",
|
||||
"console-log-level": "^1.4.0",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"ethereumjs-tx": "^1.3.0",
|
||||
"ethereumjs-wallet": "^0.6.0",
|
||||
|
|
@ -23,8 +24,10 @@
|
|||
"express-ws": "^3.0.0",
|
||||
"got": "^7.0.0",
|
||||
"helmet": "^3.6.1",
|
||||
"inquirer": "^3.1.1",
|
||||
"kraken-api": "DeX3/npm-kraken-api",
|
||||
"lodash": "^4.17.2",
|
||||
"make-dir": "^1.0.0",
|
||||
"mem": "^1.1.0",
|
||||
"migrate": "^0.2.2",
|
||||
"minimist": "^1.2.0",
|
||||
|
|
@ -68,6 +71,7 @@
|
|||
"lamassu-nuke-db": "./bin/lamassu-nuke-db"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node bin/lamassu-server",
|
||||
"test": "ava"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -21386,16 +21386,24 @@ var _pablohirafuji$elm_qrcode$QRCode_View$rectView = function (_p1) {
|
|||
_elm_lang$core$Basics$toString(_p2.row * _pablohirafuji$elm_qrcode$QRCode_View$moduleSize)),
|
||||
_1: {
|
||||
ctor: '::',
|
||||
_0: _elm_lang$svg$Svg_Attributes$width(
|
||||
_elm_lang$core$Basics$toString(_pablohirafuji$elm_qrcode$QRCode_View$moduleSize)),
|
||||
_0: _elm_lang$svg$Svg_Attributes$rx('0'),
|
||||
_1: {
|
||||
ctor: '::',
|
||||
_0: _elm_lang$svg$Svg_Attributes$height(
|
||||
_elm_lang$core$Basics$toString(_pablohirafuji$elm_qrcode$QRCode_View$moduleSize)),
|
||||
_0: _elm_lang$svg$Svg_Attributes$ry('0'),
|
||||
_1: {
|
||||
ctor: '::',
|
||||
_0: _elm_lang$svg$Svg_Attributes$fill('black'),
|
||||
_1: {ctor: '[]'}
|
||||
_0: _elm_lang$svg$Svg_Attributes$width(
|
||||
_elm_lang$core$Basics$toString(_pablohirafuji$elm_qrcode$QRCode_View$moduleSize)),
|
||||
_1: {
|
||||
ctor: '::',
|
||||
_0: _elm_lang$svg$Svg_Attributes$height(
|
||||
_elm_lang$core$Basics$toString(_pablohirafuji$elm_qrcode$QRCode_View$moduleSize)),
|
||||
_1: {
|
||||
ctor: '::',
|
||||
_0: _elm_lang$svg$Svg_Attributes$fill('black'),
|
||||
_1: {ctor: '[]'}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
107
yarn.lock
107
yarn.lock
|
|
@ -102,6 +102,10 @@ ansi-align@^2.0.0:
|
|||
dependencies:
|
||||
string-width "^2.0.0"
|
||||
|
||||
ansi-escapes@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
|
|
@ -1327,6 +1331,10 @@ cli-truncate@^1.0.0:
|
|||
slice-ansi "0.0.4"
|
||||
string-width "^2.0.0"
|
||||
|
||||
cli-width@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
|
||||
|
||||
cliui@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
|
||||
|
|
@ -1458,6 +1466,10 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||
|
||||
console-log-level@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/console-log-level/-/console-log-level-1.4.0.tgz#4035818beea37e5850a0c03c8d450ca5f2cd1217"
|
||||
|
||||
content-disposition@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
|
||||
|
|
@ -2152,6 +2164,14 @@ extend@3, extend@^3.0.0, extend@~3.0.0:
|
|||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
|
||||
|
||||
external-editor@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972"
|
||||
dependencies:
|
||||
iconv-lite "^0.4.17"
|
||||
jschardet "^1.4.2"
|
||||
tmp "^0.0.31"
|
||||
|
||||
extglob@^0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
|
||||
|
|
@ -2679,10 +2699,14 @@ hullabaloo-config-manager@^1.0.0:
|
|||
resolve-from "^3.0.0"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
iconv-lite@0.4.15, iconv-lite@^0.4.5:
|
||||
iconv-lite@0.4.15:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
|
||||
|
||||
iconv-lite@^0.4.17, iconv-lite@^0.4.5:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
|
||||
|
||||
ienoopen@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b"
|
||||
|
|
@ -2732,6 +2756,25 @@ ini@~1.3.0:
|
|||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
|
||||
|
||||
inquirer@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534"
|
||||
dependencies:
|
||||
ansi-escapes "^2.0.0"
|
||||
chalk "^1.0.0"
|
||||
cli-cursor "^2.1.0"
|
||||
cli-width "^2.0.0"
|
||||
external-editor "^2.0.4"
|
||||
figures "^2.0.0"
|
||||
lodash "^4.3.0"
|
||||
mute-stream "0.0.7"
|
||||
run-async "^2.2.0"
|
||||
rx-lite "^4.0.8"
|
||||
rx-lite-aggregates "^4.0.8"
|
||||
string-width "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
invariant@^2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
|
|
@ -3012,6 +3055,10 @@ jsbn@~0.1.0:
|
|||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
|
||||
jschardet@^1.4.2:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a"
|
||||
|
||||
jsesc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
|
||||
|
|
@ -3229,7 +3276,7 @@ lodash@^3.1.0, lodash@^3.10.1:
|
|||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||
|
||||
lodash@^4.12.0, lodash@^4.17.2, lodash@^4.2.0:
|
||||
lodash@^4.12.0, lodash@^4.17.2, lodash@^4.2.0, lodash@^4.3.0:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
|
|
@ -3464,6 +3511,10 @@ multimatch@^2.1.0:
|
|||
arrify "^1.0.0"
|
||||
minimatch "^3.0.0"
|
||||
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
||||
nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
|
||||
|
|
@ -3662,7 +3713,7 @@ os-locale@^1.4.0:
|
|||
dependencies:
|
||||
lcid "^1.0.0"
|
||||
|
||||
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
|
||||
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
||||
|
|
@ -4509,6 +4560,22 @@ rootpath@0.1.2:
|
|||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/rootpath/-/rootpath-0.1.2.tgz#5b379a87dca906e9b91d690a599439bef267ea6b"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
||||
dependencies:
|
||||
is-promise "^2.1.0"
|
||||
|
||||
rx-lite-aggregates@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
|
||||
dependencies:
|
||||
rx-lite "*"
|
||||
|
||||
rx-lite@*, rx-lite@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.0.tgz#fe4c8460397f9eaaaa58e73be46273408a45e223"
|
||||
|
|
@ -4678,7 +4745,7 @@ socket.io-adapter@~1.1.0:
|
|||
dependencies:
|
||||
debug "2.3.3"
|
||||
|
||||
socket.io-client@^2.0.3:
|
||||
socket.io-client@^2.0.3, socket.io-client@~2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.3.tgz#6caf4aff9f85b19fd91b6ce13d69adb564f8873b"
|
||||
dependencies:
|
||||
|
|
@ -4696,24 +4763,6 @@ socket.io-client@^2.0.3:
|
|||
socket.io-parser "~3.1.1"
|
||||
to-array "0.1.4"
|
||||
|
||||
socket.io-client@~2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.0.2.tgz#86f59db59ba1168724220f39be281ad49af742c1"
|
||||
dependencies:
|
||||
backo2 "1.0.2"
|
||||
base64-arraybuffer "0.1.5"
|
||||
component-bind "1.0.0"
|
||||
component-emitter "1.2.1"
|
||||
debug "~2.6.4"
|
||||
engine.io-client "~3.1.0"
|
||||
has-cors "1.1.0"
|
||||
indexof "0.0.1"
|
||||
object-component "0.0.3"
|
||||
parseqs "0.0.5"
|
||||
parseuri "0.0.5"
|
||||
socket.io-parser "~3.1.1"
|
||||
to-array "0.1.4"
|
||||
|
||||
socket.io-parser@~3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2"
|
||||
|
|
@ -5033,7 +5082,7 @@ through2@^2.0.0:
|
|||
readable-stream "^2.1.5"
|
||||
xtend "~4.0.1"
|
||||
|
||||
through@2, through@~2.3.8:
|
||||
through@2, through@^2.3.6, through@~2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
|
|
@ -5054,6 +5103,12 @@ timed-out@^4.0.0:
|
|||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
|
||||
|
||||
tmp@^0.0.31:
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.1"
|
||||
|
||||
to-array@0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
|
||||
|
|
@ -5228,11 +5283,7 @@ uuid@^2.0.1:
|
|||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
|
||||
|
||||
uuid@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
|
||||
|
||||
uuid@^3.1.0:
|
||||
uuid@^3.0.0, uuid@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue