# UAW相关接口 ### 说明 1. 通用返回格式, errcode=0 表示无错误 2. 如无特别说明, 以下接口的 Response 格式指的是 data 字段 3. 接口名中带\*的表示, 需要验证 token, token 可以设置 header 的 Authorization: Bearer JWT_token, 或 Post body 的 token 字段, 或 Get 的 query token ```json { "errcode": Number, "errmsg": String, "data": {} } ``` ### 0. 更新记录 #### 20240407 1. 增加探索预处理接口(24), 用于探索信息上链前创建一条探索记录 1. 修改 探索(13) request和response结构 1. 探索状态(12) 增加返回已探索总次数totalUsed 1. 探索状态(12), 移除signCfg, 增加seqStat, 用于标识连续签到奖励领取状态 1. 增加领取连续签到奖励(25)的接口 #### 20240408 1. 增加宝箱助力状态查询(26), 用于助力上链前查询是否符合条件 1. 用户状态接口(10)增加返回当日可助力次数 1. 开启宝箱(19), 宝箱开启记录(20)增加返回额外的物品 #### 20240409 1. 增加接口:我的助力记录(27) 2. 所有带用户信息的接口增加返回avatar(头像)字段 #### 20240411 1. 宝箱助力状态查询(26) 增加返回宝箱所有者信息 2. 社交任务活动信息(3) 增加返回基础任务id列表 3. 获取任务奖励(7)增加返回ticket #### 20240412 1. 宝箱助力列表(17) 增加返回给邀请者的额外积分 #### 20240413 1. 用户状态(10) 增加返回是否获得白名单字段 2. 增加接口: 合作伙伴NFT列表 3. 增加接口: 领取NFT holder奖励 #### 20240416 1. 增加接口: 兑换宝箱激活码(30) #### 20240423 1. 签到列表接口(11)增加返回字段: 是否已领取奖励 1. 检查签到并领取奖励(23), 增加post参数, 可以领取指定天数的奖励 1. 宝箱助力(18), 宝箱助力状态查询(26) 增加返回scoreBonus, 表示当前宝箱已得到的助力积分 #### 20240506 1. 增加验证google的access token(32) 2. 增加两种任务类型: GoogleConnect, GameAchievement #### 20240514 1. 用户状态(10) 增加返回emailId, email, gameId, gameMail 2. 增加接口: 发送邮件验证码(33), 验证邮件地址(34) #### 20240515 1. 增加接口: 验证客户端分享码(35) ### 1. 钱包预登录 #### Request - URL:`/api/wallet/nonce?address=` - 方法:`GET` query param | Name | Type | Desc | | ------- | ------ | -------- | | address | string | 钱包地址 | #### Response ```json { "nonce": String, "tips": String } ``` ### 2. 钱包登录 客户端在获得钱包地址后,须先调用预登录方法获取 nonce 和 tips, 然后调用钱包进行 EIP-721 签名. 登录成功后返回的 jwt 需要保存至本地存储, 再次载入后, 可解析并获取 exp 字段, 判断当前 token 是否已经过期 #### Request - URL:`/api/wallet/login` - 方法:`POST` - 头部: - Content-type: application/json - Body: ```json { "activity": String, "signature": String, "message": SiweMessage } ``` SiweMessage说明: https://docs.login.xyz/sign-in-with-ethereum/quickstart-guide/creating-siwe-messages SiweMessage的nonce说明(具体参考例子): ``` 1. 从钱包预登录接口获取nonce 2. nonce = nonce + '|' + 钱包类型字符串 // 比如okx钱包, nonce|okx 3. 使用 活动id 作为 key, 调用aesEncrypt 加密步骤2的字符串 4. 将hex string 转换成base58, 传给SiweMessage ``` #### Response ```json { "token": String, } ``` ### 3. 社交任务活动信息 #### Request - URL:`/api/activity/:id` - 方法:`GET` - 参数: - `id`(当前活动的ID) #### Response ```js { "_id": "TwitterConnect", // 任务id "name": "活动名称", "description": "活动描述", "baseTasks": ["taskid"], // 基础任务id "tasks": [ // 该活动需要完成的任务 { "id": "任务id", "task": "任务类型", "title": "任务名", "desc": "任务描述", "type": 1, //任务类型, 1: 一次性任务, 2: 日常任务 "repeat": 1, // 任务可重复次数 "pretasks": ["task id 1"], //前置任务 "score": 0, // 完成任务可获得的积分 "category": "", // 任务分类 "cfg": {}, // 其他一些任务相关配置参数, 比如icon, 或者其他未考虑的参数 "end": false, // 是否已经结束 "autoclaim": false // 任务完成后是否自动获取奖励 } ], "startTime": 1702628292366, // 活动开始时间 "endTime": 1705220292366 // 活动结束时间 } ``` ### 4. *社交任务进度 #### Request - URL:`/api/tasks/progress` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token - Body: {} #### Response ```js [ { "status": 2, // 任务状态, 0: 未开始, 1: 进行中, 2: 成功, 9: 失败 "id": "TwitterConnect", // 任务id "timeStart": 1703150269527, // 任务开始时间 "data": { // 当前任务带的额外信息, 比如twitter的id和昵称等 "username": "zhl01", "userid": "564269223" }, "timeFinish": 1703150280059 // 任务结束时间 } ] ``` ### 5.\* 开始某个任务 #### Request - URL:`/api/tasks/begin_task` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "task": "TwitterFollow" // 任务id } ``` #### Response ```json { "status": 1, // 任务状态, 0: 未开始, 1: 进行中, 2: 成功, 9: 失败 "id": "TwitterFollow", // 任务id "timeStart": 1703150294051 // 任务开始时间 } ``` ### 6.\* 检查任务状态 #### Request - URL:`/api/tasks/check_task` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token body: ```js { "task": "TwitterFollow" // 任务id } ``` #### Response ```json { "status": 1, // 任务状态, 0: 未开始, 1: 进行中, 2: 成功, 3: 已领取 9: 失败 "id": "TwitterFollow", // 任务id "timeStart": 1703150294051, // 任务开始时间 "timeFinish": 1703151338598 } ``` ### 7.\* 获取任务奖励 #### Request - URL:`/api/tasks/claim` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token body: ```js { "task": "TwitterFollow" // 任务id } ``` #### Response ```json { "status": 1, // 任务状态, 0: 未开始, 1: 进行中, 2: 成功, 3: 已领取 9: 失败 "score": 1, "ticket": 3, // 获得的ticket, 可能没这个字段 } ``` ### 8.\* 提交邀请码 #### Request - URL:`/api/activity/upload_invite_code` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token body: ```js { "code": "邀请人的邀请码" } ``` #### Response ```js { "score": 10, // 获得的积分 } ``` ### 9. 积分排行榜 #### Request - URL:`/api/activity/leaderboard/:activity/:page` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token - 参数: - `activity`(当前活动的ID) - `page` (返回数据的分页序号, 0 开始) > 默认返回100条记录, 如果要返回不同数量, query param传 limit #### Response ```json [ { "rank": 1, // 排名, 从1开始 "level": 1, // 段位 "nickname": "昵称", "score": 1 //获得的积分 } ] ``` ### 10.\* 用户状态 #### Request - URL:`/api/user/state` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```json { "address": "钱包地址", "boost": 1, // 正常值为1, 本次活动不用考虑 "boostExpire": 0, // 计算得分时, 如果boost过期, 即使boost大于1, 也不计算boost, 本次活动不用考虑 "twitterId": "", "twitterName": "", "twitterAvatar": "", // twitter头像 "discordId": "", "discordName": "", "scoreToday": 100, // 今日获得积分 "scoreTotal": 200, // 总积分 "rankTotal": "-", "invite": "邀请人address", "inviteCount": 0, // 我邀请的用户总数 "inviteScore": 0, // 我邀请用户总数获得的分数 "scoreSocial": 0, // 社交任务获得的分数 "code": "自己的邀请码", "mapopen": 0, // 地图开启状态, 0: 未开启, 1: 已开启 "enhanceCount": 1, // 当日剩余助力次数 "inWhiteList": 1, // 是否得到白名单 "gameId": '111', // 游戏帐号绑定的id, 优先取googleId "gameMail": '', // 游戏帐号绑定的email, 优先取gmail } ``` ### 11.\* 签到列表 #### Request - URL:`/api/user/checkin/list/:tag` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token query param | Name | Type | Desc | | ------- | ------ | -------- | | tag | string | last: 最新, 前一天+今天, 1month: 当月 | #### Response ```json [ { "address": "钱包地址", "day": "20240105", // 格式化后签到日期, 时区按SG(UTC+8) "time": 1704436745, // 具体的签到时间 "count": 0, //连签天数 "total": 10, //累计签到天数 "claimed": true, // 当日签到奖励是否已领取 }, ] ``` ### 12.\* 探索状态 #### Request - URL:`/api/game/stat` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js { ticket: 1, // 可用探索次数 totalUsed: 1, // 已探索总次数 todayStat: 0, // 当日签到状态, 0: 未签到, 1: 已签到,但未领取 9:已签到, 已领取 todayTickets: 1, // 当日签到可领取次数 daysTotal: 1, // 累计签到天数 daysSeq: 1, // 连续签到天数 totalStat: [{ // 累计签到状态 days: 3, // 天数 tickets: 2, // 满足条件后可领取数量 state: 0, // 领取状态: 0: 未领取, 1: 可领取, 9: 已领取 }], seqStat: [{ // 连续签到状态 days: 3, // 天数 tickets: 2, // 满足条件后可领取数量 state: 0, // 领取状态: 0: 未领取, 1: 可领取, 9: 已领取 }] } ``` ### 13.\* 探索 #### Request - URL:`/api/game/step` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "id": "" // 探索预处理接口返回的id } ``` #### Response ```js { score: 20, //获得积分数量 chest: [{ // 结构同 18.宝箱列表 id: 1, // 箱子id stat: 0, // 0: 锁定, 1: 正常 shareCode: '箱子的分享码', level: 1, // 箱子品级 maxBonus: 10, // 最大可助力数量 scoreInit: 5, // 初始可获得积分 scoreBonus: 10, // 助力增加的分数 bonusCount: 2, // 已助力次数 }] } ``` ### 14.\* 领取累计签到奖励 #### Request - URL:`/api/user/checkin/claim` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "days": 3 // 领取的累计签到天数 } ``` #### Response ```js { ticket: 2, //获得探索次数 } ``` ### 15.\* 已邀请列表 #### Request - URL:`/api/activity/invite_list` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js [{ level: 1, // 段位 nickname: '用户昵称', score: 100, // 获得的积分 scoreInvite: 1 // 该用户上缴给你的积分 }] ``` ### 16.\* 宝箱列表 #### Request - URL:`/api/chest/list` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js [{ id: 1, // 箱子id stat: 0, // 0: 锁定, 1: 正常, 2: 已开启, 未领取, 9: 已领取 shareCode: '箱子的分享码', level: 1, // 箱子品级 maxBonus: 10, // 最大可助力数量 scoreInit: 5, // 初始可获得积分 scoreBonus: 10, // 助力增加的分数 bonusCount: 2, // 已助力次数 }] ``` ### 17.\* 宝箱助力记录 #### Request - URL:`/api/chest/enhance/list` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { chestId: '12312313' // 宝箱id } ``` #### Response ```js [{ nickname: '用户昵称', avatar: '头像', score: 100, // 获得的积分 time: 123123123, }] ``` ### 18.\* 宝箱助力 #### Request - URL:`/api/chest/enhance` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { code: '131aasd`1' // 宝箱的分享码 } ``` #### Response ```js { score: 100, // 自己获得的积分 scoreBonus: 1 //当前箱子已助力积分 } ``` ### 19.\* 开启宝箱 #### Request - URL:`/api/chest/open` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { chestId: '131aasd`1' // 宝箱id } ``` #### Response ```js { score: 100, // 获得的积分 items: [ { id: "001", // 物品id type: 1, // 1白单, 2: nft name: "", // 物品名 desc: "", // 描述 amount: 1 // 数量 } ] } ``` ### 20.\* 宝箱开启记录 #### Request - URL:`/api/chest/open/history` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js [{ chest: '123123123', level: 1, // 箱子品级 score: 100, // 获得的积分 time: 111, // 开启时间 items: [ { id: "001", // 物品id type: 1, // 1白单, 2: nft name: "", // 物品名 desc: "", // 描述 amount: 1 // 数量 } ] }] ``` ### 21.\* 积分详情列表 #### Request - URL:`/api/activity/score_list` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js [{ score: 100, // 获得的积分 type: '', // 获取原因 time: 111 // 开启时间 }] ``` ### 22.\* 开启地图 #### Request - URL:`/api/game/open` - 方法:`GET` - 头部: - Authorization: Bearer JWT_token > 返回没errcode就表示开启成功 ### 23.\* 检查签到并领取奖励 #### Request - URL:`/api/user/checkin` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "day": "20240418" //需要领取的天数, 该字段为空的话, 领取当日的 } ``` #### Response ```js { ticket: 1 // 获得的探索次数 } ``` ### 24.\* 探索预处理 #### Request - URL:`/api/game/pre_step` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "step": 2 // 使用的次数 } ``` #### Response ```js { id: '' // 本次探索上链需要的数据 } ``` ### 25.\* 领取连续签到奖励 #### Request - URL:`/api/user/checkin/claim_seq` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "code": 3 // 领取的累计签到天数 } ``` #### Response ```js { ticket: 2, //获得探索次数 } ``` ### 26.\ 宝箱助力状态查询 #### Request - URL:`/api/chest/enhance/state` - 方法:`POST` - 头部: - Authorization: Bearer JWT_token body: ```js { "code": "1123", // 宝箱的分享code, code和chestId选择传一个, 如果两个都传, 优先使用chestId来查询箱子 "chestId": "123123" } ``` #### Response ```js { userCurrent: 1, // 用户当日已助力次数, 未登录用户可能为空 userMax: 10, // 用户当日最大可助力次数, 未登录用户可能为空 enhanced: 0, // 用户是否已经为当前宝箱助力, 未登录用户可能为空 chestCurrent: 1, // 宝箱当前助力次数 chestMax: 10, // 宝箱最大可助力次数 nickname: '11', // 宝箱所有者昵称 avatar: '', // 宝箱所有者头像, 可能为空 scoreBonus: 1 //当前箱子已助力积分 } ``` ### 27.\* 我的助力记录 #### Request - URL:`/api/user/enhance/list` - 方法:GET` - 头部: - Authorization: Bearer JWT_token #### Response ```js [{ nickname: '用户昵称', avatar: '头像', time: 123123123123, score: 100, // 我获得的积分 }] ``` ### 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", // 描述 "img": "111", // nft相关图片 "chain": 1, // 链id "status": 1, // 已登录状态下, 1表示已领取 }] ``` ### 29.\* 领取NFT holder奖励 #### Request - URL:`/api/partner/claim` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "contract": "NFT合约地址" } ``` #### Response ```js { chests: [ { // 结构同 18.宝箱列表 id: 1, // 箱子id stat: 0, // 0: 锁定, 1: 正常 shareCode: '箱子的分享码', level: 1, // 箱子品级 maxBonus: 10, // 最大可助力数量 scoreInit: 5, // 初始可获得积分 scoreBonus: 10, // 助力增加的分数 bonusCount: 2, // 已助力次数 } ] } ``` ### 30.\* 兑换宝箱激活码 #### Request - URL:`/api/voucher/claim` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "id": "兑换码" } ``` #### Response ```js { chests: [ { // 结构同 18.宝箱列表 id: 1, // 箱子id stat: 0, // 0: 锁定, 1: 正常 shareCode: '箱子的分享码', level: 1, // 箱子品级 maxBonus: 10, // 最大可助力数量 scoreInit: 5, // 初始可获得积分 scoreBonus: 10, // 助力增加的分数 bonusCount: 2, // 已助力次数 } ] } ``` ### 31.\* 生成测试用宝箱激活码 > 只在测试环境有效 > #### Request - URL:`/api/voucher/generate` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "num": 10, //要生成的激活码数量 } ``` #### Response ```js ['1234567890ab'] // 激活码列表 ``` ### 32.\* 验证google的access token #### Request - URL:`/api/user/verify_google` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "code": "google oauth access token" } ``` #### Response ```js { } ``` ### 33.\* 发送邮件验证码 #### Request - URL:`/api/email/send_code` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "email": "email" } ``` > 验证email的正则 ```js export const isEmail = (email) => { const reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/ return reg.test(email) } ``` #### Response ```js { } ``` ### 34.\* 验证邮件地址 #### Request - URL:`/api/user/verify_email` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "email": "email", "code": "123221" } ``` > 验证code的正则 ```js export const isValiedCode = (code) => { return /^\d{6}$/.test(code) } ``` #### Response ```js { } ``` ### 35.\* 验证客户端分享码 #### Request - URL:`/api/user/verify_client` - 方法:POST - 头部: - Authorization: Bearer JWT_token body: ```js { "code": "12322100" } ``` > 验证code的正则 ```js export const isValiedCode = (code) => { return /^[23456789abcdefghjkmnpqrstuvwxy]{8}$/.test(code) } ``` #### Response ```js { } ``` ### 36.\* 查询可获得的CEC #### Request - URL:`/api/cec/info/:address` - 方法:`GET` #### Response ```js { "total": "200000000000000000000", // 总量 "available": "100000000000000000000", // 当前可获取的数量 "claimed": "0", // 已领取的数量 "stages": [ // 阶段信息 { "stage": 1, "amount": "100000000000000000000", // 当前阶段可获取的数量 "status": 0, // 领取状态, 0: 未领取, 1: 领取中, 9: 已领取 "unlocked": true, // 是否已解锁 "claimTime": 1720685893000, // 领取时间 "unlockTime": 1720685893000 // 解锁时间 }, { "stage": 2, "amount": "100000000000000000000", "status": 0, "unlocked": false, "unlockTime": 1720772293000 } ], "records": [ { "address": "0x50a8e60041a206acaa5f844a1104896224be6f39", "amount": "100000000000000000000", // 获得数量 "desc": "UAW", // 获得原因 "earnTime": "2024/04/01-2024/06/01" // 获得的时间 }, { "address": "0x50a8e60041a206acaa5f844a1104896224be6f39", "amount": "100000000000000000000", "desc": "UAW ingame", "earnTime": "2024/04/01-2024/06/01" } ] } ```