From 3233306099cd973f4494cb160aab497a0875cdfb Mon Sep 17 00:00:00 2001 From: Keno Dressel Date: Wed, 14 Feb 2024 15:49:40 +0100 Subject: [PATCH] feat: upgrades types to correct sdk types --- src/lib/contracts.ts | 119 ++++++++++++++------------------- src/worker/index.ts | 26 ++++--- test/context-mockup.spec.ts | 17 ++--- test/contracts.spec.ts | 8 +-- test/swap-routes.e2e-spec.ts | 2 +- test/tokens.e2e-spec.ts | 2 +- test/utils/context.mockup.ts | 36 +++++----- test/worker-basics.e2e-spec.ts | 2 +- 8 files changed, 98 insertions(+), 114 deletions(-) diff --git a/src/lib/contracts.ts b/src/lib/contracts.ts index 620c3f7..84be53d 100644 --- a/src/lib/contracts.ts +++ b/src/lib/contracts.ts @@ -1,9 +1,14 @@ import NETWORKS from './networks'; -import { AeSdk, Node } from '@aeternity/aepp-sdk'; -import { CallData, ContractAddress, WalletAddress, nonNullable } from './utils'; +import { + AeSdk, + Node, + ContractMethodsBase, +} from '@aeternity/aepp-sdk'; +import { ContractAddress, nonNullable } from './utils'; import * as routerInterface from 'dex-contracts-v2/build/AedexV2Router.aci.json'; import * as factoryInterface from 'dex-contracts-v2/build/AedexV2Factory.aci.json'; import * as pairInterface from 'dex-contracts-v2/build/AedexV2Pair.aci.json'; +import ContractWithMethods from '@aeternity/aepp-sdk/es/contract/Contract'; let client: AeSdk; let node: Node; @@ -23,32 +28,21 @@ const getClient = async (): Promise<[AeSdk, Node]> => { }; export type RouterMethods = { - factory: () => ContractMethodResult; + factory: () => ContractAddress; }; export type FactoryMethods = { - allPairs: () => ContractMethodResult; + get_all_pairs: () => ContractAddress[]; }; -export type ContractMethodResult = Promise<{ - result: { - callerId: WalletAddress; - callerNonce: number; - contractId: ContractAddress; - gasPrice: number; - gasUsed: number; - height: number; - log: any[]; - returnType: 'ok' | 'revert'; - returnValue: CallData; - }; - decodedResult: T; -}>; export type PairMethods = { - token0: () => ContractMethodResult; - token1: () => ContractMethodResult; - totalSupply: () => ContractMethodResult; - reserves: () => ContractMethodResult<{ reserve0: bigint; reserve1: bigint }>; + token0: () => ContractAddress; + token1: () => ContractAddress; + total_supply: () => bigint; + get_reserves: () => { + reserve0: bigint; + reserve1: bigint; + }; }; export type MetaInfo = { @@ -58,76 +52,60 @@ export type MetaInfo = { }; export type Aex9Methods = { - metaInfo: () => ContractMethodResult; -}; - -const wrapRouter = (router: any): RouterMethods => { - return { - factory: router.factory, - }; -}; -const wrapFactory = (factory: any): FactoryMethods => { - return { - allPairs: factory.get_all_pairs, - }; -}; - -const wrapPair = (pair: any): PairMethods => { - return { - token0: pair.token0, - token1: pair.token1, - totalSupply: pair.total_supply, - reserves: pair.get_reserves, - }; -}; - -const wrapAex9 = (token: any): Aex9Methods => { - return { - metaInfo: token.meta_info, - }; + meta_info: () => MetaInfo; }; export type Context = { - router: RouterMethods; - factory: FactoryMethods; - getPair: (address: ContractAddress) => Promise; - getToken: (address: ContractAddress) => Promise; + router: ContractWithMethods; + factory: ContractWithMethods; + getPair: ( + address: ContractAddress, + ) => Promise>; + getToken: ( + address: ContractAddress, + ) => Promise>; node: Node; }; const createGetToken = ( - tokens: { [key: string]: Aex9Methods | undefined }, - getInstance: (source: string, address: string) => Promise, + tokens: { [key: string]: ContractWithMethods | undefined }, + getInstance: Awaited>, ) => - async (tokenAddress: string): Promise => { + async ( + tokenAddress: ContractAddress, + ): Promise> => { const cached = tokens[tokenAddress]; if (cached) { return cached; } - const token = wrapAex9(await getInstance(pairInterface, tokenAddress)); + const token = await getInstance(pairInterface, tokenAddress); tokens[tokenAddress] = token; return token; }; const createGetPair = ( - pairs: { [key: string]: PairMethods | undefined }, - getInstance: (source: string, address: string) => any, + pairs: { [key: string]: ContractWithMethods | undefined }, + getInstance: Awaited>, ) => - async (pairAddress: string): Promise => { + async ( + pairAddress: ContractAddress, + ): Promise> => { const cached = pairs[pairAddress]; if (cached) { return cached; } - const pair = wrapPair(await getInstance(pairInterface, pairAddress)); + const pair = await getInstance(pairInterface, pairAddress); pairs[pairAddress] = pair; return pair; }; const instanceFactory = async (client: AeSdk) => { - return (aci: any, contractAddress: ContractAddress) => - client.initializeContract({ aci, address: contractAddress }); + return ( + aci: any, + contractAddress: ContractAddress, + ) => client.initializeContract({ aci, address: contractAddress }); }; export const getContext = async (): Promise => { @@ -137,21 +115,24 @@ export const getContext = async (): Promise => { } const [client, node] = await getClient(); const getInstance = await instanceFactory(client); - const router = await getInstance( + const router = await getInstance( routerInterface, nonNullable(routerAddress as ContractAddress), ); - const factory = await getInstance( + const factory = await getInstance( factoryInterface, nonNullable( process.env.FACTORY_ADDRESS as ContractAddress, ), ); - const pairs: { [key: string]: PairMethods | undefined } = {}; - const tokens: { [key: string]: Aex9Methods | undefined } = {}; + const pairs: { [key: string]: ContractWithMethods | undefined } = + {}; + const tokens: { + [key: string]: ContractWithMethods | undefined; + } = {}; return { - router: wrapRouter(router), - factory: wrapFactory(factory), + router, + factory, getPair: createGetPair(pairs, getInstance), getToken: createGetToken(tokens, getInstance), node, diff --git a/src/worker/index.ts b/src/worker/index.ts index 29d7620..5d4cf8a 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -5,16 +5,17 @@ import * as mdw from './middleware'; import { Logger } from '@nestjs/common'; import { ContractAddress } from 'src/lib/utils'; +import ContractWithMethods from '@aeternity/aepp-sdk/es/contract/Contract'; const logger = new Logger('Worker'); const updateTokenMetadata = async ( address: ContractAddress, - tokenMethods: Aex9Methods, + tokenMethods: ContractWithMethods, ) => { try { const { decodedResult: { name, symbol, decimals }, - } = await tokenMethods.metaInfo(); + } = await tokenMethods.meta_info(); const tokenFromDb = await dal.token.upsertToken( address, @@ -39,7 +40,7 @@ const upsertTokenInformation = async ( if (token) { return token.id; } - let tokenMethods: Aex9Methods; + let tokenMethods: ContractWithMethods; try { tokenMethods = await ctx.getToken(address); } catch (error) { @@ -112,17 +113,22 @@ const refreshPairLiquidity = async ( height?: number, ) => { const pair = await ctx.getPair(dbPair.address as ContractAddress); - const { decodedResult: totalSupply } = await pair.totalSupply(); + const { decodedResult: totalSupply } = await pair.total_supply(); const { decodedResult: { reserve0, reserve1 }, - result: { height: heightFromDryRun }, - } = await pair.reserves(); + result, + } = await pair.get_reserves(); + const syncHeight = height || result?.height; + if (!syncHeight) { + console.error('Could not get height'); + return; + } const ret = await dal.pair.synchronise( dbPair.id, totalSupply, reserve0, reserve1, - height || heightFromDryRun, + syncHeight, ); logger.debug( `Pair ${ret.token0.symbol}/${ret.token1.symbol} [${ @@ -138,7 +144,7 @@ const refreshPairLiquidity = async ( const refreshPairs = async (ctx: Context): Promise => { logger.log(`Getting all pairs from Factory...`); - const { decodedResult: allFactoryPairs } = await ctx.factory.allPairs(); + const { decodedResult: allFactoryPairs } = await ctx.factory.get_all_pairs(); logger.log(`${allFactoryPairs.length} pairs found on DEX`); const allDbPairsLen = await dal.pair.count(true); //get new pairs, and reverse it , because allFactoryPairs is reversed by the factory contract @@ -157,7 +163,7 @@ const refreshPairs = async (ctx: Context): Promise => { const pairWithTokens = await Promise.all( newAddresses.map( async ( - pairAddress, + pairAddress: ContractAddress, ): Promise<[ContractAddress, [ContractAddress, ContractAddress]]> => [ pairAddress, await getPairTokens(ctx, pairAddress), @@ -165,7 +171,7 @@ const refreshPairs = async (ctx: Context): Promise => { ), ); - const tokenSet = new Set( + const tokenSet: Set = new Set( pairWithTokens.reduce( (acc: ContractAddress[], data) => acc.concat(data[1]), [], diff --git a/test/context-mockup.spec.ts b/test/context-mockup.spec.ts index 273ab67..abde826 100644 --- a/test/context-mockup.spec.ts +++ b/test/context-mockup.spec.ts @@ -1,17 +1,14 @@ import { Context, PairMethods } from '../src/lib/contracts'; import { mockDeep } from 'jest-mock-extended'; -import { - mockContext, - ContextData, - mockupContractMethod, -} from './utils/context.mockup'; +import { mockContext, ContextData, mockupContractMethod } from './utils'; import * as data from './data/context-mockups'; +import ContractWithMethods from '@aeternity/aepp-sdk/es/contract/Contract'; describe('Context', () => { it('sample mockup', async () => { const mocked = mockDeep(); - const mockedPM = mockDeep(); + const mockedPM = mockDeep>(); mockedPM.token0 .calledWith() .mockReturnValue(Promise.resolve(mockupContractMethod('ct_sample'))); @@ -35,14 +32,14 @@ const testContextDataMockup = (label: string, contextData: ContextData) => { }); it('test factory.allPairs()', async () => { - const { decodedResult: pairs } = await context.factory.allPairs(); + const { decodedResult: pairs } = await context.factory.get_all_pairs(); expect(pairs).toEqual(contextData.pairs.map((x) => x.address).reverse()); }); for (const token of contextData.tokens) { it(`test getToken('${token.address}')`, async () => { const methods = await context.getToken(token.address); - expect((await methods.metaInfo()).decodedResult).toEqual( + expect((await methods.meta_info()).decodedResult).toEqual( token.metaInfo, ); }); @@ -57,10 +54,10 @@ const testContextDataMockup = (label: string, contextData: ContextData) => { expect((await pairMethods.token1()).decodedResult).toBe( contextData.tokens[pair.t1].address, ); - expect((await pairMethods.totalSupply()).decodedResult).toBe( + expect((await pairMethods.total_supply()).decodedResult).toBe( pair.totalSupply, ); - expect((await pairMethods.reserves()).decodedResult).toEqual({ + expect((await pairMethods.get_reserves()).decodedResult).toEqual({ reserve0: pair.reserve0, reserve1: pair.reserve1, }); diff --git a/test/contracts.spec.ts b/test/contracts.spec.ts index ff42fef..eb073a2 100644 --- a/test/contracts.spec.ts +++ b/test/contracts.spec.ts @@ -22,11 +22,11 @@ describe('with real Context on testnet', () => { }); it('should have at least 16 pairs', async () => { expect( - (await ctx().factory.allPairs()).decodedResult.length, + (await ctx().factory.get_all_pairs()).decodedResult.length, ).toBeGreaterThanOrEqual(16); }); it('pair should return right token addresses', async () => { - const { decodedResult: allPairs } = await ctx().factory.allPairs(); + const { decodedResult: allPairs } = await ctx().factory.get_all_pairs(); const pairAddress = allPairs[allPairs.length - 1]; expect(pairAddress).toBe( 'ct_efYtiwDg4YZxDWE3iLPzvrjb92CJPvzGwriv4ZRuvuTDMNMb9', @@ -47,7 +47,7 @@ describe('with real Context on testnet', () => { 'ct_7tTzPfvv3Vx8pCEcuk1kmgtn4sFsYCQDzLi1LvFs8T5PJqgsC', ); - const { decodedResult: metaInfo } = await tokenMethods.metaInfo(); + const { decodedResult: metaInfo } = await tokenMethods.meta_info(); expect(metaInfo).toEqual({ decimals: 18n, name: 'TestAEX9-B', @@ -58,7 +58,7 @@ describe('with real Context on testnet', () => { const tokenMethods = await ctx().getToken( 'ct_JDp175ruWd7mQggeHewSLS1PFXt9AzThCDaFedxon8mF8xTRF', ); - const { decodedResult: metaInfo } = await tokenMethods.metaInfo(); + const { decodedResult: metaInfo } = await tokenMethods.meta_info(); expect(metaInfo).toEqual({ decimals: 18n, name: 'Wrapped Aeternity', diff --git a/test/swap-routes.e2e-spec.ts b/test/swap-routes.e2e-spec.ts index d4d0c82..873adcf 100644 --- a/test/swap-routes.e2e-spec.ts +++ b/test/swap-routes.e2e-spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; -import { AppModule } from './../src/api/app.module'; +import { AppModule } from '../src/api/app.module'; import { mockContext, listToken } from './utils'; import worker from '../src/worker'; diff --git a/test/tokens.e2e-spec.ts b/test/tokens.e2e-spec.ts index c482416..a651db4 100644 --- a/test/tokens.e2e-spec.ts +++ b/test/tokens.e2e-spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; -import { AppModule } from './../src/api/app.module'; +import { AppModule } from '../src/api/app.module'; import worker from '../src/worker'; import { clean as cleanDb } from './utils/db'; diff --git a/test/utils/context.mockup.ts b/test/utils/context.mockup.ts index 5bbb78a..583a491 100644 --- a/test/utils/context.mockup.ts +++ b/test/utils/context.mockup.ts @@ -4,20 +4,15 @@ import { MetaInfo, Aex9Methods, } from '../../src/lib/contracts'; -import { - ContractAddress, - WalletAddress, - CallData, - nonNullable, -} from '../../src/lib/utils'; +import { ContractAddress, CallData, nonNullable } from '../../src/lib/utils'; import { mockDeep } from 'jest-mock-extended'; - +import ContractWithMethods from '@aeternity/aepp-sdk/es/contract/Contract'; const mockupResult = () => mockDeep<{ - callerId: WalletAddress; - callerNonce: number; - contractId: ContractAddress; - gasPrice: number; + callerId: string; + callerNonce: string; + contractId: string; + gasPrice: bigint; gasUsed: number; height: number; log: any[]; @@ -26,8 +21,13 @@ const mockupResult = () => }>({ height: 1, }); + export const mockupContractMethod = (t: T) => - Promise.resolve({ decodedResult: t, result: mockupResult() }); + Promise.resolve({ + decodedResult: t, + result: mockupResult(), + } as unknown as any); + export type ContextData = { factory: ContractAddress; pairs: { @@ -50,7 +50,7 @@ export const mockContext = (data: ContextData) => { .mockReturnValue(mockupContractMethod(data.factory)); // factory - mocked.factory.allPairs + mocked.factory.get_all_pairs .calledWith() .mockReturnValue( mockupContractMethod(data.pairs.map((x) => x.address).reverse()), @@ -58,13 +58,13 @@ export const mockContext = (data: ContextData) => { //getPair for (const pair of data.pairs) { - const pairMethodsMocked = mockDeep(); + const pairMethodsMocked = mockDeep>(); mocked.getPair .calledWith(pair.address) .mockReturnValue(Promise.resolve(pairMethodsMocked)); //total supply - pairMethodsMocked.totalSupply + pairMethodsMocked.total_supply .calledWith() .mockReturnValue(mockupContractMethod(pair.totalSupply)); @@ -81,7 +81,7 @@ export const mockContext = (data: ContextData) => { ); //reserves - pairMethodsMocked.reserves.calledWith().mockReturnValue( + pairMethodsMocked.get_reserves.calledWith().mockReturnValue( mockupContractMethod({ reserve0: pair.reserve0, reserve1: pair.reserve1, @@ -91,14 +91,14 @@ export const mockContext = (data: ContextData) => { //getToken for (const token of data.tokens) { - const tokenMethodsMocked = mockDeep(); + const tokenMethodsMocked = mockDeep>(); mocked.getToken .calledWith(token.address) .mockReturnValue(Promise.resolve(tokenMethodsMocked)); //meta info - tokenMethodsMocked.metaInfo + tokenMethodsMocked.meta_info .calledWith() .mockReturnValue(mockupContractMethod(token.metaInfo)); } diff --git a/test/worker-basics.e2e-spec.ts b/test/worker-basics.e2e-spec.ts index 01b7c7a..02b92e4 100644 --- a/test/worker-basics.e2e-spec.ts +++ b/test/worker-basics.e2e-spec.ts @@ -1,4 +1,4 @@ -import { mockContext } from './utils/context.mockup'; +import { mockContext } from './utils'; import createWorkerMethods from '../src/worker'; import db from '../src/dal/client'; import { clean as cleanDb } from './utils/db';