diff --git a/packages/uni-info-watcher/.eslintrc.json b/packages/uni-info-watcher/.eslintrc.json index 476d529d..cfbe0109 100644 --- a/packages/uni-info-watcher/.eslintrc.json +++ b/packages/uni-info-watcher/.eslintrc.json @@ -23,5 +23,13 @@ "allowArgumentsExplicitlyTypedAsAny": true } ] - } + }, + "overrides": [ + { + "files": ["*.test.ts"], + "rules": { + "no-unused-expressions": "off" + } + } + ] } diff --git a/packages/uni-info-watcher/.mocharc.yml b/packages/uni-info-watcher/.mocharc.yml new file mode 100644 index 00000000..547437d9 --- /dev/null +++ b/packages/uni-info-watcher/.mocharc.yml @@ -0,0 +1,4 @@ +timeout: '20000' +bail: true +exit: true # TODO: Find out why the program doesn't exit on its own. +require: 'ts-node/register' diff --git a/packages/uni-info-watcher/package.json b/packages/uni-info-watcher/package.json index 72a6f346..5926fb24 100644 --- a/packages/uni-info-watcher/package.json +++ b/packages/uni-info-watcher/package.json @@ -22,7 +22,8 @@ "lint": "eslint .", "build": "tsc", "generate:schema": "get-graphql-schema https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-alt > docs/analysis/schema/full-schema.graphql", - "lint:schema": "graphql-schema-linter" + "lint:schema": "graphql-schema-linter", + "smoke-test": "mocha src/smoke.test.ts" }, "devDependencies": { "@types/chance": "^1.1.2", @@ -41,6 +42,8 @@ "get-graphql-schema": "^2.1.2", "graphql-schema-linter": "^2.0.1", "mocha": "^8.4.0", - "nodemon": "^2.0.7" + "nodemon": "^2.0.7", + "ts-node": "^10.0.0", + "typescript": "^4.3.2" } } diff --git a/packages/uni-info-watcher/src/smoke.test.ts b/packages/uni-info-watcher/src/smoke.test.ts new file mode 100644 index 00000000..7e1454f6 --- /dev/null +++ b/packages/uni-info-watcher/src/smoke.test.ts @@ -0,0 +1,186 @@ +import { expect } from 'chai'; +import { ethers, Contract, Signer } from 'ethers'; +import { request } from 'graphql-request'; +import 'mocha'; + +import { Config, getConfig, wait, deployTokens, createPool, initializePool } from '@vulcanize/util'; +import { Client as UniClient, watchEvent } from '@vulcanize/uni-watcher'; +import { + abi as FACTORY_ABI +} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json'; +import { + abi as POOL_ABI +} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'; + +import { + queryFactory, + queryBundle, + queryToken, + queryPoolsByTokens, + queryPoolById, + queryPoolDayData +} from '../test/queries'; + +const NETWORK_RPC_URL = 'http://localhost:8545'; + +const TICK_MIN = -887272; + +describe('uni-info-watcher', () => { + let factory: Contract; + let pool: Contract; + let token0Address: string; + let token1Address: string; + + let signer: Signer; + let config: Config; + let endpoint: string; + let uniClient: UniClient; + + before(async () => { + const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL); + signer = provider.getSigner(); + + const configFile = './environments/local.toml'; + config = await getConfig(configFile); + + const { upstream, server: { host, port } } = config; + endpoint = `http://${host}:${port}/graphql`; + + const { uniWatcher: { gqlEndpoint, gqlSubscriptionEndpoint } } = upstream; + uniClient = new UniClient({ + gqlEndpoint, + gqlSubscriptionEndpoint + }); + }); + + it('should have a Factory entity', async () => { + // Getting the Factory from uni-info-watcher graphQL endpoint. + const data = await request(endpoint, queryFactory); + expect(data.factories).to.not.be.empty; + + // Initializing the factory variable. + const factoryAddress = data.factories[0].id; + factory = new ethers.Contract(factoryAddress, FACTORY_ABI, signer); + expect(factory.address).to.not.be.empty; + }); + + it('should have a Bundle entity', async () => { + // Getting the Bundle from uni-info-watcher graphQL endpoint. + const data = await request(endpoint, queryBundle); + expect(data.bundles).to.not.be.empty; + + const bundleId = '1'; + expect(data.bundles[0].id).to.equal(bundleId); + }); + + describe('PoolCreatedEvent', () => { + // NOTE Skipping checking entity updates that cannot be gotten using queries. + + const fee = 500; + + before(async () => { + // Deploy 2 tokens. + ({ token0Address, token1Address } = await deployTokens(signer)); + expect(token0Address).to.not.be.empty; + expect(token1Address).to.not.be.empty; + }); + + it('should not have Token entities', async () => { + // Check that Token entities are absent. + const data0 = await request(endpoint, queryToken, { id: token0Address }); + expect(data0.token).to.be.null; + + const data1 = await request(endpoint, queryToken, { id: token0Address }); + expect(data1.token).to.be.null; + }); + + it('should create pool', async () => { + // Create Pool. + createPool(factory, token0Address, token1Address, fee); + + // Wait for PoolCreatedEvent. + const eventType = 'PoolCreatedEvent'; + await watchEvent(uniClient, eventType); + + // Sleeping for 5 sec for the entities to be processed. + await wait(5000); + }); + + it('should create Token entities', async () => { + // Check that Token entities are present. + const data0 = await request(endpoint, queryToken, { id: token0Address }); + expect(data0.token).to.not.be.null; + + const data1 = await request(endpoint, queryToken, { id: token0Address }); + expect(data1.token).to.not.be.null; + }); + + it('should create a Pool entity', async () => { + const variables = { + tokens: [token0Address, token1Address] + }; + // Getting the Pool that has the deployed tokens. + const data = await request(endpoint, queryPoolsByTokens, variables); + expect(data.pools).to.have.lengthOf(1); + + // Initializing the pool variable. + const poolAddress = data.pools[0].id; + pool = new Contract(poolAddress, POOL_ABI, signer); + expect(pool.address).to.not.be.empty; + + expect(data.pools[0].feeTier).to.be.equal(fee.toString()); + }); + }); + + describe('InitializeEvent', () => { + const sqrtPrice = '4295128939'; + const tick = TICK_MIN; + + it('should not have pool entity initialized', async () => { + const data = await request(endpoint, queryPoolById, { id: pool.address }); + expect(data.pool.sqrtPrice).to.not.be.equal(sqrtPrice); + expect(data.pool.tick).to.be.null; + }); + + it('should initialize pool', async () => { + initializePool(pool, sqrtPrice); + + // Wait for InitializeEvent. + const eventType = 'InitializeEvent'; + await watchEvent(uniClient, eventType); + + // Sleeping for 5 sec for the entities to be processed. + await wait(5000); + + const data = await request(endpoint, queryPoolById, { id: pool.address }); + expect(data.pool.sqrtPrice).to.be.equal(sqrtPrice); + expect(data.pool.tick).to.be.equal(tick.toString()); + }); + + it('should update PoolDayData entity', async () => { + // Get the latest PoolDayData. + const variables = { + first: 1, + orderBy: 'date', + orderDirection: 'desc', + pool: pool.address + }; + const data = await request(endpoint, queryPoolDayData, variables); + expect(data.poolDayDatas).to.not.be.empty; + + const dayPoolID: string = data.poolDayDatas[0].id; + const poolID: string = dayPoolID.split('-')[0]; + const dayID: number = +dayPoolID.split('-')[1]; + const date = data.poolDayDatas[0].date; + const tvlUSD = data.poolDayDatas[0].tvlUSD; + + const dayStartTimestamp = dayID * 86400; + const poolData = await request(endpoint, queryPoolById, { id: pool.address }); + const totalValueLockedUSD: string = poolData.pool.totalValueLockedUSD; + + expect(poolID).to.be.equal(pool.address); + expect(date).to.be.equal(dayStartTimestamp); + expect(tvlUSD).to.be.equal(totalValueLockedUSD); + }); + }); +}); diff --git a/packages/uni-info-watcher/test/queries.ts b/packages/uni-info-watcher/test/queries.ts new file mode 100644 index 00000000..da84bda9 --- /dev/null +++ b/packages/uni-info-watcher/test/queries.ts @@ -0,0 +1,54 @@ +import { gql } from 'graphql-request'; + +export const queryToken = gql` +query queryToken($id: ID!) { + token(id: $id) { + id + } +}`; + +// Getting the first Factory entity. +export const queryFactory = gql` +{ + factories(first: 1) { + id + } +}`; + +// Getting the first Bundle entity. +export const queryBundle = gql` +{ + bundles(first: 1) { + id + } +}`; + +// Getting Pool by id. +export const queryPoolById = gql` +query queryPoolById($id: ID!) { + pool(id: $id) { + id, + sqrtPrice, + tick, + totalValueLockedUSD + } +}`; + +// Getting Pool(s) filtered by tokens. +export const queryPoolsByTokens = gql` +query queryPoolsByTokens($tokens: [String!]) { + pools(where: { token0_in: $tokens, token1_in: $tokens }) { + id, + feeTier + } +}`; + +// Getting PoolDayData(s) filtered by pool and ordered by date. +export const queryPoolDayData = gql` +query queryPoolDayData($first: Int, $orderBy: PoolDayData_orderBy, $orderDirection: OrderDirection, $pool: String) { + poolDayDatas(first: $first, orderBy: $orderBy, orderDirection: $orderDirection, where: { pool: $pool }) { + id, + date, + tvlUSD + } +}`; diff --git a/packages/uni-watcher/.eslintrc.json b/packages/uni-watcher/.eslintrc.json index 9ab662bc..a6246e7d 100644 --- a/packages/uni-watcher/.eslintrc.json +++ b/packages/uni-watcher/.eslintrc.json @@ -29,7 +29,7 @@ "files": ["*.test.ts", "test/*.ts"], "rules": { "no-unused-expressions": "off", - "no-prototype-builtins":"off" + "no-prototype-builtins": "off" } } ] diff --git a/packages/uni-watcher/index.ts b/packages/uni-watcher/index.ts index cf988131..acb6ead3 100644 --- a/packages/uni-watcher/index.ts +++ b/packages/uni-watcher/index.ts @@ -1 +1,2 @@ export * from './src/client'; +export * from './src/utils/index'; diff --git a/packages/uni-watcher/src/smoke.test.ts b/packages/uni-watcher/src/smoke.test.ts index 79029e2b..88f313e5 100644 --- a/packages/uni-watcher/src/smoke.test.ts +++ b/packages/uni-watcher/src/smoke.test.ts @@ -1,9 +1,8 @@ import { expect, assert } from 'chai'; import { ethers, Contract, ContractTransaction, Signer, constants } from 'ethers'; -import 'reflect-metadata'; import 'mocha'; -import { Config, getConfig } from '@vulcanize/util'; +import { Config, getConfig, deployTokens, TESTERC20_ABI } from '@vulcanize/util'; import { Client as UniClient } from '@vulcanize/uni-watcher'; import { getCache } from '@vulcanize/cache'; import { EthClient } from '@vulcanize/ipld-eth-client'; @@ -43,10 +42,6 @@ import { checkDecreaseLiquidityEvent, checksCollectEvent } from '../test/utils'; -import { - abi as TESTERC20_ABI, - bytecode as TESTERC20_BYTECODE -} from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json'; import { abi as TESTUNISWAPV3CALLEE_ABI, bytecode as TESTUNISWAPV3CALLEE_BYTECODE @@ -56,6 +51,8 @@ import { bytecode as WETH9_BYTECODE } from '../artifacts/test/contracts/WETH9.sol/WETH9.json'; +const NETWORK_RPC_URL = 'http://localhost:8545'; + const TICK_MIN = -887272; const TICK_MAX = 887272; const getMinTick = (tickSpacing: number) => Math.ceil(TICK_MIN / tickSpacing) * tickSpacing; @@ -119,7 +116,7 @@ describe('uni-watcher', () => { gqlSubscriptionEndpoint }); - const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545'); + const provider = new ethers.providers.JsonRpcProvider(NETWORK_RPC_URL); signer = provider.getSigner(); recipient = await signer.getAddress(); }); @@ -147,15 +144,10 @@ describe('uni-watcher', () => { it('should deploy 2 tokens', async () => { // Deploy 2 tokens. - const Token = new ethers.ContractFactory(TESTERC20_ABI, TESTERC20_BYTECODE, signer); // Not initializing global token contract variables just yet; initialized in `create pool` to maintatin order coherency. - const token0 = await Token.deploy(ethers.BigNumber.from(2).pow(255)); - token0Address = token0.address; + ({ token0Address, token1Address } = await deployTokens(signer)); expect(token0Address).to.not.be.empty; - - const token1 = await Token.deploy(ethers.BigNumber.from(2).pow(255)); - token1Address = token1.address; expect(token1Address).to.not.be.empty; }); diff --git a/packages/uni-watcher/src/utils/index.ts b/packages/uni-watcher/src/utils/index.ts index fc739c68..661739c2 100644 --- a/packages/uni-watcher/src/utils/index.ts +++ b/packages/uni-watcher/src/utils/index.ts @@ -1,6 +1,7 @@ import { ethers } from 'ethers'; import { Database } from '../database'; +import { Client as UniClient } from '../client'; export async function watchContract (db: Database, address: string, kind: string, startingBlock: number): Promise { // Always use the checksum address (https://docs.ethers.io/v5/api/utils/address/#utils-getAddress). @@ -8,3 +9,22 @@ export async function watchContract (db: Database, address: string, kind: string await db.saveContract(contractAddress, kind, startingBlock); } + +export const watchEvent = async (uniClient: UniClient, eventType: string): Promise => { + return new Promise((resolve, reject) => { + (async () => { + try { + const subscription = await uniClient.watchEvents((value: any) => { + if (value.event.__typename === eventType) { + if (subscription) { + subscription.unsubscribe(); + } + resolve(value); + } + }); + } catch (error) { + reject(error); + } + })(); + }); +}; diff --git a/packages/uni-watcher/test/utils.ts b/packages/uni-watcher/test/utils.ts index 2481de10..a38994a4 100644 --- a/packages/uni-watcher/test/utils.ts +++ b/packages/uni-watcher/test/utils.ts @@ -1,11 +1,12 @@ -import { ethers, utils, Contract, Signer, BigNumber, ContractTransaction } from 'ethers'; +import { ethers, utils, Contract, Signer } from 'ethers'; import { expect } from 'chai'; import 'mocha'; import { Client as UniClient } from '@vulcanize/uni-watcher'; +import { createPool, initializePool } from '@vulcanize/util'; // https://github.com/ethers-io/ethers.js/issues/195 -export function linkLibraries ( +export const linkLibraries = ( { bytecode, linkReferences @@ -13,7 +14,7 @@ export function linkLibraries ( bytecode: string linkReferences: { [fileName: string]: { [contractName: string]: { length: number; start: number }[] } } }, - libraries: { [libraryName: string]: string }): string { + libraries: { [libraryName: string]: string }): string => { Object.keys(linkReferences).forEach((fileName) => { Object.keys(linkReferences[fileName]).forEach((contractName) => { if (!libraries.hasOwnProperty(contractName)) { @@ -31,16 +32,16 @@ export function linkLibraries ( }); }); return bytecode; -} +}; -export async function testCreatePool ( +export const testCreatePool = async ( uniClient: UniClient, factory: Contract, token0Address: string, token1Address: string, fee: number, poolAbi: any, - signer: Signer): Promise { + signer: Signer): Promise => { return new Promise((resolve, reject) => { (async () => { try { @@ -60,20 +61,19 @@ export async function testCreatePool ( }); // Create pool. - const transaction: ContractTransaction = await factory.createPool(token0Address, token1Address, fee); - await transaction.wait(); + await createPool(factory, token0Address, token1Address, fee); } catch (error) { reject(error); } })(); }); -} +}; -export function testInitialize ( +export const testInitialize = async ( uniClient: UniClient, pool: Contract, sqrtPrice: string, - tick: number): Promise { + tick: number): Promise => { return new Promise((resolve, reject) => { try { (async () => { @@ -92,30 +92,29 @@ export function testInitialize ( }); // Pool initialize. - const transaction: ContractTransaction = await pool.initialize(BigNumber.from(sqrtPrice)); - await transaction.wait(); + await initializePool(pool, sqrtPrice); })(); } catch (error) { reject(error); } }); -} +}; -function checkEventCommonValues (value: any, expectedContract: string) { +const checkEventCommonValues = (value: any, expectedContract: string) => { expect(value.block).to.not.be.empty; expect(value.tx).to.not.be.empty; expect(value.contract).to.equal(expectedContract); expect(value.eventIndex).to.be.a('number'); expect(value.proof).to.not.be.empty; -} +}; -export function checkPoolCreatedEvent ( +export const checkPoolCreatedEvent = ( value: any, expectedContract: string, token0Address: string, token1Address: string, - fee: number): string { + fee: number): string => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('PoolCreatedEvent'); @@ -126,28 +125,28 @@ export function checkPoolCreatedEvent ( expect(value.event.pool).to.not.be.empty; return value.event.pool; -} +}; -export function checkInitializeEvent ( +export const checkInitializeEvent = ( value: any, expectedContract: string, sqrtPrice: string, - tick: number): void { + tick: number): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('InitializeEvent'); expect(value.event.sqrtPriceX96).to.equal(sqrtPrice); expect(value.event.tick).to.equal(tick.toString()); -} +}; -export function checkMintEvent ( +export const checkMintEvent = ( value: any, expectedContract: string, expectedSender: string, exptectedOwner: string, tickLower: number, tickUpper: number, - amount: number): void { + amount: number): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('MintEvent'); @@ -158,15 +157,15 @@ export function checkMintEvent ( expect(value.event.amount).to.equal(amount.toString()); expect(value.event.amount0).to.not.be.empty; expect(value.event.amount1).to.not.be.empty; -} +}; -export function checkBurnEvent ( +export const checkBurnEvent = ( value: any, expectedContract: string, exptectedOwner: string, tickLower: number, tickUpper: number, - amount: number): void { + amount: number): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('BurnEvent'); @@ -176,16 +175,16 @@ export function checkBurnEvent ( expect(value.event.amount).to.equal(amount.toString()); expect(value.event.amount0).to.not.be.empty; expect(value.event.amount1).to.not.be.empty; -} +}; -export function checkSwapEvent ( +export const checkSwapEvent = ( value: any, expectedContract: string, expectedSender: string, recipient: string, sqrtPrice: string, tick: number -): void { +): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('SwapEvent'); @@ -196,40 +195,40 @@ export function checkSwapEvent ( expect(value.event.sqrtPriceX96).to.equal(sqrtPrice); expect(value.event.liquidity).to.not.be.empty; expect(value.event.tick).to.equal(tick.toString()); -} +}; -export function checkTransferEvent ( +export const checkTransferEvent = ( value: any, expectedContract: string, from: string, recipient: string -): void { +): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('TransferEvent'); expect(value.event.from).to.equal(from); expect(value.event.to).to.equal(recipient); expect(value.event.tokenId).to.equal('1'); -} +}; -export function checkIncreaseLiquidityEvent ( +export const checkIncreaseLiquidityEvent = ( value: any, expectedContract: string, amount1Desired: number -): void { +): void => { checkEventCommonValues(value, expectedContract); expect(value.event.tokenId).to.equal('1'); expect(value.event.liquidity).to.equal(amount1Desired.toString()); expect(value.event.amount0).to.equal(amount1Desired.toString()); expect(value.event.amount1).to.equal(amount1Desired.toString()); -} +}; -export function checkDecreaseLiquidityEvent ( +export const checkDecreaseLiquidityEvent = ( value: any, expectedContract: string, liquidity: number -): void { +): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('DecreaseLiquidityEvent'); @@ -237,13 +236,13 @@ export function checkDecreaseLiquidityEvent ( expect(value.event.liquidity).to.equal(liquidity.toString()); expect(value.event.amount0).to.not.be.empty; expect(value.event.amount1).to.not.be.empty; -} +}; -export function checksCollectEvent ( +export const checksCollectEvent = ( value: any, expectedContract: string, recipient: string -): void { +): void => { checkEventCommonValues(value, expectedContract); expect(value.event.__typename).to.equal('CollectEvent'); @@ -251,4 +250,4 @@ export function checksCollectEvent ( expect(value.event.recipient).to.equal(recipient); expect(value.event.amount0).to.not.be.empty; expect(value.event.amount1).to.not.be.empty; -} +}; diff --git a/packages/util/.gitignore b/packages/util/.gitignore new file mode 100644 index 00000000..3ac0fb0a --- /dev/null +++ b/packages/util/.gitignore @@ -0,0 +1,10 @@ +.idea/ +.vscode/ +node_modules/ +build/ +tmp/ +temp/ + +#Hardhat files +cache +artifacts diff --git a/packages/util/hardhat.config.ts b/packages/util/hardhat.config.ts new file mode 100644 index 00000000..d8509ad8 --- /dev/null +++ b/packages/util/hardhat.config.ts @@ -0,0 +1,18 @@ +import { HardhatUserConfig } from 'hardhat/config'; +import '@nomiclabs/hardhat-waffle'; + +const config: HardhatUserConfig = { + defaultNetwork: 'localhost', + solidity: { + compilers: [ + { + version: '0.7.6' + } + ] + }, + paths: { + sources: './test/contracts' + } +}; + +export default config; diff --git a/packages/util/index.ts b/packages/util/index.ts index e57648c5..7a770d87 100644 --- a/packages/util/index.ts +++ b/packages/util/index.ts @@ -3,3 +3,4 @@ export * from './src/database'; export * from './src/job-queue'; export * from './src/constants'; export * from './src/index'; +export * from './test/actions'; diff --git a/packages/util/package.json b/packages/util/package.json index 15e08da1..8c17ca01 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -12,10 +12,10 @@ "toml": "^3.0.0" }, "devDependencies": { - "@vulcanize/cache": "^0.1.0", "@types/fs-extra": "^9.0.11", "@typescript-eslint/eslint-plugin": "^4.25.0", "@typescript-eslint/parser": "^4.25.0", + "@vulcanize/cache": "^0.1.0", "chai": "^4.3.4", "eslint": "^7.27.0", "eslint-config-semistandard": "^15.0.1", @@ -24,11 +24,13 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-standard": "^5.0.0", + "hardhat": "^2.3.0", "mocha": "^8.4.0", "typeorm": "^0.2.32" }, "scripts": { "lint": "eslint .", - "build": "tsc" + "build": "tsc", + "test:compile": "hardhat compile" } } diff --git a/packages/util/test/actions.ts b/packages/util/test/actions.ts new file mode 100644 index 00000000..0cef07e5 --- /dev/null +++ b/packages/util/test/actions.ts @@ -0,0 +1,34 @@ +import { ethers, Contract, ContractTransaction, Signer, BigNumber } from 'ethers'; + +import { + abi as TESTERC20_ABI, + bytecode as TESTERC20_BYTECODE +} from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json'; + +export { abi as TESTERC20_ABI } from '../artifacts/test/contracts/TestERC20.sol/TestERC20.json'; + +export const deployTokens = async (signer: Signer): Promise<{token0Address: string, token1Address: string}> => { + const Token = new ethers.ContractFactory(TESTERC20_ABI, TESTERC20_BYTECODE, signer); + + const token0 = await Token.deploy(ethers.BigNumber.from(2).pow(255)); + const token0Address = token0.address; + + const token1 = await Token.deploy(ethers.BigNumber.from(2).pow(255)); + const token1Address = token1.address; + + return { token0Address, token1Address }; +}; + +export const createPool = async ( + factory: Contract, + token0Address: string, + token1Address: string, + fee: number): Promise => { + const transaction: ContractTransaction = await factory.createPool(token0Address, token1Address, fee); + await transaction.wait(); +}; + +export const initializePool = async (pool: Contract, sqrtPrice: string): Promise => { + const transaction: ContractTransaction = await pool.initialize(BigNumber.from(sqrtPrice)); + await transaction.wait(); +}; diff --git a/packages/uni-watcher/test/contracts/TestERC20.sol b/packages/util/test/contracts/TestERC20.sol similarity index 100% rename from packages/uni-watcher/test/contracts/TestERC20.sol rename to packages/util/test/contracts/TestERC20.sol diff --git a/packages/util/tsconfig.json b/packages/util/tsconfig.json index eff67a7e..c7de3980 100644 --- a/packages/util/tsconfig.json +++ b/packages/util/tsconfig.json @@ -72,6 +72,6 @@ "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ "resolveJsonModule": true /* Enabling the option allows importing JSON, and validating the types in that JSON file. */ }, - "include": ["src"], + "include": ["src", "test"], "exclude": ["dist"] }