add blockcypher [WIP]
This commit is contained in:
parent
b28c99aabb
commit
23458b6b56
10 changed files with 133 additions and 17 deletions
|
|
@ -70,7 +70,8 @@
|
||||||
"fields": [
|
"fields": [
|
||||||
"ticker",
|
"ticker",
|
||||||
"wallet",
|
"wallet",
|
||||||
"exchange"
|
"exchange",
|
||||||
|
"zeroConf"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -176,7 +177,7 @@
|
||||||
"displayBottom": "Limit",
|
"displayBottom": "Limit",
|
||||||
"fieldType": "integer",
|
"fieldType": "integer",
|
||||||
"fieldClass": "fiat",
|
"fieldClass": "fiat",
|
||||||
"cryptoScope": "both",
|
"cryptoScope": "global",
|
||||||
"machineScope": "both",
|
"machineScope": "both",
|
||||||
"enabledIf": [
|
"enabledIf": [
|
||||||
"cashOutEnabled"
|
"cashOutEnabled"
|
||||||
|
|
@ -213,6 +214,14 @@
|
||||||
"fieldValidation": [],
|
"fieldValidation": [],
|
||||||
"default": "no-exchange"
|
"default": "no-exchange"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "zeroConf",
|
||||||
|
"displayBottom": "Zero Conf",
|
||||||
|
"fieldType": "account",
|
||||||
|
"fieldClass": "zeroConf",
|
||||||
|
"fieldValidation": [],
|
||||||
|
"default": "all-zero-conf"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "fiatCurrency",
|
"code": "fiatCurrency",
|
||||||
"displayBottom": "Fiat Currency",
|
"displayBottom": "Fiat Currency",
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,10 @@ function fetchData () {
|
||||||
{code: 'mock-sms', display: 'Mock SMS', class: 'sms'},
|
{code: 'mock-sms', display: 'Mock SMS', class: 'sms'},
|
||||||
{code: 'mock-id-verify', display: 'Mock ID verifier', class: 'idVerifier'},
|
{code: 'mock-id-verify', display: 'Mock ID verifier', class: 'idVerifier'},
|
||||||
{code: 'twilio', display: 'Twilio', class: 'sms'},
|
{code: 'twilio', display: 'Twilio', class: 'sms'},
|
||||||
{code: 'mailjet', display: 'Mailjet', class: 'email'}
|
{code: 'mailjet', display: 'Mailjet', class: 'email'},
|
||||||
|
{code: 'all-zero-conf', display: 'All pass', class: 'zeroConf'},
|
||||||
|
{code: 'blockcypher', display: 'Blockcypher', class: 'zeroConf'},
|
||||||
|
{code: 'mock-zero-conf', display: 'Mock 0-conf', class: 'zeroConf'}
|
||||||
],
|
],
|
||||||
machines: machineList.map(machine => ({machine: machine.deviceId, display: machine.name}))
|
machines: machineList.map(machine => ({machine: machine.deviceId, display: machine.name}))
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ const pluginCodes = {
|
||||||
EXCHANGE: 'exchange',
|
EXCHANGE: 'exchange',
|
||||||
WALLET: 'wallet',
|
WALLET: 'wallet',
|
||||||
SMS: 'sms',
|
SMS: 'sms',
|
||||||
EMAIL: 'email'
|
EMAIL: 'email',
|
||||||
|
ZERO_CONF: 'zero-conf'
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = _.assign({load, loadSchemas}, pluginCodes)
|
module.exports = _.assign({load, loadSchemas}, pluginCodes)
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ function plugins (settings, deviceId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatus (tx) {
|
function getStatus (tx) {
|
||||||
return wallet.getStatus(settings, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode)
|
return wallet.getStatus(settings, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode, tx.fiat, deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
function newAddress (tx) {
|
function newAddress (tx) {
|
||||||
|
|
@ -471,6 +471,8 @@ function plugins (settings, deviceId) {
|
||||||
const config = configManager.machineScoped(_deviceId, settings.config)
|
const config = configManager.machineScoped(_deviceId, settings.config)
|
||||||
const cryptoCodes = config.cryptoCurrencies
|
const cryptoCodes = config.cryptoCurrencies
|
||||||
const fiatCode = config.fiatCurrency
|
const fiatCode = config.fiatCurrency
|
||||||
|
|
||||||
|
console.log('DEBUG103: %j', cryptoCodes)
|
||||||
const fiatBalancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
const fiatBalancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
||||||
|
|
||||||
return Promise.all(fiatBalancePromises)
|
return Promise.all(fiatBalancePromises)
|
||||||
|
|
|
||||||
28
lib/plugins/zero-conf/blockcypher/blockcypher.js
Normal file
28
lib/plugins/zero-conf/blockcypher/blockcypher.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
const qs = require('querystring')
|
||||||
|
const axios = require('axios')
|
||||||
|
const _ = require('lodash/fp')
|
||||||
|
|
||||||
|
module.exports = {authorize}
|
||||||
|
|
||||||
|
function authorize (account, toAddress, cryptoAtoms, cryptoCode) {
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
if (cryptoCode !== 'BTC') throw new Error('Unsupported crypto: ' + cryptoCode)
|
||||||
|
|
||||||
|
const query = qs.stringify({
|
||||||
|
token: account.token,
|
||||||
|
includeConfidence: true,
|
||||||
|
confidence: account.confidence
|
||||||
|
})
|
||||||
|
|
||||||
|
const url = `https://api.blockcypher.com/v1/btc/main/addrs/${toAddress}?${query}`
|
||||||
|
|
||||||
|
return axios.get(url)
|
||||||
|
.then(r => {
|
||||||
|
const data = r.data
|
||||||
|
const authorizedValue = _.sumBy('value', data.txrefs)
|
||||||
|
|
||||||
|
return cryptoAtoms.lte(authorizedValue)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
11
lib/plugins/zero-conf/mock-zero-conf/mock-zero-conf.js
Normal file
11
lib/plugins/zero-conf/mock-zero-conf/mock-zero-conf.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = {authorize}
|
||||||
|
|
||||||
|
function authorize (account, toAddress, cryptoAtoms, cryptoCode) {
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
if (cryptoCode !== 'BTC') throw new Error('Unsupported crypto: ' + cryptoCode)
|
||||||
|
|
||||||
|
const authorizedValue = 1e5 * 10
|
||||||
|
return cryptoAtoms.lte(authorizedValue)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,7 @@ function computeSeed (masterSeed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchWallet (settings, cryptoCode) {
|
function fetchWallet (settings, cryptoCode) {
|
||||||
|
console.log('DEBUG102')
|
||||||
return fs.readFile(options.seedPath, 'utf8')
|
return fs.readFile(options.seedPath, 'utf8')
|
||||||
.then(hex => {
|
.then(hex => {
|
||||||
const masterSeed = Buffer.from(hex.trim(), 'hex')
|
const masterSeed = Buffer.from(hex.trim(), 'hex')
|
||||||
|
|
@ -66,11 +67,39 @@ function newAddress (settings, info) {
|
||||||
.then(r => r.wallet.newAddress(r.account, info))
|
.then(r => r.wallet.newAddress(r.account, info))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatus (settings, toAddress, cryptoAtoms, cryptoCode) {
|
function getWalletStatus (settings, toAddress, cryptoAtoms, cryptoCode) {
|
||||||
return fetchWallet(settings, cryptoCode)
|
return fetchWallet(settings, cryptoCode)
|
||||||
.then(r => r.wallet.getStatus(r.account, toAddress, cryptoAtoms, cryptoCode))
|
.then(r => r.wallet.getStatus(r.account, toAddress, cryptoAtoms, cryptoCode))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function authorizeZeroConf (settings, toAddress, cryptoAtoms, cryptoCode, fiat, machineId) {
|
||||||
|
const cryptoConfig = configManager.cryptoScoped(cryptoCode, settings.config)
|
||||||
|
const machineConfig = configManager.machineScoped(machineId, settings.config)
|
||||||
|
const plugin = cryptoConfig.zeroConf
|
||||||
|
const zeroConfLimit = machineConfig.zeroConfLimit
|
||||||
|
|
||||||
|
if (fiat.gt(zeroConfLimit)) return Promise.resolve(false)
|
||||||
|
if (cryptoCode !== 'BTC' || plugin === 'all-zero-conf') return Promise.resolve(true)
|
||||||
|
|
||||||
|
const zeroConf = ph.load(ph.ZERO_CONF, plugin)
|
||||||
|
const account = settings.accounts[plugin]
|
||||||
|
|
||||||
|
return zeroConf.authorize(account, toAddress, cryptoAtoms, cryptoCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStatus (settings, toAddress, cryptoAtoms, cryptoCode, fiat, machineId) {
|
||||||
|
const promises = [
|
||||||
|
getWalletStatus(settings, toAddress, cryptoAtoms, cryptoCode),
|
||||||
|
authorizeZeroConf(settings, toAddress, cryptoAtoms, cryptoCode, fiat, machineId)
|
||||||
|
]
|
||||||
|
|
||||||
|
return Promise.all(promises)
|
||||||
|
.then(([status, isAuthorized]) => {
|
||||||
|
if (status === 'authorized') return isAuthorized ? 'authorized' : 'published'
|
||||||
|
return status
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function sweep (settings, cryptoCode, hdIndex) {
|
function sweep (settings, cryptoCode, hdIndex) {
|
||||||
return fetchWallet(settings, cryptoCode)
|
return fetchWallet(settings, cryptoCode)
|
||||||
.then(r => r.wallet.sweep(r.account, cryptoCode, hdIndex))
|
.then(r => r.wallet.sweep(r.account, cryptoCode, hdIndex))
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
|
var db = require('./db')
|
||||||
|
|
||||||
exports.up = function(next){
|
exports.up = function (next) {
|
||||||
next();
|
var sql = [
|
||||||
};
|
'alter table cash_out_txs add column error_code text'
|
||||||
|
]
|
||||||
|
db.multi(sql, next)
|
||||||
|
}
|
||||||
|
|
||||||
exports.down = function(next){
|
exports.down = function (next) {
|
||||||
next();
|
next()
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -34010,19 +34010,28 @@ var _user$project$NavBar$view = F2(
|
||||||
ctor: '::',
|
ctor: '::',
|
||||||
_0: {
|
_0: {
|
||||||
ctor: '_Tuple3',
|
ctor: '_Tuple3',
|
||||||
_0: 'Twilio',
|
_0: 'Blockcypher',
|
||||||
_1: _user$project$CoreTypes$AccountRoute('twilio'),
|
_1: _user$project$CoreTypes$AccountRoute('blockcypher'),
|
||||||
_2: true
|
_2: true
|
||||||
},
|
},
|
||||||
_1: {
|
_1: {
|
||||||
ctor: '::',
|
ctor: '::',
|
||||||
_0: {
|
_0: {
|
||||||
ctor: '_Tuple3',
|
ctor: '_Tuple3',
|
||||||
_0: 'Mailjet',
|
_0: 'Twilio',
|
||||||
_1: _user$project$CoreTypes$AccountRoute('mailjet'),
|
_1: _user$project$CoreTypes$AccountRoute('twilio'),
|
||||||
_2: true
|
_2: true
|
||||||
},
|
},
|
||||||
_1: {ctor: '[]'}
|
_1: {
|
||||||
|
ctor: '::',
|
||||||
|
_0: {
|
||||||
|
ctor: '_Tuple3',
|
||||||
|
_0: 'Mailjet',
|
||||||
|
_1: _user$project$CoreTypes$AccountRoute('mailjet'),
|
||||||
|
_2: true
|
||||||
|
},
|
||||||
|
_1: {ctor: '[]'}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
schemas/blockcypher.json
Normal file
20
schemas/blockcypher.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"code": "blockcypher",
|
||||||
|
"display": "Blockcypher",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"code": "token",
|
||||||
|
"display": "API token",
|
||||||
|
"fieldType": "password",
|
||||||
|
"required": true,
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "confidenceFactor",
|
||||||
|
"display": "Confidence Factor",
|
||||||
|
"fieldType": "string",
|
||||||
|
"required": true,
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue