增加nft holder表
This commit is contained in:
parent
5004cd4dce
commit
5ceb0445b7
@ -61,8 +61,8 @@
|
|||||||
"eslint": "^7.27.0",
|
"eslint": "^7.27.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-prettier": "^3.4.0",
|
"eslint-plugin-prettier": "^3.4.0",
|
||||||
"prettier": "^2.3.0",
|
|
||||||
"node": "18.14.0",
|
"node": "18.14.0",
|
||||||
|
"prettier": "^2.3.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"ts-node-dev": "^2.0.0",
|
"ts-node-dev": "^2.0.0",
|
||||||
"tsconfig-paths": "^3.9.0",
|
"tsconfig-paths": "^3.9.0",
|
||||||
|
36
src/models/FtHodler.ts
Normal file
36
src/models/FtHodler.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { getModelForClass, DocumentType, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||||
|
import { dbconn } from 'decorators/dbconn'
|
||||||
|
import { BaseModule } from './Base'
|
||||||
|
|
||||||
|
@dbconn()
|
||||||
|
@index({ address: 1, chain: 1 }, { unique: false })
|
||||||
|
@index({ chain: 1, address: 1, user: 1 }, { unique: true })
|
||||||
|
@modelOptions({
|
||||||
|
schemaOptions: { collection: 'ft_holder', timestamps: true },
|
||||||
|
})
|
||||||
|
export class FtHolderClass extends BaseModule {
|
||||||
|
@prop()
|
||||||
|
public chain: number
|
||||||
|
@prop({ required: true })
|
||||||
|
public address!: string
|
||||||
|
@prop()
|
||||||
|
public user: string
|
||||||
|
@prop({ default: 18 })
|
||||||
|
public decimals: number
|
||||||
|
@prop({ default: '0' })
|
||||||
|
public amount: string
|
||||||
|
@prop({ default: 0 })
|
||||||
|
public version: number
|
||||||
|
|
||||||
|
public async incAmount(this: DocumentType<FtHolderClass>, val: string) {
|
||||||
|
this.amount = (BigInt(this.amount) + BigInt(val)).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
public async decAmount(this: DocumentType<FtHolderClass>, val: string) {
|
||||||
|
this.amount = (BigInt(this.amount) - BigInt(val)).toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FtHolder = getModelForClass(FtHolderClass, {
|
||||||
|
existingConnection: FtHolderClass['db'],
|
||||||
|
})
|
@ -1,6 +1,8 @@
|
|||||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||||
import { dbconn } from 'decorators/dbconn'
|
import { dbconn } from 'decorators/dbconn'
|
||||||
import { BaseModule } from './Base'
|
import { BaseModule } from './Base'
|
||||||
|
import { FtHolder } from './FtHodler'
|
||||||
|
import { ZERO_ADDRESS } from 'common/Constants'
|
||||||
|
|
||||||
@dbconn()
|
@dbconn()
|
||||||
@index({ address: 1, chain: 1 }, { unique: false })
|
@index({ address: 1, chain: 1 }, { unique: false })
|
||||||
@ -37,6 +39,8 @@ export class FtTransferEventClass extends BaseModule {
|
|||||||
public eventId: string
|
public eventId: string
|
||||||
@prop()
|
@prop()
|
||||||
public blockTime: number
|
public blockTime: number
|
||||||
|
@prop({ default: 0 })
|
||||||
|
public version: number
|
||||||
|
|
||||||
public static async saveEvent(event: any) {
|
public static async saveEvent(event: any) {
|
||||||
const amount = event.returnValues?.value
|
const amount = event.returnValues?.value
|
||||||
|
29
src/models/NftHolder.ts
Normal file
29
src/models/NftHolder.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||||
|
import { dbconn } from 'decorators/dbconn'
|
||||||
|
import { BaseModule } from './Base'
|
||||||
|
|
||||||
|
@dbconn()
|
||||||
|
@index({ chain: 1, address: 1 }, { unique: false })
|
||||||
|
@index({ user: 1 }, { unique: false })
|
||||||
|
@index({ chain: 1, address: 1, tokenId: 1 }, { unique: true })
|
||||||
|
@modelOptions({
|
||||||
|
schemaOptions: { collection: 'nft_holder', timestamps: true },
|
||||||
|
})
|
||||||
|
export class NftHolderClass extends BaseModule {
|
||||||
|
@prop()
|
||||||
|
public chain: number
|
||||||
|
@prop({ required: true })
|
||||||
|
public address!: string
|
||||||
|
@prop()
|
||||||
|
public user: string
|
||||||
|
@prop()
|
||||||
|
public tokenId: string
|
||||||
|
@prop({ default: 0 })
|
||||||
|
public version: number
|
||||||
|
@prop()
|
||||||
|
public lastTxHash: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NftHolder = getModelForClass(NftHolderClass, {
|
||||||
|
existingConnection: NftHolderClass['db'],
|
||||||
|
})
|
@ -1,6 +1,8 @@
|
|||||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||||
import { dbconn } from 'decorators/dbconn'
|
import { dbconn } from 'decorators/dbconn'
|
||||||
import { BaseModule } from './Base'
|
import { BaseModule } from './Base'
|
||||||
|
import { NftHolder } from './NftHolder'
|
||||||
|
import { ZERO_ADDRESS } from 'common/Constants'
|
||||||
|
|
||||||
@dbconn()
|
@dbconn()
|
||||||
@index({ address: 1, chain: 1 }, { unique: false })
|
@index({ address: 1, chain: 1 }, { unique: false })
|
||||||
@ -65,7 +67,7 @@ export class NftTransferEventClass extends BaseModule {
|
|||||||
$inc: { version: 1 },
|
$inc: { version: 1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
return NftTransferEvent.insertOrUpdate(
|
await NftTransferEvent.insertOrUpdate(
|
||||||
{
|
{
|
||||||
chain: event.chain,
|
chain: event.chain,
|
||||||
transactionHash: event.transactionHash || event.hash,
|
transactionHash: event.transactionHash || event.hash,
|
||||||
@ -76,6 +78,17 @@ export class NftTransferEventClass extends BaseModule {
|
|||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
|
if (from !== to) {
|
||||||
|
await NftHolder.insertOrUpdate(
|
||||||
|
{ chain: event.chain, address, tokenId },
|
||||||
|
{
|
||||||
|
user: to,
|
||||||
|
lastTxHash: event.transactionHash || event.hash,
|
||||||
|
$inc: { version: 1 },
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
|
||||||
import { dbconn } from 'decorators/dbconn'
|
|
||||||
import logger from 'logger/logger'
|
|
||||||
import { BaseModule } from './Base'
|
|
||||||
|
|
||||||
@dbconn()
|
|
||||||
@index({ transactionHash: 1 }, { unique: true })
|
|
||||||
@modelOptions({
|
|
||||||
schemaOptions: { collection: 'schedule_confirm_event', timestamps: true },
|
|
||||||
})
|
|
||||||
export class ScheduleConfirmEventClass extends BaseModule {
|
|
||||||
@prop({ required: true })
|
|
||||||
public address!: string
|
|
||||||
@prop()
|
|
||||||
public event: string
|
|
||||||
@prop({ required: true })
|
|
||||||
public transactionHash: string
|
|
||||||
@prop()
|
|
||||||
public blockNumber: number
|
|
||||||
@prop()
|
|
||||||
public blockHash: string
|
|
||||||
@prop()
|
|
||||||
public removed: boolean
|
|
||||||
@prop()
|
|
||||||
public operater: string
|
|
||||||
@prop({ type: () => [String] })
|
|
||||||
public scheduleIds: string[]
|
|
||||||
@prop()
|
|
||||||
public blockTime: number
|
|
||||||
@prop({ default: 0 })
|
|
||||||
public version: number
|
|
||||||
|
|
||||||
public static async saveEvent(event: any) {
|
|
||||||
logger.info(JSON.stringify(event))
|
|
||||||
if (event.removed) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
address: event.address,
|
|
||||||
blockNumber: event.blockNumber,
|
|
||||||
removed: event.removed,
|
|
||||||
operater: event.returnValues.sender,
|
|
||||||
scheduleIds: event.returnValues.ids,
|
|
||||||
transactionHash: event.transactionHash,
|
|
||||||
blockTime: new Date(event.timestamp).getTime(),
|
|
||||||
$inc: { version: 1 },
|
|
||||||
}
|
|
||||||
|
|
||||||
let record = await ScheduleConfirmEvent.insertOrUpdate({ transactionHash: event.transactionHash }, data)
|
|
||||||
if (record.version === 1) {
|
|
||||||
logger.log('receive events: ' + JSON.stringify(record.scheduleIds))
|
|
||||||
for (let id of record.scheduleIds) {
|
|
||||||
// await new TaskSvr().parseOneSchedule(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return record
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ScheduleConfirmEvent = getModelForClass(ScheduleConfirmEventClass, {
|
|
||||||
existingConnection: ScheduleConfirmEventClass['db'],
|
|
||||||
})
|
|
@ -1,59 +0,0 @@
|
|||||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
|
||||||
import { dbconn } from 'decorators/dbconn'
|
|
||||||
import { BaseModule } from './Base'
|
|
||||||
|
|
||||||
@dbconn()
|
|
||||||
@index({ transactionHash: 1, scheduleId: 1 }, { unique: true })
|
|
||||||
@modelOptions({
|
|
||||||
schemaOptions: { collection: 'schedule_executed_event', timestamps: true },
|
|
||||||
})
|
|
||||||
export class ScheduleExecutedEventClass extends BaseModule {
|
|
||||||
@prop({ required: true })
|
|
||||||
public address!: string
|
|
||||||
@prop()
|
|
||||||
public event: string
|
|
||||||
@prop({ required: true })
|
|
||||||
public transactionHash: string
|
|
||||||
@prop()
|
|
||||||
public blockNumber: number
|
|
||||||
@prop()
|
|
||||||
public blockHash: string
|
|
||||||
@prop()
|
|
||||||
public removed: boolean
|
|
||||||
@prop()
|
|
||||||
public operater: string
|
|
||||||
@prop()
|
|
||||||
public scheduleId: string
|
|
||||||
@prop()
|
|
||||||
public blockTime: number
|
|
||||||
@prop({ default: 0 })
|
|
||||||
public version: number
|
|
||||||
|
|
||||||
public static async saveEvent(event: any) {
|
|
||||||
if (event.removed) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
address: event.address,
|
|
||||||
blockNumber: event.blockNumber,
|
|
||||||
removed: event.removed,
|
|
||||||
operater: event.returnValues.sender,
|
|
||||||
transactionHash: event.transactionHash,
|
|
||||||
blockTime: new Date(event.timestamp).getTime(),
|
|
||||||
$inc: { version: 1 },
|
|
||||||
}
|
|
||||||
|
|
||||||
let record = await ScheduleExecutedEvent.insertOrUpdate(
|
|
||||||
{ transactionHash: event.transactionHash, scheduleId: event.returnValues.id },
|
|
||||||
data,
|
|
||||||
)
|
|
||||||
if (record.version === 1) {
|
|
||||||
}
|
|
||||||
return record
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ScheduleExecutedEvent = getModelForClass(ScheduleExecutedEventClass, {
|
|
||||||
existingConnection: ScheduleExecutedEventClass['db'],
|
|
||||||
})
|
|
@ -1,56 +0,0 @@
|
|||||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
|
||||||
import { dbconn } from 'decorators/dbconn'
|
|
||||||
import { BaseModule } from './Base'
|
|
||||||
|
|
||||||
@dbconn()
|
|
||||||
@index({ transactionHash: 1, scheduleId: 1 }, { unique: true })
|
|
||||||
@modelOptions({
|
|
||||||
schemaOptions: { collection: 'schedule_added_event', timestamps: true },
|
|
||||||
})
|
|
||||||
export class ScheduledAddedEventClass extends BaseModule {
|
|
||||||
@prop({ required: true })
|
|
||||||
public address!: string
|
|
||||||
@prop()
|
|
||||||
public event: string
|
|
||||||
@prop({ required: true })
|
|
||||||
public transactionHash: string
|
|
||||||
@prop()
|
|
||||||
public blockNumber: number
|
|
||||||
@prop()
|
|
||||||
public blockHash: string
|
|
||||||
@prop()
|
|
||||||
public removed: boolean
|
|
||||||
@prop()
|
|
||||||
public operater: string
|
|
||||||
@prop()
|
|
||||||
public scheduleId: string
|
|
||||||
@prop()
|
|
||||||
public blockTime: number
|
|
||||||
@prop({ default: 0 })
|
|
||||||
public version: number
|
|
||||||
|
|
||||||
public static async saveEvent(event: any) {
|
|
||||||
if (event.removed) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
address: event.address,
|
|
||||||
blockNumber: event.blockNumber,
|
|
||||||
removed: event.removed,
|
|
||||||
operater: event.returnValues.sender,
|
|
||||||
transactionHash: event.transactionHash,
|
|
||||||
blockTime: new Date(event.timestamp).getTime(),
|
|
||||||
$inc: { version: 1 },
|
|
||||||
}
|
|
||||||
|
|
||||||
return ScheduledAddedEvent.insertOrUpdate(
|
|
||||||
{ transactionHash: event.transactionHash, scheduleId: event.returnValues.id },
|
|
||||||
data,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ScheduledAddedEvent = getModelForClass(ScheduledAddedEventClass, {
|
|
||||||
existingConnection: ScheduledAddedEventClass['db'],
|
|
||||||
})
|
|
@ -1,10 +1,9 @@
|
|||||||
import { RequestTask } from 'models/RequestTask'
|
import { RequestTask } from 'models/RequestTask'
|
||||||
|
|
||||||
const graphql = require('graphql')
|
const graphql = require('graphql')
|
||||||
import { BlockChain } from 'chain/BlockChain'
|
|
||||||
import { getFirstToken } from 'service/chain.service'
|
import { getFirstToken } from 'service/chain.service'
|
||||||
|
|
||||||
const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLID, GraphQLList, GraphQLNonNull } = graphql
|
const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLList } = graphql
|
||||||
|
|
||||||
const nftType = new GraphQLObjectType({
|
const nftType = new GraphQLObjectType({
|
||||||
name: 'erc721',
|
name: 'erc721',
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"target": "es2019",
|
"target": "es2020",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"baseUrl": "./src",
|
"baseUrl": "./src",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
"lib": ["es2019"],
|
"lib": ["es2020"],
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
"typings/extend.d.ts"
|
"typings/extend.d.ts"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user