diff --git a/.vscode/launch.json b/.vscode/launch.json index 370882e..52751da 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,5 +17,18 @@ ], "type": "pwa-node" }, + { + "name": "Debug Scription", + "request": "launch", + "runtimeArgs": [ + "run-script", + "dev:scription" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "pwa-node" + }, ] } \ No newline at end of file diff --git a/config/scription_list.json b/config/scription_list.json index 26bc376..fe0d5bf 100644 --- a/config/scription_list.json +++ b/config/scription_list.json @@ -2,7 +2,7 @@ { "chain": 421614, "rpc": "https://arb-sepolia.g.alchemy.com/v2/EKR1je8ZGia332kkemNc4mtXQuFskIq3", - "fromBlock": 5624211, + "fromBlock": 26760154, "filters": [{ "key": "input", "op": "eq", @@ -15,5 +15,22 @@ "value": "0x50a8e60041a206acaa5f844a1104896224be6f39" }], "dataModel": "CheckIn" + }, + { + "chain": 421614, + "rpc": "https://arb-sepolia.g.alchemy.com/v2/EKR1je8ZGia332kkemNc4mtXQuFskIq3", + "fromBlock": 26760154, + "filters": [{ + "key": "input", + "op": "like", + "type": "regex", + "value": "data:,{\"p\":\"cf-20\",\"op\":\"chest_open\",\"id\":\"(.+?)\"}" + },{ + "key": "to", + "op": "eq", + "type": "address", + "value": "0x50a8e60041a206acaa5f844a1104896224be6f39" + }], + "dataModel": "ChestRecord" } ] \ No newline at end of file diff --git a/src/models/CheckIn.ts b/src/models/CheckIn.ts index 3c2a7cf..2067cde 100644 --- a/src/models/CheckIn.ts +++ b/src/models/CheckIn.ts @@ -28,8 +28,10 @@ export class CheckInClass extends BaseModule { @prop() public dateTag: string // 连签天数 - @prop({ default: 0 }) + @prop({ default: 1 }) public count: number + @prop({ default: 1 }) + public total: number @prop() public value: string @prop() @@ -41,6 +43,8 @@ export class CheckInClass extends BaseModule { if (preDayEvent) { event.count = preDayEvent.count + 1 } + const total = await CheckIn.countDocuments({ from: event.from }) + event.total = total + 1 try { await CheckIn.insertOrUpdate({ from: event.from, dateTag: event.dateTag }, event) } catch (err) { diff --git a/src/models/ChestRecord.ts b/src/models/ChestRecord.ts new file mode 100644 index 0000000..957c2ef --- /dev/null +++ b/src/models/ChestRecord.ts @@ -0,0 +1,60 @@ +import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose' +import { dbconn } from 'decorators/dbconn' +import { BaseModule } from './Base' +import { hexToUtf8 } from 'zutils/utils/string.util' +import logger from 'logger/logger' + +@dbconn() +@index({ from: 1 }, { unique: false }) +@index({ from: 1, chestId: 1 }, { unique: true }) +@index({ from: 1, blockTime: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'chest_open_record', timestamps: true }, +}) +export class ChestRecordClass extends BaseModule { + @prop({ required: true }) + public from!: string + @prop() + public to: string + @prop({ required: true }) + public hash: string + @prop() + public blockNumber: string + @prop() + public blockHash: string + @prop() + public blockTime: number + @prop() + public dateTag: string + @prop() + public chestId: string + @prop() + public value: string + @prop() + public input: string + + public static async saveEvent(event: any) { + const dataStr = hexToUtf8(event.input) + const regexp = /data:,{\"p\":\"cf-20\",\"op\":\"chest_open\",\"id\":\"(.+?)\"}/ + const match = dataStr.match(regexp) + if (!match) { + logger.log('not a chest open event:', event.hash) + return + } + event.chestId = match[1] + logger.log('open chest with id:', event.chestId) + return ChestRecord.insertOrUpdate({ hash: event.hash }, event) + } + + public toJson() { + return { + address: this.from, + day: this.dateTag, + time: this.blockTime, + } + } +} + +export const ChestRecord = getModelForClass(ChestRecordClass, { + existingConnection: ChestRecordClass['db'], +}) diff --git a/src/models/GeneralEvent.ts b/src/models/GeneralEvent.ts index 1447c34..50f436f 100644 --- a/src/models/GeneralEvent.ts +++ b/src/models/GeneralEvent.ts @@ -5,6 +5,7 @@ import { NftHolder } from './NftHolder' @dbconn() @index({ chain: 1, hash: 1, logIndex: 1 }, { unique: true }) +@index({ chain: 1, address: 1, blockNumber: 1 }, { unique: false }) @modelOptions({ schemaOptions: { collection: 'general_event', timestamps: true }, options: { allowMixed: Severity.ALLOW }, diff --git a/src/scriptions.ts b/src/scriptions.ts index 781dd53..5a7daf7 100644 --- a/src/scriptions.ts +++ b/src/scriptions.ts @@ -11,14 +11,19 @@ import { IScriptionCfg } from 'interface/IScriptionCfg' import { buildScriptionFilters } from 'utils/block.util' import { CheckIn } from 'models/CheckIn' import { ZRedisClient } from 'zutils' +import { hexToUtf8 } from 'zutils/utils/string.util' +import { ChestRecord } from 'models/ChestRecord' let svrs: any[] = [] let lock = false let eventProcessers = { CheckIn: CheckIn, + ChestRecord: ChestRecord, } +global.hexToUtf8 = hexToUtf8 + async function initEventSvrs() { const cfgMap: Map = new Map() for (let cfg of scriptions) { diff --git a/src/utils/block.util.ts b/src/utils/block.util.ts index 6d28f09..68187cf 100644 --- a/src/utils/block.util.ts +++ b/src/utils/block.util.ts @@ -180,7 +180,7 @@ export const buildScriptionFilters = (cfg: IScriptionCfg) => { } else if (filter.type === 'boolean') { value = !!value } else { - value = `'${value}'` + value = `${value}` } if (op) { if (op === 'in') { @@ -188,9 +188,9 @@ export const buildScriptionFilters = (cfg: IScriptionCfg) => { } else if (op === 'nin') { body += `!(event.${filter.key}.indexOf(${value}) >= 0)` } else if (op === 'nlike') { - body += `!new RegExp(${value}).test(event.${filter.key})` + body += `!new RegExp(/${value}/).test(hexToUtf8(event.${filter.key}))` } else if (op === 'like') { - body += new RegExp(value).test(`event.${filter.key}`) + body += `new RegExp(/${value}/).test(hexToUtf8(event.${filter.key}))` } else { body += `event.${filter.key}${op}${value}` } diff --git a/start.json b/start.json index d31cafc..947fc51 100644 --- a/start.json +++ b/start.json @@ -4,7 +4,7 @@ "name": "chain-client", "script": "npm", "args": "run prod:api", - "cwd": "/data/apps/web_chain_client", + "cwd": "/home/kingsome/code/web_chain_client", "max_memory_restart": "1024M", "log_date_format": "YYYY-MM-DD HH:mm Z", "watch": false,