sdk.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  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/czz')
  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 stat = require('../model/server_data_statistics')
  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. async function filterTransfers(result) {
  98. try {
  99. if (typeof result === 'string') {
  100. var ret = JSON.parse(result)
  101. if (ret.code == 0 && ret.data.total > 0) {
  102. var new_ret = []
  103. for (let index = 0; index < ret.data.results.length; index++) {
  104. const element = ret.data.results[index];
  105. if (element.trx_hash == await getCollectCoinsHash(element.trx_hash)) {
  106. logger.debug('element.trx_hash == await getCollectCoinsHash(element.trx_hash)', element)
  107. } else {
  108. new_ret.push(element)
  109. }
  110. }
  111. return {
  112. code: ret.code,
  113. data: {
  114. total: new_ret.length,
  115. results: new_ret,
  116. errMsg: ''
  117. }
  118. }
  119. } else {
  120. return result
  121. }
  122. }
  123. } catch (error) {
  124. logger.error('filterTransfers', JSON.parse(error))
  125. return result
  126. }
  127. }
  128. /**
  129. * 获取交易记录
  130. * @param {*} ctx
  131. */
  132. async function getTransfersV2(ctx) {
  133. const obj = ctx.request.body;
  134. console.log("getTransfers body", obj);
  135. if (!obj.chain)//默认 bsc 币安链
  136. obj.chain = 'bsc_mainnet'
  137. var temp_obj = { ...obj }
  138. var index = 0
  139. var result = await moralis.getTokenTransfersV2(obj)
  140. // await moralis.getTokenTransfersV2(obj).then((result) => {
  141. logger.log('getTokenTransfersV2 response', 'index=' + index, result)
  142. ctx.body = await filterTransfers(result);
  143. if (result) {
  144. //提交归集任务 native 能获取到 gas 、token 无法获取到 gas 费
  145. try {
  146. if (temp_obj.address && moralis.isTransferSucceed(result)) {
  147. var log_obj = { ...obj }
  148. log_obj.results = result
  149. log_obj.type = report.REPORT_TYPE.transfer_record
  150. //埋点日志上报-入金检查
  151. report.logReport(log_obj)
  152. var json_obj = JSON.parse(result);
  153. //缓存当前交易的 gas 费用
  154. var tr = moralis.getTransferRecordGasFree('native', json_obj, temp_obj.address)
  155. logger.log('getTransferRecordGasFree:', tr, temp_obj.address)
  156. if (tr && tr.totalGasFree > 0) {
  157. logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_BNB_FREE:', tr)
  158. // redis.redis_set(reids_token_config.LAST_BNB_PRICE, tr.gas_price.toString());
  159. // redis.redis_set(reids_token_config.LAST_TOKEN_PRICE, tr.gas_price.toString().toString());
  160. redis.writeAppendRedis(reids_token_config.LAST_BNB_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  161. redis.writeAppendRedis(reids_token_config.LAST_TOKEN_PRICE, temp_obj.chain, '', tr.gas_price.toString());
  162. }
  163. if (json_obj.data.total > 0) {
  164. //提交归集任务
  165. if (temp_obj.address) {
  166. logger.log('pushCollectConisObj>>>', temp_obj.address)
  167. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  168. }
  169. }
  170. }
  171. } catch (error) {
  172. console.error('pushCollectConisObj error=', error)
  173. }
  174. }
  175. // })
  176. }
  177. async function getAllTokenWithdrawInfoLists(ctx) {
  178. if (ctx.request == null || ctx.request.body == null) {
  179. ctx.body = utils.toJson(-1, null, "request error. ");
  180. return
  181. }
  182. ctx.body = await moralis.getAllTokenWithdrawInfoLists(ctx);
  183. }
  184. async function check_czz_withdraw_task() {
  185. while (true) {
  186. var exec_obj;
  187. try {
  188. exec_obj = await redis.redis_pop(reids_token_config.CHECK_CZZ_WITHDRAW_STATUS_QUEUE)
  189. logger.log("check_czz_withdraw_task redis_pop", exec_obj)
  190. if (!exec_obj) {
  191. logger.log("没有 czz hash check")
  192. await utils.sleep(2 * 60 * 1000)
  193. continue
  194. }
  195. exec_obj = JSON.parse(exec_obj)
  196. if (utils.getTimestamp() - exec_obj.create_time > exec_obj.lifecycle) {
  197. logger.error('已过期 check_czz_withdraw_task :', JSON.stringify(exec_obj))
  198. var update_obj = {}
  199. update_obj.withdraw_status = 3
  200. update_obj.withdraw_hash = ''
  201. update_obj.nonce = -1
  202. update_obj.gas_price = ''
  203. update_obj.gas_limit = ''
  204. update_obj.value = '0'
  205. update_obj.errorMsg = 'czz timeout'
  206. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  207. continue
  208. }
  209. var obj = await czz.check_withdraw_status(exec_obj)
  210. if (obj.code == 0) {
  211. var nonce = obj.data.nonce
  212. var curGasPrice = obj.data.gasPrice.toString()
  213. var curGasLimit = obj.data.gasLimit.toString()
  214. var hash = obj.data.hash
  215. var update_obj = {}
  216. update_obj.withdraw_status = 2
  217. update_obj.withdraw_hash = hash
  218. update_obj.nonce = nonce
  219. update_obj.gas_price = curGasPrice.toString()
  220. update_obj.gas_limit = curGasLimit.toString()
  221. update_obj.value = utils.scientificNotationToString(obj.data.value).toString()
  222. update_obj.errorMsg = ''
  223. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  224. } else {
  225. redis.redis_push(reids_token_config.CHECK_CZZ_WITHDRAW_STATUS_QUEUE, JSON.stringify(exec_obj))
  226. }
  227. await utils.sleep(2 * 60 * 1000)
  228. } catch (error) {
  229. logger.error('check_czz_withdraw_task error', error.toString(), JSON.stringify(exec_obj))
  230. }
  231. }
  232. }
  233. async function collect_conis_task() {
  234. logger.log("collect_conis_task start")
  235. var last_address = ' ';
  236. var last_time = utils.getTimestamp();
  237. while (true) {
  238. var isPause = 0
  239. try {
  240. isPause = await remote_config_db.isPause('collect_coins')
  241. if (isPause) {
  242. logger.error("collect_conis_task pause")
  243. await utils.sleep(60000)
  244. continue
  245. }
  246. } catch (error) {
  247. logger.error("collect_conis_task isPause error", error.toString())
  248. }
  249. var start_time = utils.getTimestamp()
  250. var exec_obj = await redis.redis_pop(reids_token_config.COLLECT_CONIS_QUEUE_KEY)
  251. if (!exec_obj) {
  252. logger.log("没有归集任务")
  253. await utils.sleep(30000)
  254. continue
  255. }
  256. try {
  257. exec_obj = JSON.parse(exec_obj)
  258. logger.log('collect_conis_task exec item>>>>', exec_obj);
  259. try {
  260. //是否是黑名单
  261. var isBlackList = await remote_config_db.isBlackList('collect_coins', exec_obj.chain, exec_obj.address)
  262. if (isBlackList) {
  263. logger.error('collect_conis_task isBlackList', JSON.stringify(exec_obj));
  264. continue
  265. }
  266. } catch (error) {
  267. logger.error('collect_conis_task isBlackList error', JSON.stringify(exec_obj));
  268. }
  269. if (last_address && exec_obj.address && last_address == exec_obj.address && utils.getTimestamp() - last_time < 2 * 60 * 1000) {
  270. logger.info('collect coins wait...');
  271. await utils.sleep(60000)
  272. }
  273. //开始收集用户地址里面的币到归集地址
  274. var ret = await moralis.collectCoins(exec_obj)
  275. logger.log('collect_conis_task ret =', exec_obj, ret)
  276. try {
  277. var ret_obj = JSON.parse(ret)
  278. if (ret_obj.code == 0) {
  279. logger.log('触发归集 delay collect_conis_task ret =', exec_obj, ret)
  280. last_address = exec_obj.address
  281. }
  282. } catch (error) { }
  283. } catch (error) {
  284. logger.error('collect_conis_task error', error.toString());
  285. }
  286. logger.log("collect_conis_task cost-time", utils.getTimestamp() - start_time, exec_obj)
  287. last_time = utils.getTimestamp()
  288. }
  289. }
  290. async function withdraw_task() {
  291. logger.log("withdraw_task start")
  292. let last_time = 0
  293. let last_hash = ''
  294. let last_chain = ''
  295. while (true) {
  296. var isPause = 0
  297. try {
  298. isPause = await remote_config_db.isPause('withdraw')
  299. logger.info("withdraw_task pause", isPause)
  300. if (isPause) {
  301. logger.error("withdraw_task pause")
  302. await utils.sleep(60000)
  303. continue
  304. }
  305. } catch (error) {
  306. logger.error("withdraw_task isPause error", error.toString())
  307. }
  308. var exec_obj = await redis.redis_pop(reids_token_config.WITHDRAW_QUEUE_KEY)
  309. if (!exec_obj) {
  310. await utils.sleep(10000)
  311. logger.log("没有出金任务")
  312. continue
  313. }
  314. try {
  315. exec_obj = JSON.parse(exec_obj)
  316. } catch (error) {
  317. logger.error('withdraw_task item parse error', error);
  318. continue
  319. }
  320. try {
  321. logger.info('withdraw exec obj', exec_obj)
  322. //是否是黑名单
  323. var isBlackList = await remote_config_db.isBlackList('withdraw', exec_obj.chain, exec_obj.receiver)
  324. if (isBlackList) {
  325. var update_obj = {}
  326. update_obj.withdraw_status = 3
  327. update_obj.errorMsg = 'blackList'
  328. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  329. logger.error('withdraw_task isBlackList', JSON.stringify(exec_obj));
  330. continue
  331. }
  332. } catch (error) {
  333. logger.error('withdraw_task isBlackList error', JSON.stringify(exec_obj));
  334. }
  335. var temp_obj = { ...exec_obj }
  336. if (utils.getTimestamp() - last_time < 60000) {
  337. //有可能上一个区块还未更新,这里做一个尝试限制
  338. //Error: Failed to make "eth_sendRawTransaction" request with networkConnector: "already known"
  339. //通过 交易 hash 获取块。last_hash
  340. if (last_hash && last_chain) {
  341. var options = {
  342. transaction_hash: last_hash,
  343. chain: last_chain,
  344. endTime: '2099-01-01'
  345. }
  346. var tryCount = 3;
  347. do {
  348. try {
  349. //通过获取上一个交易记录来进行确认
  350. var transaction = await moralis.getTokenTransfersV2(options);
  351. logger.log('withdraw_task exectransaction', transaction, options, tryCount);
  352. if (typeof transaction === 'string')
  353. transaction = JSON.parse(transaction)
  354. if (transaction.code == 0) {
  355. if (transaction.data.results.length <= 0) {
  356. logger.log('等待10s');
  357. await utils.sleep(10000)
  358. } else {
  359. logger.log('等待5s');
  360. await utils.sleep(5000)
  361. break
  362. }
  363. } else {
  364. break
  365. }
  366. tryCount -= 1
  367. } catch (error) {
  368. logger.error('withdraw_task exectransaction err', error.toString());
  369. }
  370. if (tryCount < 0) {
  371. logger.error('withdraw_task getTokenTransfersV2 警告交易未更新:', JSON.stringify(options));
  372. }
  373. } while (tryCount >= 0);
  374. }
  375. }
  376. //如果失败重试一次
  377. var tryCount = 1;
  378. for (let index = 0; index < 1 + tryCount; index++) {
  379. var result;
  380. var obj;
  381. var curGasPrice = 0;
  382. var curGasLimit = 0;
  383. var value = 0
  384. var nonce = -1
  385. try {
  386. result = await withdraw_({ ...temp_obj })
  387. last_time = utils.getTimestamp()
  388. logger.log('withdraw_task withdraw_ =', result, last_time)
  389. if (result && moralis.getTransferCode(result) == 0) {
  390. if (typeof result === 'string') {
  391. obj = JSON.parse(result)
  392. }
  393. nonce = obj.data.nonce
  394. try {
  395. curGasPrice = BigNumber(obj.data.gasPrice.hex).toNumber()
  396. curGasLimit = BigNumber(obj.data.gasLimit.hex).toNumber()
  397. //不是 czz chain
  398. if (obj.data.chainId != 2019) {
  399. value = BigNumber(obj.data.value.hex).toNumber()
  400. } else {
  401. value = obj.data.value.number
  402. }
  403. } catch (error) {
  404. logger.error('BigNumber toNumber error')
  405. }
  406. var hash = obj.data.hash
  407. last_hash = hash
  408. last_chain = temp_obj.chain
  409. var update_obj = {}
  410. update_obj.withdraw_status = 2
  411. update_obj.withdraw_hash = hash
  412. update_obj.nonce = nonce
  413. update_obj.gas_price = curGasPrice.toString()
  414. update_obj.gas_limit = curGasLimit.toString()
  415. try {
  416. update_obj.value = utils.scientificNotationToString(value).toString()
  417. } catch (error) {
  418. logger.error('scientificNotationToString error')
  419. }
  420. update_obj.errorMsg = ''
  421. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  422. break
  423. } else if (result && moralis.getTransferCode(result) == 1) {
  424. moralis.pushChainDetailTOQueue(1, exec_obj, result);
  425. break
  426. } else {
  427. logger.error('withdraw_task withdraw_ error=', result, JSON.stringify(temp_obj))
  428. if (index < 1 + tryCount && result.includes('eth_sendRawTransaction')) {
  429. logger.error('try withdraw_:', JSON.stringify(temp_obj), index)
  430. await utils.sleep(3000)
  431. continue
  432. }
  433. var update_obj = {}
  434. update_obj.withdraw_status = 3
  435. if (typeof result === 'string') {
  436. try {
  437. result = JSON.parse(result)
  438. update_obj.errorMsg = result.errMsg
  439. } catch (error) {
  440. logger.error('withdraw_task=', result)
  441. }
  442. }
  443. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  444. break
  445. }
  446. } catch (error) {
  447. var update_obj = {}
  448. update_obj.withdraw_status = 3
  449. update_obj.errorMsg = error.toString()
  450. await withdraw_db.update_withdraw_task(exec_obj.withdraw_id, update_obj)
  451. if (result)
  452. logger.error('withdraw_task error=', error.toString(), JSON.stringify(temp_obj), JSON.stringify(result))
  453. else {
  454. logger.error('withdraw_task error=', error.toString(), JSON.stringify(temp_obj))
  455. }
  456. break
  457. }
  458. }
  459. }
  460. logger.log("withdraw_task end")
  461. }
  462. /**
  463. * 队列版本
  464. * @param {*} ctx
  465. * @returns
  466. */
  467. async function withdrawV3(ctx) {
  468. logger.log('withdrawV3')
  469. if (ctx.request == null || ctx.request.body == null) {
  470. ctx.body = utils.toJson(-1, null, "request error. ");
  471. return
  472. }
  473. const obj = ctx.request.body;
  474. var log_obj = { ...obj }
  475. logger.log('withdrawV3', log_obj)
  476. var obj_ = decrypt_withdraw_content(log_obj.content)
  477. obj_.withdraw_id = obj_.withdrawId;
  478. // obj_.withdraw_id = utils.getTimestamp().toString();
  479. // var obj_ = log_obj
  480. if (obj_.withdraw_id) {
  481. var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)
  482. if (isExist) {
  483. logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')
  484. ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')
  485. return
  486. }
  487. var info = await moralis.queryCompanyInfoFromId(0);
  488. obj_.user_address = info.user_address
  489. await withdraw_db.create_withdraw_task(obj_)
  490. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  491. // withdraw_task()
  492. ctx.body = utils.toJson(0, obj_.withdraw_id, null)
  493. } else {
  494. return utils.toJson(-2, null, ' withdraw_id not empty.')
  495. }
  496. }
  497. async function withdrawV3Test(ctx) {
  498. logger.log('withdrawV3Test')
  499. if (ctx.request == null || ctx.request.body == null) {
  500. ctx.body = utils.toJson(-1, null, "request error. ");
  501. return
  502. }
  503. const obj = ctx.request.body;
  504. // for (let index = 0; index < 10; index++) {
  505. var log_obj = { ...obj }
  506. logger.log('withdrawV3', log_obj)
  507. var obj_ = decrypt_withdraw_content(log_obj.content)
  508. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  509. // var obj_ = log_obj
  510. if (obj_.withdraw_id) {
  511. var isExist = await withdraw_db.withdraw_id_exist(obj_.withdraw_id)
  512. if (isExist) {
  513. logger.error('withdraw_id_exist', obj_.withdraw_id + ' is already in the queue.')
  514. ctx.body = utils.toJson(-2, null, obj_.withdraw_id + ' is already in the queue.')
  515. return
  516. }
  517. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  518. var info = await moralis.queryCompanyInfoFromId(0);
  519. obj_.user_address = info.user_address
  520. await withdraw_db.create_withdraw_task(obj_)
  521. ctx.body = utils.toJson(0, obj_.withdraw_id, null)
  522. } else {
  523. return utils.toJson(-2, null, ' withdraw_id not empty.')
  524. }
  525. // }
  526. }
  527. function decrypt_withdraw_content(content) {
  528. // const encryptText = utils.encrypt(log_obj);
  529. const encryptText = content;
  530. logger.log("加密", encryptText);
  531. let decryptObj = utils.decrypt(encryptText);
  532. try {
  533. logger.log("解密 before", decryptObj);
  534. decryptObj = JSON.parse(decryptObj);
  535. console.log("解密 json parse", decryptObj);
  536. } catch (error) {
  537. logger.error("json error:", error);
  538. decryptObj = null;
  539. }
  540. return decryptObj;
  541. }
  542. /**
  543. *
  544. * @param {鉴权版本} ctx
  545. */
  546. async function withdrawV2(ctx) {
  547. if (ctx.request == null || ctx.request.body == null) {
  548. ctx.body = utils.toJson(-1, null, "request error. ");
  549. return
  550. }
  551. const obj = ctx.request.body;
  552. var log_obj = { ...obj }
  553. // const encryptText = utils.encrypt(log_obj);
  554. const encryptText = log_obj.content;
  555. logger.log("加密", encryptText);
  556. let decryptObj = utils.decrypt(encryptText);
  557. try {
  558. logger.log("解密 before", decryptObj);
  559. decryptObj = JSON.parse(decryptObj);
  560. // console.log("解密 json parse", decryptObj);
  561. await withdraw_(decryptObj).then(result => {
  562. ctx.body = result;
  563. })
  564. } catch (error) {
  565. logger.error("json error:", error);
  566. ctx.body = utils.toJson(-1, null, error.toString());
  567. }
  568. }
  569. async function withdraw_(obj) {
  570. console.log("withdraw_", obj);
  571. var log_obj = { ...obj }
  572. var info = await moralis.queryCompanyInfoFromId(0);
  573. // log_obj.company_address_total_balance_before = await moralis.queryCollectBalance(info.user_address, obj.chain)
  574. log_obj.company_public_key = info.user_address
  575. logger.log('withdraw log', log_obj);
  576. return new Promise((resolve) => {
  577. moralis.withdraw(obj).then((result) => {
  578. if (moralis.getTransferCode(result) == 0) {
  579. //提币日志上报
  580. log_obj.results = result
  581. log_obj.type = report.REPORT_TYPE.withdraw
  582. //缓存当前交易的 gas 费用
  583. if (result && log_obj.contractAddress) {
  584. var tr = moralis.getTransferGasFree('token', result)
  585. log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()
  586. } else {
  587. var tr = moralis.getTransferGasFree('native', result)
  588. log_obj.withdrawTotalGasFee = tr.totalGasFree.toString()
  589. }
  590. //日志上报
  591. report.logReport(log_obj)
  592. }
  593. resolve(result)
  594. });
  595. })
  596. }
  597. //出金
  598. async function withdraw(ctx) {
  599. if (ctx.request == null || ctx.request.body == null) {
  600. ctx.body = utils.toJson(-1, null, "request error. ");
  601. return
  602. }
  603. const obj = ctx.request.body;
  604. await withdraw_(obj).then(result => {
  605. ctx.body = result;
  606. })
  607. }
  608. /**
  609. * 查询出金状态
  610. * @param {*} ctx
  611. */
  612. async function getWithdrawStatus(ctx) {
  613. if (ctx.request == null || ctx.request.body == null) {
  614. ctx.body = utils.toJson(-1, null, "request error. ");
  615. return
  616. }
  617. const obj = ctx.request.body;
  618. var info = await withdraw_db.queryWithdrawInfoFromWithdrawId(obj.withdrawId)
  619. logger.log('getWithdrawStatus info', JSON.stringify(info))
  620. if (info) {
  621. if (info.withdraw_status != 3) {
  622. ctx.body = utils.toJson(0, {
  623. withdrawId: info.withdraw_id,
  624. withdrawStatus: info.withdraw_status,
  625. withdrawHash: info.withdraw_hash,
  626. chainId: info.chain_id,
  627. transferTimestamp: info.update_time,
  628. }, null)
  629. } else {
  630. ctx.body = utils.toJson(0, {
  631. withdrawId: info.withdraw_id,
  632. withdrawStatus: info.withdraw_status,
  633. withdrawHash: info.withdraw_hash,
  634. chainId: info.chain_id,
  635. transferTimestamp: info.update_time,
  636. errorMsg: info.errorMsg
  637. }, info.errorMsg)
  638. }
  639. } else {
  640. ctx.body = utils.toJson(-1, null, obj.withdraw_id + ' id does not exist.')
  641. }
  642. }
  643. async function timer_collect_conis_bsc_task() {
  644. var index = 0
  645. var delay = 60 * 1000 * 60
  646. while (1) {
  647. var temp_obj = {
  648. "chain": "bsc_testnet",
  649. "address": "0x3B525c35DdC323B08241493f148340D89e3A73a7"
  650. }
  651. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  652. await utils.sleep(delay)
  653. index += 1
  654. }
  655. }
  656. async function timer_collect_conis_czz_task() {
  657. var index = 0
  658. var delay = 60 * 1000 * 60
  659. while (1) {
  660. var temp_obj = {
  661. "chain": "czz",
  662. "address": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076",
  663. }
  664. redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
  665. await utils.sleep(delay)
  666. index += 1
  667. }
  668. }
  669. async function timer_transfer_bsc_task() {
  670. var index = 0
  671. var delay = 60 * 1000 * 60
  672. while (1) {
  673. var obj_ = {
  674. "type": "erc20",
  675. "contractAddress": "0xFF94950Ee8A79c52cC4B0Aa5178C8cEa48A3F3A6",
  676. "amount": "123000000000000000000",
  677. "chain": "bsc_testnet",
  678. "receiver": "0x3B525c35DdC323B08241493f148340D89e3A73a7",
  679. "withdrawId": index.toString()
  680. }
  681. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  682. var info = await moralis.queryCompanyInfoFromId(0);
  683. obj_.user_address = info.user_address
  684. await withdraw_db.create_withdraw_task(obj_)
  685. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  686. await utils.sleep(delay)
  687. index += 1
  688. }
  689. }
  690. async function timer_transfer_czz_task() {
  691. var index = 0
  692. var delay = 60 * 1000 * 60
  693. while (1) {
  694. var obj_ = {
  695. "type": "erc20",
  696. "contractAddress": "0xfb16179d5e84b0e3e7524ed61a9cf7b98d039b20",
  697. "amount": "100000000000000000000",
  698. "chain": "czz",
  699. "receiver": "0x39ACD9CC975D792D8160215Dc84fa00E4934F076"
  700. }
  701. obj_.withdraw_id = utils.getCurrentDateFormat('YYYY-MM-DD-HH:mm:ss:SSS').toString()
  702. var info = await moralis.queryCompanyInfoFromId(0);
  703. obj_.user_address = info.user_address
  704. await withdraw_db.create_withdraw_task(obj_)
  705. redis.redis_push(reids_token_config.WITHDRAW_QUEUE_KEY, JSON.stringify(obj_))
  706. await utils.sleep(delay)
  707. index += 1
  708. }
  709. }
  710. async function checkout_taxhash(exec_obj) {
  711. logger.info('bsc_log_monitoring exec start:', exec_obj)
  712. var delay = 60 * 1000
  713. try {
  714. if (typeof exec_obj === 'string')
  715. exec_obj = JSON.parse(exec_obj)
  716. } catch (error) {
  717. logger.error('bsc_log_monitoring:', error)
  718. }
  719. var tryCount = 5
  720. do {
  721. if (tryCount == 0) {
  722. logger.error('数据在5分钟未更新', JSON.stringify(exec_obj))
  723. break
  724. }
  725. if (exec_obj.transactionHash) {
  726. var ret = await account_mysql.getAccountTransactions({
  727. type: 'only_hash',
  728. transaction_hash: exec_obj.transactionHash
  729. })
  730. if (ret && ret.code == 0 && ret.data.total > 0) {
  731. break
  732. }
  733. }
  734. --tryCount
  735. logger.debug('getAccountTransactions', tryCount, exec_obj)
  736. await utils.sleep(delay)
  737. } while (tryCount >= 0);
  738. }
  739. async function bsc_log_monitoring() {
  740. while (1) {
  741. var exec_obj = await redis.redis_pop(reids_token_config.BSC_LOG_MONITORING_KEY)
  742. if (!exec_obj) {
  743. await utils.sleep(10000)
  744. logger.log("no new check tasks")
  745. continue
  746. }
  747. checkout_taxhash(exec_obj)
  748. }
  749. }
  750. //获取交易记录
  751. router.post('/getTransfers', getTransfers)
  752. router.post('/getTransfersV2', getTransfersV2)
  753. // 获取所有代币价格
  754. router.post('/getAllTotkenPrice', getAllTotkenPrice)
  755. router.post('/getAllTokenPrice', getAllTokenPrice)
  756. // router.post('/transfer', transfer)
  757. //提现
  758. router.post('/withdraw', withdraw);
  759. //提现鉴权-body 加密
  760. router.post('/withdrawV2', withdrawV2);
  761. //队列的形式
  762. router.post('/withdrawV3', withdrawV3);
  763. // if (process.env.NODE_ENV == 'dev' || process.env.NODE_ENV == 'test') {
  764. router.post('/withdrawV3Test', withdrawV3Test);
  765. // }
  766. //查询出金服务
  767. router.post('/getWithdrawStatus', getWithdrawStatus);
  768. //获取所有地址的所要消耗的最低提取费
  769. router.post('/getAllTokenWithdrawInfoLists', getAllTokenWithdrawInfoLists)
  770. router.get('/report2FeishuTable', async (ctx) => {
  771. ctx.body = await stat.report2FeishuTable()
  772. })
  773. // 定时任务 提币+归集
  774. withdraw_task();
  775. collect_conis_task();
  776. //czz 504 检查
  777. check_czz_withdraw_task();
  778. // bsc 监控
  779. bsc_log_monitoring()
  780. if (process.env.NODE_ENV == 'dev' || process.env.NODE_ENV == 'test') {
  781. timer_transfer_bsc_task()
  782. timer_transfer_czz_task()
  783. timer_collect_conis_bsc_task()
  784. timer_collect_conis_czz_task()
  785. }
  786. module.exports = router