sdk.js 38 KB

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