reformat code

This commit is contained in:
CounterFire2023 2024-01-17 17:38:02 +08:00
parent 95cd194db2
commit 32b0e9d01e
20 changed files with 388 additions and 405 deletions

View File

@ -113,7 +113,7 @@ class LoginController extends BaseController {
const user = await Account.insertOrUpdate({ plat: channel, openId }, data) const user = await Account.insertOrUpdate({ plat: channel, openId }, data)
const { unionAccount, walletUser } = await parseBindAccount(account, channel, user) const { unionAccount, walletUser } = await parseBindAccount(account, channel, user)
if (plat.afterLogin) { if (plat.afterLogin) {
await plat.afterLogin(user); await plat.afterLogin(user)
} }
const ztoken = await res.jwtSign({ const ztoken = await res.jwtSign({
id: walletUser.id, id: walletUser.id,

View File

@ -115,21 +115,21 @@ class OkxController extends BaseController {
async queryWalletTransInfo(req, res) { async queryWalletTransInfo(req, res) {
let { chainId, walletId, orderId } = req.params let { chainId, walletId, orderId } = req.params
chainId = chainId || DEFAULT_CHAINID chainId = chainId || DEFAULT_CHAINID
let result = await queryTranDetail({walletId, orderId, chainId}) let result = await queryTranDetail({ walletId, orderId, chainId })
return result.data return result.data
} }
@router('post /wallet/okx/sendtran') @router('post /wallet/okx/sendtran')
async sendWalletTran(req, res) { async sendWalletTran(req, res) {
let { data } = req.params let { data } = req.params
let user = req.user; let user = req.user
let record = await Wallet.findOne({ account: user.id }) let record = await Wallet.findOne({ account: user.id })
if (!record || !record.address) { if (!record || !record.address) {
throw new ZError(11, 'no wallet found') throw new ZError(11, 'no wallet found')
} }
data.chainId = data.chainId || DEFAULT_CHAINID data.chainId = data.chainId || DEFAULT_CHAINID
data.walletId = record.id; data.walletId = record.id
console.log('send trans: ' + JSON.stringify(data)); console.log('send trans: ' + JSON.stringify(data))
let result = await sendTran(data) let result = await sendTran(data)
if (result.status !== 200) { if (result.status !== 200) {
throw new ZError(result.status, result.statusText) throw new ZError(result.status, result.statusText)
@ -140,17 +140,20 @@ class OkxController extends BaseController {
if (result.data?.data) { if (result.data?.data) {
setImmediate(async () => { setImmediate(async () => {
try { try {
await TranRecord.insertOrUpdate({ await TranRecord.insertOrUpdate(
transactionHash: data.txHash, {
}, { transactionHash: data.txHash,
okxOrderId: result.data.data.orderId, },
}) {
okxOrderId: result.data.data.orderId,
},
)
logger.log(`success update log: ${data.txHash}`) logger.log(`success update log: ${data.txHash}`)
} catch (err) { } catch (err) {
logger.log(`error update log: ${data.txHash} with error: ${err}`) logger.log(`error update log: ${data.txHash} with error: ${err}`)
} }
}); })
} }
return {txHash: data.txHash} return { txHash: data.txHash }
} }
} }

View File

@ -1,24 +1,24 @@
import BaseController, {ROLE_ANON, ROLE_SESSION} from 'common/base.controller' import BaseController, { ROLE_ANON, ROLE_SESSION } from 'common/base.controller'
import {ZError} from 'common/ZError' import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router' import { role, router } from 'decorators/router'
import logger from 'logger/logger' import logger from 'logger/logger'
import {RelayRecord, RelayStatusEnum} from 'modules/RelayRecord' import { RelayRecord, RelayStatusEnum } from 'modules/RelayRecord'
import {RelaySession} from 'modules/RelaySession' import { RelaySession } from 'modules/RelaySession'
import {checkPersionalSign} from 'utils/ether.util' import { checkPersionalSign } from 'utils/ether.util'
class RelayController extends BaseController { class RelayController extends BaseController {
@role(ROLE_ANON) @role(ROLE_ANON)
@router('post /wallet/relay/prepare') @router('post /wallet/relay/prepare')
async prepareClient(req, res) { async prepareClient(req, res) {
let {msg, address, signature} = req.params; let { msg, address, signature } = req.params
if (!msg || !address || !signature) { if (!msg || !address || !signature) {
throw new ZError(10, 'params mismatch' ) throw new ZError(10, 'params mismatch')
} }
// check signature // check signature
if (!checkPersionalSign(msg, address, signature)) { if (!checkPersionalSign(msg, address, signature)) {
throw new ZError(11, 'signature mismatch' ) throw new ZError(11, 'signature mismatch')
} }
let session = new RelaySession({ msg, address, signature }) let session = new RelaySession({ msg, address, signature })
await session.save() await session.save()
const ztoken = await res.jwtSign({ const ztoken = await res.jwtSign({
sid: session.id, sid: session.id,
@ -29,58 +29,56 @@ class RelayController extends BaseController {
@role(ROLE_SESSION) @role(ROLE_SESSION)
@router('post /wallet/relay/putdata') @router('post /wallet/relay/putdata')
async uploadData(req, res) { async uploadData(req, res) {
let {data, type, session_id} = req.params; let { data, type, session_id } = req.params
if (type == undefined || !data) { if (type == undefined || !data) {
throw new ZError(10, 'params mismatch' ) throw new ZError(10, 'params mismatch')
} }
type = parseInt(type); type = parseInt(type)
let record = new RelayRecord({ sid: session_id, type, data }) let record = new RelayRecord({ sid: session_id, type, data })
await record.save() await record.save()
return {id: record.id} return { id: record.id }
} }
@role(ROLE_SESSION) @role(ROLE_SESSION)
@router('post /wallet/relay/updata') @router('post /wallet/relay/updata')
async updateData(req, res) { async updateData(req, res) {
let {data, id} = req.params; let { data, id } = req.params
if (!id || !data) { if (!id || !data) {
throw new ZError(10, 'params mismatch' ) throw new ZError(10, 'params mismatch')
} }
let record = await RelayRecord.findById(id); let record = await RelayRecord.findById(id)
record.status = RelayStatusEnum.RESOLVED; record.status = RelayStatusEnum.RESOLVED
record.resp = data; record.resp = data
await record.save() await record.save()
return {id: record.id} return { id: record.id }
} }
@role(ROLE_SESSION) @role(ROLE_SESSION)
@router('post /wallet/relay/getlast') @router('post /wallet/relay/getlast')
async fetchLast(req, res) { async fetchLast(req, res) {
let { session_id, type } = req.params; let { session_id, type } = req.params
if (type == undefined) { if (type == undefined) {
throw new ZError(10, 'params mismatch' ) throw new ZError(10, 'params mismatch')
} }
type = parseInt(type); type = parseInt(type)
let record = await RelayRecord.findLastRecord(session_id, type); let record = await RelayRecord.findLastRecord(session_id, type)
if (!record) { if (!record) {
throw new ZError(11, 'record not found' ) throw new ZError(11, 'record not found')
} }
return {id: record.id, data: record.data, status: record.status} return { id: record.id, data: record.data, status: record.status }
} }
@role(ROLE_SESSION) @role(ROLE_SESSION)
@router('post /wallet/relay/getdata') @router('post /wallet/relay/getdata')
async fetchData(req, res) { async fetchData(req, res) {
let { id } = req.params; let { id } = req.params
if (!id ) { if (!id) {
throw new ZError(10, 'params mismatch' ) throw new ZError(10, 'params mismatch')
} }
let record = await RelayRecord.findById(id); let record = await RelayRecord.findById(id)
if (!record) { if (!record) {
throw new ZError(11, 'record not found' ) throw new ZError(11, 'record not found')
} }
return {id: record.id, data: record.data, resp: record.resp, status: record.status} return { id: record.id, data: record.data, resp: record.resp, status: record.status }
} }
} }

View File

@ -1,9 +1,9 @@
import BaseController, {ROLE_ANON} from 'common/base.controller' import BaseController, { ROLE_ANON } from 'common/base.controller'
import {ZError} from 'common/ZError' import { ZError } from 'common/ZError'
import { role, router } from 'decorators/router' import { role, router } from 'decorators/router'
import logger from 'logger/logger' import logger from 'logger/logger'
import {DEFAULT_EXPIRED, NonceRecord} from 'modules/NonceRecord' import { DEFAULT_EXPIRED, NonceRecord } from 'modules/NonceRecord'
import {SiweMessage} from 'siwe' import { SiweMessage } from 'siwe'
import { checkParamsNeeded } from 'utils/net.util' import { checkParamsNeeded } from 'utils/net.util'
const LOGIN_TIP = 'This signature is just to verify your identity' const LOGIN_TIP = 'This signature is just to verify your identity'
@ -23,7 +23,7 @@ class SignController extends BaseController {
const { signature, message } = req.params const { signature, message } = req.params
checkParamsNeeded(signature, message) checkParamsNeeded(signature, message)
if (!message.nonce) { if (!message.nonce) {
throw new ZError(11, 'Invalid nonce'); throw new ZError(11, 'Invalid nonce')
} }
let record = await NonceRecord.findById(message.nonce) let record = await NonceRecord.findById(message.nonce)
if (!record || record.status !== 0) { if (!record || record.status !== 0) {
@ -34,9 +34,9 @@ class SignController extends BaseController {
} }
record.status = 1 record.status = 1
await record.save() await record.save()
const msgSign = new SiweMessage(message); const msgSign = new SiweMessage(message)
try { try {
await msgSign.verify({ signature, nonce: record.id }); await msgSign.verify({ signature, nonce: record.id })
} catch (e) { } catch (e) {
throw new ZError(14, 'signature invalid') throw new ZError(14, 'signature invalid')
} }

View File

@ -17,10 +17,10 @@ const DEFAULT_CHAINID = 42161
const bindOkx = async (record: any) => { const bindOkx = async (record: any) => {
console.log('bindOkx: ', record.address) console.log('bindOkx: ', record.address)
let res = await createWallet({ let res = await createWallet({
addresses: [{ chainId: DEFAULT_CHAINID, address: record.address}], addresses: [{ chainId: DEFAULT_CHAINID, address: record.address }],
walletId: record.id walletId: record.id,
}) })
console.log('bind result: '+ JSON.stringify(res.data)); console.log('bind result: ' + JSON.stringify(res.data))
if (!res.data.code || res.data.code == 81102) { if (!res.data.code || res.data.code == 81102) {
record.toOkx = true record.toOkx = true
await record.save() await record.save()
@ -42,8 +42,8 @@ class WalletController extends BaseController {
} }
if (!record.toOkx && record.address) { if (!record.toOkx && record.address) {
setImmediate(async () => { setImmediate(async () => {
await bindOkx(record) await bindOkx(record)
}); })
} }
Object.assign(data, record.toJson()) Object.assign(data, record.toJson())
return data return data
@ -90,8 +90,8 @@ class WalletController extends BaseController {
if (!record.toOkx) { if (!record.toOkx) {
if (!record.toOkx && record.address) { if (!record.toOkx && record.address) {
setImmediate(async () => { setImmediate(async () => {
await bindOkx(record) await bindOkx(record)
}); })
} }
} }
return {} return {}

View File

@ -1,4 +1,4 @@
export enum RelayTypeEnum { export enum RelayTypeEnum {
TO_WALLET = 0, TO_WALLET = 0,
FROM_WALLET = 1 FROM_WALLET = 1,
} }

View File

@ -18,4 +18,3 @@ class NonceRecordClass extends BaseModule {
} }
export const NonceRecord = getModelForClass(NonceRecordClass, { existingConnection: NonceRecordClass['db'] }) export const NonceRecord = getModelForClass(NonceRecordClass, { existingConnection: NonceRecordClass['db'] })

View File

@ -1,13 +1,13 @@
import { getModelForClass, index, modelOptions, mongoose, prop, Severity } from '@typegoose/typegoose' import { getModelForClass, index, modelOptions, mongoose, prop, Severity } from '@typegoose/typegoose'
import { dbconn } from 'decorators/dbconn' import { dbconn } from 'decorators/dbconn'
import {RelayTypeEnum} from 'enums/RelayTypeEnum' import { RelayTypeEnum } from 'enums/RelayTypeEnum'
import { BaseModule } from './Base' import { BaseModule } from './Base'
export const DEFAULT_EXPIRED = 1000 * 60 * 5 export const DEFAULT_EXPIRED = 1000 * 60 * 5
export enum RelayStatusEnum { export enum RelayStatusEnum {
PENDING = 0, PENDING = 0,
RESOLVED = 1, RESOLVED = 1,
FINISHED = 2, FINISHED = 2,
FAILED = 9, FAILED = 9,
} }
@ -21,16 +21,16 @@ class RelayRecordClass extends BaseModule {
@prop({ enum: RelayStatusEnum, default: RelayStatusEnum.PENDING }) @prop({ enum: RelayStatusEnum, default: RelayStatusEnum.PENDING })
public status: RelayStatusEnum public status: RelayStatusEnum
@prop({required: true}) @prop({ required: true })
public sid: string public sid: string
@prop({ enum: RelayTypeEnum, default: RelayTypeEnum.TO_WALLET }) @prop({ enum: RelayTypeEnum, default: RelayTypeEnum.TO_WALLET })
public type: RelayTypeEnum public type: RelayTypeEnum
@prop({ required: true, type: mongoose.Schema.Types.Mixed }) @prop({ required: true, type: mongoose.Schema.Types.Mixed })
public data: any public data: any
@prop({type: mongoose.Schema.Types.Mixed }) @prop({ type: mongoose.Schema.Types.Mixed })
public resp: any public resp: any
public static async findLastRecord(sid: string, type: RelayTypeEnum) { public static async findLastRecord(sid: string, type: RelayTypeEnum) {
@ -43,4 +43,3 @@ class RelayRecordClass extends BaseModule {
} }
export const RelayRecord = getModelForClass(RelayRecordClass, { existingConnection: RelayRecordClass['db'] }) export const RelayRecord = getModelForClass(RelayRecordClass, { existingConnection: RelayRecordClass['db'] })

View File

@ -16,9 +16,9 @@ class RelaySessionClass extends BaseModule {
@prop({ default: Date.now() + DEFAULT_EXPIRED }) @prop({ default: Date.now() + DEFAULT_EXPIRED })
public expired: number public expired: number
public async refreshExpired() { public async refreshExpired() {
this.expired = Date.now() + DEFAULT_EXPIRED; this.expired = Date.now() + DEFAULT_EXPIRED
} }
public static async removeExpired() { public static async removeExpired() {
@ -27,4 +27,3 @@ class RelaySessionClass extends BaseModule {
} }
export const RelaySession = getModelForClass(RelaySessionClass, { existingConnection: RelaySessionClass['db'] }) export const RelaySession = getModelForClass(RelaySessionClass, { existingConnection: RelaySessionClass['db'] })

View File

@ -28,7 +28,7 @@ class WalletClass extends BaseModule {
@prop({ required: true, default: true }) @prop({ required: true, default: true })
public nweRecord: boolean public nweRecord: boolean
@prop({default: false}) @prop({ default: false })
public toOkx: boolean public toOkx: boolean
public static async findByAccount(this: ReturnModelType<typeof WalletClass>, account: string) { public static async findByAccount(this: ReturnModelType<typeof WalletClass>, account: string) {

View File

@ -1,21 +1,21 @@
import { checkParamsNeeded } from 'utils/net.util' import { checkParamsNeeded } from 'utils/net.util'
import { IPlat } from './IPlat' import { IPlat } from './IPlat'
import { ZError } from 'common/ZError'; import { ZError } from 'common/ZError'
import { NonceRecord } from 'modules/NonceRecord'; import { NonceRecord } from 'modules/NonceRecord'
import { SiweMessage } from 'siwe'; import { SiweMessage } from 'siwe'
import { DocumentType } from '@typegoose/typegoose' import { DocumentType } from '@typegoose/typegoose'
import { AccountClass } from 'modules/Account' import { AccountClass } from 'modules/Account'
import { Wallet } from 'modules/Wallet'; import { Wallet } from 'modules/Wallet'
export class PlatExternalWallet implements IPlat { export class PlatExternalWallet implements IPlat {
async verifyToken(req: any): Promise<any> { async verifyToken(req: any): Promise<any> {
// here code is signature // here code is signature
let { code, message } = req.params let { code, message } = req.params
checkParamsNeeded(code, message); checkParamsNeeded(code, message)
if (!message.nonce) { if (!message.nonce) {
throw new ZError(11, 'Invalid nonce'); throw new ZError(11, 'Invalid nonce')
} }
let record = await NonceRecord.findById(message.nonce) let record = await NonceRecord.findById(message.nonce)
if (!record || record.status !== 0) { if (!record || record.status !== 0) {
throw new ZError(12, 'nonce invalid') throw new ZError(12, 'nonce invalid')
@ -25,13 +25,13 @@ export class PlatExternalWallet implements IPlat {
} }
record.status = 1 record.status = 1
await record.save() await record.save()
const msgSign = new SiweMessage(message); const msgSign = new SiweMessage(message)
try { try {
await msgSign.verify({ signature: code, nonce: record.id }); await msgSign.verify({ signature: code, nonce: record.id })
} catch (e) { } catch (e) {
throw new ZError(14, 'signature invalid') throw new ZError(14, 'signature invalid')
} }
const openId = message.address const openId = message.address
let data: any = {} let data: any = {}
const { api_platform } = req.headers const { api_platform } = req.headers

View File

@ -1,8 +1,8 @@
import {ROLE_ANON, ROLE_SESSION} from 'common/base.controller' import { ROLE_ANON, ROLE_SESSION } from 'common/base.controller'
import { FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify' import { FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify'
import fastifyPlugin from 'fastify-plugin' import fastifyPlugin from 'fastify-plugin'
import { Account } from 'modules/Account' import { Account } from 'modules/Account'
import {RelaySession} from 'modules/RelaySession' import { RelaySession } from 'modules/RelaySession'
declare module 'fastify' { declare module 'fastify' {
interface FastifyRequest { interface FastifyRequest {
@ -48,8 +48,8 @@ const apiAuthPlugin: FastifyPluginAsync<ApiAuthOptions> = async function (fastif
} catch (err) { } catch (err) {
return reply.send({ errcode: 401, errmsg: 'need auth' }) return reply.send({ errcode: 401, errmsg: 'need auth' })
} }
} else if ( !!request.roles && request.roles.indexOf(ROLE_SESSION) != -1) { } else if (!!request.roles && request.roles.indexOf(ROLE_SESSION) != -1) {
try{ try {
if (!request.token) { if (!request.token) {
return reply.send({ errcode: 11, errmsg: 'need login' }) return reply.send({ errcode: 11, errmsg: 'need login' })
} }
@ -62,13 +62,13 @@ const apiAuthPlugin: FastifyPluginAsync<ApiAuthOptions> = async function (fastif
if (!session) { if (!session) {
return reply.send({ errcode: 10, errmsg: 'need login' }) return reply.send({ errcode: 10, errmsg: 'need login' })
} }
session.refreshExpired(); session.refreshExpired()
await session.save(); await session.save()
request.params['session_id'] = session.id; request.params['session_id'] = session.id
request.params['session_address'] = session.address; request.params['session_address'] = session.address
} catch (err) { } catch (err) {
return reply.send({ errcode: 401, errmsg: 'need auth' }) return reply.send({ errcode: 401, errmsg: 'need auth' })
} }
} }
}) })
} }

View File

@ -1,37 +1,26 @@
import { import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify'
FastifyInstance, import fastifyPlugin from 'fastify-plugin'
FastifyPluginAsync,
FastifyReply,
FastifyRequest,
} from "fastify";
import fastifyPlugin from "fastify-plugin";
/** /**
* post get req.params * post get req.params
*/ */
declare module "fastify" { declare module 'fastify' {
interface FastifyInstance { interface FastifyInstance {
zReqParser: (request: FastifyRequest, reply: FastifyReply) => {}; zReqParser: (request: FastifyRequest, reply: FastifyReply) => {}
} }
} }
const zReqParserPlugin: FastifyPluginAsync = async function ( const zReqParserPlugin: FastifyPluginAsync = async function (fastify: FastifyInstance, options?: any) {
fastify: FastifyInstance, fastify.addHook('preValidation', async (request: FastifyRequest, reply: FastifyReply) => {
options?: any let params = request.params || {}
) { if (request.query) {
fastify.addHook( Object.assign(params, request.query)
"preValidation",
async (request: FastifyRequest, reply: FastifyReply) => {
let params = request.params || {};
if (request.query) {
Object.assign(params, request.query);
}
if (request.body) {
Object.assign(params, request.body);
}
request.params = params;
} }
); if (request.body) {
return; Object.assign(params, request.body)
}; }
request.params = params
})
return
}
export default fastifyPlugin(zReqParserPlugin, "4.x"); export default fastifyPlugin(zReqParserPlugin, '4.x')

View File

@ -1,73 +1,62 @@
import { import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify'
FastifyInstance, import fastifyPlugin from 'fastify-plugin'
FastifyPluginAsync,
FastifyReply,
FastifyRequest,
} from "fastify";
import fastifyPlugin from "fastify-plugin";
const getTokenFromHeader = function (request) { const getTokenFromHeader = function (request) {
let token: string | undefined; let token: string | undefined
if (request.headers && request.headers.authorization) { if (request.headers && request.headers.authorization) {
const parts = request.headers.authorization.split(" "); const parts = request.headers.authorization.split(' ')
if (parts.length === 2) { if (parts.length === 2) {
const scheme = parts[0]; const scheme = parts[0]
if (/^Bearer$/i.test(scheme)) { if (/^Bearer$/i.test(scheme)) {
token = parts[1]; token = parts[1]
} }
} }
} }
return token; return token
}; }
const getTokenFromCookie = function (request) { const getTokenFromCookie = function (request) {
let token: string | undefined; let token: string | undefined
if (request.cookies) { if (request.cookies) {
if (request.cookies["token"]) { if (request.cookies['token']) {
token = request.cookies["token"]; token = request.cookies['token']
} }
} }
return token; return token
}; }
const getTokenFromParams = function (request) { const getTokenFromParams = function (request) {
let token: string | undefined; let token: string | undefined
token = request.params && request.params.token; token = request.params && request.params.token
return token; return token
}; }
const getTokenFromQuery = function (request) { const getTokenFromQuery = function (request) {
let token: string | undefined; let token: string | undefined
token = request.query && request.query.token; token = request.query && request.query.token
return token; return token
}; }
const getTokenFromBody = function (request) { const getTokenFromBody = function (request) {
let token: string | undefined; let token: string | undefined
token = request.body && request.body.token; token = request.body && request.body.token
return token; return token
}; }
const zTokenParserPlugin: FastifyPluginAsync = async function ( const zTokenParserPlugin: FastifyPluginAsync = async function (fastify: FastifyInstance, options?: any) {
fastify: FastifyInstance, fastify.addHook('preValidation', async (request: FastifyRequest, reply: FastifyReply) => {
options?: any request['token'] =
) { getTokenFromHeader(request) ||
fastify.addHook( getTokenFromCookie(request) ||
"preValidation", getTokenFromParams(request) ||
async (request: FastifyRequest, reply: FastifyReply) => { getTokenFromQuery(request) ||
request["token"] = getTokenFromBody(request)
getTokenFromHeader(request) || })
getTokenFromCookie(request) || return
getTokenFromParams(request) || }
getTokenFromQuery(request) ||
getTokenFromBody(request);
}
);
return;
};
/** /**
* request的header, cookie, params, query和body中获取token, request.token中 * request的header, cookie, params, query和body中获取token, request.token中
* header中的字段key为authorization, Bearer xxxx * header中的字段key为authorization, Bearer xxxx
* key都为 token * key都为 token
*/ */
export default fastifyPlugin(zTokenParserPlugin, "4.x"); export default fastifyPlugin(zTokenParserPlugin, '4.x')

View File

@ -1,5 +1,5 @@
import { singleton } from 'decorators/singleton' import { singleton } from 'decorators/singleton'
import {NonceRecord} from 'modules/NonceRecord' import { NonceRecord } from 'modules/NonceRecord'
import * as schedule from 'node-schedule' import * as schedule from 'node-schedule'
/** /**
@ -8,11 +8,11 @@ import * as schedule from 'node-schedule'
@singleton @singleton
export default class NonceRecordSchedule { export default class NonceRecordSchedule {
async parseAllFinishedRecord() { async parseAllFinishedRecord() {
await NonceRecord.deleteMany({status: 1}); await NonceRecord.deleteMany({ status: 1 })
} }
async parseAllExpiredRecord() { async parseAllExpiredRecord() {
let now = Date.now() let now = Date.now()
await NonceRecord.deleteMany({expired: {$lt: now}}) await NonceRecord.deleteMany({ expired: { $lt: now } })
} }
scheduleAll() { scheduleAll() {
schedule.scheduleJob('*/1 * * * *', async () => { schedule.scheduleJob('*/1 * * * *', async () => {

View File

@ -1,6 +1,6 @@
import axios, { AxiosResponse } from 'axios' import axios, { AxiosResponse } from 'axios'
import logger from 'logger/logger' import logger from 'logger/logger'
import { prepareOkxReqCfg } from 'utils/okx.utils'; import { prepareOkxReqCfg } from 'utils/okx.utils'
export const OKX_BASE = 'https://www.okx.com/api/v5/waas' export const OKX_BASE = 'https://www.okx.com/api/v5/waas'
@ -13,23 +13,23 @@ export interface IOkxRes {
/** /**
* Get dynamic gas price * Get dynamic gas price
* https://www.okx.com/web3/build/docs/waas/api-transaction-get-gas-price * https://www.okx.com/web3/build/docs/waas/api-transaction-get-gas-price
* @param chainId * @param chainId
* @returns * @returns
*/ */
export function getGasPrice(chainId: string|number) { export function getGasPrice(chainId: string | number) {
let config = { let config = {
method: 'get', method: 'get',
url: `${OKX_BASE}/transaction/get-gas-price?chainId=${chainId}` url: `${OKX_BASE}/transaction/get-gas-price?chainId=${chainId}`,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Get data required for signature * Get data required for signature
* https://www.okx.com/web3/build/docs/waas/api-transaction-get-sign-info * https://www.okx.com/web3/build/docs/waas/api-transaction-get-sign-info
* @param data * @param data
* @returns * @returns
*/ */
export function getSignInfo(data: any) { export function getSignInfo(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
@ -38,17 +38,17 @@ export function getSignInfo(data: any) {
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/transaction/get-sign-info`, url: `${OKX_BASE}/transaction/get-sign-info`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Send transaction * Send transaction
* https://www.okx.com/web3/build/docs/waas/api-transaction-send-transaction * https://www.okx.com/web3/build/docs/waas/api-transaction-send-transaction
* @param data * @param data
* @returns * @returns
*/ */
export function sendTran(data: any): Promise<AxiosResponse<IOkxRes>> { export function sendTran(data: any): Promise<AxiosResponse<IOkxRes>> {
if (typeof data === 'object') { if (typeof data === 'object') {
@ -57,74 +57,86 @@ export function sendTran(data: any): Promise<AxiosResponse<IOkxRes>> {
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/transaction/send-transaction`, url: `${OKX_BASE}/transaction/send-transaction`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Query transaction details * Query transaction details
* https://www.okx.com/web3/build/docs/waas/api-transaction-get-transaction-detail * https://www.okx.com/web3/build/docs/waas/api-transaction-get-transaction-detail
* @param data * @param data
* @returns * @returns
*/ */
export function queryTranDetail({walletId, orderId, chainId} export function queryTranDetail({
:{walletId: string, orderId: string, chainId: string}) { walletId,
orderId,
let config = { chainId,
method: 'get', }: {
url: `${OKX_BASE}/transaction/get-transaction-detail?walletId=${walletId}&orderId=${orderId}&chainId=${chainId}` walletId: string
}; orderId: string
config = prepareOkxReqCfg(config); chainId: string
return axios.request(config) }) {
let config = {
method: 'get',
url: `${OKX_BASE}/transaction/get-transaction-detail?walletId=${walletId}&orderId=${orderId}&chainId=${chainId}`,
} }
config = prepareOkxReqCfg(config)
return axios.request(config)
}
export async function ensureTxhash({walletId, orderId, chainId} export async function ensureTxhash({
:{walletId: string, orderId: string, chainId: string}) { walletId,
return new Promise(async (resolve, reject) => { orderId,
let interReq = setInterval(async () => { chainId,
try { }: {
let res = await queryTranDetail({walletId, orderId, chainId}) walletId: string
let {code, data} = res.data orderId: string
if (code === 0) { chainId: string
let {txHash, txStatus} = data }) {
if (txHash && txStatus === 4) { return new Promise(async (resolve, reject) => {
clearInterval(interReq) let interReq = setInterval(async () => {
resolve && resolve(txHash) try {
} else if (txStatus == 3) { let res = await queryTranDetail({ walletId, orderId, chainId })
clearInterval(interReq) let { code, data } = res.data
reject && reject('trade error') if (code === 0) {
} let { txHash, txStatus } = data
if (txHash && txStatus === 4) {
clearInterval(interReq)
resolve && resolve(txHash)
} else if (txStatus == 3) {
clearInterval(interReq)
reject && reject('trade error')
} }
} catch (err) {
logger.log('ensureTxhash err', err)
} }
}, 1000); } catch (err) {
}); logger.log('ensureTxhash err', err)
} }
}, 1000)
})
}
/** /**
* Query transaction history * Query transaction history
* https://www.okx.com/web3/build/docs/waas/api-transaction-get-transactions-history * https://www.okx.com/web3/build/docs/waas/api-transaction-get-transactions-history
* @param data * @param data
* @returns * @returns
*/ */
export function queryTranHistory(data: any) { export function queryTranHistory(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/transaction/get-transactions`, url: `${OKX_BASE}/transaction/get-transactions`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
// end of tranactions // end of tranactions
// begin of Wallet // begin of Wallet
/** /**
* Create wallet * Create wallet
* https://www.okx.com/api/v5/waas/wallet/create-wallet * https://www.okx.com/api/v5/waas/wallet/create-wallet
@ -148,18 +160,18 @@ export function queryTranDetail({walletId, orderId, chainId}
} }
* @returns * @returns
*/ */
export function createWallet(data: any) { export function createWallet(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/wallet/create-wallet`, url: `${OKX_BASE}/wallet/create-wallet`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Sync wallet other chain addresses * Sync wallet other chain addresses
@ -188,47 +200,47 @@ export function queryTranDetail({walletId, orderId, chainId}
} }
* @returns * @returns
*/ */
export function syncAddress(data: any) { export function syncAddress(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/wallet/sync-address`, url: `${OKX_BASE}/wallet/sync-address`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Query current wallet address * Query current wallet address
* https://www.okx.com/web3/build/docs/waas/api-wallet-get-wallet-address * https://www.okx.com/web3/build/docs/waas/api-wallet-get-wallet-address
* @returns * @returns
*/ */
export function getAddresses(walletId: string) { export function getAddresses(walletId: string) {
let config = { let config = {
method: 'get', method: 'get',
url: `${OKX_BASE}/wallet/get-addresses?walletId=${walletId}` url: `${OKX_BASE}/wallet/get-addresses?walletId=${walletId}`,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
// end of Wallet // end of Wallet
// begin of Assets // begin of Assets
/** /**
* Query all supported coin information * Query all supported coin information
* https://www.okx.com/web3/build/docs/waas/api-asset-get-all-coins * https://www.okx.com/web3/build/docs/waas/api-asset-get-all-coins
* @param type 0: Platform coin, 1: Custom token * @param type 0: Platform coin, 1: Custom token
*/ */
export function getAllCoins(type: string) { export function getAllCoins(type: string) {
let config = { let config = {
method: 'get', method: 'get',
url: `${OKX_BASE}/asset/get-all-coins?type=${type}` url: `${OKX_BASE}/asset/get-all-coins?type=${type}`,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Add custom coins * Add custom coins
* https://www.okx.com/web3/build/docs/waas/api-asset-add-coin * https://www.okx.com/web3/build/docs/waas/api-asset-add-coin
@ -243,18 +255,18 @@ export function queryTranDetail({walletId, orderId, chainId}
} }
* @returns * @returns
*/ */
export function addCoin(data: any) { export function addCoin(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/asset/add-coin`, url: `${OKX_BASE}/asset/add-coin`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Delete custom coin * Delete custom coin
@ -266,18 +278,18 @@ export function queryTranDetail({walletId, orderId, chainId}
} }
* @returns * @returns
*/ */
export function removeCoin(data: any) { export function removeCoin(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/asset/del-coin`, url: `${OKX_BASE}/asset/del-coin`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* Query wallet token assets * Query wallet token assets
@ -289,16 +301,16 @@ export function queryTranDetail({walletId, orderId, chainId}
} }
* @returns * @returns
*/ */
export function queryCoin(data: any) { export function queryCoin(data: any) {
if (typeof data === 'object') { if (typeof data === 'object') {
data = JSON.stringify(data) data = JSON.stringify(data)
} }
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/asset/get-assets`, url: `${OKX_BASE}/asset/get-assets`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
// end of assets // end of assets

View File

@ -1,9 +1,9 @@
import axios from 'axios' import axios from 'axios'
import logger from 'logger/logger' import logger from 'logger/logger'
import {generateKVStr} from 'utils/net.util'; import { generateKVStr } from 'utils/net.util'
import { prepareOkxReqCfg } from 'utils/okx.utils'; import { prepareOkxReqCfg } from 'utils/okx.utils'
const OKX_BASE = 'https://www.okx.com/api/v5/mktplace'; const OKX_BASE = 'https://www.okx.com/api/v5/mktplace'
/** /**
* https://www.okx.com/web3/build/docs/build-dapp/marketplace-create-a-listing * https://www.okx.com/web3/build/docs/build-dapp/marketplace-create-a-listing
@ -15,9 +15,9 @@ export function beginSell(data: any) {
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/nft/markets/create-listing`, url: `${OKX_BASE}/nft/markets/create-listing`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
export function submitOrder(data: any) { export function submitOrder(data: any) {
@ -27,9 +27,9 @@ export function submitOrder(data: any) {
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/nft/markets/submit-listing`, url: `${OKX_BASE}/nft/markets/submit-listing`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
@ -42,9 +42,9 @@ export function buyOrder(data: any) {
let config = { let config = {
method: 'post', method: 'post',
url: `${OKX_BASE}/nft/markets/buy`, url: `${OKX_BASE}/nft/markets/buy`,
data data,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
@ -52,29 +52,29 @@ export function buyOrder(data: any) {
* https://www.okx.com/web3/build/docs/build-dapp/marketplace-query-listing * https://www.okx.com/web3/build/docs/build-dapp/marketplace-query-listing
*/ */
export function listings(data: any) { export function listings(data: any) {
let uri = `${OKX_BASE}/nft/markets/listings`; let uri = `${OKX_BASE}/nft/markets/listings`
if (data) { if (data) {
uri = generateKVStr({data, uri}) uri = generateKVStr({ data, uri })
} }
let config = { let config = {
method: 'get', method: 'get',
url: uri url: uri,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }
/** /**
* https://www.okx.com/web3/build/docs/build-dapp/marketplace-query-offer * https://www.okx.com/web3/build/docs/build-dapp/marketplace-query-offer
*/ */
export function offers(data: any) { export function offers(data: any) {
let uri = `${OKX_BASE}/nft/markets/offers`; let uri = `${OKX_BASE}/nft/markets/offers`
if (data) { if (data) {
uri = generateKVStr({data, uri}) uri = generateKVStr({ data, uri })
} }
let config = { let config = {
method: 'get', method: 'get',
url: uri url: uri,
}; }
config = prepareOkxReqCfg(config); config = prepareOkxReqCfg(config)
return axios.request(config) return axios.request(config)
} }

View File

@ -1,27 +1,25 @@
import {bytesToHex} from '@noble/hashes/utils' import { bytesToHex } from '@noble/hashes/utils'
import {keccak_256} from '@noble/hashes/sha3' import { keccak_256 } from '@noble/hashes/sha3'
import {recoverPersonalSignature} from '@metamask/eth-sig-util'; import { recoverPersonalSignature } from '@metamask/eth-sig-util'
export function toEIP55(address: string) { export function toEIP55(address: string) {
const lowerAddress = `${address}`.toLowerCase().replace('0x', ''); const lowerAddress = `${address}`.toLowerCase().replace('0x', '')
var hash = bytesToHex(keccak_256(lowerAddress)) var hash = bytesToHex(keccak_256(lowerAddress))
var ret = '0x'; var ret = '0x'
for (var i = 0; i < lowerAddress.length; i++) { for (var i = 0; i < lowerAddress.length; i++) {
if (parseInt(hash[i], 16) >= 8) { if (parseInt(hash[i], 16) >= 8) {
ret += lowerAddress[i].toUpperCase(); ret += lowerAddress[i].toUpperCase()
} } else {
else { ret += lowerAddress[i]
ret += lowerAddress[i]; }
}
} }
return ret; return ret
} }
export function checkPersionalSign(message: string, address: string, signature: string) {
export function checkPersionalSign(message: string, address: string, signature: string ) {
if (!signature.startsWith('0x')) { if (!signature.startsWith('0x')) {
signature = '0x' + signature signature = '0x' + signature
} }
const recovered = recoverPersonalSignature({data: message, signature}) const recovered = recoverPersonalSignature({ data: message, signature })
return recovered === address return recovered === address
} }

View File

@ -1,4 +1,4 @@
import { ZError } from "common/ZError" import { ZError } from 'common/ZError'
const TIMEOUT_ERROR = new Error('timeout') const TIMEOUT_ERROR = new Error('timeout')
@ -130,32 +130,32 @@ export function generateKVStr({
sort = false, sort = false,
encode = false, encode = false,
ignoreNull = true, ignoreNull = true,
splitChar = "&", splitChar = '&',
equalChar = "=", equalChar = '=',
uri = "", uri = '',
}: { }: {
data?: any; data?: any
sort?: boolean; sort?: boolean
encode?: boolean; encode?: boolean
ignoreNull?: boolean; ignoreNull?: boolean
splitChar?: string; splitChar?: string
equalChar?: string; equalChar?: string
uri?: string; uri?: string
}) { }) {
const keys = Object.keys(data); const keys = Object.keys(data)
sort && keys.sort(); sort && keys.sort()
let result = keys let result = keys
.filter((key) => !ignoreNull || data[key]) .filter(key => !ignoreNull || data[key])
.map((key) => { .map(key => {
const value = encode ? encodeURIComponent(data[key]) : data[key]; const value = encode ? encodeURIComponent(data[key]) : data[key]
return `${key}${equalChar}${value}`; return `${key}${equalChar}${value}`
}) })
.join(splitChar); .join(splitChar)
if (uri) { if (uri) {
const joinChar = uri.search(/\?/) === -1 ? "?" : "&"; const joinChar = uri.search(/\?/) === -1 ? '?' : '&'
result = uri + joinChar + result; result = uri + joinChar + result
} }
return result; return result
} }
/** /**
@ -164,25 +164,23 @@ export function generateKVStr({
* @param splitChar , & * @param splitChar , &
* @param equalChar = * @param equalChar =
*/ */
export function keyValToObject( export function keyValToObject(str: string, splitChar: string = '&', equalChar = '='): {} {
str: string, let result: any = {}
splitChar: string = "&",
equalChar = "="
): {} {
let result: any = {};
if (!str) { if (!str) {
return result; return result
} }
let arrs = str.split(splitChar); let arrs = str.split(splitChar)
for (let sub of arrs) { for (let sub of arrs) {
let subArr = sub.split(equalChar); let subArr = sub.split(equalChar)
result[subArr[0]] = subArr[1]; result[subArr[0]] = subArr[1]
} }
return result; return result
} }
export const checkParamsNeeded = (...args) => { export const checkParamsNeeded = (...args) => {
args.forEach((arg) => {if (!arg) { args.forEach(arg => {
throw new ZError(10, 'params mismatch'); if (!arg) {
}}); throw new ZError(10, 'params mismatch')
}
})
} }

View File

@ -1,23 +1,22 @@
import crypto from 'crypto' import crypto from 'crypto'
const apiKey = process.env.OKX_API_KEY; const apiKey = process.env.OKX_API_KEY
const projectId = process.env.OKX_PROJECT_ID; const projectId = process.env.OKX_PROJECT_ID
const pass = process.env.OKX_PASS; const pass = process.env.OKX_PASS
const secretKey = process.env.OKX_SECRET_KEY; const secretKey = process.env.OKX_SECRET_KEY
export function prepareOkxReqCfg(config: any) { export function prepareOkxReqCfg(config: any) {
let timestamp = new Date().toISOString(); let timestamp = new Date().toISOString()
let url = new URL(config.url); let url = new URL(config.url)
let method = config.method.toUpperCase(); let method = config.method.toUpperCase()
let signStr = timestamp + method + url.pathname; let signStr = timestamp + method + url.pathname
if (method === 'GET') { if (method === 'GET') {
signStr += url.search signStr += url.search
} else if (method === 'POST') { } else if (method === 'POST') {
let bodyStr = JSON.stringify(JSON.parse(config.data)) let bodyStr = JSON.stringify(JSON.parse(config.data))
signStr+=bodyStr; signStr += bodyStr
} }
const mac = crypto.createHmac('sha256', secretKey); const mac = crypto.createHmac('sha256', secretKey)
const sign = mac.update(signStr).digest('base64') const sign = mac.update(signStr).digest('base64')
config.headers = { config.headers = {
'OK-ACCESS-PROJECT': projectId, 'OK-ACCESS-PROJECT': projectId,
@ -25,7 +24,7 @@ export function prepareOkxReqCfg(config: any) {
'OK-ACCESS-SIGN': sign, 'OK-ACCESS-SIGN': sign,
'OK-ACCESS-TIMESTAMP': timestamp, 'OK-ACCESS-TIMESTAMP': timestamp,
'OK-ACCESS-PASSPHRASE': pass, 'OK-ACCESS-PASSPHRASE': pass,
'Content-Type': 'application/json' 'Content-Type': 'application/json',
} }
return config; return config
} }