sdk.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. var router = require('koa-router')();
  2. var moralis = require('../model/moralis_sdk.js')
  3. var utils = require('../model/utils.js');
  4. var { reids_token_config, account_config } = require('../config/config.js');
  5. const logger = require('../model/logger.js');
  6. router.prefix('/sdk');
  7. const redis = require("../model/db/redis_db") //导入 db.js
  8. const withdraw_db = require("../model/db/withdraw_db") //导入 db.js
  9. const report = require("../model/report") //导入 db.js
  10. const BigNumber = require('bignumber.js')
  11. const czz = require('../model/http_withdraw')
  12. var remote_config_db = require("../model/db/remote_config_db");
  13. const account_mysql = require("../model/db/account_info_db") //导入 db.js
  14. var collect_coins_db = require("../model/db/collect_coins_db");
  15. /**
  16. * 获取代币价格
  17. * @param {*} ctx
  18. */
  19. async function getAllTotkenPrice(ctx) {
  20. console.log('getTotkenPrice in:')
  21. var ret = await moralis.getAllTotkenPrice(ctx.request.body)
  22. console.log('getTotkenPrice result:', ret)
  23. if (ret)
  24. ctx.body = utils.toJson(0, ret, null);
  25. else ctx.body = utils.toJson(-1, null, "redis read error.");
  26. }
  27. async function getAllTokenPrice(ctx) {
  28. var ret = await moralis.getAllTotkenPrice(ctx.request.body)
  29. console.log('getTotkenPrice result:', ret)
  30. if (ret)
  31. ctx.body = utils.toJson(0, ret, null);
  32. else ctx.body = utils.toJson(-1, null, "redis read error.");
  33. }
  34. /**
  35. * 获取交易记录
  36. * @param {*} ctx
  37. */
  38. async function getTransfers(ctx) {
  39. const obj = ctx.request.body;
  40. console.log("getTransfers body", obj);
  41. if (!obj.chain)//默认 bsc 币安链
  42. obj.chain = 'bsc_mainnet'
  43. var temp_obj = { ...obj }
  44. var index = 0
  45. await moralis.getTokenTransfers(obj).then((result) => {
  46. logger.log('getTransfers response', 'index=' + index, result)
  47. ctx.body = result;
  48. if (result) {
  49. //提交归集任务 native 能获取到 gas 、token 无法获取到 gas 费
  50. try {
  51. if (temp_obj.address && moralis.isTransferSucceed(result)) {
  52. var log_obj = { ...obj }
  53. log_obj.results = result
  54. log_obj.type = report.REPORT_TYPE.transfer_record
  55. //埋点日志上报-入金检查
  56. report.logReport(log_obj)
  57. var json_obj = JSON.parse(result);
  58. //缓存当前交易的 gas 费用
  59. var tr = moralis.getTransferRecordGasFree('native', json_obj, temp_obj.address)
  60. logger.log('getTransferRecordGasFree:', tr, temp_obj.address)
  61. if (tr && tr.totalGasFree > 0) {
  62. logger.log('getTransferRecordGasFree redis_set LAST_PRICE:', tr)
  63. // redis.redis_set(reids_token_config.LAST_BNB_PRICE, tr.gas_price.toString());
  64. // redis.redis_set(reids_token_config.LAST_TOKEN_PRICE, tr.gas_price.toString());
  65. redis.writeAppendRedis(reids_token_config.LAST_BNB_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  66. redis.writeAppendRedis(reids_token_config.LAST_TOKEN_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  67. }
  68. if (json_obj.data.total > 0) {
  69. //提交归集任务
  70. if (temp_obj.address) {
  71. logger.log('pushCollectConisObj>>>', temp_obj.address)
  72. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  73. }
  74. }
  75. if (json_obj.data.total > 0) {
  76. //提交归集任务
  77. if (temp_obj.address) {
  78. logger.log('pushCollectConisObj>>>', temp_obj.address)
  79. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  80. }
  81. }
  82. }
  83. } catch (error) {
  84. console.error('pushCollectConisObj error=', error)
  85. }
  86. }
  87. })
  88. }
  89. async function getCollectCoinsHash(trx_hash) {
  90. var ret = await collect_coins_db.query_collect_hash(trx_hash);
  91. if (ret && Array.isArray(ret) && ret.length > 0) {
  92. return trx_hash
  93. }
  94. return ' '
  95. }
  96. function isExistHash(trx_hash, arrs) {
  97. if (arrs && Array.isArray(arrs) && arrs.length > 0) {
  98. var ret = arrs.filter(element => {
  99. return element.gas_trx_hash == trx_hash
  100. })
  101. logger.info('isExistHash', trx_hash, ret)
  102. return ret == null ? false : ret.length > 0
  103. } else {
  104. return false
  105. }
  106. }
  107. async function filterTransfers(result) {
  108. try {
  109. if (typeof result === 'string') {
  110. var ret = JSON.parse(result)
  111. if (ret.code == 0 && ret.data.total > 0) {
  112. var new_ret = []
  113. var filter_list = await collect_coins_db.query_collect_hash_list()
  114. for (let index = 0; index < ret.data.results.length; index++) {
  115. const element = ret.data.results[index];
  116. // if (element.trx_hash == await getCollectCoinsHash(element.trx_hash)) {
  117. if (isExistHash(element.trx_hash, filter_list)) {
  118. logger.debug('element.trx_hash == await getCollectCoinsHash(element.trx_hash)', element)
  119. } else {
  120. new_ret.push(element)
  121. logger.debug('element.trx_hash != await getCollectCoinsHash(element.trx_hash)', new_ret.length)
  122. }
  123. }
  124. return {
  125. code: ret.code,
  126. data: {
  127. total: new_ret.length,
  128. results: new_ret,
  129. errMsg: ''
  130. }
  131. }
  132. } else {
  133. return result
  134. }
  135. }
  136. } catch (error) {
  137. logger.error('filterTransfers', JSON.parse(error))
  138. return result
  139. }
  140. }
  141. /**
  142. * 获取交易记录
  143. * @param {*} ctx
  144. */
  145. async function getTransfersV2(ctx) {
  146. const obj = ctx.request.body;
  147. console.log("getTransfers body", obj);
  148. if (!obj.chain)//默认 bsc 币安链
  149. obj.chain = 'bsc_mainnet'
  150. var temp_obj = { ...obj }
  151. var index = 0
  152. var result = await moralis.getTokenTransfersV2(obj)
  153. // await moralis.getTokenTransfersV2(obj).then((result) => {
  154. logger.log('getTokenTransfersV2 response', 'index=' + index, result)
  155. ctx.body = await filterTransfers(result);
  156. if (result) {
  157. //提交归集任务 native 能获取到 gas 、token 无法获取到 gas 费
  158. try {
  159. if (temp_obj.address && moralis.isTransferSucceed(result)) {
  160. var log_obj = { ...obj }
  161. log_obj.results = result
  162. log_obj.type = report.REPORT_TYPE.transfer_record
  163. //埋点日志上报-入金检查
  164. report.logReport(log_obj)
  165. var json_obj = JSON.parse(result);
  166. //缓存当前交易的 gas 费用
  167. var tr = moralis.getTransferRecordGasFree('native', json_obj, temp_obj.address)
  168. logger.log('getTransferRecordGasFree:', tr, temp_obj.address)
  169. if (tr && tr.totalGasFree > 0) {
  170. logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_BNB_FREE:', tr)
  171. // redis.redis_set(reids_token_config.LAST_BNB_PRICE, tr.gas_price.toString());
  172. // redis.redis_set(reids_token_config.LAST_TOKEN_PRICE, tr.gas_price.toString().toString());
  173. redis.writeAppendRedis(reids_token_config.LAST_BNB_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  174. redis.writeAppendRedis(reids_token_config.LAST_TOKEN_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  175. }
  176. if (json_obj.data.total > 0) {
  177. //提交归集任务
  178. if (temp_obj.address) {
  179. logger.log('pushCollectConisObj>>>', temp_obj.address)
  180. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  181. }
  182. }
  183. }
  184. } catch (error) {
  185. console.error('pushCollectConisObj error=', error)
  186. }
  187. }
  188. // })
  189. }
  190. async function getAllTokenWithdrawInfoLists(ctx) {
  191. if (ctx.request == null || ctx.request.body == null) {
  192. ctx.body = utils.toJson(-1, null, "request error. ");
  193. return
  194. }
  195. ctx.body = await moralis.getAllTokenWithdrawInfoLists(ctx);
  196. }
  197. async function check_czz_withdraw_task() {
  198. while (true) {
  199. var exec_obj;
  200. try {
  201. exec_obj = await redis.redis_pop(reids_token_config.CHECK_CZZ_WITHDRAW_STATUS_QUEUE)
  202. logger.log("check_czz_withdraw_task redis_pop", exec_obj)
  203. if (!exec_obj) {
  204. logger.log("没有 czz hash check")
  205. await utils.sleep(2 * 60 * 1000)
  206. continue
  207. }
  208. exec_obj = JSON.parse(exec_obj)
  209. if (utils.getTimestamp() - exec_obj.create_time > exec_obj.lifecycle) {
  210. logger.error('已过期 check_czz_withdraw_task :', JSON.stringify(exec_obj))
  211. var update_obj = {}
  212. update_obj.withdraw_status = 3
  213. update_obj.withdraw_hash = ''
  214. update_obj.nonce = -1
  215. update_obj.gas_price = ''
  216. update_obj.gas_limit = ''
  217. update_obj.value = '0'
  218. update_obj.errorMsg = 'czz timeout'
  219. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  220. continue
  221. }
  222. if (!exec_obj.hash || !exec_obj.chain) {
  223. logger.error('check_withdraw_status error:', JSON.stringify(exec_obj))
  224. continue
  225. }
  226. var obj = await czz.check_withdraw_status(exec_obj)
  227. if (obj.code == 0) {
  228. var nonce = obj.data.nonce
  229. var curGasPrice = obj.data.gasPrice.toString()
  230. var curGasLimit = obj.data.gasLimit.toString()
  231. var hash = obj.data.hash
  232. var update_obj = {}
  233. update_obj.withdraw_status = 2
  234. update_obj.withdraw_hash = hash
  235. update_obj.nonce = nonce
  236. update_obj.gas_price = curGasPrice.toString()
  237. update_obj.gas_limit = curGasLimit.toString()
  238. update_obj.value = utils.scientificNotationToString(obj.data.value).toString()
  239. update_obj.errorMsg = ''
  240. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  241. } else {
  242. redis.redis_push(reids_token_config.CHECK_CZZ_WITHDRAW_STATUS_QUEUE, JSON.stringify(exec_obj))
  243. }
  244. await utils.sleep(2 * 60 * 1000)
  245. } catch (error) {
  246. logger.error('check_czz_withdraw_task error', error.toString(), JSON.stringify(exec_obj))
  247. }
  248. }
  249. }
  250. async function collect_conis_task() {
  251. logger.log("collect_conis_task start")
  252. var last_address = ' ';
  253. var last_time = utils.getTimestamp();
  254. while (true) {
  255. var isPause = 0
  256. try {
  257. isPause = await remote_config_db.isPause('collect_coins')
  258. if (isPause) {
  259. logger.error("collect_conis_task pause")
  260. await utils.sleep(60000)
  261. continue
  262. }
  263. } catch (error) {
  264. logger.error("collect_conis_task isPause error", error.toString())
  265. }
  266. var start_time = utils.getTimestamp()
  267. var exec_obj = await redis.redis_pop(reids_token_config.COLLECT_CONIS_QUEUE_KEY)
  268. if (!exec_obj) {
  269. logger.log("没有归集任务")
  270. await utils.sleep(30000)
  271. continue
  272. }
  273. try {
  274. exec_obj = JSON.parse(exec_obj)
  275. logger.log('collect_conis_task exec item>>>>', exec_obj);
  276. try {
  277. //是否是黑名单
  278. var isBlackList = await remote_config_db.isBlackList('collect_coins', exec_obj.chain, exec_obj.address)
  279. if (isBlackList) {
  280. logger.error('collect_conis_task isBlackList', JSON.stringify(exec_obj));
  281. continue
  282. }
  283. } catch (error) {
  284. logger.error('collect_conis_task isBlackList error', JSON.stringify(exec_obj));
  285. }
  286. if (last_address && exec_obj.address && last_address == exec_obj.address && utils.getTimestamp() - last_time < 2 * 60 * 1000) {
  287. logger.info('collect coins wait...');
  288. await utils.sleep(60000)
  289. }
  290. //开始收集用户地址里面的币到归集地址
  291. var ret = await moralis.collectCoins(exec_obj)
  292. logger.log('collect_conis_task ret =', exec_obj, ret)
  293. try {
  294. var ret_obj = JSON.parse(ret)
  295. if (ret_obj.code == 0) {
  296. logger.log('触发归集 delay collect_conis_task ret =', exec_obj, ret)
  297. last_address = exec_obj.address
  298. }
  299. } catch (error) { }
  300. } catch (error) {
  301. logger.error('collect_conis_task error', error.toString());
  302. }
  303. logger.log("collect_conis_task cost-time", utils.getTimestamp() - start_time, exec_obj)
  304. last_time = utils.getTimestamp()
  305. }
  306. }
  307. async function withdraw_task() {
  308. logger.log("withdraw_task start")
  309. let last_time = 0
  310. let last_hash = ''
  311. let last_chain = ''
  312. while (true) {
  313. var isPause = 0
  314. try {
  315. isPause = await remote_config_db.isPause('withdraw')
  316. logger.info("withdraw_task pause", isPause)
  317. if (isPause) {
  318. logger.error("withdraw_task pause")
  319. await utils.sleep(60000)
  320. continue
  321. }
  322. } catch (error) {
  323. logger.error("withdraw_task isPause error", error.toString())
  324. }
  325. var exec_obj = await redis.redis_pop(reids_token_config.WITHDRAW_QUEUE_KEY)
  326. if (!exec_obj) {
  327. await utils.sleep(10000)
  328. logger.log("没有出金任务")
  329. continue
  330. }
  331. try {
  332. exec_obj = JSON.parse(exec_obj)
  333. } catch (error) {
  334. logger.error('withdraw_task item parse error', error);
  335. continue
  336. }
  337. try {
  338. logger.info('withdraw exec obj', exec_obj)
  339. //是否是黑名单
  340. var isBlackList = await remote_config_db.isBlackList('withdraw', exec_obj.chain, exec_obj.receiver)
  341. if (isBlackList) {
  342. var update_obj = {}
  343. update_obj.withdraw_status = 3
  344. update_obj.errorMsg = 'blackList'
  345. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  346. logger.error('withdraw_task isBlackList', JSON.stringify(exec_obj));
  347. continue
  348. }
  349. } catch (error) {
  350. logger.error('withdraw_task isBlackList error', JSON.stringify(exec_obj));
  351. }
  352. var temp_obj = { ...exec_obj }
  353. if (utils.getTimestamp() - last_time < 60000) {
  354. //有可能上一个区块还未更新,这里做一个尝试限制
  355. //Error: Failed to make "eth_sendRawTransaction" request with networkConnector: "already known"
  356. //通过 交易 hash 获取块。last_hash
  357. if (last_hash && last_chain) {
  358. var options = {
  359. transaction_hash: last_hash,
  360. chain: last_chain,
  361. endTime: '2099-01-01'
  362. }
  363. var tryCount = 3;
  364. do {
  365. try {
  366. //通过获取上一个交易记录来进行确认
  367. var transaction = await moralis.getTokenTransfersV2(options);
  368. logger.log('withdraw_task exectransaction', transaction, options, tryCount);
  369. if (typeof transaction === 'string')
  370. transaction = JSON.parse(transaction)
  371. if (transaction.code == 0) {
  372. if (transaction.data.results.length <= 0) {
  373. logger.log('等待10s');
  374. await utils.sleep(10000)
  375. } else {
  376. logger.log('等待5s');
  377. await utils.sleep(5000)
  378. break
  379. }
  380. } else {
  381. break
  382. }
  383. tryCount -= 1
  384. } catch (error) {
  385. logger.error('withdraw_task exectransaction err', error.toString());
  386. }
  387. if (tryCount < 0) {
  388. logger.error('withdraw_task getTokenTransfersV2 40s内 警告交易未更新:', JSON.stringify(options));
  389. }
  390. } while (tryCount >= 0);
  391. }
  392. }
  393. //如果失败重试一次
  394. var tryCount = 1;
  395. for (let index = 0; index < 1 + tryCount; index++) {
  396. var result;
  397. var obj;
  398. var curGasPrice = 0;
  399. var curGasLimit = 0;
  400. var value = 0
  401. var nonce = -1
  402. try {
  403. result = await withdraw_({ ...temp_obj })
  404. last_time = utils.getTimestamp()
  405. logger.log('withdraw_task withdraw_ =', result, last_time)
  406. if (result && moralis.getTransferCode(result) == 0) {
  407. if (typeof result === 'string') {
  408. obj = JSON.parse(result)
  409. }
  410. nonce = obj.data.nonce
  411. try {
  412. curGasPrice = BigNumber(obj.data.gasPrice.hex).toNumber()
  413. curGasLimit = BigNumber(obj.data.gasLimit.hex).toNumber()
  414. if (!obj.data.value.number) {
  415. value = BigNumber(obj.data.value.hex).toNumber()
  416. } else {
  417. value = obj.data.value.number
  418. }
  419. } catch (error) {
  420. logger.error('BigNumber toNumber error')
  421. }
  422. var hash = obj.data.hash
  423. last_hash = hash
  424. last_chain = temp_obj.chain
  425. var update_obj = {}
  426. update_obj.withdraw_status = 2
  427. update_obj.withdraw_hash = hash
  428. update_obj.nonce = nonce
  429. update_obj.gas_price = curGasPrice.toString()
  430. update_obj.gas_limit = curGasLimit.toString()
  431. try {
  432. update_obj.value = utils.scientificNotationToString(value).toString()
  433. } catch (error) {
  434. logger.error('scientificNotationToString error')
  435. }
  436. update_obj.errorMsg = ''
  437. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  438. break
  439. } else if (result && moralis.getTransferCode(result) == 1) {
  440. moralis.pushChainDetailTOQueue(1, exec_obj, result);
  441. break
  442. } else {
  443. logger.error('withdraw_task withdraw_ error=', result, JSON.stringify(temp_obj))
  444. if (index < 1 + tryCount && result.includes('eth_sendRawTransaction')) {
  445. logger.error('try withdraw_:', JSON.stringify(temp_obj), index)
  446. await utils.sleep(3000)
  447. continue
  448. }
  449. var update_obj = {}
  450. update_obj.withdraw_status = 3
  451. if (typeof result === 'string') {
  452. try {
  453. result = JSON.parse(result)
  454. update_obj.errorMsg = result.errMsg
  455. } catch (error) {
  456. logger.error('withdraw_task=', result)
  457. }
  458. }
  459. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  460. break
  461. }
  462. } catch (error) {
  463. var update_obj = {}
  464. update_obj.withdraw_status = 3
  465. update_obj.errorMsg = error.toString()
  466. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  467. if (result)
  468. logger.error('withdraw_task error=', error.toString(), JSON.stringify(temp_obj), JSON.stringify(result))
  469. else {
  470. logger.error('withdraw_task error=', error.toString(), JSON.stringify(temp_obj))
  471. }
  472. break
  473. }
  474. }
  475. }
  476. logger.log("withdraw_task end")
  477. }
  478. /**
  479. * 队列版本
  480. * @param {*} ctx
  481. * @returns
  482. */
  483. async function withdrawV3(ctx) {
  484. logger.log('withdrawV3')
  485. if (ctx.request == null || ctx.request.body == null) {
  486. ctx.body = utils.toJson(-1, null, "request error. ");
  487. return
  488. }
  489. const obj = ctx.request.body;
  490. var log_obj = { ...obj }
  491. logger.log('withdrawV3', log_obj)
  492. var obj_ = decrypt_withdraw_content(log_obj.content)
  493. obj_.withdraw_id = obj_.withdrawId;
  494. // obj_.withdraw_id = utils.getTimestamp().toString();
  495. // var obj_ = log_obj
  496. if (obj_.withdraw_id) {
  497. var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)
  498. if (isExist) {
  499. logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')
  500. ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')
  501. return
  502. }
  503. var info = await moralis.queryCompanyInfoFromId(0);
  504. obj_.user_address = info.user_address
  505. await withdraw_db.create_withdraw_task(obj_)
  506. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  507. // withdraw_task()
  508. ctx.body = utils.toJson(0, obj_.withdraw_id, null)
  509. } else {
  510. return utils.toJson(-2, null, ' withdraw_id not empty.')
  511. }
  512. }
  513. async function withdrawV3Test(ctx) {
  514. logger.log('withdrawV3Test')
  515. if (ctx.request == null || ctx.request.body == null) {
  516. ctx.body = utils.toJson(-1, null, "request error. ");
  517. return
  518. }
  519. const obj = ctx.request.body;
  520. // for (let index = 0; index < 10; index++) {
  521. var log_obj = { ...obj }
  522. logger.log('withdrawV3', log_obj)
  523. var obj_ = decrypt_withdraw_content(log_obj.content)
  524. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  525. // var obj_ = log_obj
  526. if (obj_.withdraw_id) {
  527. var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)
  528. if (isExist) {
  529. logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')
  530. ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')
  531. return
  532. }
  533. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  534. var info = await moralis.queryCompanyInfoFromId(0);
  535. obj_.user_address = info.user_address
  536. await withdraw_db.create_withdraw_task(obj_)
  537. ctx.body = utils.toJson(0, obj_.withdraw_id, null)
  538. } else {
  539. return utils.toJson(-2, null, ' withdraw_id not empty.')
  540. }
  541. // }
  542. }
  543. function decrypt_withdraw_content(content) {
  544. // const encryptText = utils.encrypt(log_obj);
  545. const encryptText = content;
  546. logger.log("加密", encryptText);
  547. let decryptObj = utils.decrypt(encryptText);
  548. try {
  549. logger.log("解密 before", decryptObj);
  550. decryptObj = JSON.parse(decryptObj);
  551. console.log("解密 json parse", decryptObj);
  552. } catch (error) {
  553. logger.error("json error:", error);
  554. decryptObj = null;
  555. }
  556. return decryptObj;
  557. }
  558. /**
  559. *
  560. * @param {鉴权版本} ctx
  561. */
  562. async function withdrawV2(ctx) {
  563. if (ctx.request == null || ctx.request.body == null) {
  564. ctx.body = utils.toJson(-1, null, "request error. ");
  565. return
  566. }
  567. const obj = ctx.request.body;
  568. var log_obj = { ...obj }
  569. // const encryptText = utils.encrypt(log_obj);
  570. const encryptText = log_obj.content;
  571. logger.log("加密", encryptText);
  572. let decryptObj = utils.decrypt(encryptText);
  573. try {
  574. logger.log("解密 before", decryptObj);
  575. decryptObj = JSON.parse(decryptObj);
  576. // console.log("解密 json parse", decryptObj);
  577. await withdraw_(decryptObj).then(result => {
  578. ctx.body = result;
  579. })
  580. } catch (error) {
  581. logger.error("json error:", error);
  582. ctx.body = utils.toJson(-1, null, error.toString());
  583. }
  584. }
  585. async function withdraw_(obj) {
  586. console.log("withdraw_", obj);
  587. var log_obj = { ...obj }
  588. var info = await moralis.queryCompanyInfoFromId(0);
  589. // log_obj.company_address_total_balance_before = await moralis.queryCollectBalance(info.user_address, obj.chain)
  590. log_obj.company_public_key = info.user_address
  591. logger.log('withdraw log', log_obj);
  592. return new Promise((resolve) => {
  593. moralis.withdraw(obj).then((result) => {
  594. if (moralis.getTransferCode(result) == 0) {
  595. //提币日志上报
  596. log_obj.results = result
  597. log_obj.type = report.REPORT_TYPE.withdraw
  598. //缓存当前交易的 gas 费用
  599. if (result && log_obj.contractAddress) {
  600. var tr = moralis.getTransferGasFree('token', result)
  601. log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()
  602. } else {
  603. var tr = moralis.getTransferGasFree('native', result)
  604. log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()
  605. }
  606. //日志上报
  607. report.logReport(log_obj)
  608. }
  609. resolve(result)
  610. });
  611. })
  612. }
  613. //出金
  614. async function withdraw(ctx) {
  615. if (ctx.request == null || ctx.request.body == null) {
  616. ctx.body = utils.toJson(-1, null, "request error. ");
  617. return
  618. }
  619. const obj = ctx.request.body;
  620. await withdraw_(obj).then(result => {
  621. ctx.body = result;
  622. })
  623. }
  624. /**
  625. * 查询出金状态
  626. * @param {*} ctx
  627. */
  628. async function getWithdrawStatus(ctx) {
  629. if (ctx.request == null || ctx.request.body == null) {
  630. ctx.body = utils.toJson(-1, null, "request error. ");
  631. return
  632. }
  633. const obj = ctx.request.body;
  634. var info = await withdraw_db.queryWithdrawInfoFromWithdrawId(obj.withdrawId)
  635. logger.log('getWithdrawStatus info', JSON.stringify(info))
  636. if (info) {
  637. if (info.withdraw_status != 3) {
  638. ctx.body = utils.toJson(0, {
  639. withdrawId: info.withdraw_id,
  640. withdrawStatus: info.withdraw_status,
  641. withdrawHash: info.withdraw_hash,
  642. chainId: info.chain_id,
  643. transferTimestamp: info.update_time,
  644. }, null)
  645. } else {
  646. ctx.body = utils.toJson(0, {
  647. withdrawId: info.withdraw_id,
  648. withdrawStatus: info.withdraw_status,
  649. withdrawHash: info.withdraw_hash,
  650. chainId: info.chain_id,
  651. transferTimestamp: info.update_time,
  652. errorMsg: info.errorMsg
  653. }, info.errorMsg)
  654. }
  655. } else {
  656. ctx.body = utils.toJson(-1, null, obj.withdraw_id + ' id does not exist.')
  657. }
  658. }
  659. async function timer_collect_conis_bsc_task() {
  660. var index = 0
  661. var delay = 60 * 1000 * 60
  662. while (1) {
  663. var temp_obj = {
  664. "chain": "bsc_testnet",
  665. "address": "0x3B525c35DdC323B08241493f148340D89e3A73a7"
  666. }
  667. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  668. await utils.sleep(delay)
  669. index += 1
  670. }
  671. }
  672. async function timer_collect_conis_task(chain, address) {
  673. var index = 0
  674. var delay = 60 * 1000 * 60
  675. while (1) {
  676. var temp_obj = {
  677. "chain": chain,
  678. "address": address,
  679. }
  680. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  681. await utils.sleep(delay)
  682. index += 1
  683. }
  684. }
  685. async function timer_collect_conis_czz_task() {
  686. var index = 0
  687. var delay = 60 * 1000 * 60
  688. while (1) {
  689. var temp_obj = {
  690. "chain": "czz",
  691. "address": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  692. }
  693. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  694. await utils.sleep(delay)
  695. index += 1
  696. }
  697. }
  698. async function timer_transfer_task(obj_) {
  699. var index = 0
  700. var delay = 60 * 1000 * 60
  701. while (1) {
  702. // var obj_ = {
  703. // "type": "erc20",
  704. // "contractAddress": "0xFF94950Ee8A79c52cC4B0Aa5178C8cEa48A3F3A6",
  705. // "amount": "123000000000000000000",
  706. // "chain": "bsc_testnet",
  707. // "receiver": "0x3B525c35DdC323B08241493f148340D89e3A73a7",
  708. // "withdrawId": index.toString()
  709. // }
  710. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  711. var info = await moralis.queryCompanyInfoFromId(0);
  712. obj_.user_address = info.user_address
  713. await withdraw_db.create_withdraw_task(obj_)
  714. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  715. await utils.sleep(delay)
  716. index += 1
  717. }
  718. }
  719. async function timer_transfer_czz_task() {
  720. var index = 0
  721. var delay = 60 * 1000 * 60
  722. while (1) {
  723. var obj_ = {
  724. "type": "erc20",
  725. "contractAddress": "0xfb16179d5e84b0e3e7524ed61a9cf7b98d039b20",
  726. "amount": "100000000000000000000",
  727. "chain": "czz",
  728. "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076"
  729. }
  730. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  731. var info = await moralis.queryCompanyInfoFromId(0);
  732. obj_.user_address = info.user_address
  733. await withdraw_db.create_withdraw_task(obj_)
  734. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  735. await utils.sleep(delay)
  736. index += 1
  737. }
  738. }
  739. async function checkout_taxhash(exec_obj) {
  740. logger.info('bsc_log_monitoring exec start:', exec_obj)
  741. var delay = 60 * 1000
  742. try {
  743. if (typeof exec_obj === 'string')
  744. exec_obj = JSON.parse(exec_obj)
  745. } catch (error) {
  746. logger.error('bsc_log_monitoring:', error)
  747. }
  748. var tryCount = 5
  749. do {
  750. if (tryCount == 0) {
  751. logger.error('数据在5分钟未更新', JSON.stringify(exec_obj))
  752. break
  753. }
  754. if (exec_obj.transactionHash) {
  755. var ret = await account_mysql.getAccountTransactions({
  756. type: 'only_hash',
  757. transaction_hash: exec_obj.transactionHash
  758. })
  759. if (ret && ret.code == 0 && ret.data.total > 0) {
  760. break
  761. }
  762. }
  763. --tryCount
  764. logger.debug('getAccountTransactions', tryCount, exec_obj)
  765. await utils.sleep(delay)
  766. } while (tryCount >= 0);
  767. }
  768. async function bsc_log_monitoring() {
  769. while (1) {
  770. var exec_obj = await redis.redis_pop(reids_token_config.BSC_LOG_MONITORING_KEY)
  771. if (!exec_obj) {
  772. await utils.sleep(10000)
  773. logger.log("no new check tasks")
  774. continue
  775. }
  776. checkout_taxhash(exec_obj)
  777. }
  778. }
  779. //获取交易记录
  780. router.post('/getTransfers', getTransfers)
  781. router.post('/getTransfersV2', getTransfersV2)
  782. // 获取所有代币价格
  783. router.post('/getAllTotkenPrice', getAllTotkenPrice)
  784. router.post('/getAllTokenPrice', getAllTokenPrice)
  785. // router.post('/transfer', transfer)
  786. //提现
  787. router.post('/withdraw', withdraw);
  788. //提现鉴权-body 加密
  789. router.post('/withdrawV2', withdrawV2);
  790. //队列的形式
  791. router.post('/withdrawV3', withdrawV3);
  792. // if (process.env.NODE_ENV == 'dev' || process.env.NODE_ENV == 'test') {
  793. router.post('/withdrawV3Test', withdrawV3Test);
  794. // }
  795. //查询出金服务
  796. router.post('/getWithdrawStatus', getWithdrawStatus);
  797. //获取所有地址的所要消耗的最低提取费
  798. router.post('/getAllTokenWithdrawInfoLists', getAllTokenWithdrawInfoLists)
  799. // 定时任务 提币+归集
  800. withdraw_task();
  801. collect_conis_task();
  802. // //czz 504 检查
  803. // check_czz_withdraw_task();
  804. // bsc 监控
  805. // bsc_log_monitoring()
  806. if (process.env.NODE_ENV == 'dev' || process.env.NODE_ENV == 'test') {
  807. /*** test */
  808. //bsc
  809. // timer_transfer_task({
  810. // "type": "erc20",
  811. // "contractAddress": "0xFF94950Ee8A79c52cC4B0Aa5178C8cEa48A3F3A6",
  812. // "amount": "123000000000000000000",
  813. // "chain": "bsc_testnet",
  814. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  815. // "withdrawId": 5
  816. // })
  817. // timer_transfer_task({
  818. // "type": "native",
  819. // "amount": "100000000000000000",
  820. // "chain": "bsc_testnet",
  821. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  822. // "withdrawId": 6
  823. // })
  824. //czz
  825. // timer_transfer_task({
  826. // "type": "erc20",
  827. // "contractAddress": "0xfb16179d5e84b0e3e7524ed61a9cf7b98d039b20",
  828. // "amount": "100000000000000000000",
  829. // "chain": "czz",
  830. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  831. // "withdrawId": 5
  832. // })
  833. // timer_transfer_task({
  834. // "type": "native",
  835. // "amount": "100000000000000000",
  836. // "chain": "czz",
  837. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  838. // "withdrawId": 6
  839. // })
  840. //kcc
  841. // timer_transfer_task({
  842. // "type": "erc20",
  843. // "contractAddress": "0x9984086cb9d93dbe47c4e70890aad5454bbc2518",
  844. // "amount": "1300000000000000000000",
  845. // "chain": "kcc_testnet",
  846. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  847. // "withdrawId": 1
  848. // })
  849. // timer_transfer_task({
  850. // "type": "native",
  851. // "amount": "110000000000000000",
  852. // "chain": "kcc_testnet",
  853. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  854. // "withdrawId": 2
  855. // })
  856. //okc
  857. // timer_transfer_task({
  858. // "type": "erc20",
  859. // "contractAddress": "0xc2BaBFb3Bd1516D138B05c7c7e316f1648E90B7C",
  860. // "amount": "1200000000000000000000",
  861. // "chain": "okc_testnet",
  862. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  863. // "withdrawId": 3
  864. // })
  865. // timer_transfer_task({
  866. // "type": "native",
  867. // "amount": "100000000000000000",
  868. // "chain": "okc_testnet",
  869. // "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  870. // "withdrawId": 4
  871. // })
  872. /*** main */
  873. //bsc
  874. // timer_transfer_task({
  875. // "type": "erc20",
  876. // "contractAddress": "0x9984086CB9d93dbe47C4e70890aAD5454bBc2518",
  877. // "amount": "123000000000000000000",
  878. // "chain": "bsc_mainnet",
  879. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  880. // "withdrawId": 5
  881. // })
  882. // timer_transfer_task({
  883. // "type": "native",
  884. // "amount": "1000000000000000",
  885. // "chain": "bsc_mainnet",
  886. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  887. // "withdrawId": 6
  888. // })
  889. //czz
  890. // timer_transfer_task({
  891. // "type": "erc20",
  892. // "contractAddress": "0xfb16179d5e84b0e3e7524ed61a9cf7b98d039b20",
  893. // "amount": "100000000000000000000",
  894. // "chain": "czz",
  895. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  896. // "withdrawId": 5
  897. // })
  898. // timer_transfer_task({
  899. // "type": "native",
  900. // "amount": "1000000000000000",
  901. // "chain": "czz",
  902. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  903. // "withdrawId": 6
  904. // })
  905. //kcc
  906. // timer_transfer_task({
  907. // "type": "erc20",
  908. // "contractAddress": "0x9984086cb9d93dbe47c4e70890aad5454bbc2518",
  909. // "amount": "1300000000000000000000",
  910. // "chain": "kcc_mainnet",
  911. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  912. // "withdrawId": 1
  913. // })
  914. // timer_transfer_task({
  915. // "type": "native",
  916. // "amount": "110000000000000000",
  917. // "chain": "kcc_mainnet",
  918. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  919. // "withdrawId": 2
  920. // })
  921. //okc
  922. // timer_transfer_task({
  923. // "type": "erc20",
  924. // "contractAddress": "0x9984086CB9d93dbe47C4e70890aAD5454bBc2518",
  925. // "amount": "1200000000000000000000",
  926. // "chain": "okc_mainnet",
  927. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  928. // "withdrawId": 3
  929. // })
  930. // timer_transfer_task({
  931. // "type": "native",
  932. // "amount": "100000000000000000",
  933. // "chain": "okc_mainnet",
  934. // "receiver": "0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50",
  935. // "withdrawId": 4
  936. // })
  937. // timer_collect_conis_task('okc_testnet','0x39ACD9CC975D792D8160215Dc84fa00E4934F076')
  938. // timer_collect_conis_task('kcc_testnet','0x39ACD9CC975D792D8160215Dc84fa00E4934F076')
  939. // timer_collect_conis_task('bsc_testnet','0x39ACD9CC975D792D8160215Dc84fa00E4934F076')
  940. // timer_collect_conis_task('czz','0x39ACD9CC975D792D8160215Dc84fa00E4934F076')
  941. // timer_collect_conis_task('okc_testnet','0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50')
  942. // timer_collect_conis_task('kcc_mainnet','0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50')
  943. // timer_collect_conis_task('bsc_testnet','0x0001Df2b3c3cde767343e4e54Ab083e083CD1C50')
  944. }
  945. module.exports = router