增加合作方nft相关接口

This commit is contained in:
CounterFire2023 2024-04-13 11:55:13 +08:00
parent 149a44cc76
commit db5babe823
6 changed files with 8176 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,11 @@
1. 宝箱助力列表(17) 增加返回给邀请者的额外积分
#### 20240413
1. 用户状态(10) 增加返回是否获得白名单字段
2. 增加
### 1. 钱包预登录
#### Request
@ -349,7 +354,8 @@ body:
"scoreSocial": 0, // 社交任务获得的分数
"code": "自己的邀请码",
"mapopen": 0, // 地图开启状态, 0: 未开启, 1: 已开启
"enhanceCount": 1 // 当日剩余助力次数
"enhanceCount": 1, // 当日剩余助力次数
"inWhiteList": 1, // 是否得到白名单
}
```
@ -803,4 +809,55 @@ body:
}]
```
###
### 28. 合作伙伴NFT列表
#### Request
- URL`/api/partner/nfts`
- 方法GET`
- 头部:
- Authorization: Bearer JWT_token
#### Response
```js
[{
"projectName": "L3E7", // 项目名称
"link": "https://twitter.com/L3E7_Official", // 项目方twitter
"contract": "0x20577896ea6113ed8c94b2f08f3893bdc08eba22", //合约地址
"collection": "l3e7 worlds", // NFT的collection名称
"remarks": "600 collection", // 描述
"chain": 1, // 链id
"status": 1, // 已登录状态下, 1表示已领取
}]
```
### 29.\* 领取NFT holder奖励
#### Request
- URL`/api/partner/claim`
- 方法POST
- 头部:
- Authorization: Bearer JWT_token
#### Response
```js
{
chests: [
{ // 结构同 18.宝箱列表
id: 1, // 箱子id
stat: 0, // 0: 锁定, 1: 正常
shareCode: '箱子的分享码',
level: 1, // 箱子品级
maxBonus: 10, // 最大可助力数量
scoreInit: 5, // 初始可获得积分
scoreBonus: 10, // 助力增加的分数
bonusCount: 2, // 已助力次数
}
]
}
```

View File

@ -0,0 +1,76 @@
import { ChestStatusEnum } from 'models/ActivityChest'
import { NFTHolderRecord } from 'models/NFTHodlerRecord'
import { queryNftBalance } from 'services/chain.svr'
import { generateChestLevel, generateNewChest } from 'services/game.svr'
import { SyncLocker, BaseController, router, role, ROLE_ANON, ZError } from 'zutils'
const nftList = require('../../configs/partner_nft_list.json')
const nftListStr = JSON.stringify(nftList)
const nftMap = new Map()
nftList.forEach(o => nftMap.set(o.contract.toLowerCase(), o))
/**
*
*/
class NftController extends BaseController {
/**
* NFT
*/
@role(ROLE_ANON)
@router('get /api/partner/nfts')
async nftList(req) {
const user = req.user
let list = JSON.parse(nftListStr)
list.forEach(o => {
o.status = 0
})
if (user) {
let records = await NFTHolderRecord.find({ user: user.id })
let recordSet = new Set(records.map(o => o.contract.toLowerCase()))
for (let sub of list) {
list.status = recordSet.has(sub.contract.toLowerCase())
}
}
return list
}
/**
* nft holder奖励
*/
@router('post /api/partner/claim')
async claimNftHolderReward(req) {
new SyncLocker().checkLock(req)
const user = req.user
let { contract } = req.params
if (!contract) {
throw new ZError(11, 'contract not found')
}
contract = contract.toLowerCase()
if (!nftMap.has(contract)) {
throw new ZError(12, 'contract not found')
}
let record = await NFTHolderRecord.findOne({ user: user.id, contract })
if (record) {
throw new ZError(13, 'already claimed')
}
let rpcRes = await queryNftBalance(contract, user.address)
console.log('check result:', rpcRes)
if (rpcRes.error) {
throw new ZError(20, `check error: ${rpcRes.error.message}`)
}
let count = parseInt(rpcRes.result)
if (count === 0) {
throw new ZError(14, 'not match claim condition')
}
let randomLevel = generateChestLevel()
let chest = generateNewChest(user.id, user.activity, randomLevel, ChestStatusEnum.NORMAL)
await chest.save()
let recordNew = new NFTHolderRecord({
user: user.id,
contract,
chain: nftMap.get(contract).chain,
holderNum: count,
rewards: [chest.id],
})
await recordNew.save()
return { chests: [chest.toJson()] }
}
}

View File

@ -148,6 +148,7 @@ class SignController extends BaseController {
code: user.inviteCode,
mapopen: gameRecord.status,
enhanceCount,
inWhiteList: user.inWhiteList ? 1 : 0,
}
return result
}

View File

@ -0,0 +1,33 @@
import { Severity, getModelForClass, index, modelOptions, mongoose, prop } from '@typegoose/typegoose'
import { dbconn } from 'decorators/dbconn'
import { BaseModule } from './Base'
/**
* nft hodler claim record
*/
@dbconn()
@index({ user: 1 }, { unique: false })
@index({ user: 1, chain: 1, address: 1 }, { unique: true })
@modelOptions({
schemaOptions: { collection: 'nft_holder_claim_record', timestamps: true },
options: { allowMixed: Severity.ALLOW },
})
class NFTHolderRecordClass extends BaseModule {
@prop({ required: true })
public user: string
@prop()
public chain: number
@prop({ required: true })
public contract: string
@prop({ type: () => [String], default: [] })
public tokenId?: string[]
@prop()
public holderNum: number
@prop({ type: () => [String], default: [] })
public rewards: string[]
}
export const NFTHolderRecord = getModelForClass(NFTHolderRecordClass, {
existingConnection: NFTHolderRecordClass['db'],
})

View File

@ -68,3 +68,24 @@ export const queryStakeList = async (userAddress: string) => {
let records = await NftStake.find({ chain, nft: address, user: userAddress.toLowerCase() })
return records
}
export const queryNftBalance = async (contract: string, address: string) => {
const rpc = 'https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8'
const data = {
id: (Date.now() / 1000) | 0,
jsonrpc: '2.0',
method: 'eth_call',
params: [
{
data: `0x70a08231000000000000000000000000${address.replace('0x', '')}`,
from: address,
to: contract,
},
'latest',
],
}
return fetch(rpc, {
body: JSON.stringify(data),
method: 'POST',
}).then(res => res.json())
}