| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 | var router = require('koa-router')();var moralis = require('../model/moralis_sdk.js')var utils = require('../model/utils.js');var { reids_token_config, account_config } = require('../config/config.js');const logger = require('../model/logger.js');router.prefix('/sdk');const redis = require("../model/db/redis_db")  //导入 db.jsconst withdraw_db = require("../model/db/withdraw_db")  //导入 db.jsconst report = require("../model/report")  //导入 db.jsconst BigNumber = require('bignumber.js')/** * 获取代币价格 * @param {*} ctx  */async function getAllTotkenPrice(ctx) {    console.log('getTotkenPrice in:')    var ret = await moralis.getAllTotkenPrice()    console.log('getTotkenPrice result:', ret)    if (ret)        ctx.body = utils.toJson(0, ret, null);    else ctx.body = utils.toJson(-1, null, "redis read error.");}/** * 获取交易记录 * @param {*} ctx  */async function getTransfers(ctx) {    const obj = ctx.request.body;    console.log("getTransfers body", obj);    if (!obj.chain)//默认 bsc 币安链        obj.chain = 'bsc_mainnet'    var temp_obj = { ...obj }    var index = 0    // for (let index = 0; index < 30; index++) {    await moralis.getTokenTransfers(obj).then((result) => {        logger.log('getTransfers response', 'index=' + index, result)        ctx.body = result;        if (result) {            //提交归集任务 native 能获取到 gas 、token 无法获取到 gas 费            try {                if (temp_obj.address && moralis.isTransferSucceed(result)) {                    var log_obj = { ...obj }                    log_obj.results = result                    log_obj.type = report.REPORT_TYPE.transfer_record                    //埋点日志上报-入金检查                    report.logReport(log_obj)                    var json_obj = JSON.parse(result);                    //缓存当前交易的 gas 费用                    var tr = moralis.getTransferRecordGasFree('native', json_obj, temp_obj.address)                    logger.log('getTransferRecordGasFree:', tr, temp_obj.address)                    if (tr && tr.totalGasFree > 0) {                        logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_BNB_FREE:', tr.totalGasFree.toString())                        logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_TOKEN_FREE:', (parseInt(tr.totalGasFree) * parseInt(account_config.TOKEN_GAS_LIMIT)).toString())                        redis.redis_set(reids_token_config.LAST_TOTAL_BNB_FREE, tr.totalGasFree.toString());                        redis.redis_set(reids_token_config.LAST_TOTAL_TOKEN_FREE, (parseInt(tr.gas_price) * parseInt(account_config.TOKEN_GAS_LIMIT)).toString());                    }                    //提交归集任务                    if (temp_obj.address) {                        logger.log('pushCollectConisObj>>>', temp_obj.address)                        // moralis.pushCollectConisObj(temp_obj)                        redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))                    }                }            } catch (error) {                console.error('pushCollectConisObj error=', error)            }        }    })    // }}async function getAllTokenWithdrawInfoLists(ctx) {    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    ctx.body = await moralis.getAllTokenWithdrawInfoLists(ctx);}async function collect_conis_task() {    while (true) {        var exec_obj = await redis.redis_pop(reids_token_config.COLLECT_CONIS_QUEUE_KEY)        if (!exec_obj) {            await utils.sleep(10000)            logger.log("没有归集任务")            continue        }        try {            exec_obj = JSON.parse(exec_obj)        } catch (error) {            logger.error('item parse error', error);            break        }        logger.log('collect_conis_task exec item>>>>', exec_obj);        //开始收集用户地址里面的币到归集地址        var ret = await moralis.collectCoins(exec_obj)        logger.log('collect_conis_task ret =', exec_obj, ret)    }}async function withdraw_task() {    let last_time = 0    let last_hash = ''    while (true) {        var exec_obj = await redis.redis_pop(reids_token_config.WITHDRAW_QUEUE_KEY)        if (!exec_obj) {            await utils.sleep(10000)            logger.log("没有出金任务")            continue        }        try {            exec_obj = JSON.parse(exec_obj)        } catch (error) {            logger.error('item parse error', error);            break        }        var temp_obj = { ...exec_obj }        if (utils.getTimestamp() - last_time < 60000) {            //有可能上一个区块还未更新,这里做一个尝试限制            //Error: Failed to make "eth_sendRawTransaction" request with networkConnector: "already known"            //通过 交易 hash 获取块。last_hash            if (last_hash) {                var options = {                    transaction_hash: last_hash,                    chain: temp_obj.chain,                    endTime: '2099-01-01'                }                var tryCount = 10;                do {                    try {                        var transaction = await moralis.getTokenTransfers(options);                        logger.log('withdraw_task exectransaction', transaction, options, tryCount);                        transaction = JSON.parse(transaction)                        if (transaction.code == 0) {                            if (transaction.data.result.length <= 0) {                                await utils.sleep(1500)                            } else {                                break                            }                        } else {                            break                        }                        tryCount -= 1                    } catch (error) {                        logger.error('withdraw_task exectransaction', error.toString());                    }                } while (tryCount >= 0);            }        }        try {            var result = await withdraw_({ ...exec_obj })            last_time = utils.getTimestamp()            logger.log('withdraw_task=', result, last_time)            if (result && moralis.isTransferSucceed(result)) {                var obj = JSON.parse(result)                var nonce = obj.data.nonce                var curGasPrice = BigNumber(obj.data.gasPrice.hex).toNumber()                var curGasLimit = BigNumber(obj.data.gasLimit.hex).toNumber()                var value = BigNumber(obj.data.value.hex).toNumber()                var hash = obj.data.hash                last_hash = hash                var update_obj = {}                update_obj.withdraw_status = 2                update_obj.withdraw_hash = hash                update_obj.nonce = nonce                update_obj.gas_price = curGasPrice.toString()                update_obj.gas_limit = curGasLimit.toString()                update_obj.value = value.toString()                update_obj.errorMsg = ''                await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)            } else {                var update_obj = {}                update_obj.withdraw_status = 3                if (typeof result === 'string') {                    try {                        result = JSON.parse(result)                        update_obj.errorMsg = result.errMsg                    } catch (error) {                        logger.error('withdraw_task=', result)                    }                }                await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)            }        } catch (error) {            var update_obj = {}            update_obj.withdraw_status = 3            update_obj.errorMsg = error.toString()            await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)            logger.error('withdraw_task error=', error)        }    }}/** * 队列版本 * @param {*} ctx  * @returns  */async function withdrawV3(ctx) {    logger.log('withdrawV3')    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    const obj = ctx.request.body;    // for (let index = 0; index < 10; index++) {    var log_obj = { ...obj }    logger.log('withdrawV3', log_obj)    var obj_ = decrypt_withdraw_content(log_obj.content)    obj_.withdraw_id = obj_.withdrawId;    // obj_.withdraw_id = utils.getTimestamp().toString();    // var obj_ = log_obj    if (obj_.withdraw_id) {        var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)        if (isExist) {            logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')            ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')            return        }        redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))        var info = await moralis.queryCompanyInfoFromId(0);        obj_.user_address = info.user_address        await withdraw_db.create_withdraw_task(obj_)        // withdraw_task()        ctx.body = utils.toJson(0, obj_.withdraw_id, null)    } else {        return utils.toJson(-2, null, ' withdraw_id not empty.')    }    // }}async function withdrawV3Test(ctx) {    logger.log('withdrawV3Test')    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    const obj = ctx.request.body;    // for (let index = 0; index < 10; index++) {    var log_obj = { ...obj }    logger.log('withdrawV3', log_obj)    var obj_ = decrypt_withdraw_content(log_obj.content)    obj_.withdraw_id = obj_.withdrawId;    obj_.withdraw_id = utils.getTimestamp().toString();    // var obj_ = log_obj    if (obj_.withdraw_id) {        var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)        if (isExist) {            logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')            ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')            return        }        redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))        var info = await moralis.queryCompanyInfoFromId(0);        obj_.user_address = info.user_address        await withdraw_db.create_withdraw_task(obj_)        ctx.body = utils.toJson(0, obj_.withdraw_id, null)    } else {        return utils.toJson(-2, null, ' withdraw_id not empty.')    }    // }}function decrypt_withdraw_content(content) {    // const encryptText = utils.encrypt(log_obj);    const encryptText = content;    logger.log("加密", encryptText);    let decryptObj = utils.decrypt(encryptText);    try {        logger.log("解密 before", decryptObj);        decryptObj = JSON.parse(decryptObj);        console.log("解密 json parse", decryptObj);    } catch (error) {        logger.error("json error:", error);        decryptObj = null;    }    return decryptObj;}/** *  * @param {鉴权版本} ctx  */async function withdrawV2(ctx) {    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    const obj = ctx.request.body;    var log_obj = { ...obj }    // const encryptText = utils.encrypt(log_obj);    const encryptText = log_obj.content;    logger.log("加密", encryptText);    let decryptObj = utils.decrypt(encryptText);    try {        logger.log("解密 before", decryptObj);        decryptObj = JSON.parse(decryptObj);        // console.log("解密 json parse", decryptObj);        await withdraw_(decryptObj).then(result => {            ctx.body = result;        })    } catch (error) {        logger.error("json error:", error);        ctx.body = utils.toJson(-1, null, error.toString());    }}async function withdraw_(obj) {    console.log("withdraw_", obj);    var log_obj = { ...obj }    var info = await moralis.queryCompanyInfoFromId(0);    log_obj.company_address_total_balance_before = await moralis.queryCollectBalance(info.user_address, obj.chain)    log_obj.company_public_key = info.user_address    logger.log('withdraw log', log_obj);    return new Promise((resolve) => {        moralis.withdraw(obj).then((result) => {            if (moralis.isTransferSucceed(result)) {                //提币日志上报                log_obj.results = result                log_obj.type = report.REPORT_TYPE.withdraw                //缓存当前交易的 gas 费用                if (result && log_obj.contractAddress) {                    var tr = moralis.getTransferGasFree('token', result)                    log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()                } else {                    var tr = moralis.getTransferGasFree('native', result)                    log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()                }                // log_obj.receiver_address_total_balance_after = await queryCollectBalance(info.user_address, utils.getChainName(obj.chain))                //日志上报                report.logReport(log_obj)            }            resolve(result)        });    })}//出金async function withdraw(ctx) {    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    const obj = ctx.request.body;    await withdraw_(obj).then(result => {        ctx.body = result;    })}/** * 查询出金状态 * @param {*} ctx  */async function getWithdrawStatus(ctx) {    if (ctx.request == null || ctx.request.body == null) {        ctx.body = utils.toJson(-1, null, "request error. ");        return    }    const obj = ctx.request.body;    var info = await withdraw_db.queryWithdrawInfoFromWithdrawId(obj.withdrawId)    logger.log('getWithdrawStatus info', JSON.stringify(info))    if (info) {        if (info.withdraw_status != 3) {            ctx.body = utils.toJson(0, {                withdrawId: info.withdraw_id,                withdrawStatus: info.withdraw_status,                withdrawHash: info.withdraw_hash,                chainId: info.chain_id,                transferTimestamp: info.update_time,            }, null)        } else {            ctx.body = utils.toJson(0, {                withdrawId: info.withdraw_id,                withdrawStatus: info.withdraw_status,                withdrawHash: info.withdraw_hash,                chainId: info.chain_id,                transferTimestamp: info.update_time,                errorMsg: info.errorMsg            }, null)        }    } else {        ctx.body = utils.toJson(-1, null, obj.withdraw_id + ' id does not exist.')    }}//获取交易记录router.post('/getTransfers', getTransfers)// 获取所有代币价格router.post('/getAllTotkenPrice', getAllTotkenPrice)// router.post('/transfer', transfer)//提现router.post('/withdraw', withdraw);//提现鉴权-body 加密router.post('/withdrawV2', withdrawV2);//队列的形式router.post('/withdrawV3', withdrawV3);router.post('/withdrawV3Test', withdrawV3Test);//查询出金服务router.post('/getWithdrawStatus', getWithdrawStatus);//获取所有地址的所要消耗的最低提取费router.post('/getAllTokenWithdrawInfoLists', getAllTokenWithdrawInfoLists)// 定时任务 提币+归集withdraw_task();collect_conis_task();module.exports = router
 |