import { Contract } from 'ethers' import { CheckIn } from 'models/chain/CheckIn' import { NftHolder } from 'models/chain/NftHolder' import { NftStake } from 'models/chain/NftStake' import { sign } from 'utils/sign.utils' import { getMonthBegin, getNDayAgo } from 'utils/utcdate.util' import { timeoutFetch } from 'zutils/utils/net.util' import { numberToBN } from 'zutils/utils/number.util' const DEFAULT_TIMEOUT = 30000 const ACTIVITY_RPC_URL = process.env.ACTIVITY_RPC_URL export const queryCheckInList = async (address: string, days: string | number | string[], limit: number = 0) => { let query: any = { from: address.toLowerCase() } if (!limit) { if (typeof days === 'number') { let begin = getNDayAgo(days, true) query.blockTime = { $gt: (begin.getTime() / 1000) | 0 } } else if (typeof days === 'string') { if (days === '1month') { let date = getMonthBegin(new Date()) query.blockTime = { $gt: (date.getTime() / 1000) | 0 } } else { query.dateTag = days } } else if (Array.isArray(days)) { query.dateTag = { $in: days } } } let records if (limit) { records = await CheckIn.find(query).sort({ _id: -1 }).limit(limit) } else { records = await CheckIn.find(query).sort({ _id: -1 }) } let result = [] for (let record of records) { result.push(record.toJson()) } return result } export const queryCheckInSeq = async (address: string) => { const record = await CheckIn.findOne({ from: address.toLowerCase() }).sort({ count: -1 }) return record.toJson() } export const queryBurnNftList = async (address: string, user: string, chain: string) => { address = address.toLowerCase() user = user.toLowerCase() let records = await NftHolder.find({ address, chain, user, burn: true }).sort({ blockNumber: -1 }) let result = [] for (let record of records) { result.push({ address: record.address, chain: record.chain, user: record.user, tokenId: record.tokenId, }) } return result } export const checkHadGacha = async (user: string) => { const chain = process.env.CHAIN + '' const address = process.env.GACHA_CONTRACT const record = await NftHolder.findOne({ user, chain, address }) return !!record } export const queryStakeList = async (userAddress: string) => { const chain = process.env.CHAIN + '' const address = process.env.BADGE_CONTRACT let records = await NftStake.find({ chain, nft: address, user: userAddress.toLowerCase() }) return records } const requestChain = async (rpc: string, method: string, params: any) => { const data = { id: Date.now(), jsonrpc: '2.0', method, params, } const options: any = { method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8', }, body: JSON.stringify(data), } return timeoutFetch(rpc, options, DEFAULT_TIMEOUT).then(res => res.json()) } export const queryNftBalance = async (contract: string, address: string) => { const rpc = 'https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8' const params = [ { data: `0x70a08231000000000000000000000000${address.replace('0x', '')}`, from: address, to: contract, }, 'latest', ] return requestChain(rpc, 'eth_call', params) } export const fetchChainStatus = async (address: string, data: string) => { console.log(data) const params = [ { data: data, from: address, to: process.env.ACTIVITY_CONTRACT, }, 'latest', ] return requestChain(ACTIVITY_RPC_URL, 'eth_call', params) } export const fetchCheckInStatus = async (address: string) => { const days = (Date.now() / 1000 / 60 / 60 / 24) | 0 const valStr = days.toString(16).padStart(64, '0') const addressStr = address.replace('0x', '').padStart(64, '0') const method = '86cd4926' return fetchChainStatus(address, `0x${method}${addressStr}${valStr}`) } export const fetchExploreStatus = async (address: string, exploreId: string) => { const valStr = exploreId.toString().padStart(64, '0') const addressStr = address.replace('0x', '').padStart(64, '0') const method = '36028275' return fetchChainStatus(address, `0x${method}${addressStr}${valStr}`) } export const fetchOpenBoxtatus = async (address: string, boxId: string) => { const valStr = boxId.padStart(64, '0') const addressStr = address.replace('0x', '').padStart(64, '0') const method = 'd869bb29' return fetchChainStatus(address, `0x${method}${addressStr}${valStr}`) } export const fetchEnhanceStatus = async (address: string, shareCode: string) => { const shareCodeHex = shareCode .split('') .map(c => c.charCodeAt(0).toString(16).padStart(2, '0')) .join('') const valStr = shareCodeHex.padStart(64, '0') const addressStr = address.replace('0x', '').padStart(64, '0') const method = '9b68ea4c' let res = await fetchChainStatus(address, `0x${method}${addressStr}${valStr}`) if (res.error) { throw new Error(res.error.message) } let result = parseInt(res.result) return !!result } export const fetchClaimStatus = async (address: string, taskId: string) => { const taskIdHex = taskId .split('') .map(c => c.charCodeAt(0).toString(16).padStart(2, '0')) .join('') const valStr = taskIdHex.padStart(64, '0') const addressStr = address.replace('0x', '').padStart(64, '0') const method = '4902f7e0' return fetchChainStatus(address, `0x${method}${addressStr}${valStr}`) } const claimTokenAbi = [ 'function claim(address,address,uint256[4],bytes)', ] const claimKeyArr = ["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"] export const buildTokenClaimData = async ({address, account, token, amount, bit, nonce}: { address: string, account: string, token: string, amount: string, bit: number | string, nonce: string }) => { const contract = new Contract(process.env.CLAIM_CONTRACT, claimTokenAbi) const time = (Date.now() / 1000 | 0)+'' bit = bit +'' const signValArr = [address, account, token, process.env.CLAIM_CONTRACT, process.env.CLAIM_CHAIN, amount, bit, time, nonce] const signature = await sign(process.env.SIGN_PRIVATE_KEY, claimKeyArr, signValArr) const vals = [amount, bit, time, nonce] const params = [account, token, vals, signature] console.log(JSON.stringify(params)) return contract.populateTransaction['claim'](...params) }