task-svr/src/services/chain.svr.ts
2024-08-21 16:30:49 +08:00

194 lines
6.3 KiB
TypeScript

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)
}