sdk.js 38 KB

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