From 7d3cd73afcc4da369d8659e66783c51a64f4b691 Mon Sep 17 00:00:00 2001 From: CounterFire2023 <136581895+CounterFire2023@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:07:48 +0800 Subject: [PATCH] reformat code --- src/api.server.ts | 17 +- src/common/LotteryCache.ts | 32 ++-- src/common/SyncLocker.ts | 28 ++-- src/configs/boost.ts | 12 +- src/configs/fusion.ts | 4 +- src/configs/items.ts | 2 +- src/configs/lottery.ts | 20 ++- src/controllers/activity.controller.ts | 39 +++-- src/controllers/chain.controller.ts | 50 +++--- src/controllers/lottery.controller.ts | 215 +++++++++++++------------ src/controllers/sign.controller.ts | 94 +++++------ src/controllers/tasks.controller.ts | 161 +++++++++--------- src/initdata.ts | 4 +- src/models/ActivityInfo.ts | 20 ++- src/models/ActivityItem.ts | 17 +- src/models/ActivityUser.ts | 37 +++-- src/models/Base.ts | 4 +- src/models/LoginRecord.ts | 5 +- src/models/LotteryRecord.ts | 23 +-- src/models/LotteryStats.ts | 32 ++-- src/models/NFTBrunRecord.ts | 14 +- src/models/NonceRecord.ts | 1 - src/models/ScoreRecord.ts | 14 +- src/models/TokenClaimHistory.ts | 19 ++- src/models/chain/CheckIn.ts | 20 +-- src/models/chain/NftHolder.ts | 14 +- src/models/chain/NftStake.ts | 19 ++- src/schedule/cache.schedule.ts | 9 +- src/schedule/noncerecord.schedule.ts | 6 +- src/services/chain.svr.ts | 38 ++--- src/services/oauth.svr.ts | 15 +- src/services/rank.svr.ts | 48 +++--- src/tasks/BurnNft.ts | 32 ++-- src/tasks/DailyCheckIn.ts | 60 +++---- src/tasks/DiscordConnect.ts | 21 ++- src/tasks/DiscordJoin.ts | 21 ++- src/tasks/DiscordRole.ts | 21 ++- src/tasks/OkxLogin.ts | 25 ++- src/tasks/ShareCode.ts | 59 +++---- src/tasks/TwitterConnect.ts | 22 ++- src/tasks/TwitterFollow.ts | 21 ++- src/tasks/TwitterRetweet.ts | 19 ++- src/tasks/YoutubeFollow.ts | 21 ++- src/tasks/YoutubePost.ts | 19 ++- src/tasks/base/ITask.ts | 30 ++-- src/utils/chain.util.ts | 43 ++--- src/utils/date.util.ts | 26 +-- src/utils/net.util.ts | 10 +- src/utils/nft.util.ts | 4 - src/utils/number.util.ts | 202 +++++++++++------------ src/utils/security.util.ts | 69 ++++---- 51 files changed, 890 insertions(+), 868 deletions(-) diff --git a/src/api.server.ts b/src/api.server.ts index 40176ff..5eeaee3 100644 --- a/src/api.server.ts +++ b/src/api.server.ts @@ -162,13 +162,16 @@ export class ApiServer { self.setErrHandler() self.setFormatSend() self.initSchedules() - this.server.listen({ port: parseInt(process.env.API_PORT), host: process.env.API_HOST }, (err: any, address: any) => { - if (err) { - logger.log(err) - process.exit(0) - } - resolve && resolve(address) - }) + this.server.listen( + { port: parseInt(process.env.API_PORT), host: process.env.API_HOST }, + (err: any, address: any) => { + if (err) { + logger.log(err) + process.exit(0) + } + resolve && resolve(address) + }, + ) }) } } diff --git a/src/common/LotteryCache.ts b/src/common/LotteryCache.ts index 26a069a..219d244 100644 --- a/src/common/LotteryCache.ts +++ b/src/common/LotteryCache.ts @@ -1,32 +1,32 @@ -import { singleton } from "decorators/singleton"; -import { LotteryStats } from "models/LotteryStats"; -import { formatDate } from "utils/date.util"; +import { singleton } from 'decorators/singleton' +import { LotteryStats } from 'models/LotteryStats' +import { formatDate } from 'utils/date.util' -const EXPIRE_TIME = 1000 * 60 * 60; +const EXPIRE_TIME = 1000 * 60 * 60 @singleton export class LotteryCache { - map: Map = new Map(); - lastUsed: Map = new Map(); + map: Map = new Map() + lastUsed: Map = new Map() public async getData(user: string, activity: string) { - const dateTag = formatDate(new Date()); - if (!this.map.has(user+dateTag)) { - const record = await LotteryStats.insertOrUpdate({user, activity, dateTag}, {}) - this.map.set(user+dateTag, record); + const dateTag = formatDate(new Date()) + if (!this.map.has(user + dateTag)) { + const record = await LotteryStats.insertOrUpdate({ user, activity, dateTag }, {}) + this.map.set(user + dateTag, record) } - this.lastUsed.set(user+dateTag, Date.now()); - return this.map.get(user+dateTag); + this.lastUsed.set(user + dateTag, Date.now()) + return this.map.get(user + dateTag) } public async flush() { for (let [key, record] of this.map.entries()) { // record.modifiedPaths() if (record.isModified()) { - await record.save(); + await record.save() } if (Date.now() - this.lastUsed.get(key) > EXPIRE_TIME) { - this.map.delete(key); - this.lastUsed.delete(key); + this.map.delete(key) + this.lastUsed.delete(key) } } } -} \ No newline at end of file +} diff --git a/src/common/SyncLocker.ts b/src/common/SyncLocker.ts index 65dcf59..2048ee4 100644 --- a/src/common/SyncLocker.ts +++ b/src/common/SyncLocker.ts @@ -1,36 +1,36 @@ -import { singleton } from "decorators/singleton"; -import { FastifyRequest } from "fastify"; -import { ZError } from "./ZError"; +import { singleton } from 'decorators/singleton' +import { FastifyRequest } from 'fastify' +import { ZError } from './ZError' @singleton export class SyncLocker { - map: Map = new Map(); + map: Map = new Map() public lock(req: FastifyRequest) { const key = `${req.method}:${req.url}:${req.user?.id || ''}` if (this.map.has(key)) { - return false; + return false } - this.map.set(key, true); - return true; + this.map.set(key, true) + return true } - + public unlock(req: FastifyRequest) { const key = `${req.method}:${req.url}:${req.user?.id || ''}` - this.map.delete(key); + this.map.delete(key) } public checkLock(req: FastifyRequest) { const key = `${req.method}:${req.url}:${req.user?.id || ''}` if (this.map.has(key)) { - throw new ZError(100, 'request too fast'); + throw new ZError(100, 'request too fast') } - this.lock(req); - return true; + this.lock(req) + return true } public isLocked(req: FastifyRequest) { const key = `${req.method}:${req.url}:${req.user?.id || ''}` - return this.map.has(key); + return this.map.has(key) } -} \ No newline at end of file +} diff --git a/src/configs/boost.ts b/src/configs/boost.ts index 4f8be37..4f645aa 100644 --- a/src/configs/boost.ts +++ b/src/configs/boost.ts @@ -1,20 +1,20 @@ -const ROUND = 1000000; +const ROUND = 1000000 export const BOOST_CFG = [ { value: 2, - probability: 500000 + probability: 500000, }, { value: 3, - probability: 300000 + probability: 300000, }, { value: 4, - probability: 150000 + probability: 150000, }, { value: 5, - probability: 50000 + probability: 50000, }, -] \ No newline at end of file +] diff --git a/src/configs/fusion.ts b/src/configs/fusion.ts index 2cab3f3..f2e063b 100644 --- a/src/configs/fusion.ts +++ b/src/configs/fusion.ts @@ -24,5 +24,5 @@ export const FUSION_CFG = { id: 'kindle', amount: 1, }, - ] -} \ No newline at end of file + ], +} diff --git a/src/configs/items.ts b/src/configs/items.ts index eca16e7..df295f3 100644 --- a/src/configs/items.ts +++ b/src/configs/items.ts @@ -35,6 +35,6 @@ export const ALL_ITEMS: IItem[] = [ }, { id: 'torch', - name: 'Torch' + name: 'Torch', }, ] diff --git a/src/configs/lottery.ts b/src/configs/lottery.ts index d338b2e..0129e05 100644 --- a/src/configs/lottery.ts +++ b/src/configs/lottery.ts @@ -1,4 +1,3 @@ - export const LOTTERY_CFG = { start: '2024-01-01 00:00:00', end: '2025-01-01 00:00:00', @@ -6,38 +5,37 @@ export const LOTTERY_CFG = { { item: 'usdt', amount: 20, - probability: 10000 + probability: 10000, }, { item: 'flame', amount: 30, - probability: 300000 + probability: 300000, }, { item: 'thunder', amount: 1, - probability: 170000 + probability: 170000, }, { item: 'light', amount: 1, - probability: 180000 + probability: 180000, }, { item: 'spark', amount: 1, - probability: 130000 + probability: 130000, }, { item: 'blaze', amount: 1, - probability: 100000 + probability: 100000, }, { item: 'kindle', amount: 1, - probability: 10000 + probability: 10000, }, - - ] -} \ No newline at end of file + ], +} diff --git a/src/controllers/activity.controller.ts b/src/controllers/activity.controller.ts index deae0af..f9f0998 100644 --- a/src/controllers/activity.controller.ts +++ b/src/controllers/activity.controller.ts @@ -1,16 +1,15 @@ -import { SyncLocker } from "common/SyncLocker"; -import { ZError } from "common/ZError"; -import BaseController, { ROLE_ANON } from "common/base.controller"; -import { role, router } from "decorators/router"; -import { ActivityInfo } from "models/ActivityInfo"; -import { ActivityUser } from "models/ActivityUser"; -import { RedisClient } from "redis/RedisClient"; -import { rankKey } from "services/rank.svr"; -import { yesterday } from "utils/date.util"; +import { SyncLocker } from 'common/SyncLocker' +import { ZError } from 'common/ZError' +import BaseController, { ROLE_ANON } from 'common/base.controller' +import { role, router } from 'decorators/router' +import { ActivityInfo } from 'models/ActivityInfo' +import { ActivityUser } from 'models/ActivityUser' +import { RedisClient } from 'redis/RedisClient' +import { rankKey } from 'services/rank.svr' +import { yesterday } from 'utils/date.util' const MAX_LIMIT = 50 export default class ActivityController extends BaseController { - @role(ROLE_ANON) @router('get /api/activity/:id') async info(req) { @@ -27,14 +26,14 @@ export default class ActivityController extends BaseController { /** * 更新邀请码 - * @param req - * @returns + * @param req + * @returns */ @router('post /api/activity/upload_invite_code') async uploadInviteCode(req) { - new SyncLocker().checkLock(req); + new SyncLocker().checkLock(req) let { code } = req.params - let user = req.user; + let user = req.user if (user.inviteUser) { throw new ZError(11, 'already set invite user') } @@ -58,8 +57,8 @@ export default class ActivityController extends BaseController { const end = start + limit - 1 const records = await new RedisClient().zrevrange(`${activity}:score`, start, end) let results: any = [] - const yesterdayKey = rankKey(activity, yesterday()); - for (let i = 0; i < records.length; i+=2) { + const yesterdayKey = rankKey(activity, yesterday()) + for (let i = 0; i < records.length; i += 2) { const id = records[i] let score = parseInt(records[i + 1]) const user = await ActivityUser.findById(id) @@ -76,9 +75,9 @@ export default class ActivityController extends BaseController { address: user?.address || 'unknow', invite, score, - yesterday: yesterdayScore ? parseInt(yesterdayScore+'') : 0 + yesterday: yesterdayScore ? parseInt(yesterdayScore + '') : 0, }) } - return results; - } -} \ No newline at end of file + return results + } +} diff --git a/src/controllers/chain.controller.ts b/src/controllers/chain.controller.ts index 67ebaa3..7c483b2 100644 --- a/src/controllers/chain.controller.ts +++ b/src/controllers/chain.controller.ts @@ -1,44 +1,46 @@ +import { SyncLocker } from 'common/SyncLocker' +import { ZError } from 'common/ZError' +import BaseController from 'common/base.controller' +import { router } from 'decorators/router' +import { FastifyRequest } from 'fastify' +import { ActivityItem } from 'models/ActivityItem' +import { TokenClaimHistory } from 'models/TokenClaimHistory' +import { queryStakeList } from 'services/chain.svr' +import { sign } from 'utils/chain.util' -import { SyncLocker } from "common/SyncLocker"; -import { ZError } from "common/ZError"; -import BaseController from "common/base.controller"; -import { router } from "decorators/router"; -import { FastifyRequest } from "fastify"; -import { ActivityItem } from "models/ActivityItem"; -import { TokenClaimHistory } from "models/TokenClaimHistory"; -import { queryStakeList } from "services/chain.svr"; -import { sign } from "utils/chain.util"; - - -const MAX_LIMIT = 50 export default class ChainController extends BaseController { - @router('get /api/stake/list') async stakeList(req) { - const user = req.user; + const user = req.user const records = await queryStakeList(user.address) - const result = records.map((r) => r.toJson()) + const result = records.map(r => r.toJson()) return result } @router('post /api/lottery/claim_usdt') async preClaimUsdt(req: FastifyRequest) { - new SyncLocker().checkLock(req); - let user = req.user; + new SyncLocker().checkLock(req) + let user = req.user if (user.address) { throw new ZError(11, 'no address') } const minClaimNum = +process.env.MINI_CLAIM_USDT - const record = await ActivityItem.findOne({user: user.id, activity: user.activity, item: 'usdt'}) + const record = await ActivityItem.findOne({ user: user.id, activity: user.activity, item: 'usdt' }) if (!record || record.amount < minClaimNum) { throw new ZError(10, 'no enough usdt') } - const amount = record.amount + ''; - record.amount = 0; + const amount = record.amount + '' + record.amount = 0 await record.save() - const token = process.env.USDT_CONTRACT; - const history = await TokenClaimHistory.addOne({user: user.id, activity: user.activity, address: user.address, token, amount}) - const res = await sign({user: user.address, token, amount, saltNonce: history.id}) + const token = process.env.USDT_CONTRACT + const history = await TokenClaimHistory.addOne({ + user: user.id, + activity: user.activity, + address: user.address, + token, + amount, + }) + const res = await sign({ user: user.address, token, amount, saltNonce: history.id }) return res } -} \ No newline at end of file +} diff --git a/src/controllers/lottery.controller.ts b/src/controllers/lottery.controller.ts index 7ed3d3f..db7f343 100644 --- a/src/controllers/lottery.controller.ts +++ b/src/controllers/lottery.controller.ts @@ -1,78 +1,77 @@ -import { EMPTY_REWARD, ITEM_FRAME } from "common/Constants"; -import { LotteryCache } from "common/LotteryCache"; -import { SyncLocker } from "common/SyncLocker"; -import { ZError } from "common/ZError"; -import BaseController from "common/base.controller"; -import { FUSION_CFG } from "configs/fusion"; -import { ALL_ITEMS } from "configs/items"; -import { LOTTERY_CFG } from "configs/lottery"; -import { router } from "decorators/router"; -import { FastifyRequest } from "fastify"; -import { ActivityItem } from "models/ActivityItem"; -import { LotteryRecord } from "models/LotteryRecord"; -import { updateRankScore } from "services/rank.svr"; -import { formatDate } from "utils/date.util"; +import { EMPTY_REWARD, ITEM_FRAME } from 'common/Constants' +import { LotteryCache } from 'common/LotteryCache' +import { SyncLocker } from 'common/SyncLocker' +import { ZError } from 'common/ZError' +import BaseController from 'common/base.controller' +import { FUSION_CFG } from 'configs/fusion' +import { ALL_ITEMS } from 'configs/items' +import { LOTTERY_CFG } from 'configs/lottery' +import { router } from 'decorators/router' +import { FastifyRequest } from 'fastify' +import { ActivityItem } from 'models/ActivityItem' +import { LotteryRecord } from 'models/LotteryRecord' +import { updateRankScore } from 'services/rank.svr' +import { formatDate } from 'utils/date.util' -const ROUND = 1000000; +const ROUND = 1000000 // Get random prizes according to the set probability -const draw = (rewards: {probability: number}[]) => { - let total = 0; - let random = Math.floor(Math.random() * ROUND); - let reward = null; +const draw = (rewards: { probability: number }[]) => { + let total = 0 + let random = Math.floor(Math.random() * ROUND) + let reward = null for (let r of rewards) { - total += r.probability; + total += r.probability if (random < total) { - reward = r; - break; + reward = r + break } } - return {id: reward?.item || EMPTY_REWARD, amount: reward?.amount || 1}; + return { id: reward?.item || EMPTY_REWARD, amount: reward?.amount || 1 } } export default class LotteryController extends BaseController { @router('get /api/lottery/stats') async userStats(req) { - let user = req.user; - let record = await new LotteryCache().getData(user.id, user.activity); - let result:any = record.toJson(); - let items = await ActivityItem.find({user: user.id, activity: user.activity}); - result.items = items.map((i) => i.toJson()); - return result; + let user = req.user + let record = await new LotteryCache().getData(user.id, user.activity) + let result: any = record.toJson() + let items = await ActivityItem.find({ user: user.id, activity: user.activity }) + result.items = items.map(i => i.toJson()) + return result } @router('post /api/lottery/history') async userLotteryHistory(req) { - let user = req.user; - let { day, page, limit } = req.params; - const query: any = {user: user.id, activity: user.activity}; + let user = req.user + let { day, page, limit } = req.params + const query: any = { user: user.id, activity: user.activity } if (day !== 'all') { - query.dateTag = day; + query.dateTag = day } page = +page || 1 limit = +limit || 10 let start = page * limit || 0 - - let historys = await LotteryRecord.find(query).skip(start).limit(limit); - let total = await LotteryRecord.countDocuments(query); + let historys = await LotteryRecord.find(query).skip(start).limit(limit) + let total = await LotteryRecord.countDocuments(query) return { count: total, page: +page, limit, - records: historys.map((h) => h.toJson()) + records: historys.map(h => h.toJson()), } } @router('get /api/lottery/items') async items(req) { - const items = ALL_ITEMS; - const cfgs = LOTTERY_CFG; - const itemMap = new Map(); + const items = ALL_ITEMS + const cfgs = LOTTERY_CFG + const itemMap = new Map() for (let item of items) { - itemMap.set(item.id, item); + itemMap.set(item.id, item) } - let result = []; + let result = [] for (let cfg of cfgs.rewards) { result.push({ id: cfg.item, @@ -80,47 +79,46 @@ export default class LotteryController extends BaseController { name: itemMap.get(cfg.item).name, }) } - return {items: result, start: cfgs.start, end: cfgs.end}; + return { items: result, start: cfgs.start, end: cfgs.end } } - @router('get /api/lottery/draw') async draw(req) { - new SyncLocker().checkLock(req); - let user = req.user; - const { start, end, rewards } = LOTTERY_CFG; - const startTime = new Date(start).getTime(); - const endTime = new Date(end).getTime(); - const now = Date.now(); + new SyncLocker().checkLock(req) + let user = req.user + const { start, end, rewards } = LOTTERY_CFG + const startTime = new Date(start).getTime() + const endTime = new Date(end).getTime() + const now = Date.now() if (now < startTime) { - throw new ZError(10, 'lottery not start'); + throw new ZError(10, 'lottery not start') } if (now > endTime) { - throw new ZError(11, 'lottery end'); + throw new ZError(11, 'lottery end') } - let record = await new LotteryCache().getData(user.id, user.activity); + let record = await new LotteryCache().getData(user.id, user.activity) if (record.amount <= 0) { - throw new ZError(12, 'no chance'); + throw new ZError(12, 'no chance') } - record.amount -= 1; - record.used += 1; - let reward = draw(rewards); - const dateTag = formatDate(new Date()); + record.amount -= 1 + record.used += 1 + let reward = draw(rewards) + const dateTag = formatDate(new Date()) let history = new LotteryRecord({ user: user.id, activity: user.activity, dateTag, reward: reward?.id || EMPTY_REWARD, amount: reward.amount || 0, - }); - await history.save(); - const items = ALL_ITEMS; - const itemMap = new Map(); + }) + await history.save() + const items = ALL_ITEMS + const itemMap = new Map() for (let item of items) { - itemMap.set(item.id, item); + itemMap.set(item.id, item) } if (itemMap.get(reward.id)?.score) { - let score = (reward?.amount || 0) * itemMap.get(reward.id).score; + let score = (reward?.amount || 0) * itemMap.get(reward.id).score if (user.boost > 1 && Date.now() < user.boostExpire) { score = Math.floor(score * user.boost) } @@ -128,67 +126,72 @@ export default class LotteryController extends BaseController { user: user.id, score, activity: user.activity, - scoreType: "draw", + scoreType: 'draw', scoreParams: { - date: dateTag - } + date: dateTag, + }, }) - } - await ActivityItem.insertOrUpdate({ - user: user.id, - activity: user.activity, - item: reward.id - }, - { - $inc: {amount: reward.amount}, - last: Date.now() - }) - return reward; + } + await ActivityItem.insertOrUpdate( + { + user: user.id, + activity: user.activity, + item: reward.id, + }, + { + $inc: { amount: reward.amount }, + last: Date.now(), + }, + ) + return reward } @router('get /api/lottery/fusion') async fusion(req) { - new SyncLocker().checkLock(req); - let user = req.user; - let items = await ActivityItem.find({user: user.id, activity: user.activity}); - let itemCountMap = new Map(); + new SyncLocker().checkLock(req) + let user = req.user + let items = await ActivityItem.find({ user: user.id, activity: user.activity }) + let itemCountMap = new Map() for (let item of items) { - itemCountMap.set(item.item, item.amount); + itemCountMap.set(item.item, item.amount) } for (let item of FUSION_CFG.source) { if (!itemCountMap.has(item.id)) { - throw new ZError(13, 'no enough item'); + throw new ZError(13, 'no enough item') } if (itemCountMap.get(item.id) < item.amount) { - throw new ZError(14, 'no enough item'); + throw new ZError(14, 'no enough item') } } for (let item of FUSION_CFG.source) { - await ActivityItem.insertOrUpdate({ - user: user.id, - activity: user.activity, - item: item.id - }, - { - $inc: {amount: -item.amount}, - last: Date.now() - }) + await ActivityItem.insertOrUpdate( + { + user: user.id, + activity: user.activity, + item: item.id, + }, + { + $inc: { amount: -item.amount }, + last: Date.now(), + }, + ) } - await ActivityItem.insertOrUpdate({ - user: user.id, - activity: user.activity, - item: FUSION_CFG.target.id - }, - { - $inc: {amount: FUSION_CFG.target.amount}, - last: Date.now() - }) - + await ActivityItem.insertOrUpdate( + { + user: user.id, + activity: user.activity, + item: FUSION_CFG.target.id, + }, + { + $inc: { amount: FUSION_CFG.target.amount }, + last: Date.now(), + }, + ) + return { id: FUSION_CFG.target.id, amount: FUSION_CFG.target.amount, } } - -} \ No newline at end of file +} diff --git a/src/controllers/sign.controller.ts b/src/controllers/sign.controller.ts index fce8ace..846ed5b 100644 --- a/src/controllers/sign.controller.ts +++ b/src/controllers/sign.controller.ts @@ -1,33 +1,33 @@ -import BaseController, {ROLE_ANON} from 'common/base.controller' +import BaseController, { ROLE_ANON } from 'common/base.controller' import { SyncLocker } from 'common/SyncLocker' -import {ZError} from 'common/ZError' +import { ZError } from 'common/ZError' import { BOOST_CFG } from 'configs/boost' import { role, router } from 'decorators/router' import logger from 'logger/logger' import { ActivityUser } from 'models/ActivityUser' -import {DEFAULT_EXPIRED, NonceRecord} from 'models/NonceRecord' +import { DEFAULT_EXPIRED, NonceRecord } from 'models/NonceRecord' import { ScoreRecord } from 'models/ScoreRecord' import { LoginRecordQueue } from 'queue/loginrecord.queue' import { RedisClient } from 'redis/RedisClient' import { queryCheckInList } from 'services/chain.svr' import { rankKey } from 'services/rank.svr' -import {SiweMessage} from 'siwe' +import { SiweMessage } from 'siwe' import { nextday, yesterday } from 'utils/date.util' import { checkParamsNeeded } from 'utils/net.util' import { aesDecrypt, base58ToHex } from 'utils/security.util' const LOGIN_TIP = 'This signature is just to verify your identity' -const ROUND = 1000000; -const generateBoost = (rewards: {probability: number}[]) => { - let total = 0; - let random = Math.floor(Math.random() * ROUND); - let reward = null; +const ROUND = 1000000 +const generateBoost = (rewards: { probability: number }[]) => { + let total = 0 + let random = Math.floor(Math.random() * ROUND) + let reward = null for (let r of rewards) { - total += r.probability; + total += r.probability if (random < total) { - reward = r; - break; + reward = r + break } } return reward.value @@ -48,19 +48,19 @@ class SignController extends BaseController { const { signature, message, activity } = req.params checkParamsNeeded(signature, message) if (!message.nonce) { - throw new ZError(11, 'Invalid nonce'); + throw new ZError(11, 'Invalid nonce') } let nonce = message.nonce let source = 'unknow' if (nonce.length > 24) { - nonce = base58ToHex(nonce); - let nonceStr = aesDecrypt(nonce, activity); - if (nonceStr.indexOf('|') >=0 ) { + nonce = base58ToHex(nonce) + let nonceStr = aesDecrypt(nonce, activity) + if (nonceStr.indexOf('|') >= 0) { const split = nonceStr.split('|') - nonce = split[0]; - source = split[1]; + nonce = split[0] + source = split[1] } else { - nonce = nonceStr; + nonce = nonceStr } } let record = await NonceRecord.findById(nonce) @@ -75,9 +75,9 @@ class SignController extends BaseController { } record.status = 1 await record.save() - const msgSign = new SiweMessage(message); + const msgSign = new SiweMessage(message) try { - await msgSign.verify({ signature, nonce: message.nonce }); + await msgSign.verify({ signature, nonce: message.nonce }) } catch (e) { throw new ZError(15, 'signature invalid') } @@ -92,16 +92,20 @@ class SignController extends BaseController { await accountData.save() new LoginRecordQueue().addLog(req, accountData.id, activity, source) - const token = await res.jwtSign({ id: accountData.id, address: accountData.address, activity: accountData.activity }) + const token = await res.jwtSign({ + id: accountData.id, + address: accountData.address, + activity: accountData.activity, + }) return { token } } @router('get /api/user/state') - async userInfo(req){ - const user = req.user; - const todayKey = rankKey(user.activity, new Date()); + async userInfo(req) { + const user = req.user + const todayKey = rankKey(user.activity, new Date()) const todayScore = await new RedisClient().zscore(todayKey, user.id) - const totalKey = rankKey(user.activity); + const totalKey = rankKey(user.activity) const totalScore = await new RedisClient().zscore(totalKey, user.id) const totalRank = await new RedisClient().zrevrank(totalKey, user.id) let invite = '' @@ -112,9 +116,9 @@ class SignController extends BaseController { } } const records = await ScoreRecord.find({ user: user.id, activity: user.activity, scoreType: 'invite' }) - let score = 0; + let score = 0 for (let record of records) { - score += record.score; + score += record.score } let result = { address: user.address, @@ -124,34 +128,34 @@ class SignController extends BaseController { twitterName: user.twitterName, discordId: user.discordId, discordName: user.discordName, - scoreToday: todayScore ? parseInt(todayScore+'') : 0, - scoreTotal: totalScore ? parseInt(totalScore+'') : 0, + scoreToday: todayScore ? parseInt(todayScore + '') : 0, + scoreTotal: totalScore ? parseInt(totalScore + '') : 0, rankTotal: totalRank ? totalRank : '-', invite, inviteCount: records.length, inviteScore: score, code: user.inviteCode, } - return result; + return result } @router('get /api/user/state/boost') - async boost(req){ - new SyncLocker().checkLock(req); - const user = req.user; + async boost(req) { + new SyncLocker().checkLock(req) + const user = req.user if (user.boost > 1 && user.boostExpire && user.boostExpire > Date.now()) { throw new ZError(11, 'already boosted') } user.boost = generateBoost(BOOST_CFG) - user.boostExpire = nextday(); - await user.save(); - return { boost: user.boost, boostExpire: user.boostExpire }; + user.boostExpire = nextday() + await user.save() + return { boost: user.boost, boostExpire: user.boostExpire } } @router('get /api/user/checkin/list/:tag') - async checkInList(req){ - const user = req.user; - const {tag} = req.params; - let days: any = 1; + async checkInList(req) { + const user = req.user + const { tag } = req.params + let days: any = 1 if (tag === '1month') { days = '1month' } else if (tag === 'last') { @@ -161,13 +165,12 @@ class SignController extends BaseController { return res.data } - /** * regist user by token from wallet-svr * TODO:: - * @param req - * @param res - * @returns + * @param req + * @param res + * @returns */ @role(ROLE_ANON) @router('post /api/wallet/verify_token') @@ -175,5 +178,4 @@ class SignController extends BaseController { const { wallet_token } = req.params return {} } - } diff --git a/src/controllers/tasks.controller.ts b/src/controllers/tasks.controller.ts index 006d6be..771a5af 100644 --- a/src/controllers/tasks.controller.ts +++ b/src/controllers/tasks.controller.ts @@ -1,40 +1,39 @@ -import { SyncLocker } from "common/SyncLocker"; -import { ZError } from "common/ZError"; -import BaseController from "common/base.controller"; -import { router } from "decorators/router"; -import { TaskCfg, TaskTypeEnum } from "models/ActivityInfo"; -import { TaskStatus, TaskStatusEnum } from "models/ActivityUser"; +import { SyncLocker } from 'common/SyncLocker' +import { ZError } from 'common/ZError' +import BaseController from 'common/base.controller' +import { router } from 'decorators/router' +import { TaskCfg, TaskTypeEnum } from 'models/ActivityInfo' +import { TaskStatus, TaskStatusEnum } from 'models/ActivityUser' import { join } from 'path' -import { formatDate } from "utils/date.util"; +import { formatDate } from 'utils/date.util' const fs = require('fs') const prod = process.env.NODE_ENV === 'production' const initTasks = () => { const tasks = join(__dirname, '../tasks') - const list = new Map(); - fs.readdirSync(tasks) - .filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/)) - .forEach((file: any) => { - const Task = require('../tasks/' + file); - list.set(Task.default.name, { - name: Task.default.name, - desc: Task.default.desc, - show: Task.default.show}) + const list = new Map() + fs.readdirSync(tasks) + .filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/)) + .forEach((file: any) => { + const Task = require('../tasks/' + file) + list.set(Task.default.name, { + name: Task.default.name, + desc: Task.default.desc, + show: Task.default.show, }) - return list + }) + return list } -const allTasks = initTasks(); - +const allTasks = initTasks() export default class TasksController extends BaseController { - @router('post /api/tasks/progress') async taskProgress(req) { - let user = req.user; - let activity = req.activity; - const dateTag = formatDate(new Date()); - let taskAddedSet = new Set(); + let user = req.user + let activity = req.activity + const dateTag = formatDate(new Date()) + let taskAddedSet = new Set() for (let task of user.taskProgress) { if (task.dateTag) { taskAddedSet.add(task.id + ':' + task.dateTag) @@ -42,52 +41,51 @@ export default class TasksController extends BaseController { taskAddedSet.add(task.id) } } - let modified = false; - let visibleTasks = new Set(); + let modified = false + let visibleTasks = new Set() for (let task of activity.tasks) { if (!allTasks.has(task.task)) { - continue; + continue } if (!task.isVaild()) { - continue; + continue } - if (task.type === TaskTypeEnum.DAILY ) { + if (task.type === TaskTypeEnum.DAILY) { let id = `${task.id}:${dateTag}` if (!taskAddedSet.has(id)) { - modified = true; - user.taskProgress.push({id, task:task.task ,dateTag: dateTag, status: TaskStatusEnum.NOT_START}) + modified = true + user.taskProgress.push({ id, task: task.task, dateTag: dateTag, status: TaskStatusEnum.NOT_START }) } - if (task.show) visibleTasks.add(id); - } else if (task.type === TaskTypeEnum.ONCE ) { + if (task.show) visibleTasks.add(id) + } else if (task.type === TaskTypeEnum.ONCE) { if (!taskAddedSet.has(task.id)) { - modified = true; - user.taskProgress.push({id: task.id, task: task.task, status: TaskStatusEnum.NOT_START}) + modified = true + user.taskProgress.push({ id: task.id, task: task.task, status: TaskStatusEnum.NOT_START }) } - if (task.show) visibleTasks.add(task.id); + if (task.show) visibleTasks.add(task.id) } } if (modified) { - await user.save(); + await user.save() } - return user.taskProgress.filter((t: TaskStatus) => visibleTasks.has(t.id)); + return user.taskProgress.filter((t: TaskStatus) => visibleTasks.has(t.id)) } - @router('post /api/tasks/begin_task') async beginTask(req) { - new SyncLocker().checkLock(req); - let user = req.user; - let activity = req.activity; - let { task } = req.params; - const [taskId, dateTag] = task.split(':'); - const currentDateTag = formatDate(new Date()); + new SyncLocker().checkLock(req) + let user = req.user + let activity = req.activity + let { task } = req.params + const [taskId, dateTag] = task.split(':') + const currentDateTag = formatDate(new Date()) if (dateTag && currentDateTag !== dateTag) { throw new ZError(11, 'task date not match') } if (!activity.isVaild()) { throw new ZError(15, 'activity not start or end') } - let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId); + let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId) if (!cfg) { throw new ZError(12, 'task not found') } @@ -100,85 +98,93 @@ export default class TasksController extends BaseController { if (cfg.pretasks && cfg.pretasks.length > 0) { for (let preTask of cfg.pretasks) { let preTaskData = user.taskProgress.find((t: TaskStatus) => { - if (preTask.type === TaskTypeEnum.DAILY) { + if (preTask.type === TaskTypeEnum.DAILY) { //这种情况下只要完成一次就算完成了 return t.id.indexOf(preTask) > -1 } return t.id === preTask - }); - if (!preTaskData || (preTaskData.status === TaskStatusEnum.NOT_START || preTaskData.status === TaskStatusEnum.RUNNING)) { + }) + if ( + !preTaskData || + preTaskData.status === TaskStatusEnum.NOT_START || + preTaskData.status === TaskStatusEnum.RUNNING + ) { throw new ZError(14, 'task previous not finish') } } } - let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task); - if (currentTask.status === TaskStatusEnum.PART_SUCCESS || currentTask.status === TaskStatusEnum.SUCCESS || currentTask.status === TaskStatusEnum.CLAIMED) { + let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task) + if ( + currentTask.status === TaskStatusEnum.PART_SUCCESS || + currentTask.status === TaskStatusEnum.SUCCESS || + currentTask.status === TaskStatusEnum.CLAIMED + ) { throw new ZError(15, 'task already end') } if (currentTask.status === TaskStatusEnum.NOT_START) { - currentTask.timeStart = Date.now(); - currentTask.status = TaskStatusEnum.RUNNING; + currentTask.timeStart = Date.now() + currentTask.status = TaskStatusEnum.RUNNING } - await user.save(); + await user.save() return currentTask } @router('post /api/tasks/check_task') async checkTask(req) { - const user = req.user; - const activity = req.activity; - const { task } = req.params; - const [taskId, dateTag] = task.split(':'); - const currentDateTag = formatDate(new Date()); + const user = req.user + const activity = req.activity + const { task } = req.params + const [taskId, dateTag] = task.split(':') + const currentDateTag = formatDate(new Date()) if (dateTag && currentDateTag !== dateTag) { throw new ZError(11, 'task date not match') } if (!activity.isVaild()) { throw new ZError(15, 'activity not start or end') } - let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId); + let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId) if (!cfg) { throw new ZError(12, 'task not found') } if (!cfg.isVaild()) { throw new ZError(16, 'task not start or end') } - let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task); + let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task) if (!currentTask) { throw new ZError(11, 'task not found') } if (currentTask.status === TaskStatusEnum.CLAIMED) { - return currentTask; + return currentTask } if (currentTask.status === TaskStatusEnum.NOT_START) { - throw new ZError(11, 'task not begin'); + throw new ZError(11, 'task not begin') } if (currentTask.status === TaskStatusEnum.RUNNING || currentTask.status === TaskStatusEnum.PART_SUCCESS) { - let Task = require('../tasks/' + currentTask.task); - let taskInstance = new Task.default({user, activity}); - await taskInstance.execute({task: currentTask}); + let Task = require('../tasks/' + currentTask.task) + let taskInstance = new Task.default({ user, activity }) + await taskInstance.execute({ task: currentTask }) } return currentTask } @router('post /api/tasks/claim') async claimTask(req) { - new SyncLocker().checkLock(req); - const user = req.user; - const activity = req.activity; - const { task } = req.params; - const [taskId, dateTag] = task.split(':'); + new SyncLocker().checkLock(req) + const user = req.user + const activity = req.activity + const { task } = req.params + const [taskId, dateTag] = task.split(':') if (!activity.isVaild()) { throw new ZError(15, 'activity not start or end') } - let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId); + let cfg = activity.tasks.find((t: TaskCfg) => t.id === taskId) if (!cfg) { throw new ZError(14, 'task not found') } if (!cfg.isVaild()) { throw new ZError(16, 'task not start or end') } - let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task); + let currentTask = user.taskProgress.find((t: TaskStatus) => t.id === task) if (!currentTask) { throw new ZError(11, 'task not found') } @@ -189,10 +195,9 @@ export default class TasksController extends BaseController { throw new ZError(13, 'task not end') } - const Task = require('../tasks/' + currentTask.task); - const taskInstance = new Task.default({user, activity}); - await taskInstance.claimReward(currentTask); + const Task = require('../tasks/' + currentTask.task) + const taskInstance = new Task.default({ user, activity }) + await taskInstance.claimReward(currentTask) return currentTask } - -} \ No newline at end of file +} diff --git a/src/initdata.ts b/src/initdata.ts index 42f404e..09a3484 100644 --- a/src/initdata.ts +++ b/src/initdata.ts @@ -7,7 +7,6 @@ const dir = `${__dirname}/../initdatas` const db = mongoose.connection var ejson = require('mongodb-extended-json') - ;(async () => { try { await mongoose.connect(process.env.DB_MAIN) @@ -18,7 +17,7 @@ var ejson = require('mongodb-extended-json') const collection_name = list[i].replace('.json', '') const parsedJSON = require(dir + '/' + list[i]) const jsonArry = ejson.deserialize(parsedJSON) - await db.collection(collection_name).insertMany(jsonArry); + await db.collection(collection_name).insertMany(jsonArry) console.log('Inserted ' + jsonArry.length + ' documents into the "' + collection_name + '" collection.') } console.log('Finished inserting documents into the database') @@ -27,4 +26,3 @@ var ejson = require('mongodb-extended-json') } process.exit(0) })() - diff --git a/src/models/ActivityInfo.ts b/src/models/ActivityInfo.ts index 726c04b..1af0adc 100644 --- a/src/models/ActivityInfo.ts +++ b/src/models/ActivityInfo.ts @@ -5,12 +5,11 @@ import findOrCreate from 'mongoose-findorcreate' import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses' import { BaseModule } from './Base' - export enum TaskTypeEnum { ONCE = 1, DAILY = 2, } -@modelOptions({ schemaOptions: { _id: false }, options: { allowMixed: Severity.ALLOW }, }) +@modelOptions({ schemaOptions: { _id: false }, options: { allowMixed: Severity.ALLOW } }) export class TaskCfg { @prop() id: string @@ -20,19 +19,19 @@ export class TaskCfg { title: string @prop({ enum: TaskTypeEnum, default: TaskTypeEnum.ONCE }) type: TaskTypeEnum - @prop({default: 1}) + @prop({ default: 1 }) repeat: number @prop() desc: string @prop({ type: mongoose.Schema.Types.Mixed }) category: any - @prop({default: false}) + @prop({ default: false }) autoclaim: boolean @prop({ type: () => [String], default: [] }) pretasks: string[] @prop() score: number - @prop({default: true}) + @prop({ default: true }) show: boolean @prop({ type: mongoose.Schema.Types.Mixed }) cfg: any @@ -92,7 +91,7 @@ class ActivityInfoClass extends BaseModule { @prop() public endTime: number - + @prop() public comment?: string @@ -117,13 +116,13 @@ class ActivityInfoClass extends BaseModule { for (let task of this.tasks) { if (task.show && task.isStart()) { tasks.push({ - id: task.id, + id: task.id, task: task.task, - title: task.title, - desc: task.desc, + title: task.title, + desc: task.desc, type: task.type, repeat: task.repeat, - pretasks: task.pretasks, + pretasks: task.pretasks, score: task.score, category: task.category, autoclaim: task.autoclaim, @@ -135,7 +134,6 @@ class ActivityInfoClass extends BaseModule { result.tasks = tasks return result } - } export const ActivityInfo = getModelForClass(ActivityInfoClass, { existingConnection: ActivityInfoClass.db }) diff --git a/src/models/ActivityItem.ts b/src/models/ActivityItem.ts index 45c02ec..c83b73f 100644 --- a/src/models/ActivityItem.ts +++ b/src/models/ActivityItem.ts @@ -6,9 +6,12 @@ import { BaseModule } from './Base' /** */ @dbconn() -@index({ user: 1, activity: 1}, { unique: false }) +@index({ user: 1, activity: 1 }, { unique: false }) @index({ user: 1, activity: 1, item: 1 }, { unique: true }) -@modelOptions({ schemaOptions: { collection: 'activity_item', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@modelOptions({ + schemaOptions: { collection: 'activity_item', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class ActivityItemClass extends BaseModule { @prop() public user: string @@ -16,16 +19,16 @@ class ActivityItemClass extends BaseModule { public activity: string @prop() public item: string - @prop({default: 0}) + @prop({ default: 0 }) public amount: number @prop() public last: number public toJson() { - return { - id: this.item, - amount: this.amount - } + return { + id: this.item, + amount: this.amount, + } } } export const ActivityItem = getModelForClass(ActivityItemClass, { existingConnection: ActivityItemClass['db'] }) diff --git a/src/models/ActivityUser.ts b/src/models/ActivityUser.ts index 07cb5b6..01e43cd 100644 --- a/src/models/ActivityUser.ts +++ b/src/models/ActivityUser.ts @@ -1,4 +1,13 @@ -import { getModelForClass, index, modelOptions, mongoose, pre, prop, ReturnModelType, Severity } from '@typegoose/typegoose' +import { + getModelForClass, + index, + modelOptions, + mongoose, + pre, + prop, + ReturnModelType, + Severity, +} from '@typegoose/typegoose' import { dbconn } from 'decorators/dbconn' // @ts-ignore import findOrCreate from 'mongoose-findorcreate' @@ -16,7 +25,7 @@ export enum TaskStatusEnum { PART_SUCCESS = 4, } -@modelOptions({ schemaOptions: { _id: false }, options: { allowMixed: Severity.ALLOW }}) +@modelOptions({ schemaOptions: { _id: false }, options: { allowMixed: Severity.ALLOW } }) export class TaskStatus { @prop() id: string @@ -44,18 +53,21 @@ interface ActivityUserClass extends Base, TimeStamps {} @index({ inviteUser: 1, activity: 1 }, { unique: false }) @index({ twitterId: 1 }, { unique: true, partialFilterExpression: { twitterId: { $exists: true } } }) @index({ discordId: 1 }, { unique: true, partialFilterExpression: { discordId: { $exists: true } } }) -@modelOptions({ schemaOptions: { collection: 'activity_user', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@modelOptions({ + schemaOptions: { collection: 'activity_user', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) @pre('save', async function () { if (!this.inviteCode) { - // 取ObjectId的time和inc段, + // 取ObjectId的time和inc段, // 将time段倒序(倒序后, 如果以0开始, 则移除0, 随机拼接一个hex字符), 然后拼接inc段, 再转换成52进制 - let timeStr = this.id.slice(0, 8).split("").reverse().join(""); + let timeStr = this.id.slice(0, 8).split('').reverse().join('') if (timeStr.indexOf('0') === 0) { - let randomStr = convert({ numStr: (Math.random() * 51 | 0 + 1) + '', base:10, to: 52}) + let randomStr = convert({ numStr: ((Math.random() * 51) | (0 + 1)) + '', base: 10, to: 52 }) timeStr = randomStr + timeStr.slice(1) } let shortId = timeStr + this.id.slice(-6) - this.inviteCode = convert({numStr: shortId, base: 16, to: 52, alphabet}) + this.inviteCode = convert({ numStr: shortId, base: 16, to: 52, alphabet }) } }) class ActivityUserClass extends BaseModule { @@ -89,7 +101,7 @@ class ActivityUserClass extends BaseModule { @prop() public discordName?: string - @prop({default: 1}) + @prop({ default: 1 }) public boost: number /** * boost过期时间 @@ -100,14 +112,17 @@ class ActivityUserClass extends BaseModule { @prop() public lastLogin?: Date - + @prop({ type: () => [TaskStatus], default: [] }) public taskProgress?: TaskStatus[] - public static async findByCode(this: ReturnModelType, inviteCode: string, activity: string) { + public static async findByCode( + this: ReturnModelType, + inviteCode: string, + activity: string, + ) { return this.findOne({ inviteCode, activity }).exec() } - } export const ActivityUser = getModelForClass(ActivityUserClass, { existingConnection: ActivityUserClass.db }) diff --git a/src/models/Base.ts b/src/models/Base.ts index adbd036..8d58374 100644 --- a/src/models/Base.ts +++ b/src/models/Base.ts @@ -102,7 +102,7 @@ export abstract class BaseModule extends FindOrCreate { * @return {{opt: any, sort: {_id: number}}} */ public static parseQueryParam(params: {}, options?: any) { - const opt: any = { deleted: { $ne: true } } + const opt: any = { deleted: { $ne: true } } // @ts-ignore let obj = this.schema.paths for (let key in params) { @@ -201,6 +201,6 @@ export abstract class BaseModule extends FindOrCreate { public getTimestampOfID() { // Extract the timestamp from the ObjectId // @ts-ignore - return this._id.getTimestamp(); + return this._id.getTimestamp() } } diff --git a/src/models/LoginRecord.ts b/src/models/LoginRecord.ts index 30af115..bcc799a 100644 --- a/src/models/LoginRecord.ts +++ b/src/models/LoginRecord.ts @@ -8,7 +8,10 @@ import { BaseModule } from './Base' */ @dbconn() @index({ user: 1, activity: 1, wallet: 1 }, { unique: false }) -@modelOptions({ schemaOptions: { collection: 'user_login_record', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@modelOptions({ + schemaOptions: { collection: 'user_login_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class LoginRecordClass extends BaseModule { @prop() public user: string diff --git a/src/models/LotteryRecord.ts b/src/models/LotteryRecord.ts index 7608737..1baebf1 100644 --- a/src/models/LotteryRecord.ts +++ b/src/models/LotteryRecord.ts @@ -7,27 +7,30 @@ import { BaseModule } from './Base' * 用户抽奖记录 */ @dbconn() -@index({ user: 1, activity: 1}, { unique: false }) -@index({ user: 1, activity: 1, dateTag: 1}, { unique: false }) -@modelOptions({ schemaOptions: { collection: 'lottery_record', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@index({ user: 1, activity: 1 }, { unique: false }) +@index({ user: 1, activity: 1, dateTag: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'lottery_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class LotteryRecordClass extends BaseModule { @prop() public user: string @prop() public activity: string @prop() - public dateTag: string + public dateTag: string @prop() public reward?: string - @prop({default: 0}) + @prop({ default: 0 }) public amount: number public toJson() { - return { - day: this.dateTag, - id: this.reward, - amount: this.amount, - } + return { + day: this.dateTag, + id: this.reward, + amount: this.amount, + } } } export const LotteryRecord = getModelForClass(LotteryRecordClass, { existingConnection: LotteryRecordClass['db'] }) diff --git a/src/models/LotteryStats.ts b/src/models/LotteryStats.ts index d5d4f39..72b6b6a 100644 --- a/src/models/LotteryStats.ts +++ b/src/models/LotteryStats.ts @@ -7,35 +7,37 @@ import { BaseModule } from './Base' * 用户抽奖状态 */ @dbconn() -@index({ user: 1, activity: 1, dateTag: 1}, { unique: false }) -@modelOptions({ schemaOptions: { collection: 'lottery_stats', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@index({ user: 1, activity: 1, dateTag: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'lottery_stats', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class LotteryStatsClass extends BaseModule { @prop() public user: string @prop() public activity: string - @prop({default: 0}) + @prop({ default: 0 }) public amount: number - @prop({default: 0}) + @prop({ default: 0 }) public daily: number - @prop({default: 0}) + @prop({ default: 0 }) public gacha: number - @prop({default: 0 }) + @prop({ default: 0 }) public share: number - @prop({default: 0}) + @prop({ default: 0 }) public used: number @prop() public dateTag: string - public toJson() { - return { - amount: this.amount, - daily: this.daily, - gacha: this.gacha, - used: this.used, - day: this.dateTag, - } + return { + amount: this.amount, + daily: this.daily, + gacha: this.gacha, + used: this.used, + day: this.dateTag, + } } } export const LotteryStats = getModelForClass(LotteryStatsClass, { existingConnection: LotteryStatsClass['db'] }) diff --git a/src/models/NFTBrunRecord.ts b/src/models/NFTBrunRecord.ts index c86b5ee..03c9680 100644 --- a/src/models/NFTBrunRecord.ts +++ b/src/models/NFTBrunRecord.ts @@ -2,17 +2,19 @@ import { Severity, getModelForClass, index, modelOptions, mongoose, prop } from import { dbconn } from 'decorators/dbconn' import { BaseModule } from './Base' - @dbconn() -@index({ user: 1, chain: 1, address: 1}, { unique: false }) +@index({ user: 1, chain: 1, address: 1 }, { unique: false }) @index({ user: 1, chain: 1, address: 1, tokenId: 1 }, { unique: true }) -@modelOptions({ schemaOptions: { collection: 'nft_burn_record', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@modelOptions({ + schemaOptions: { collection: 'nft_burn_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class NftBurnRecordClass extends BaseModule { - @prop({ required: true}) + @prop({ required: true }) public user: string @prop() public chain: number - @prop({ required: true}) + @prop({ required: true }) public address: string @prop() public tokenId: string @@ -20,8 +22,6 @@ class NftBurnRecordClass extends BaseModule { public activity: string @prop() public task: string - } export const NftBurnRecord = getModelForClass(NftBurnRecordClass, { existingConnection: NftBurnRecordClass['db'] }) - diff --git a/src/models/NonceRecord.ts b/src/models/NonceRecord.ts index 630b181..343a651 100644 --- a/src/models/NonceRecord.ts +++ b/src/models/NonceRecord.ts @@ -21,4 +21,3 @@ class NonceRecordClass extends BaseModule { } export const NonceRecord = getModelForClass(NonceRecordClass, { existingConnection: NonceRecordClass['db'] }) - diff --git a/src/models/ScoreRecord.ts b/src/models/ScoreRecord.ts index 54dc398..11aa67d 100644 --- a/src/models/ScoreRecord.ts +++ b/src/models/ScoreRecord.ts @@ -2,17 +2,19 @@ import { Severity, getModelForClass, index, modelOptions, mongoose, prop } from import { dbconn } from 'decorators/dbconn' import { BaseModule } from './Base' - @dbconn() @index({ user: 1 }, { unique: false }) @index({ activity: 1 }, { unique: false }) -@index({user: 1, activity: 1, type: 1}, { unique: false }) -@modelOptions({ schemaOptions: { collection: 'score_record', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@index({ user: 1, activity: 1, type: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'score_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class ScoreRecordClass extends BaseModule { - @prop({ required: true}) + @prop({ required: true }) public user: string - @prop({ required: true}) + @prop({ required: true }) public activity: string @prop() @@ -23,8 +25,6 @@ class ScoreRecordClass extends BaseModule { @prop({ type: mongoose.Schema.Types.Mixed }) public data: any - } export const ScoreRecord = getModelForClass(ScoreRecordClass, { existingConnection: ScoreRecordClass['db'] }) - diff --git a/src/models/TokenClaimHistory.ts b/src/models/TokenClaimHistory.ts index 7e88758..b0a5fd5 100644 --- a/src/models/TokenClaimHistory.ts +++ b/src/models/TokenClaimHistory.ts @@ -2,17 +2,19 @@ import { Severity, getModelForClass, index, modelOptions, mongoose, prop } from import { dbconn } from 'decorators/dbconn' import { BaseModule } from './Base' - @dbconn() @index({ user: 1 }, { unique: false }) @index({ activity: 1 }, { unique: false }) -@index({user: 1, activity: 1, type: 1}, { unique: false }) -@modelOptions({ schemaOptions: { collection: 'token_claim_record', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) +@index({ user: 1, activity: 1, type: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'token_claim_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) class TokenClaimHistoryClass extends BaseModule { - @prop({ required: true}) + @prop({ required: true }) public user: string - @prop({ required: true}) + @prop({ required: true }) public activity: string /** * 冗余字段, 方便查找 @@ -31,7 +33,7 @@ class TokenClaimHistoryClass extends BaseModule { * 1: 已确认 * -1: 已明确失败 */ - @prop({default: 0}) + @prop({ default: 0 }) public status: number // 转账交易hash @prop() @@ -44,5 +46,6 @@ class TokenClaimHistoryClass extends BaseModule { } } -export const TokenClaimHistory = getModelForClass(TokenClaimHistoryClass, { existingConnection: TokenClaimHistoryClass['db'] }) - +export const TokenClaimHistory = getModelForClass(TokenClaimHistoryClass, { + existingConnection: TokenClaimHistoryClass['db'], +}) diff --git a/src/models/chain/CheckIn.ts b/src/models/chain/CheckIn.ts index d8d9dc9..ab9c639 100644 --- a/src/models/chain/CheckIn.ts +++ b/src/models/chain/CheckIn.ts @@ -5,8 +5,8 @@ import { formatDate, yesterday } from 'utils/date.util' @dbconn('chain') @index({ from: 1 }, { unique: false }) -@index({ from: 1, dateTag: 1}, { unique: true }) -@index({ from: 1, blockTime: 1}, { unique: false }) +@index({ from: 1, dateTag: 1 }, { unique: true }) +@index({ from: 1, blockTime: 1 }, { unique: false }) @modelOptions({ schemaOptions: { collection: 'check_in_event', timestamps: true }, }) @@ -26,7 +26,7 @@ export class CheckInClass extends BaseModule { @prop() public dateTag: string // 连签天数 - @prop({default: 0}) + @prop({ default: 0 }) public count: number @prop() public value: string @@ -34,7 +34,7 @@ export class CheckInClass extends BaseModule { public input: string public static async saveEvent(event: any) { - const preDay = formatDate(yesterday()); + const preDay = formatDate(yesterday()) const preDayEvent = await CheckIn.findOne({ from: event.from, dateTag: preDay }) if (preDayEvent) { event.count = preDayEvent.count + 1 @@ -43,12 +43,12 @@ export class CheckInClass extends BaseModule { } public toJson() { - return { - address: this.from, - day: this.dateTag, - time: this.blockTime, - count: this.count - } + return { + address: this.from, + day: this.dateTag, + time: this.blockTime, + count: this.count, + } } } diff --git a/src/models/chain/NftHolder.ts b/src/models/chain/NftHolder.ts index e07274d..dcc2529 100644 --- a/src/models/chain/NftHolder.ts +++ b/src/models/chain/NftHolder.ts @@ -20,15 +20,14 @@ export class NftHolderClass extends BaseModule { public blockNumber: number @prop() public user: string - @prop({default: false}) + @prop({ default: false }) public burn: boolean - public static async saveData(event: any) { - const address = event.address; - const chain = event.chain; - const tokenId = event.tokenId; - const blockNumer = event.blockNumber; + const address = event.address + const chain = event.chain + const tokenId = event.tokenId + const blockNumer = event.blockNumber const burn = event.to === ZERO_ADDRESS let record = await NftHolder.findOne({ address, chain, tokenId }) @@ -44,8 +43,7 @@ export class NftHolderClass extends BaseModule { record.blockNumber = blockNumer } } - await record.save(); - + await record.save() } } diff --git a/src/models/chain/NftStake.ts b/src/models/chain/NftStake.ts index b918f99..fa65a01 100644 --- a/src/models/chain/NftStake.ts +++ b/src/models/chain/NftStake.ts @@ -2,10 +2,9 @@ import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoos import { dbconn } from 'decorators/dbconn' import { BaseModule } from '../Base' - @dbconn('chain') -@index({ chain: 1, nft: 1, tokenId: 1, start: 1 }, { unique: true }) -@index({ chain:1, user: 1, nft: 1}, {unique: false}) +@index({ chain: 1, nft: 1, tokenId: 1, start: 1 }, { unique: true }) +@index({ chain: 1, user: 1, nft: 1 }, { unique: false }) @modelOptions({ schemaOptions: { collection: 'nft_stake_info', timestamps: true }, }) @@ -38,13 +37,13 @@ export class NftStakeClass extends BaseModule { public version: number public toJson() { - return { - nft: this.nft, - nftid: this.tokenId, - start: this.start, - cd: +process.env.STAKE_CD, - stakeTime: this.stakeTime - } + return { + nft: this.nft, + nftid: this.tokenId, + start: this.start, + cd: +process.env.STAKE_CD, + stakeTime: this.stakeTime, + } } } diff --git a/src/schedule/cache.schedule.ts b/src/schedule/cache.schedule.ts index e9c5c1e..0438ef9 100644 --- a/src/schedule/cache.schedule.ts +++ b/src/schedule/cache.schedule.ts @@ -1,7 +1,6 @@ -import { LotteryCache } from 'common/LotteryCache'; +import { LotteryCache } from 'common/LotteryCache' import { singleton } from 'decorators/singleton' -import logger from 'logger/logger'; -import {NonceRecord} from 'models/NonceRecord' +import logger from 'logger/logger' import * as schedule from 'node-schedule' /** @@ -9,14 +8,12 @@ import * as schedule from 'node-schedule' */ @singleton export default class CacheSchedule { - async updateCache() { try { - new LotteryCache().flush(); + new LotteryCache().flush() } catch (err) { logger.warn(err) } - } scheduleAll() { schedule.scheduleJob('*/10 * * * * *', async () => { diff --git a/src/schedule/noncerecord.schedule.ts b/src/schedule/noncerecord.schedule.ts index f29ffa9..1ecd63c 100644 --- a/src/schedule/noncerecord.schedule.ts +++ b/src/schedule/noncerecord.schedule.ts @@ -1,5 +1,5 @@ import { singleton } from 'decorators/singleton' -import {NonceRecord} from 'models/NonceRecord' +import { NonceRecord } from 'models/NonceRecord' import * as schedule from 'node-schedule' /** @@ -8,11 +8,11 @@ import * as schedule from 'node-schedule' @singleton export default class NonceRecordSchedule { async parseAllFinishedRecord() { - await NonceRecord.deleteMany({status: 1}); + await NonceRecord.deleteMany({ status: 1 }) } async parseAllExpiredRecord() { let now = Date.now() - await NonceRecord.deleteMany({expired: {$lt: now}}) + await NonceRecord.deleteMany({ expired: { $lt: now } }) } scheduleAll() { schedule.scheduleJob('*/1 * * * *', async () => { diff --git a/src/services/chain.svr.ts b/src/services/chain.svr.ts index 752eae9..e146656 100644 --- a/src/services/chain.svr.ts +++ b/src/services/chain.svr.ts @@ -1,53 +1,53 @@ -import { NftHolder } from "models/chain/NftHolder" -import { NftStake } from "models/chain/NftStake" +import { NftHolder } from 'models/chain/NftHolder' +import { NftStake } from 'models/chain/NftStake' export const queryCheckInList = async (address: string, days: string | number | string[], limit: number = 0) => { const url = process.env.CHAIN_SVR + '/task/check_in' return fetch(url, { method: 'POST', - headers: {"Content-Type": "application/json"}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address, days, - limit - }) - }).then((res) => res.json()) + limit, + }), + }).then(res => res.json()) } -export const queryCheckInSeq = async (address: string) =>{ +export const queryCheckInSeq = async (address: string) => { const url = process.env.CHAIN_SVR + '/task/check_in/max_seq' return fetch(url, { method: 'POST', - headers: {"Content-Type": "application/json"}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address, - }) - }).then((res) => res.json()) + }), + }).then(res => res.json()) } export const queryBurnNftList = async (address: string, user: string, chain: number) => { const url = process.env.CHAIN_SVR + '/task/nft/checkburn' return fetch(url, { method: 'POST', - headers: {"Content-Type": "application/json"}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address, user, - chain - }) - }).then((res) => res.json()) + chain, + }), + }).then(res => res.json()) } export const checkHadGacha = async (user: string) => { - const chain = process.env.CHAIN+'' + const chain = process.env.CHAIN + '' const address = process.env.GACHA_CONTRACT - const record = await NftHolder.findOne({user, chain, address}) + const record = await NftHolder.findOne({ user, chain, address }) return !!record } export const queryStakeList = async (userAddress: string) => { - const chain = process.env.CHAIN+'' + const chain = process.env.CHAIN + '' const address = process.env.BADGE_CONTRACT - let records = await NftStake.find({chain, nft: address, user: userAddress.toLowerCase()}) + let records = await NftStake.find({ chain, nft: address, user: userAddress.toLowerCase() }) return records -} \ No newline at end of file +} diff --git a/src/services/oauth.svr.ts b/src/services/oauth.svr.ts index a9a4d24..50f4314 100644 --- a/src/services/oauth.svr.ts +++ b/src/services/oauth.svr.ts @@ -1,4 +1,4 @@ -import { hmacSha256 } from "utils/security.util" +import { hmacSha256 } from 'utils/security.util' import axios from 'axios' const SECRET_KEY = process.env.HASH_SALT @@ -10,14 +10,13 @@ function createSign(address: string) { } export function checkTwitter(address: string) { - let sign = createSign(address); + let sign = createSign(address) const url = `${process.env.OAUTH_SVR_URL}/activity/twitter/${address}?sign=${sign}` - return axios.get(url); + return axios.get(url) } - export function checkDiscord(address: string) { - let sign = createSign(address); - const url = `${process.env.OAUTH_SVR_URL}/activity/discord/${address}?sign=${sign}`; - return axios.get(url); -} \ No newline at end of file + let sign = createSign(address) + const url = `${process.env.OAUTH_SVR_URL}/activity/discord/${address}?sign=${sign}` + return axios.get(url) +} diff --git a/src/services/rank.svr.ts b/src/services/rank.svr.ts index 2494976..fbbc49a 100644 --- a/src/services/rank.svr.ts +++ b/src/services/rank.svr.ts @@ -1,10 +1,10 @@ -import { ScoreRecord } from "models/ScoreRecord"; -import { RedisClient } from "redis/RedisClient"; -import { formatDate } from "utils/date.util"; +import { ScoreRecord } from 'models/ScoreRecord' +import { RedisClient } from 'redis/RedisClient' +import { formatDate } from 'utils/date.util' /** * 更新排行榜 - * @param param0 + * @param param0 * user: 用户id * score: 分数 * activity: 活动id @@ -16,12 +16,12 @@ export const updateRankScore = async ({ score, activity, scoreType, - scoreParams + scoreParams, }: { - user: string, - score: number, - activity: string, - scoreType: string, + user: string + score: number + activity: string + scoreType: string scoreParams: any }) => { let record = new ScoreRecord({ @@ -29,37 +29,37 @@ export const updateRankScore = async ({ activity: activity, score, type: scoreType, - data: scoreParams + data: scoreParams, }) - await record.save(); - const key = rankKey(activity); - await updateRank(key, score, user); + await record.save() + const key = rankKey(activity) + await updateRank(key, score, user) // add daily score - const dailyKey = rankKey(activity, new Date()); - await updateRank(dailyKey, score, user); + const dailyKey = rankKey(activity, new Date()) + await updateRank(dailyKey, score, user) } /** * 更新排行榜 - * @param key - * @param score - * @param member + * @param key + * @param score + * @param member */ const updateRank = async (key: string, score: number, member: string) => { - let scoreSaved = await new RedisClient().zscore(key, member) + ''; + let scoreSaved = (await new RedisClient().zscore(key, member)) + '' if (scoreSaved) { scoreSaved = scoreSaved.substring(0, scoreSaved.indexOf('.')) } - let scoreOld = parseInt(scoreSaved || '0'); - score = score + scoreOld; - const scoreToSave = score + 1 - (Date.now() / 1000 / 10000000000) - await new RedisClient().zadd(key, scoreToSave, member); + let scoreOld = parseInt(scoreSaved || '0') + score = score + scoreOld + const scoreToSave = score + 1 - Date.now() / 1000 / 10000000000 + await new RedisClient().zadd(key, scoreToSave, member) } export const rankKey = (activity: string, date?: Date) => { if (!date) { return `${activity}:score` } - const dateTag = formatDate(date); + const dateTag = formatDate(date) return `${activity}:score:${dateTag}` } diff --git a/src/tasks/BurnNft.ts b/src/tasks/BurnNft.ts index d6388d0..7632c2a 100644 --- a/src/tasks/BurnNft.ts +++ b/src/tasks/BurnNft.ts @@ -1,9 +1,9 @@ -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { ZError } from "common/ZError"; -import { TaskCfg } from "models/ActivityInfo"; -import { queryBurnNftList } from "services/chain.svr"; -import { NftBurnRecord } from "models/NFTBrunRecord"; +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' +import { ZError } from 'common/ZError' +import { TaskCfg } from 'models/ActivityInfo' +import { queryBurnNftList } from 'services/chain.svr' +import { NftBurnRecord } from 'models/NFTBrunRecord' export default class BurnNft extends ITask { static desc = 'Butn NFT' @@ -23,9 +23,9 @@ export default class BurnNft extends ITask { chain, address, }) - const localNftSet = new Set(); - let finishAmount = 0; - let tmpNftSet = new Set(); + const localNftSet = new Set() + let finishAmount = 0 + let tmpNftSet = new Set() for (let nft of localNft) { localNftSet.add(nft.tokenId) if (nft.activity === this.activity.id && nft.task === task.id) { @@ -33,13 +33,13 @@ export default class BurnNft extends ITask { tmpNftSet.add(nft.tokenId) } } - let finishNfts = new Set(); + let finishNfts = new Set() for (let nft of nftList) { if (!localNftSet.has(nft.tokenId)) { finishNfts.add(nft.tokenId) finishAmount += 1 if (finishAmount >= cfg.repeat) { - break; + break } } } @@ -50,7 +50,7 @@ export default class BurnNft extends ITask { address, tokenId: finishNft, activity: this.activity.id, - task: task.id + task: task.id, }) await record.save() } @@ -67,16 +67,16 @@ export default class BurnNft extends ITask { } try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } -} \ No newline at end of file +} diff --git a/src/tasks/DailyCheckIn.ts b/src/tasks/DailyCheckIn.ts index 7d9056a..1f459a3 100644 --- a/src/tasks/DailyCheckIn.ts +++ b/src/tasks/DailyCheckIn.ts @@ -1,10 +1,10 @@ -import { ITask } from "./base/ITask"; -import { ZError } from "common/ZError"; -import { TaskStatus, TaskStatusEnum } from "models/ActivityUser"; -import { TaskCfg, TaskTypeEnum } from "models/ActivityInfo"; -import { queryCheckInList, queryCheckInSeq } from "services/chain.svr"; -import { updateRankScore } from "services/rank.svr"; -import { LotteryCache } from "common/LotteryCache"; +import { ITask } from './base/ITask' +import { ZError } from 'common/ZError' +import { TaskStatus, TaskStatusEnum } from 'models/ActivityUser' +import { TaskCfg, TaskTypeEnum } from 'models/ActivityInfo' +import { queryCheckInList, queryCheckInSeq } from 'services/chain.svr' +import { updateRankScore } from 'services/rank.svr' +import { LotteryCache } from 'common/LotteryCache' /** * 检查每日签到 @@ -22,27 +22,30 @@ export default class DailyCheckIn extends ITask { let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) const days = cfg.params.days || 1 const limit = cfg.params.limit || 0 - const res = cfg.type === TaskTypeEnum.DAILY ? - await queryCheckInList(address, days - 1, limit) - : await queryCheckInSeq(address) + const res = + cfg.type === TaskTypeEnum.DAILY + ? await queryCheckInList(address, days - 1, limit) + : await queryCheckInSeq(address) if (res.errcode) { throw new ZError(res.errcode, res.errmsg) } - - if ((cfg.type === TaskTypeEnum.DAILY && task.status === TaskStatusEnum.RUNNING && res.data.length >= days) - || (cfg.type === TaskTypeEnum.ONCE && task.status === TaskStatusEnum.RUNNING && res.data.count >= days)) { + + if ( + (cfg.type === TaskTypeEnum.DAILY && task.status === TaskStatusEnum.RUNNING && res.data.length >= days) || + (cfg.type === TaskTypeEnum.ONCE && task.status === TaskStatusEnum.RUNNING && res.data.count >= days) + ) { task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = res.data try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save daily checkin failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } @@ -52,17 +55,17 @@ export default class DailyCheckIn extends ITask { public async claimReward(task: TaskStatus) { // 增加连续签到奖励分 - // 请求前7天的签到记录, 往前查找连续签到的记录, + // 请求前7天的签到记录, 往前查找连续签到的记录, let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) if (cfg.type === TaskTypeEnum.DAILY) { const res = await queryCheckInList(this.user.address, 1, 0) - const [taskId, dateTag] = task.id.split(':'); - let list: { day: string, time: number, count: number }[] = res.data; - - const countCfg = cfg.params.score.length; - let count = list.length > 0 ? list[0].count : 0; - let seq = count % countCfg; - let score = cfg.params.score[seq] || 0 + cfg.score; + const [taskId, dateTag] = task.id.split(':') + let list: { day: string; time: number; count: number }[] = res.data + + const countCfg = cfg.params.score.length + let count = list.length > 0 ? list[0].count : 0 + let seq = count % countCfg + let score = cfg.params.score[seq] || 0 + cfg.score const user = this.user if (user.boost > 1 && Date.now() < user.boostExpire) { score = Math.floor(score * user.boost) @@ -77,18 +80,17 @@ export default class DailyCheckIn extends ITask { date: dateTag, bouns: score, boost: user.boost, - } + }, }) await this.claimItem(cfg) } else { - await super.claimReward(task); + await super.claimReward(task) } // 更新gacha拥有者抽奖次数, 这里写死, 等想到好的方式再处理 - let record = await new LotteryCache().getData(this.user.id, this.user.activity); + let record = await new LotteryCache().getData(this.user.id, this.user.activity) if (record.daily === 0) { record.daily += 1 record.amount += 1 } } - -} \ No newline at end of file +} diff --git a/src/tasks/DiscordConnect.ts b/src/tasks/DiscordConnect.ts index cfc5278..68eb6ee 100644 --- a/src/tasks/DiscordConnect.ts +++ b/src/tasks/DiscordConnect.ts @@ -1,8 +1,8 @@ -import { checkDiscord } from "services/oauth.svr"; -import { ITask } from "./base/ITask"; -import { ZError } from "common/ZError"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { TaskCfg } from "models/ActivityInfo"; +import { checkDiscord } from 'services/oauth.svr' +import { ITask } from './base/ITask' +import { ZError } from 'common/ZError' +import { TaskStatusEnum } from 'models/ActivityUser' +import { TaskCfg } from 'models/ActivityInfo' export default class DiscordConnect extends ITask { static desc = 'join discord' @@ -19,7 +19,7 @@ export default class DiscordConnect extends ITask { if (res.data.errcode) { throw new ZError(res.data.errcode, res.data.errmsg) } - + if (res.data.data.userid && task.status === TaskStatusEnum.RUNNING) { task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() @@ -28,18 +28,17 @@ export default class DiscordConnect extends ITask { this.user.discordName = res.data.data.username try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'discord already binded') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/DiscordJoin.ts b/src/tasks/DiscordJoin.ts index b260af1..1524053 100644 --- a/src/tasks/DiscordJoin.ts +++ b/src/tasks/DiscordJoin.ts @@ -1,7 +1,7 @@ -import { ITask } from "./base/ITask"; -import { ZError } from "common/ZError"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { TaskCfg } from "models/ActivityInfo"; +import { ITask } from './base/ITask' +import { ZError } from 'common/ZError' +import { TaskStatusEnum } from 'models/ActivityUser' +import { TaskCfg } from 'models/ActivityInfo' export default class DiscordJoin extends ITask { static desc = 'join discord' @@ -10,30 +10,29 @@ export default class DiscordJoin extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'check discord join failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'check discord join failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'already join discord') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/DiscordRole.ts b/src/tasks/DiscordRole.ts index 873876a..b10e3d0 100644 --- a/src/tasks/DiscordRole.ts +++ b/src/tasks/DiscordRole.ts @@ -1,7 +1,7 @@ -import { ZError } from "common/ZError"; -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { TaskCfg } from "models/ActivityInfo"; +import { ZError } from 'common/ZError' +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' +import { TaskCfg } from 'models/ActivityInfo' export default class DiscordRole extends ITask { static desc = 'acquire discord role' @@ -9,30 +9,29 @@ export default class DiscordRole extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'check discord role failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'check discord role failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'already acquired discord role') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/OkxLogin.ts b/src/tasks/OkxLogin.ts index 9107b56..c38e348 100644 --- a/src/tasks/OkxLogin.ts +++ b/src/tasks/OkxLogin.ts @@ -1,9 +1,8 @@ -import { ITask } from "./base/ITask"; -import { ZError } from "common/ZError"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { TaskCfg } from "models/ActivityInfo"; -import { UserLog } from "models/UserLog"; -import { LoginRecord } from "models/LoginRecord"; +import { ITask } from './base/ITask' +import { ZError } from 'common/ZError' +import { TaskStatusEnum } from 'models/ActivityUser' +import { TaskCfg } from 'models/ActivityInfo' +import { LoginRecord } from 'models/LoginRecord' export default class OkxLogin extends ITask { static desc = 'okx wallet login' @@ -13,25 +12,25 @@ export default class OkxLogin extends ITask { const { task } = data const { activity } = this.user let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let wallet = 'okx'; - let record = LoginRecord.findOne({ user: this.user.id, activity, wallet}) - if (!record ) { + let wallet = 'okx' + let record = LoginRecord.findOne({ user: this.user.id, activity, wallet }) + if (!record) { throw new ZError(11, 'task not finished') } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'discord already binded') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } -} \ No newline at end of file +} diff --git a/src/tasks/ShareCode.ts b/src/tasks/ShareCode.ts index a3aa713..57a991b 100644 --- a/src/tasks/ShareCode.ts +++ b/src/tasks/ShareCode.ts @@ -1,18 +1,24 @@ -import { ActivityUser, TaskStatus, TaskStatusEnum } from "models/ActivityUser"; -import { ITask } from "./base/ITask"; -import { TaskCfg } from "models/ActivityInfo"; -import { updateRankScore } from "services/rank.svr"; -import { ActivityItem } from "models/ActivityItem"; -import { LotteryCache } from "common/LotteryCache"; -import { checkHadGacha } from "services/chain.svr"; +import { ActivityUser, TaskStatus, TaskStatusEnum } from 'models/ActivityUser' +import { ITask } from './base/ITask' +import { TaskCfg } from 'models/ActivityInfo' +import { updateRankScore } from 'services/rank.svr' +import { ActivityItem } from 'models/ActivityItem' +import { LotteryCache } from 'common/LotteryCache' +import { checkHadGacha } from 'services/chain.svr' -const updateInviteScore = async (user: typeof ActivityUser, scores: number[], items: any[], level: number, reason: string) => { +const updateInviteScore = async ( + user: typeof ActivityUser, + scores: number[], + items: any[], + level: number, + reason: string, +) => { if (!user.inviteUser || scores.length <= level) { - return; + return } let userSup = await ActivityUser.findById(user.inviteUser) if (!userSup || !userSup.address) { - return; + return } await updateRankScore({ user: userSup.id, @@ -21,22 +27,21 @@ const updateInviteScore = async (user: typeof ActivityUser, scores: number[], it scoreType: reason, scoreParams: { user: user.id, - level - } + level, + }, }) // 更新gacha拥有者抽奖次数, 这里写死, 等想到好的方式再处理 - let record = await new LotteryCache().getData(userSup.id, userSup.activity); + let record = await new LotteryCache().getData(userSup.id, userSup.activity) record.share += 1 record.amount += 1 - if (record.gacha ===0 && checkHadGacha(userSup.address)) { + if (record.gacha === 0 && checkHadGacha(userSup.address)) { record.gacha += 1 record.amount += 1 } if (items.length > level) { for (let key in items[level]) { let amount = items[level][key] - await ActivityItem.insertOrUpdate( - {user: userSup, activity: userSup.activity, item: key}, {$inc: {amount}}) + await ActivityItem.insertOrUpdate({ user: userSup, activity: userSup.activity, item: key }, { $inc: { amount } }) } } await updateInviteScore(userSup, scores, items, level + 1, reason) @@ -45,25 +50,25 @@ const updateInviteScore = async (user: typeof ActivityUser, scores: number[], it export default class ShareCode extends ITask { static desc = 'update invite score' static show: boolean = false - + async execute(data: any) { let { task } = data let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) if (!this.user.inviteUser) { throw new Error('not finished') } - let scores = cfg.params.score; - const items = cfg.params.inviteItems || []; + let scores = cfg.params.score + const items = cfg.params.inviteItems || [] task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} - await this.user.save(); + await this.user.save() // According to configuration, add score to user who invite current user if (cfg.autoclaim) { try { - await super.claimReward(task); + await super.claimReward(task) await updateInviteScore(this.user, scores, items, 0, task.task) - } catch(err) { + } catch (err) { console.log(err) } } @@ -71,10 +76,10 @@ export default class ShareCode extends ITask { } public async claimReward(task: TaskStatus) { - await super.claimReward(task); + await super.claimReward(task) let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let scores = cfg.params.score; - const items = cfg.params.inviteItems || []; - await updateInviteScore(this.user, scores, items, 0, "invite") + let scores = cfg.params.score + const items = cfg.params.inviteItems || [] + await updateInviteScore(this.user, scores, items, 0, 'invite') } -} \ No newline at end of file +} diff --git a/src/tasks/TwitterConnect.ts b/src/tasks/TwitterConnect.ts index cac695e..f4d418c 100644 --- a/src/tasks/TwitterConnect.ts +++ b/src/tasks/TwitterConnect.ts @@ -1,13 +1,13 @@ -import { checkTwitter } from "services/oauth.svr"; -import { ITask } from "./base/ITask"; -import { ActivityUser, TaskStatusEnum } from "models/ActivityUser"; -import { ZError } from "common/ZError"; -import { TaskCfg } from "models/ActivityInfo"; +import { checkTwitter } from 'services/oauth.svr' +import { ITask } from './base/ITask' +import { ActivityUser, TaskStatusEnum } from 'models/ActivityUser' +import { ZError } from 'common/ZError' +import { TaskCfg } from 'models/ActivityInfo' export default class TwitterConnect extends ITask { static desc = 'twitter connect' static show: boolean = true - + async execute(data: any) { let { address } = this.user let res = await checkTwitter(address) @@ -26,20 +26,18 @@ export default class TwitterConnect extends ITask { this.user.twitterName = res.data.data.username try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'twitter already binded') } let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } - } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/TwitterFollow.ts b/src/tasks/TwitterFollow.ts index 87a28d5..45eefe0 100644 --- a/src/tasks/TwitterFollow.ts +++ b/src/tasks/TwitterFollow.ts @@ -1,7 +1,7 @@ -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { ZError } from "common/ZError"; -import { TaskCfg } from "models/ActivityInfo"; +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' +import { ZError } from 'common/ZError' +import { TaskCfg } from 'models/ActivityInfo' export default class TwitterFollow extends ITask { static desc = 'twitter follow' @@ -9,30 +9,29 @@ export default class TwitterFollow extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'follow failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'follow failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/TwitterRetweet.ts b/src/tasks/TwitterRetweet.ts index ff9d706..c56c658 100644 --- a/src/tasks/TwitterRetweet.ts +++ b/src/tasks/TwitterRetweet.ts @@ -1,6 +1,6 @@ -import { ZError } from "common/ZError"; -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; +import { ZError } from 'common/ZError' +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' export default class TwitterRetweet extends ITask { static desc = 'twitter retweet' @@ -8,30 +8,29 @@ export default class TwitterRetweet extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find(t => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'retweet failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'retweet failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/YoutubeFollow.ts b/src/tasks/YoutubeFollow.ts index b2770b4..7ea9a05 100644 --- a/src/tasks/YoutubeFollow.ts +++ b/src/tasks/YoutubeFollow.ts @@ -1,7 +1,7 @@ -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; -import { ZError } from "common/ZError"; -import { TaskCfg } from "models/ActivityInfo"; +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' +import { ZError } from 'common/ZError' +import { TaskCfg } from 'models/ActivityInfo' export default class YoutubeFollow extends ITask { static desc = 'youtube follow' @@ -9,30 +9,29 @@ export default class YoutubeFollow extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'follow failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'follow failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/YoutubePost.ts b/src/tasks/YoutubePost.ts index 15377dc..42d5e0b 100644 --- a/src/tasks/YoutubePost.ts +++ b/src/tasks/YoutubePost.ts @@ -1,6 +1,6 @@ -import { ZError } from "common/ZError"; -import { ITask } from "./base/ITask"; -import { TaskStatusEnum } from "models/ActivityUser"; +import { ZError } from 'common/ZError' +import { ITask } from './base/ITask' +import { TaskStatusEnum } from 'models/ActivityUser' export default class YoutubePost extends ITask { static desc = 'youtube post' @@ -8,30 +8,29 @@ export default class YoutubePost extends ITask { async execute(data: any) { const { task } = data let cfg = this.activity.tasks.find(t => t.id === task.id) - let time = cfg.params.time; + let time = cfg.params.time if (Date.now() - task.timeStart < time * 1000) { throw new ZError(11, 'post failed') } let num = Math.random() * 100 if (num < cfg.params.failRate) { throw new ZError(12, 'post failed') - } + } task.status = TaskStatusEnum.SUCCESS task.timeFinish = Date.now() task.data = {} try { await this.user.save() - } catch(err) { + } catch (err) { throw new ZError(100, 'save failed') } if (cfg.autoclaim) { try { - await this.claimReward(task); - } catch(err) { + await this.claimReward(task) + } catch (err) { console.log(err) } } return true } - -} \ No newline at end of file +} diff --git a/src/tasks/base/ITask.ts b/src/tasks/base/ITask.ts index 3f9c203..2835a15 100644 --- a/src/tasks/base/ITask.ts +++ b/src/tasks/base/ITask.ts @@ -1,7 +1,7 @@ -import { ActivityInfo, TaskCfg } from "models/ActivityInfo" -import { ActivityItem } from "models/ActivityItem" -import { ActivityUser, TaskStatus, TaskStatusEnum } from "models/ActivityUser" -import { updateRankScore } from "services/rank.svr" +import { ActivityInfo, TaskCfg } from 'models/ActivityInfo' +import { ActivityItem } from 'models/ActivityItem' +import { ActivityUser, TaskStatus, TaskStatusEnum } from 'models/ActivityUser' +import { updateRankScore } from 'services/rank.svr' export abstract class ITask { static desc: string @@ -11,8 +11,7 @@ export abstract class ITask { user: typeof ActivityUser activity: typeof ActivityInfo - - constructor({user, activity}: {user: typeof ActivityUser, activity: typeof ActivityInfo}) { + constructor({ user, activity }: { user: typeof ActivityUser; activity: typeof ActivityInfo }) { // do nothing this.user = user this.activity = activity @@ -21,10 +20,10 @@ export abstract class ITask { public async claimReward(task: any) { const user = this.user - const [taskId, dateTag] = task.id.split(':'); + const [taskId, dateTag] = task.id.split(':') const cfg = this.activity.tasks.find((t: TaskCfg) => t.id === taskId) if (!cfg.score) { - return; + return } let claimAmount = task.data.claimAmount || 0 let score = cfg.score @@ -41,18 +40,17 @@ export abstract class ITask { scoreParams: { date: dateTag, taskId: task.id, - boost: user.boost - } + boost: user.boost, + }, }) claimAmount += 1 } task.data.claimAmount = claimAmount task.markModified('data') - if ((cfg.repeat > 1 && claimAmount >= cfg.repeat) - || (cfg.repeat === 1 && claimAmount >= 1)) { + if ((cfg.repeat > 1 && claimAmount >= cfg.repeat) || (cfg.repeat === 1 && claimAmount >= 1)) { task.status = TaskStatusEnum.CLAIMED task.timeClaim = Date.now() - } + } await this.claimItem(cfg) await user.save() } @@ -62,8 +60,10 @@ export abstract class ITask { for (let key in cfg.params.items) { let amount = cfg.params.items[key] await ActivityItem.insertOrUpdate( - {user: this.user.id, activity: this.user.activity, item: key}, {$inc: {amount}, last: Date.now()}) + { user: this.user.id, activity: this.user.activity, item: key }, + { $inc: { amount }, last: Date.now() }, + ) } } } -} \ No newline at end of file +} diff --git a/src/utils/chain.util.ts b/src/utils/chain.util.ts index d28631e..1eafbd7 100644 --- a/src/utils/chain.util.ts +++ b/src/utils/chain.util.ts @@ -1,6 +1,6 @@ import { recoverTypedSignature, SignTypedDataVersion } from '@metamask/eth-sig-util' import { soliditySha3, toWei } from 'web3-utils' -import Web3 from 'web3'; +import Web3 from 'web3' export function recoverTypedSignatureV4(signObj: any, signature: string) { return recoverTypedSignature({ @@ -46,22 +46,29 @@ export function buildLoginSignMsg(nonce: string, tips: string) { return signObj } - -export const sign = async ({ user, token, amount, saltNonce } - : {user: string, token: string, amount: number | string, saltNonce?: string}) => { - const web3 = new Web3(); - let privateKey = process.env.SIGN_PRIVATE_KEY; - const acc = web3.eth.accounts.privateKeyToAccount(privateKey); - const account = web3.eth.accounts.wallet.add(acc); +export const sign = async ({ + user, + token, + amount, + saltNonce, +}: { + user: string + token: string + amount: number | string + saltNonce?: string +}) => { + const web3 = new Web3() + let privateKey = process.env.SIGN_PRIVATE_KEY + const acc = web3.eth.accounts.privateKeyToAccount(privateKey) + const account = web3.eth.accounts.wallet.add(acc) const executor = account.address - const amountBn = toWei(amount+''); - const chainId = process.env.CHAIN; - const claimContract = process.env.CLAIM_CONTRACT; - const startTime = Date.now() / 1000 | 0 - saltNonce = saltNonce || ((Math.random() * 1000) | 0) + ''; - let signStr = soliditySha3.apply(this, - [user, token, claimContract, chainId, amountBn, startTime, saltNonce]); - let signature = await web3.eth.sign(signStr, executor); - signature = signature.replace(/00$/, "1b").replace(/01$/, "1c"); - return {token, amount: amountBn, startTime, saltNonce, signature} + const amountBn = toWei(amount + '') + const chainId = process.env.CHAIN + const claimContract = process.env.CLAIM_CONTRACT + const startTime = (Date.now() / 1000) | 0 + saltNonce = saltNonce || ((Math.random() * 1000) | 0) + '' + let signStr = soliditySha3.apply(this, [user, token, claimContract, chainId, amountBn, startTime, saltNonce]) + let signature = await web3.eth.sign(signStr, executor) + signature = signature.replace(/00$/, '1b').replace(/01$/, '1c') + return { token, amount: amountBn, startTime, saltNonce, signature } } diff --git a/src/utils/date.util.ts b/src/utils/date.util.ts index 68184fc..5c57243 100644 --- a/src/utils/date.util.ts +++ b/src/utils/date.util.ts @@ -1,20 +1,20 @@ // format the date to the format we want export const formatDate = (date: Date): string => { - const year = date.getFullYear(); - const month = (date.getMonth() + 1 + '').padStart(2, '0'); - const day = (date.getDate() + '').padStart(2, '0'); - return `${year}${month}${day}`; -}; + const year = date.getFullYear() + const month = (date.getMonth() + 1 + '').padStart(2, '0') + const day = (date.getDate() + '').padStart(2, '0') + return `${year}${month}${day}` +} // get formated datestring of yesterday export const yesterday = (date?: Date) => { - date = date || new Date(); - date.setDate(date.getDate() - 1); - return date; -}; + date = date || new Date() + date.setDate(date.getDate() - 1) + return date +} export const nextday = (date?: Date) => { - date = date || new Date(); - date.setDate(date.getDate() + 1); - return date; -} \ No newline at end of file + date = date || new Date() + date.setDate(date.getDate() + 1) + return date +} diff --git a/src/utils/net.util.ts b/src/utils/net.util.ts index e811c51..aa83981 100644 --- a/src/utils/net.util.ts +++ b/src/utils/net.util.ts @@ -1,4 +1,4 @@ -import { ZError } from "common/ZError" +import { ZError } from 'common/ZError' const TIMEOUT_ERROR = new Error('timeout') @@ -140,7 +140,9 @@ export function generateHeader() { } export const checkParamsNeeded = (...args) => { - args.forEach((arg) => {if (!arg) { - throw new ZError(10, 'params mismatch'); - }}); + args.forEach(arg => { + if (!arg) { + throw new ZError(10, 'params mismatch') + } + }) } diff --git a/src/utils/nft.util.ts b/src/utils/nft.util.ts index c6a2cae..e244872 100644 --- a/src/utils/nft.util.ts +++ b/src/utils/nft.util.ts @@ -1,5 +1,3 @@ - - export const ONE_DAY = 24 * 60 * 60 * 1000 export const NFT_BEGIN_DAY = new Date(2023, 4, 8) @@ -21,5 +19,3 @@ export function daysBetween(date1: Date, date2: Date) { const diffInDays = Math.round(diffInMs / ONE_DAY) return diffInDays } - - diff --git a/src/utils/number.util.ts b/src/utils/number.util.ts index e0500f2..87a90b0 100644 --- a/src/utils/number.util.ts +++ b/src/utils/number.util.ts @@ -1,5 +1,5 @@ -import Web3 from 'web3'; -import { BN } from 'ethereumjs-util'; +import Web3 from 'web3' +import { BN } from 'ethereumjs-util' /** * Converts some token minimal unit to render format string, showing 5 decimals @@ -10,23 +10,17 @@ import { BN } from 'ethereumjs-util'; * @returns {String} - Number of token minimal unit, in render format * If value is less than 5 precision decimals will show '< 0.00001' */ -export function renderFromTokenMinimalUnit( - tokenValue, - decimals, - decimalsToShow = 5 -) { - const minimalUnit = fromTokenMinimalUnit(tokenValue || 0, decimals); - const minimalUnitNumber = parseFloat(minimalUnit); - let renderMinimalUnit; +export function renderFromTokenMinimalUnit(tokenValue, decimals, decimalsToShow = 5) { + const minimalUnit = fromTokenMinimalUnit(tokenValue || 0, decimals) + const minimalUnitNumber = parseFloat(minimalUnit) + let renderMinimalUnit if (minimalUnitNumber < 0.00001 && minimalUnitNumber > 0) { - renderMinimalUnit = "< 0.00001"; + renderMinimalUnit = '< 0.00001' } else { - const base = Math.pow(10, decimalsToShow); - renderMinimalUnit = ( - Math.round(minimalUnitNumber * base) / base - ).toString(); + const base = Math.pow(10, decimalsToShow) + renderMinimalUnit = (Math.round(minimalUnitNumber * base) / base).toString() } - return renderMinimalUnit; + return renderMinimalUnit } /** * Converts token minimal unit to readable string value @@ -36,25 +30,25 @@ export function renderFromTokenMinimalUnit( * @returns {string} - String containing the new number */ export function fromTokenMinimalUnit(minimalInput, decimals) { - minimalInput = addHexPrefix(Number(minimalInput).toString(16)); - let minimal = safeNumberToBN(minimalInput); - const negative = minimal.lt(new BN(0)); - const base = Web3.utils.toBN(Math.pow(10, decimals).toString()); + minimalInput = addHexPrefix(Number(minimalInput).toString(16)) + let minimal = safeNumberToBN(minimalInput) + const negative = minimal.lt(new BN(0)) + const base = Web3.utils.toBN(Math.pow(10, decimals).toString()) if (negative) { - minimal = minimal.mul(new BN(-1)); + minimal = minimal.mul(new BN(-1)) } - let fraction = minimal.mod(base).toString(10); + let fraction = minimal.mod(base).toString(10) while (fraction.length < decimals) { - fraction = "0" + fraction; + fraction = '0' + fraction } - fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]; - const whole = minimal.div(base).toString(10); - let value = "" + whole + (fraction === "0" ? "" : "." + fraction); + fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1] + const whole = minimal.div(base).toString(10) + let value = '' + whole + (fraction === '0' ? '' : '.' + fraction) if (negative) { - value = "-" + value; + value = '-' + value } - return value; + return value } /** @@ -65,20 +59,20 @@ export function fromTokenMinimalUnit(minimalInput, decimals) { * @returns {String} - Number of token minimal unit, in render format * If value is less than 5 precision decimals will show '< 0.00001' */ - export function renderFromWei(value, decimalsToShow = 5) { - let renderWei = '0'; +export function renderFromWei(value, decimalsToShow = 5) { + let renderWei = '0' // avoid undefined if (value) { - const wei = Web3.utils.fromWei(value); - const weiNumber = parseFloat(wei); + const wei = Web3.utils.fromWei(value) + const weiNumber = parseFloat(wei) if (weiNumber < 0.00001 && weiNumber > 0) { - renderWei = '< 0.00001'; + renderWei = '< 0.00001' } else { - const base = Math.pow(10, decimalsToShow); - renderWei = (Math.round(weiNumber * base) / base).toString(); + const base = Math.pow(10, decimalsToShow) + renderWei = (Math.round(weiNumber * base) / base).toString() } } - return renderWei; + return renderWei } /** @@ -89,7 +83,7 @@ export function fromTokenMinimalUnit(minimalInput, decimals) { * @returns {string} - String of the hex token value */ export function calcTokenValueToSend(value, decimals) { - return value ? (value * Math.pow(10, decimals)).toString(16) : 0; + return value ? (value * Math.pow(10, decimals)).toString(16) : 0 } /** @@ -99,11 +93,7 @@ export function calcTokenValueToSend(value, decimals) { * @returns {boolean} - True if the string is a valid decimal */ export function isDecimal(value) { - return ( - Number.isFinite(parseFloat(value)) && - !Number.isNaN(parseFloat(value)) && - !isNaN(+value) - ); + return Number.isFinite(parseFloat(value)) && !Number.isNaN(parseFloat(value)) && !isNaN(+value) } /** @@ -113,7 +103,7 @@ export function isDecimal(value) { * @returns {Object} - BN instance */ export function toBN(value) { - return Web3.utils.toBN(value); + return Web3.utils.toBN(value) } /** @@ -123,20 +113,20 @@ export function toBN(value) { * @returns {string} The prefixed string. */ export const addHexPrefix = (str: string) => { - if (typeof str !== "string" || str.match(/^-?0x/u)) { - return str; + if (typeof str !== 'string' || str.match(/^-?0x/u)) { + return str } if (str.match(/^-?0X/u)) { - return str.replace("0X", "0x"); + return str.replace('0X', '0x') } - if (str.startsWith("-")) { - return str.replace("-", "-0x"); + if (str.startsWith('-')) { + return str.replace('-', '-0x') } - return `0x${str}`; -}; + return `0x${str}` +} /** * Wraps 'numberToBN' method to avoid potential undefined and decimal values @@ -145,8 +135,8 @@ export const addHexPrefix = (str: string) => { * @returns {Object} - The converted value as BN instance */ export function safeNumberToBN(value: number | string) { - const safeValue = fastSplit(value.toString()) || "0"; - return numberToBN(safeValue); + const safeValue = fastSplit(value.toString()) || '0' + return numberToBN(safeValue) } /** @@ -157,66 +147,58 @@ export function safeNumberToBN(value: number | string) { * @returns {string} - the selected splitted element */ -export function fastSplit(value, divider = ".") { - value += ""; - const [from, to] = [value.indexOf(divider), 0]; - return value.substring(from, to) || value; +export function fastSplit(value, divider = '.') { + value += '' + const [from, to] = [value.indexOf(divider), 0] + return value.substring(from, to) || value } export function stripHexPrefix(str: string) { - if (typeof str !== "string") { - return str; + if (typeof str !== 'string') { + return str } - return str.slice(0, 2) === "0x" ? str.slice(2) : str; + return str.slice(0, 2) === '0x' ? str.slice(2) : str } export function numberToBN(arg) { - if (typeof arg === "string" || typeof arg === "number") { + if (typeof arg === 'string' || typeof arg === 'number') { var multiplier = Web3.utils.toBN(1); // eslint-disable-line - var formattedString = String(arg).toLowerCase().trim(); - var isHexPrefixed = - formattedString.substr(0, 2) === "0x" || - formattedString.substr(0, 3) === "-0x"; + var formattedString = String(arg).toLowerCase().trim() + var isHexPrefixed = formattedString.substr(0, 2) === '0x' || formattedString.substr(0, 3) === '-0x' var stringArg = stripHexPrefix(formattedString); // eslint-disable-line - if (stringArg.substr(0, 1) === "-") { - stringArg = stripHexPrefix(stringArg.slice(1)); - multiplier = Web3.utils.toBN(-1); + if (stringArg.substr(0, 1) === '-') { + stringArg = stripHexPrefix(stringArg.slice(1)) + multiplier = Web3.utils.toBN(-1) } - stringArg = stringArg === "" ? "0" : stringArg; + stringArg = stringArg === '' ? '0' : stringArg if ( (!stringArg.match(/^-?[0-9]+$/) && stringArg.match(/^[0-9A-Fa-f]+$/)) || stringArg.match(/^[a-fA-F]+$/) || (isHexPrefixed === true && stringArg.match(/^[0-9A-Fa-f]+$/)) ) { - return Web3.utils.toBN(stringArg).mul(multiplier); + return Web3.utils.toBN(stringArg).mul(multiplier) } - if ( - (stringArg.match(/^-?[0-9]+$/) || stringArg === "") && - isHexPrefixed === false - ) { - return Web3.utils.toBN(stringArg).mul(multiplier); + if ((stringArg.match(/^-?[0-9]+$/) || stringArg === '') && isHexPrefixed === false) { + return Web3.utils.toBN(stringArg).mul(multiplier) } - } else if (typeof arg === "object" && arg.toString && !arg.pop && !arg.push) { - if ( - arg.toString(10).match(/^-?[0-9]+$/) && - (arg.mul || arg.dividedToIntegerBy) - ) { - return Web3.utils.toBN(arg.toString(10)); + } else if (typeof arg === 'object' && arg.toString && !arg.pop && !arg.push) { + if (arg.toString(10).match(/^-?[0-9]+$/) && (arg.mul || arg.dividedToIntegerBy)) { + return Web3.utils.toBN(arg.toString(10)) } } throw new Error( - "[number-to-bn] while converting number " + + '[number-to-bn] while converting number ' + JSON.stringify(arg) + - " to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported." - ); + ' to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported.', + ) } function checkRadixLegal(radix) { - return radix >= 2 && radix <= 62; + return radix >= 2 && radix <= 62 } /** @@ -226,18 +208,18 @@ function checkRadixLegal(radix) { */ function transformCharToNum(letter, base) { if (base <= 36) { - letter = letter.toLowerCase(); + letter = letter.toLowerCase() } if (letter >= '0' && letter <= '9') { - return parseInt(letter); + return parseInt(letter) } if (letter >= 'a' && letter <= 'z') { - return letter.charCodeAt(0) - 'a'.charCodeAt(0) + 10; + return letter.charCodeAt(0) - 'a'.charCodeAt(0) + 10 } if (letter >= 'A' && letter <= 'Z') { - return letter.charCodeAt(0) - 'A'.charCodeAt(0) + 36; + return letter.charCodeAt(0) - 'A'.charCodeAt(0) + 36 } - return 0; + return 0 } /** @@ -246,8 +228,8 @@ function transformCharToNum(letter, base) { * @return {string} */ function transformNumToChar(num, alphabet) { - alphabet = alphabet || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - return alphabet.charAt(num); + alphabet = alphabet || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + return alphabet.charAt(num) } /** @@ -257,30 +239,40 @@ function transformNumToChar(num, alphabet) { * @param {number} to 转换后的进制 * @return {string} */ -export function convert({numStr, base, to, alphabet}: {numStr: string, base: number, to: number, alphabet?: string}): string { +export function convert({ + numStr, + base, + to, + alphabet, +}: { + numStr: string + base: number + to: number + alphabet?: string +}): string { // 当base和to相等 或 base和to超出转换范围,则原样返回 if (base === to || !checkRadixLegal(base) || !checkRadixLegal(to)) { - return numStr; + return numStr } // 先转成10进制 - let p = 0; - let number10 = 0; + let p = 0 + let number10 = 0 while (p < numStr.length) { - number10 *= base; - number10 += transformCharToNum(numStr.charAt(p), base); - p++; + number10 *= base + number10 += transformCharToNum(numStr.charAt(p), base) + p++ } // 若要转换的正好是进制,则直接返回 if (to === 10) { - return number10.toString(); + return number10.toString() } - let result = ''; - let cur; + let result = '' + let cur while (number10) { - cur = number10 % to; - result = transformNumToChar(cur, alphabet) + result; - number10 = Math.floor(number10 / to); + cur = number10 % to + result = transformNumToChar(cur, alphabet) + result + number10 = Math.floor(number10 / to) } - return result; + return result } diff --git a/src/utils/security.util.ts b/src/utils/security.util.ts index f6f2bce..9be14dd 100644 --- a/src/utils/security.util.ts +++ b/src/utils/security.util.ts @@ -82,73 +82,72 @@ export function checkSign({ // } export const aesEncrypt = (plaintText, key) => { - key = CryptoJS.SHA1(key).toString().substring(0,16) + key = CryptoJS.SHA1(key).toString().substring(0, 16) key = CryptoJS.enc.Base64.parse(key) let encryptedData = CryptoJS.AES.encrypt(plaintText, key, { - mode: CryptoJS.mode.ECB, - padding: CryptoJS.pad.Pkcs7 - }); + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7, + }) - return encryptedData.toString(CryptoJS.format.Hex); + return encryptedData.toString(CryptoJS.format.Hex) } export const aesDecrypt = (encryptedDataHexStr, key) => { - key = CryptoJS.SHA1(key).toString().substring(0,16) + key = CryptoJS.SHA1(key).toString().substring(0, 16) key = CryptoJS.enc.Base64.parse(key) - let encryptedHex = CryptoJS.enc.Hex.parse(encryptedDataHexStr); - let encryptedBase64 = CryptoJS.enc.Base64.stringify(encryptedHex); + let encryptedHex = CryptoJS.enc.Hex.parse(encryptedDataHexStr) + let encryptedBase64 = CryptoJS.enc.Base64.stringify(encryptedHex) var decryptedData = CryptoJS.AES.decrypt(encryptedBase64, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7, - }); + }) - return decryptedData.toString(CryptoJS.enc.Utf8); + return decryptedData.toString(CryptoJS.enc.Utf8) } - -const base58Alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; +const base58Alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' export const hexToBase58 = (hexString: string) => { - const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)); - let base58String = ''; + const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)) + let base58String = '' - let num = BigInt('0x' + hexString); + let num = BigInt('0x' + hexString) while (num > BigInt(0)) { - const remainder = num % BigInt(58); - num = num / BigInt(58); - base58String = base58Alphabet[Number(remainder)] + base58String; + const remainder = num % BigInt(58) + num = num / BigInt(58) + base58String = base58Alphabet[Number(remainder)] + base58String } - return base58String; + return base58String } export const base58ToHex = (base58String: string) => { - const base58Length = base58String.length; - let num = BigInt(0); - let leadingZeros = 0; + const base58Length = base58String.length + let num = BigInt(0) + let leadingZeros = 0 for (let i = 0; i < base58Length; i++) { - const charIndex = base58Alphabet.indexOf(base58String[i]); + const charIndex = base58Alphabet.indexOf(base58String[i]) if (charIndex === -1) { - throw new Error('Invalid Base58 string'); + throw new Error('Invalid Base58 string') } - num = num * BigInt(58) + BigInt(charIndex); + num = num * BigInt(58) + BigInt(charIndex) } - return num.toString(16); + return num.toString(16) } export const hexToBase32 = (hexString: string) => { - const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)); - const base32Alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; - let base32String = ''; + const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)) + const base32Alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' + let base32String = '' - let num = BigInt('0x' + hexString); + let num = BigInt('0x' + hexString) while (num > BigInt(0)) { - const remainder = num % BigInt(32); - num = num / BigInt(32); - base32String = base32Alphabet[Number(remainder)] + base32String; + const remainder = num % BigInt(32) + num = num / BigInt(32) + base32String = base32Alphabet[Number(remainder)] + base32String } - return base32String; -} \ No newline at end of file + return base32String +}