From 0146bcf34a42e360c90fbb5490a4bfe06c062085 Mon Sep 17 00:00:00 2001 From: WYANG008 Date: Wed, 20 Feb 2019 16:11:21 +0800 Subject: [PATCH] FIN-1063 #comment update with vivaldi --- package-lock.json | 7 +- package.json | 6 +- src/common/constants.ts | 2 + src/index.ts | 8 +- src/services/ContractService.test.ts | 73 +++-- src/services/ContractService.ts | 159 ++++++++-- .../ContractService.test.ts.snap | 272 ++++++++++++++++++ src/utils/eventUtil.ts | 10 +- 8 files changed, 477 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index a7dae23..909621a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,9 +49,8 @@ } }, "@finbook/duo-contract-wrapper": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@finbook/duo-contract-wrapper/-/duo-contract-wrapper-1.1.2.tgz", - "integrity": "sha512-iVNNR1fnUrHuFMvg6OcTOJAp2kClSkr0A9NmXU6vrfNYw0EUykmUm5C/3XvSihcviibzYBYzdvVe0uTrnvy/xg==", + "version": "file:finbook-duo-contract-wrapper-1.2.0.tgz", + "integrity": "sha512-soqSFa29BzvRhXEGW6UJDskYmm8T7l4+bA7D0YffNaGB0WQX/bK1MquXJ52/ott0kp96VcW6EqPCk9n+UaAixw==", "requires": { "@ledgerhq/hw-transport-u2f": "4.35.0", "@ledgerhq/web3-subprovider": "4.36.0", @@ -66,7 +65,7 @@ "resolved": "https://registry.npmjs.org/@finbook/duo-market-data/-/duo-market-data-1.0.1.tgz", "integrity": "sha512-JroAbr7D/y+ptpxXmzG6I615/644ku5u+NId891fvvC6sMfzX0h200AUbQOXLig8f7pnq0LQ7iV6bkLnLJ2u+A==", "requires": { - "@finbook/duo-contract-wrapper": "1.1.2", + "@finbook/duo-contract-wrapper": "file:finbook-duo-contract-wrapper-1.2.0.tgz", "aws-sdk": "2.400.0", "moment": "2.24.0" } diff --git a/package.json b/package.json index 6df455c..d612322 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "cleanDB": "ts-node ./src/index cleanDB", "fetchPrice": "ts-node ./src/index fetchPrice", "fetchEvents": "ts-node ./src/index fetchEvents", - "startCustodian": "ts-node ./src/index startCustodian" + "startCustodian": "ts-node ./src/index startCustodian", + "startRound": "ts-node ./src/index startRound", + "endRound": "ts-node ./src/index endRound" }, "jest": { "roots": [ @@ -49,7 +51,7 @@ }, "dependencies": { "@babel/polyfill": "^7.2.5", - "@finbook/duo-contract-wrapper": "^1.1.2", + "@finbook/duo-contract-wrapper": "^1.2.0", "@finbook/duo-market-data": "^1.0.1", "@google-cloud/storage": "^2.4.1", "aws-cli-js": "^2.0.4", diff --git a/src/common/constants.ts b/src/common/constants.ts index 3dbe18c..f6df337 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -6,6 +6,8 @@ export const CLEAN_DB = 'cleanDB'; export const FETCH_PRICE = 'fetchPrice'; export const START_CUSTODIAN = 'startCustodian'; export const FETCH_EVENTS = 'fetchEvents'; +export const START_ROUND = 'startRound'; +export const END_ROUND = 'endRound'; // db setting export const DB_SQL_SCHEMA_PRICEFEED = 'priceFeedDB'; diff --git a/src/index.ts b/src/index.ts index b6193cf..3118e79 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,7 +44,7 @@ dbUtil.init(tool, option).then(() => { new MarketDataService().cleanDb(); break; case CST.START_CUSTODIAN: - new ContractService(tool, option).startCustodian(); + new ContractService(tool, option).startCustodian(option); break; case CST.TRIGGER: new ContractService(tool, option).trigger(); @@ -55,6 +55,12 @@ dbUtil.init(tool, option).then(() => { case CST.FETCH_PRICE: new ContractService(tool, option).fetchPrice(); break; + case CST.START_ROUND: + new ContractService(tool, option).startRound(option); + break; + case CST.END_ROUND: + new ContractService(tool, option).endRound(option); + break; default: util.logInfo('no such tool ' + tool); break; diff --git a/src/services/ContractService.test.ts b/src/services/ContractService.test.ts index 9bf173b..f557dbb 100644 --- a/src/services/ContractService.test.ts +++ b/src/services/ContractService.test.ts @@ -6,6 +6,28 @@ import keyUtil from '../utils/keyUtil'; import priceUtil from '../utils/priceUtil'; import ContractService from './ContractService'; +const option = { + forceREST: false, + live: false, + dbLive: false, + server: false, + dynamo: false, + aws: false, + gcp: false, + azure: false, + force: false, + pair: 'pair', + contractType: 'Beethoven', + tenor: '100C-3H', + assets: [''], + sources: [''], + exSources: [''], + source: '', + event: '', + provider: '', + period: 1 +}; + jest.mock('@finbook/duo-contract-wrapper', () => ({ Constants: Constants, Web3Wrapper: jest.fn(() => ({ @@ -21,6 +43,9 @@ jest.mock('@finbook/duo-contract-wrapper', () => ({ DualClassWrapper: jest.fn(() => ({ contract: 'dualClassWrapper' })), + VivaldiWrapper: jest.fn(() => ({ + contract: 'VivaldiWrapper' + })), EsplanadeWrapper: jest.fn(() => ({ contract: 'EsplanadeWrapper' })), @@ -125,22 +150,25 @@ test('fetchPrice', async () => { test('startCustodian, worng type', async () => { contractService.createDuoWrappers = jest.fn(); - await contractService.startCustodian(); + await contractService.startCustodian(option); expect(contractService.createDuoWrappers as jest.Mock).not.toBeCalled(); }); test('fetchEvent', async () => { eventUtil.fetch = jest.fn(); - contractService.createDuoWrappers = jest.fn(() => ({ - Beethoven: { - Perpetual: 'BTV-PPT', - M19: 'BTV-M19' - }, - Mozart: { - Perpetual: 'MZT-PPT', - M19: 'MZT-M19' - } - } as any)); + contractService.createDuoWrappers = jest.fn( + () => + ({ + Beethoven: { + Perpetual: 'BTV-PPT', + M19: 'BTV-M19' + }, + Mozart: { + Perpetual: 'MZT-PPT', + M19: 'MZT-M19' + } + } as any) + ); await contractService.fetchEvent(); expect((eventUtil.fetch as jest.Mock).mock.calls).toMatchSnapshot(); }); @@ -158,16 +186,19 @@ test('startCustodian', async () => { } as any); const startCustodian = jest.fn(); - contractService1.createDuoWrappers = jest.fn(() => ({ - Beethoven: { - Perpetual: { - startCustodian: startCustodian, - web3Wrapper: { - contractAddresses: kovan + contractService1.createDuoWrappers = jest.fn( + () => + ({ + Beethoven: { + Perpetual: { + startCustodian: startCustodian, + web3Wrapper: { + contractAddresses: kovan + } + } } - } - } - } as any)); - await contractService1.startCustodian(); + } as any) + ); + await contractService1.startCustodian(option); expect((startCustodian as jest.Mock).mock.calls).toMatchSnapshot(); }); diff --git a/src/services/ContractService.ts b/src/services/ContractService.ts index 74d6c75..24c2d82 100644 --- a/src/services/ContractService.ts +++ b/src/services/ContractService.ts @@ -1,16 +1,20 @@ import { + Constants, Constants as WrapperConstants, DualClassWrapper, EsplanadeWrapper, MagiWrapper, + VivaldiWrapper, Web3Wrapper } from '@finbook/duo-contract-wrapper'; +import moment from 'moment'; import { IOption } from '../common/types'; import dbUtil from '../utils/dbUtil'; import eventUtil from '../utils/eventUtil'; import keyUtil from '../utils/keyUtil'; import priceUtil from '../utils/priceUtil'; import util from '../utils/util'; +const schedule = require('node-schedule'); export default class ContractService { public web3Wrapper: Web3Wrapper; @@ -25,7 +29,9 @@ export default class ContractService { this.web3Wrapper = new Web3Wrapper(null, option.provider, '', option.live); } - public createDuoWrappers(): { [type: string]: { [tenor: string]: DualClassWrapper } } { + public createDuoWrappers(): { + [type: string]: { [tenor: string]: DualClassWrapper | VivaldiWrapper }; + } { return { Beethoven: { Perpetual: new DualClassWrapper( @@ -46,6 +52,14 @@ export default class ContractService { this.web3Wrapper, this.web3Wrapper.contractAddresses.Custodians.Mozart.M19.custodian.address ) + }, + Vivaldi: { + '100C-3H': new VivaldiWrapper( + this.web3Wrapper, + this.web3Wrapper.contractAddresses.Custodians.Vivaldi[ + '100C-3H' + ].custodian.address + ) } }; } @@ -75,15 +89,16 @@ export default class ContractService { public async trigger() { await this.fetchKey(); - const dualClassCustodianWrappers = this.createDuoWrappers(); + const duoWrappers = this.createDuoWrappers(); eventUtil.trigger( this.address, [ - dualClassCustodianWrappers.Beethoven.Perpetual, - dualClassCustodianWrappers.Beethoven.M19, - dualClassCustodianWrappers.Mozart.Perpetual, - dualClassCustodianWrappers.Mozart.M19 + duoWrappers.Beethoven.Perpetual as DualClassWrapper, + duoWrappers.Beethoven.M19 as DualClassWrapper, + duoWrappers.Mozart.Perpetual as DualClassWrapper, + duoWrappers.Mozart.M19 as DualClassWrapper, + duoWrappers.Vivaldi['100C-3H'] as VivaldiWrapper ], this.option.event ); @@ -103,18 +118,95 @@ export default class ContractService { priceUtil.fetchPrice( this.address, [ - dualClassCustodianWrappers.Beethoven.Perpetual, - dualClassCustodianWrappers.Beethoven.M19, - dualClassCustodianWrappers.Mozart.Perpetual, - dualClassCustodianWrappers.Mozart.M19 + dualClassCustodianWrappers.Beethoven.Perpetual as DualClassWrapper, + dualClassCustodianWrappers.Beethoven.M19 as DualClassWrapper, + dualClassCustodianWrappers.Mozart.Perpetual as DualClassWrapper, + dualClassCustodianWrappers.Mozart.M19 as DualClassWrapper ], magiWrapper ); setInterval(() => dbUtil.insertHeartbeat(), 30000); } - public async startCustodian() { - let kovanManagerAccount = { + public async startRound(option: IOption) { + await this.fetchKey(); + const custodianContract = this.createDuoWrappers(); + const contractWrapper: DualClassWrapper | VivaldiWrapper = + custodianContract[option.contractType][option.tenor]; + const states = await contractWrapper.getStates(); + + if (states.lastPriceTime === 0) + await (contractWrapper as VivaldiWrapper).startRound(this.address); + else if (util.getUTCNowTimestamp() - states.lastPriceTime > states.period) + throw new Error(' option contract has skipped one period!'); + + const numOfHours = states.period / 1000 / 3600; + const rule = `* * /${numOfHours} * * *`; + util.logInfo( + `startRound every ${numOfHours} hours, starting from ${moment + .utc(states.lastPriceTime) + .format('YYYY-MM-DD hh:mm:ss')}` + ); + schedule.scheduleJob( + { + start: + states.lastPriceTime === 0 + ? states.lastPriceTime + states.period * 1.5 + : states.lastPriceTime, + rule + }, + () => this.safeStartRound(contractWrapper as VivaldiWrapper) + ); + } + + private async safeStartRound(contractWrapper: VivaldiWrapper) { + let retryTimes = 0; + let isRoundStarted = false; + while (retryTimes < 5 && !isRoundStarted) { + await contractWrapper.startRound(this.address); + const states = await contractWrapper.getStates(); + if (states.lastPriceTime >= states.resetPriceTime) isRoundStarted = true; + else retryTimes++; + } + } + + public async endRound(option: IOption) { + await this.fetchKey(); + const custodianContract = this.createDuoWrappers(); + const contractWrapper: DualClassWrapper | VivaldiWrapper = + custodianContract[option.contractType][option.tenor]; + const states = await contractWrapper.getStates(); + + if (util.getUTCNowTimestamp() - states.resetPriceTime > states.period) + throw new Error(' option contract has skipped one period!'); + + const numOfHours = states.period / 1000 / 3600; + const rule = `* * /${numOfHours} * * *`; + util.logInfo( + `endRound every ${numOfHours} hours, starting from ${moment + .utc(states.resetPriceTime) + .format('YYYY-MM-DD hh:mm:ss')}` + ); + schedule.scheduleJob({ start: states.resetPriceTime, rule }, () => + this.safeEndRound(contractWrapper as VivaldiWrapper) + ); + } + + private async safeEndRound(contractWrapper: VivaldiWrapper) { + let retryTimes = 0; + let isEnded = false; + while (retryTimes < 5 && !isEnded) { + await contractWrapper.endRound(this.address); + const states = await contractWrapper.getStates(); + if (states.state === Constants.CTD_TRADING) retryTimes++; + else isEnded = true; + } + } + + public async startCustodian(option: IOption) { + let kovanManagerAccount: { + [type: string]: { operator: { privateKey: string; address: string } }; + } = { Beethoven: { operator: { address: 'account', @@ -130,28 +222,47 @@ export default class ContractService { this.web3Wrapper = new Web3Wrapper( null, this.option.provider, - kovanManagerAccount.Beethoven.operator.privateKey, + kovanManagerAccount[option.contractType].operator.privateKey, this.option.live ); const account = kovanManagerAccount.Beethoven.operator.address; const type = this.option.contractType; const tenor = this.option.tenor; if ( - ![WrapperConstants.BEETHOVEN, WrapperConstants.MOZART].includes(type) || - ![WrapperConstants.TENOR_PPT, WrapperConstants.TENOR_M19].includes(tenor) + ![ + WrapperConstants.BEETHOVEN, + WrapperConstants.MOZART, + WrapperConstants.VIVALDI + ].includes(type) || + ![WrapperConstants.TENOR_PPT, WrapperConstants.TENOR_M19, '100C-3H'].includes(tenor) ) { util.logDebug('no contract type or tenor specified'); return; } - const dualClassCustodianWrappers = this.createDuoWrappers(); - const contractWrapper: DualClassWrapper = dualClassCustodianWrappers[type][tenor]; - - contractWrapper.startCustodian( - account, - contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].aToken.address, - contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].bToken.address, - contractWrapper.web3Wrapper.contractAddresses.Oracles[0].address - ); + const custodianContract = this.createDuoWrappers(); + const contractWrapper: DualClassWrapper | VivaldiWrapper = custodianContract[type][tenor]; + if (option.contractType === WrapperConstants.VIVALDI) { + util.logInfo(`start custodian of vivaldi`); + (contractWrapper as VivaldiWrapper).startCustodian( + account, + contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].aToken + .address, + contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].bToken + .address, + contractWrapper.web3Wrapper.contractAddresses.Oracles[0].address, + 1.0, + true, + true + ); + } else + (contractWrapper as DualClassWrapper).startCustodian( + account, + contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].aToken + .address, + contractWrapper.web3Wrapper.contractAddresses.Custodians[type][tenor].bToken + .address, + contractWrapper.web3Wrapper.contractAddresses.Oracles[0].address + ); } public fetchEvent() { diff --git a/src/services/__snapshots__/ContractService.test.ts.snap b/src/services/__snapshots__/ContractService.test.ts.snap index c41e7be..5c72c54 100644 --- a/src/services/__snapshots__/ContractService.test.ts.snap +++ b/src/services/__snapshots__/ContractService.test.ts.snap @@ -43,6 +43,11 @@ Object { "contract": "dualClassWrapper", }, }, + "Vivaldi": Object { + "100C-3H": Object { + "contract": "VivaldiWrapper", + }, + }, } `; @@ -112,6 +117,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -200,6 +249,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -288,6 +381,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -376,6 +513,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -475,6 +656,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -574,6 +799,50 @@ Array [ }, }, }, + "Vivaldi": Object { + "095P-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-095P-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-095C-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-095P-3H", + }, + }, + "100C-3H": Object { + "aToken": Object { + "address": "0x1A93a7ce3Dc8858648482A4763a9f3B9e6E97873", + "code": "ETH-100C-3H", + }, + "bToken": Object { + "address": "0x8e158382191E23B299375d16Ce614f8c456CDB3a", + "code": "ETH-100P-3H", + }, + "custodian": Object { + "address": "0xdAe93661F5d44E331bbf852C661363427607cF7D", + "code": "VIVALDI-100C-3H", + }, + }, + "105C-3H": Object { + "aToken": Object { + "address": "0x0", + "code": "ETH-105C-3H", + }, + "bToken": Object { + "address": "0x0", + "code": "ETH-105P-3H", + }, + "custodian": Object { + "address": "0x0", + "code": "VIVALDI-105C-3H", + }, + }, + }, }, "MultiSigManagers": Array [ Object { @@ -720,6 +989,9 @@ Array [ Object { "contract": "dualClassWrapper", }, + Object { + "contract": "VivaldiWrapper", + }, ], "event", ], diff --git a/src/utils/eventUtil.ts b/src/utils/eventUtil.ts index a23bca2..2c7c34c 100644 --- a/src/utils/eventUtil.ts +++ b/src/utils/eventUtil.ts @@ -1,17 +1,11 @@ -import { - BaseContractWrapper, - Constants as WrapperConstants, - DualClassWrapper, - IEvent, - Web3Wrapper -} from '@finbook/duo-contract-wrapper'; +import { BaseContractWrapper, Constants as WrapperConstants, DualClassWrapper, IEvent, VivaldiWrapper, Web3Wrapper } from '@finbook/duo-contract-wrapper'; import { Constants as DataConstants } from '@finbook/duo-market-data'; import * as CST from '../common/constants'; import dbUtil from './dbUtil'; import util from './util'; class EventUtil { - public async trigger(account: string, dualClassWrappers: DualClassWrapper[], event: string) { + public async trigger(account: string, dualClassWrappers: Array, event: string) { util.logInfo('subscribing to ' + event); if ( ![WrapperConstants.EVENT_START_PRE_RESET, WrapperConstants.EVENT_START_RESET].includes(