honeycomb-spkcc/processing_routes/dex.js

804 lines
46 KiB
JavaScript

const config = require('./../config')
const { store, GetNodeOps, spliceOp, plasma } = require('./../index')
const { getPathObj, getPathNum } = require('./../getPathObj')
const { DEX, release } = require('./../helpers')
const { add, addCol, addGov, deletePointer, credit, chronAssign, hashThis, isEmpty, addMT } = require('./../lil_ops')
const { postToDiscord } = require('./../discord')
const stringify = require('json-stable-stringify');
const fetch = require('node-fetch');
exports.dex_sell = (json, from, active, pc) => {
let PfromBal = getPathNum(['balances', from]),
PStats = getPathObj(['stats']),
PSB = getPathObj(['dex', 'hive']),
order = {}
if(parseInt(json.hive)){
order.type = 'LIMIT'
order.target = parseInt(json.hive)
order.rate = parseFloat( parseInt(json.hive) / parseInt(json[config.jsonTokenName]) ).toFixed(6)
order.pair = 'hive'
} else if(parseInt(json.hbd)){
PSB = getPathObj(['dex', 'hbd'])
order.type = 'LIMIT'
order.pair = 'hbd'
order.target = parseInt(json.hbd)
order.rate = parseFloat( parseInt(json.hbd) / parseInt(json[config.jsonTokenName]) ).toFixed(6)
} else if (json.pair == 'HBD'){
PSB = getPathObj(['dex', 'hbd'])
order.type = 'MARKET'
order.pair = 'hbd'
} else {
order = {
type: 'MARKET',
pair: 'hive',
amount: json[config.jsonTokenName]
}
}
order[config.jsonTokenName] = parseInt(json[config.jsonTokenName])
console.log(order)
Promise.all([PfromBal, PStats, PSB]).then(a => {
let bal = a[0],
stats = a[1],
dex = a[2],
ops = [],
adds = [],
his = {},
fee = 0,
hours = parseInt(json.hours) || 720
if (hours > 720) { hours = 720 }
const expBlock = json.block_num + (hours * 1200)
if (order[config.jsonTokenName] <= bal && order[config.jsonTokenName] >= 4 && active) {
let remaining = json[config.jsonTokenName],
filled = 0,
pair = 0,
i = 0,
path = 0,
contract = ''
while(remaining){
let price = parseFloat(dex.buyBook.split('_')[0])
let item
if(price)item = dex.buyBook.split('_')[1].split(',')[0]
if (item && (order.type == 'MARKET' || parseFloat(price) >= order.rate)){
let next = dex.buyOrders[`${price.toFixed(6)}:${item}`]
console.log({price, item, next})
if (next.amount <= remaining){
filled += next.amount
adds.push([next.from, next.amount - next.fee])
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'sell', t:Date.parse(json.timestamp + '.000Z'), block: json.block_num, base_vol: next.amount, target_vol: next[order.pair], target: order.pair, price: next.rate, id: json.transaction_id + i}
fee += next.fee //add the fees
remaining -= next.amount
dex.tick = price.toFixed(6)
pair += next[order.pair]
dex.buyBook = DEX.remove(item, dex.buyBook) //adjust the orderbook
console.log(dex.buyBook)
delete dex.buyOrders[`${price.toFixed(6)}:${item}`]
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": from,
"amount": parseFloat(next[order.pair]/1000).toFixed(3) + ' ' + order.pair.toUpperCase(),
"memo": `Filled ${item}:${json.transaction_id}`
}
]
let msg = `@${from} sold ${parseFloat(parseInt(next.amount)/1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(next[order.pair])/1000).toFixed(3)} ${order.pair.toUpperCase()} to ${next.from} (${item})`
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
ops.push({type: 'put', path: ['msa', `${item}:${json.transaction_id}:${json.block_num}`], data: stringify(transfer)}) //send HIVE out via MS
ops.push({type: 'del', path: ['dex', order.pair, 'buyOrders', `${price.toFixed(6)}:${item}`]}) //remove the order
ops.push({type: 'del', path: ['contracts', next.from , item]}) //remove the contract
ops.push({type: 'del', path: ['chrono', next.expire_path]}) //remove the chrono
} else {
const thisfee = parseInt((remaining/next.amount)*next.fee)
const thistarget = parseInt((remaining/next.amount)*next[order.pair])
next.fee -= thisfee
next[order.pair] -= thistarget
next.amount -= remaining
filled += remaining
pair += thistarget
adds.push([next.from, remaining - thisfee])
dex.tick = price.toFixed(6)
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'sell', t:Date.parse(json.timestamp), block: json.block_num, base_vol: remaining, target_vol: thistarget + thisfee, target: order.pair, price: next.rate, id: json.transaction_id + i}
fee += thisfee
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": from,
"amount": parseFloat(thistarget/1000).toFixed(3) + ' ' + order.pair.toUpperCase(),
"memo": `Partial Filled ${item}:${json.transaction_id}`
}
]
let msg = `@${from} sold ${parseFloat(parseInt(remaining)/1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(thistarget)/1000).toFixed(3)} ${order.pair.toUpperCase()} to ${next.from} (${item})`
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
ops.push({type: 'put', path: ['msa', `${item}:${json.transaction_id}:${json.block_num}`], data: stringify(transfer)}) //send HIVE out via MS
ops.push({type: 'put', path: ['contracts', next.from , item], data: next}) //remove the contract
dex.buyOrders[`${price.toFixed(6)}:${item}`] = next
remaining = 0
}
} else {
let txid = config.TOKEN + hashThis(from + json.transaction_id),
cfee = parseInt(remaining * parseFloat(stats.dex_fee)),
crate = parseFloat((order.target - pair)/remaining).toFixed(6),
hours = 720
if (crate == 'NaN') { crate = dex.tick }
contract = {
txid,
from: from,
hive: 0,
hbd: 0,
fee: cfee,
amount: remaining,
rate: crate,
block: json.block_num,
type: `${order.pair}:sell`
}
contract[order.pair] = parseInt(remaining * parseFloat(crate))
dex.sellBook = DEX.insert(txid, crate, dex.sellBook, 'sell')
path = chronAssign(expBlock, {
block: expBlock,
op: 'expire',
from,
txid
})
remaining = 0
}
i++
}
var addops = {}
for (var j = 0; j < adds.length; j++){
if (addops[adds[j][0]]){
addops[adds[j][0]] += adds[j][1]
} else {
addops[adds[j][0]] = adds[j][1]
}
}
console.log({bal})
bal -= json[config.jsonTokenName]
if (addops[from]){
bal += addops[from]
delete addops[from]
}
console.log({bal})
var waitfor = [add('rn', fee)]
for(var to in addops){
waitfor.push(add(to, addops[to]))
}
const msg = `@${from}| Sell order confirmed.`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg }]
ops.push({type: 'put', path: ['balances', from], data: bal})
ops.push({type: 'put', path: ['dex', order.pair], data: dex})
if(Object.keys(his).length)ops.push({type: 'put', path: ['dex', order.pair, 'his'], data: his})
if(path){
Promise.all([path, ...waitfor])
.then(expPath =>{
contract.expire_path = expPath[0]
ops.push({type: 'put', path: ['contracts', from , contract.txid], data: contract})
if(dex.sellOrders){
dex.sellOrders[`${contract.rate}:${contract.txid}`] = contract
} else {
dex.sellOrders = {[`${contract.rate}:${contract.txid}`]: contract}
}
let msg = `@${from} is selling ${parseFloat(parseInt(contract.amount)/1000).toFixed(3)} ${config.TOKEN} for ${parseFloat(parseInt(contract[order.pair])/1000).toFixed(3)} ${order.pair.toUpperCase()}(${contract.rate}:${contract.txid})`
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
})
} else {
Promise.all([...waitfor])
.then(nada =>{
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
})
}
} else {
const msg = `@${from}| tried to sell ${config.TOKEN} but sent an invalid order.`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg }]
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
}
}).catch(e => {
console.log(e)
})
}
exports.transfer = (json, pc) => {
if (json.to == config.mainICO && json.amount.split(' ')[1] == 'HIVE' && json.from != config.msaccount) { //the ICO disribution... should be in multi sig account
const amount = parseInt(parseFloat(json.amount) * 1000)
var purchase,
Pstats = getPathObj(['stats']),
Pbal = getPathNum(['balances', json.from]),
Pinv = getPathNum(['balances', 'ri'])
Promise.all([Pstats, Pbal, Pinv]).then(function(v) {
var stats = v[0],
b = v[1],
i = v[2],
ops = []
if (!stats.outOnBlock) {
purchase = parseInt(amount / stats.icoPrice * 1000)
.then(empty => {
if (purchase < i) {
i -= purchase
b += purchase
const msg = `@${json.from}| bought ${parseFloat(purchase / 1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(amount / 1000).toFixed(3)} HIVE`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg },
{ type: 'put', path: ['balances', json.from], data: b },
{ type: 'put', path: ['balances', 'ri'], data: i }
]
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
} else {
b += i
const left = purchase - i
stats.outOnBlock = json.block_num
const msg = `@${json.from}| bought ALL ${parseFloat(parseInt(purchase - left)).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(amount) / 1000).toFixed(3)} HIVE. And bid in the over-auction`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [
{ type: 'put', path: ['ico', `${json.block_num}`, json.from], data: parseInt(amount * left / purchase) },
{ type: 'put', path: ['balances', json.from], data: b },
{ type: 'put', path: ['balances', 'ri'], data: 0 },
{ type: 'put', path: ['stats'], data: stats },
{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg }
]
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
}
})
.catch(e => { console.log(e) })
} else {
const msg = `@${json.from}| bought ALL ${parseFloat(parseInt(purchase - left)).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(amount) / 1000).toFixed(3)} HIVE. And bid in the over-auction`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [
{ type: 'put', path: ['ico', `${json.block_num}`, json.from], data: parseInt(amount) },
{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg }
]
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
}
})
} else if (json.to == config.msaccount && json.from != config.mainICO) {
if(json.memo.split(' ')[0] == 'NFT'){
/*
lth[`set:hash`]{
h,//millihive
b,//millihbd
q,//qty
d,//distro string
i:`${json.set}:${hash}`,//item for canceling
e:'pb:startdate_enddate,max:3',
s:'account1_1,account2_2,account3_1',
p,//pending sales
}
*/
let item = json.memo.split(' ')[1],
setname = item.split(':')[0],
Pset = getPathObj(['set', setname]),
Pitem = getPathObj(['lth', item])
Promise.all([Pset, Pitem]).then(mem =>{
let set = mem[0],
listing = mem[1],
amount = parseInt(json.amount.split(' ')[0] * 1000),
type = json.amount.split(' ')[1],
ops = [],
qty = 0,
refund_amount = amount,
transfers = [],
enf = enforce(listing.e),
allowed = 9999999,
whoBoughtIndex,
whoBoughtAmount = 0
if(listing){
if(!listing.s)listing.s = ''
if(enf.max){
allowed = enf.max
whoBoughtIndex = listing.s.indexOf(`${json.from}_`)
if(whoBoughtIndex != -1){
whoBoughtAmount = parseInt(listing.s.split(`${json.from}_`)[1].split(',')[0])
allowed -= whoBoughtAmount
}
}
if(type == 'HIVE' && amount >= listing.h && listing.h != 0){
qty = parseInt(amount/listing.h)
refund_amount = amount % parseInt(listing.h)
if(qty > allowed){
tor = qty - allowed
qty = allowed
refund_amount += tor * listing.h
}
} else if (type == 'HBD' && amount >= listing.b && listing.b != 0){
qty = parseInt(amount/listing.b)
refund_amount = amount % parseInt(listing.b)
if(qty > allowed){
tor = qty - allowed
qty = allowed
refund_amount += tor * listing.b
}
}
if(enf.max && whoBoughtIndex != -1){
listing.s.replace(`${json.from}_${whoBoughtAmount}`, `${json.from}_${whoBoughtAmount + qty}`)
} else if (enf.max){
listing.s += `,${json.from}_${qty}`
}
listing.q -= qty
if(enf.max){
if(!listing.p)listing.p = 0
listing.p += qty
}
ops.push({type: 'put', path: ['lth', item], data: listing})
if(listing.q <= 0){
qty += listing.q
refund_amount += (listing.h * listing.q) + (listing.b * listing.q)
if(!listing.p)ops.push({type: 'del', path: ['lth', item]})
}
if(qty && !enf.pb){
addMT(['rnfts', setname, json.from], parseInt(qty))
transfers = [...buildSplitTransfers(qty*listing.h+qty*listing.b, type, listing.d, `${qty} ${setname}${qty>1?"'s":""} purchased - ${json.from}:${json.transaction_id.substr(0,8)}:`)]
} else if(qty && enf.pb){
addMT(['pcon', 'lth', listing.i, json.from], parseInt(qty))
postVerify(enf.pb, json.from, listing.i, 'lth')
transfers= []
}
if(refund_amount){
transfers.push(['transfer',{
to:json.from,
from: config.msaccount,
amount: parseFloat(refund_amount/1000).toFixed(3) + ` ${type}`,
memo: `Refund ${setname} mint token purchase:${json.transaction_id}:`
}])
}
for(var i = 0; i < transfers.length; i++){
ops.push({type: 'put', path: ['msa', `${i}:${json.transaction_id}:${json.block_num}`], data: stringify(transfers[i])})
}
const msg = `@${json.from}| bought ${qty} ${setname} token${qty>1?'s':''} with ${parseFloat(parseInt(amount) / 1000).toFixed(3)} ${type}`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops.push({
type: 'put',
path: ['feed', `${json.block_num}:${json.transaction_id}`],
data: msg
})
store.batch(ops, pc)
} else {
ops.push({type: 'put', path: ['msa', `${i}:${json.transaction_id}:${json.block_num}`], data: stringify(['transfer',{
to:json.from,
from: config.msaccount,
amount: json.amount,
memo: `Refund: Item(s) not found.`
}])})
const msg = `@${json.from}| can't locate item(s). Refund in progress.`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops.push({
type: 'put',
path: ['feed', `${json.block_num}:${json.transaction_id}`],
data: msg
})
store.batch(ops, pc)
}
})
} else {
let order = {
type: 'LIMIT'
},
path = '',
contract = ''
try {order = JSON.parse(json.memo)} catch (e) {}
if (!order.rate) {
order.type = 'MARKET'
order.rate = parseFloat(order.rate) || 0
} else {
order.type = 'LIMIT'
order.rate = parseFloat(order.rate) || 0
}
order.pair = json.amount.split(' ')[1].toLowerCase()
order.amount = parseInt(parseFloat(json.amount.split(' ')[0] * 1000))
if (order.type == 'MARKET' || order.type == 'LIMIT') {
let pDEX = getPathObj(['dex', order.pair]),
pBal = getPathNum(['balances', json.from]),
pInv = getPathNum(['balances', 'ri']),
pStats = getPathObj(['stats']);
Promise.all([pDEX, pBal, pInv, pStats]).then(mem => {
let dex = mem[0],
bal = mem[1],
inv = mem[2],
stats = mem[3],
filled = 0,
remaining = order.amount,
ops = [],
his = {},
fee = 0,
i = 0
while (remaining){
i++
const price = parseFloat(dex.sellBook.split('_')[0])
let item = ''
if(price)item = dex.sellBook.split('_')[1].split(',')[0]
console.log(price, item)
if (item && (order.pair == 'hbd' || (order.pair == 'hive' && (price <= stats.icoPrice/1000))) && ( order.type == 'MARKET' || (order.type == 'LIMIT' && order.rate >= price))) {
var next = dex.sellOrders[`${price.toFixed(6)}:${item}`]
console.log(next)
if (next[order.pair] <= remaining){
filled += next.amount - next.fee
bal += next.amount - next.fee //update the balance
fee += next.fee //add the fees
remaining -= next[order.pair]
dex.tick = next.rate
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'buy', t:Date.parse(json.timestamp), block: json.block_num, base_vol: next.amount, target_vol: next[order.pair], target: order.pair, price: next.rate, id: json.transaction_id + i}
dex.sellBook = DEX.remove(item, dex.sellBook) //adjust the orderbook
delete dex.sellOrders[`${price.toFixed(6)}:${item}`]
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": next.from,
"amount": parseFloat(next[order.pair]/1000).toFixed(3) + ' ' + order.pair.toUpperCase(),
"memo": `Filled ${item}:${json.transaction_id}`
}
]
let msg = `@${json.from} bought ${parseFloat(parseInt(next.amount)/1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(next[order.pair])/1000).toFixed(3)} ${order.pair.toUpperCase()} from ${next.from} (${item})`
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
if(Object.keys(his).length)ops.push({type: 'put', path: ['dex', order.pair, 'his'], data: his})
ops.push({type: 'put', path: ['msa', `${item}:${json.transaction_id}:${i}`], data: stringify(transfer)}) //send HIVE out via MS
ops.push({type: 'del', path: ['dex', order.pair, 'sellOrders', `${price.toFixed(6)}:${item}`]}) //remove the order
ops.push({type: 'del', path: ['contracts', next.from , item]}) //remove the contract
ops.push({type: 'del', path: ['chrono', next.expire_path]}) //remove the chrono
} else {
next[order.pair] = next[order.pair] - remaining // modify the contract
const tokenAmount = parseInt(remaining / parseFloat(next.rate))
const feeAmount = parseInt((tokenAmount / next.amount) * next.fee)
filled += tokenAmount - feeAmount
bal += tokenAmount - feeAmount //update the balance
fee += feeAmount //add the fees
next.amount -= tokenAmount
next.fee -= feeAmount
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'buy', t:Date.parse(json.timestamp), block: json.block_num, base_vol: tokenAmount, target_vol: remaining, target: order.pair, price: next.rate, id: json.transaction_id + i}
if(!next.partial){
next.partial = {[json.transaction_id]:{token: tokenAmount, coin: remaining}}
} else {
next.partial[json.transaction_id] = {token: tokenAmount, coin: remaining}
}
dex.tick = next.rate
dex.sellOrders[`${price.toFixed(6)}:${item}`] = next
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": next.from,
"amount": parseFloat(remaining/1000).toFixed(3) + ' ' + order.pair.toUpperCase(),
"memo": `Partial Filled ${item}:${json.transaction_id}`
}
]
let msg = `@${json.from} bought ${parseFloat(parseInt(tokenAmount)/1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(remaining)/1000).toFixed(3)} ${order.pair.toUpperCase()} from ${next.from} (${item})`
remaining = 0
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
ops.push({type: 'put', path: ['balances', json.from], data: bal})
ops.push({type: 'put', path: ['dex', order.pair, 'his'], data: his})
ops.push({type: 'put', path: ['msa', `${item}:${json.transaction_id}:${i}`], data: stringify(transfer)}) //send HIVE out via MS
//ops.push({type: 'put', path: ['dex', order.pair, 'sellOrders', `${price.toFixed(6)}:${item}`], data: next}) //update the order
ops.push({type: 'put', path: ['contracts', next.from , item], data: next}) //update the contract
}
} else {
if (order.pair == 'hive' && ( order.type == 'MARKET' || (order.type == 'LIMIT' && order.rate >= stats.icoPrice/1000 ))){
let purchase
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": config.mainICO,
"amount": parseFloat(remaining/1000).toFixed(3) + ' ' + order.pair.toUpperCase(),
"memo": `ICO Buy from ${json.from}:${json.transaction_id}`
}
]
ops.push({type: 'put', path: ['msa', `ICO@${json.from}:${json.transaction_id}:${json.block_num}`], data: stringify(transfer)}) //send HIVE out via MS
dex.tick = parseFloat(stats.icoPrice/1000).toFixed(6)
if (!stats.outOnBlock) {
purchase = parseInt(remaining / stats.icoPrice * 1000)
filled += purchase
if (purchase < inv) {
inv -= purchase
bal += purchase
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'buy', t:Date.parse(json.timestamp), block: json.block_num, base_vol: purchase, target_vol: remaining, target: order.pair, price: parseFloat(stats.icoPrice/1000).toFixed(6), id: json.transaction_id + i}
const msg = `@${json.from}| bought ${parseFloat(purchase / 1000).toFixed(3)} ${config.TOKEN} with ${parseFloat(remaining / 1000).toFixed(3)} HIVE`
ops.push({ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}:${i}`], data: msg },
{ type: 'put', path: ['balances', 'ri'], data: inv })
} else {
bal += inv
const left = purchase - inv
stats.outOnBlock = json.block_num
his[`${json.block_num}:${i}:${json.transaction_id}`] = {type: 'buy', t:Date.parse(json.timestamp), block: json.block_num, base_vol: inv, target_vol: remaining, target: order.pair, price: parseFloat(stats.icoPrice/1000).toFixed(6), id: json.transaction_id + i}
const msg = `@${json.from}| bought ALL ${parseFloat(parseInt(purchase - left)).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(amount) / 1000).toFixed(3)} HIVE. And bid in the over-auction`
ops.push({ type: 'put', path: ['ico', `${json.block_num}`, json.from], data: parseInt(amount * left / purchase) },
{ type: 'put', path: ['balances', 'ri'], data: 0 },
{ type: 'put', path: ['stats'], data: stats },
{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg })
}
remaining = 0
} else {
const msg = `@${json.from}| bought ALL ${parseFloat(parseInt(purchase - left)).toFixed(3)} ${config.TOKEN} with ${parseFloat(parseInt(amount) / 1000).toFixed(3)} HIVE. And bid in the over-auction`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops = [
{ type: 'put', path: ['ico', `${json.block_num}`, json.from], data: parseInt(amount) },
{ type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}`], data: msg }
]
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
}
} else {
const txid = config.TOKEN + hashThis(json.from + json.transaction_id),
cfee = parseInt(remaining * parseFloat(stats.dex_fee)),
crate = order.rate.toFixed(6) || dex.tick,
hours = 720,
expBlock = json.block_num + (hours * 1200)
contract = {
txid,
from: json.from,
hive: 0,
hbd: 0,
fee: cfee,
amount: 0,
rate: crate,
block: json.block_num,
type: `${order.pair}:buy`
}
contract.amount = parseInt(remaining / crate)
contract[order.pair] = remaining
dex.buyBook = DEX.insert(txid, crate, dex.buyBook, 'buy')
path = chronAssign(expBlock, {
block: expBlock,
op: 'expire',
from: json.from,
txid
})
remaining = 0
}
}
}
let msg = ''
if(remaining == order.amount){
msg = `@${json.from} set a buy order at ${contrate.rate}.`
} else {
msg = `@${json.from} | order recieved.`
add('rn', fee)
}
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops.push({type: 'put', path: ['balances', json.from], data: bal})
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i++}`], data: msg})
if(Object.keys(his).length)ops.push({type: 'put', path: ['dex', order.pair, 'his'], data: his})
if(!path){
ops.push({type: 'put', path: ['dex', order.pair], data: dex})
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
} else {
Promise.all([path]).then(expPath => {
contract.expire_path = expPath[0]
ops.push({type: 'put', path: ['contracts', json.from , contract.txid], data: contract})
if(dex.buyOrders){
dex.buyOrders[`${contract.rate}:${contract.txid}`] = contract
} else {
dex.buyOrders = {[`${contract.rate}:${contract.txid}`]: contract}
}
let msg = `@${json.from} is buying ${parseFloat(parseInt(contract.amount)/1000).toFixed(3)} ${config.TOKEN} for ${parseFloat(parseInt(contract[order.pair])/1000).toFixed(3)} ${order.pair.toUpperCase()}(${contract.rate}:${contract.txid})`
ops.push({type: 'put', path: ['dex', order.pair], data: dex})
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
})
}
})
} else {
const transfer = [
"transfer",
{
"from": config.msaccount,
"to": json.from,
"amount": json.amount,
"memo": `This doesn't appear to be formatted correctly to buy ${config.TOKEN}`
}
]
let msg = `@${json.from} sent a weird transaction to ${config.msaccount}: refunding`
ops.push({type: 'put', path: ['feed', `${json.block_num}:${json.transaction_id}.${i}`], data: msg})
ops.push({type: 'put', path: ['msa', `refund@${json.from}:${json.transaction_id}:${json.block_num}`], data: stringify(transfer)})
store.batch(ops, pc)
}
}
} else if (json.from == config.msaccount){
getPathObj(['mss']).then(mss => {
var done = false
for (var block in mss){
if(block.split(':').length < 2 && mss[block].indexOf(json.memo) > 0){
store.batch([{type:'del', path:['mss', `${block}`]}, {type:'del', path:['mss', `${block}:sigs`]}],pc)
done = true
}
}
if (!done) {
pc[0](pc[2])
}
})
} else {
store.get(['escrow', json.from, json.memo.split(' ')[0] + ':transfer'], function(e, a) {
var ops = []
if (!e && !isEmpty(a)) {
let auth = true,
terms = Object.keys(a[1])
for (i = 0; i < terms.length; i++) {
if (json[terms[i]] !== a[1][terms[i]]) {
auth = false
}
}
console.log('authed ' + auth)
if (auth) {
const msg = `@${json.from}| sent @${json.to} ${json.amount} for ${json.memo.split(' ')[0]}`
if (config.hookurl || config.status) postToDiscord(msg, `${json.block_num}:${json.transaction_id}`)
ops.push({
type: 'put',
path: ['feed', `${json.block_num}:${json.transaction_id}`],
data: msg
})
let addr = json.memo.split(' ')[0],
co = json.memo.split(' ')[2],
cp = getPathObj(['contracts', co, addr]),
sp = getPathObj(['contracts', json.to, addr]),
gp = getPathNum(['gov', json.from])
Promise.all([cp, gp, sp])
.then(ret => {
let d = ret[1],
c = ret[0]
if (!c.escrow_id) {
c = ret[2]
co = c.co
}
eo = c.buyer,
g = c.escrow
if (c.type === 'sb' || c.type === 'db')
eo = c.from
console.log(c)
let lil_ops = [
addGov(json.from, parseInt(c.escrow)),
addCol(json.from, -parseInt(c.escrow)),
add(json.from, parseInt(c.fee / 3)),
deletePointer(c.escrow_id, eo),
credit(json.from)
]
console.log(json.from, parseInt(c.fee / 3))
ops.push({ type: 'del', path: ['escrow', json.from, addr + ':transfer'] })
ops.push({ type: 'del', path: ['contracts', co, addr] })
ops.push({ type: 'del', path: ['chrono', c.expire_path] })
if (json.from == config.username) {
//delete plasma.pending[i + ':transfer']
let NodeOps = GetNodeOps()
for (var i = 0; i < NodeOps.length; i++) {
if (NodeOps[i][1][1].from == json.from && NodeOps[i][1][1].to == json.to && NodeOps[i][1][0] == 'transfer' && NodeOps[i][1][1].hive_amount == json.hive_amount && NodeOps[i][1][1].hbd_amount == json.hbd_amount) {
spliceOp(i)
}
}
}
Promise.all(lil_ops).then(empty => {
if (process.env.npm_lifecycle_event == 'test') pc[2] = ops
store.batch(ops, pc)
})
.catch(e => { reject(e) })
})
.catch(e => { console.log(e) })
} else {
pc[0](pc[2])
}
} else {
pc[0](pc[2])
}
})
}
}
exports.dex_clear = (json, from, active, pc) => {
if (active) {
var q = [],
promises = []
if (typeof json.txid == 'string') {
q.push(json.txid)
}
// else {
// q = json.txid
// } //book string collision
for (i = 0; i < q.length; i++) {
store.get(['contracts', from, q[i]], function(e, a) {
if (!e) {
var b = a
switch (b.type) {
case 'hive:sell':
store.get(['dex', 'hive', 'sellOrders', `${b.rate}:${b.txid}`], function(e, a) {
if (e) { console.log(e) } else if (isEmpty(a)) { console.log('Nothing here' + b.txid) } else {
promises.push(new Promise ((res,rej)=>{release(from, b.txid, json.block_num, json.transaction_id).then(y => {res(y)}).catch(e=>{rej(e)})}))
}
})
break
case 'hbd:sell':
store.get(['dex', 'hbd', 'sellOrders', `${b.rate}:${b.txid}`], function(e, a) {
if (e) { console.log(e) } else if (isEmpty(a)) { console.log('Nothing here' + b.txid) } else {
promises.push(new Promise ((res,rej)=>{release(from, b.txid, json.block_num, json.transaction_id).then(y => {res(y)}).catch(e=>{rej(e)})}))
}
})
break
case 'hive:buy':
store.get(['dex', 'hive', 'buyOrders', `${b.rate}:${b.txid}`], function(e, a) {
if (e) { console.log(e) } else if (isEmpty(a)) { console.log('Nothing here' + b.txid) } else {
promises.push(new Promise ((res,rej)=>{release(from, b.txid, json.block_num, json.transaction_id).then(y => {res(y)}).catch(e=>{rej(e)})}))
}
})
break
case 'hbd:buy':
store.get(['dex', 'hbd', 'buyOrders', `${b.rate}:${b.txid}`], function(e, a) {
if (e) { console.log(e) } else if (isEmpty(a)) { console.log('Nothing here' + b.txid) } else {
promises.push(new Promise ((res,rej)=>{release(from, b.txid, json.block_num, json.transaction_id).then(y => {res(y)}).catch(e=>{rej(e)})}))
}
})
break
default:
}
} else {
console.log(e)
}
})
}
Promise.all(promises).then(empty => {pc[0](pc[2])}).catch(e=>{console.log(e)})
}
}
function buildSplitTransfers(amount, pair, ds, memos){
console.log({amount, pair, ds, memos})
let tos = ds.split(',') || 0
if (!tos)return []
let ops = [],
total = 0
for(var i = tos.length - 1; i >= 0; i--) {
let dis = parseInt((amount*parseInt(tos[i].split('_')[1])/10000))
if(!i)dis = amount - total
total += dis
ops.push(['transfer',{
to: tos[i].split('_')[0],
from: config.msaccount,
amount: `${parseFloat(dis/1000).toFixed(3)} ${pair.toUpperCase()}`,
memo: memos + `:${parseFloat(parseInt(tos[i].split('_')[1])/100).toFixed(2)}%`
}])
}
return ops
}
function enforce(str){
str = str || ''
let enforce = {},
arr = str.split(',')
for(let i = 0; i < arr.length; i++){
let s = arr[i].split(':')
enforce[s[0]] = arr[i].replace(`${s[0]}:`, '')
}
return enforce
}
function postVerify(str, from, loc){
fetch("https://api.hive.blog", {
body: `{"jsonrpc":"2.0", "method":"bridge.get_account_posts", "params":{"sort":"posts", "account": "${from}", "limit": 25}, "id":1}`,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
method: "POST"
})
.then(res => res.json()).then(json => {
var valid = false
for(var i = 0; i < json.result.length; i++){
if(new Date(`${json.result[i].created}.000Z`).getTime() > new Date(`${str.split('_')[0]}:00.000Z`).getTime() && new Date(`${json.result[i].created}.000Z`).getTime() < new Date(`${str.split('_')[1]}:00.000Z`).getTime()){
valid = true
break
}
}
if (plasma.oracle){
plasma.oracle[`${loc}:${from}`] = 'lth:' + valid
} else {
plasma.oracle = {}
plasma.oracle[`${loc}:${from}`] = 'lth:' + valid
}
})
}