diff --git a/apps/api/src/app/routes/trading/README.md b/apps/api/src/app/routes/trading/README.md index ff53c31c..d5f280be 100644 --- a/apps/api/src/app/routes/trading/README.md +++ b/apps/api/src/app/routes/trading/README.md @@ -12,8 +12,6 @@ fetch('http://127.0.0.1:8080/trading/getQuote', {method: 'POST', headers: {'Cont kind: 'sell', sellToken: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", buyToken: "0xdef1ca1fb7fbcdc777520aa7f396b4e015f497ab", - sellTokenDecimals: 18, - buyTokenDecimals: 18, amount: '12000000000000000' } })}) @@ -32,8 +30,6 @@ fetch('http://127.0.0.1:8080/trading/getQuote', {method: 'POST', headers: {'Cont kind: 'sell', sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14', buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59', - sellTokenDecimals: 18, - buyTokenDecimals: 18, amount: '100000000000000000' } diff --git a/apps/api/src/app/routes/trading/schemas.ts b/apps/api/src/app/routes/trading/schemas.ts index 59d00131..e6be4fc8 100644 --- a/apps/api/src/app/routes/trading/schemas.ts +++ b/apps/api/src/app/routes/trading/schemas.ts @@ -1,5 +1,7 @@ import { JSONSchema } from 'json-schema-to-ts'; +import { omit } from '@cowprotocol/shared'; + import QuoterParametersSchema from '../../../tradingSchemas/QuoterParameters'; import TradeParametersSchema from '../../../tradingSchemas/TradeParameters'; import QuoteResultsSchema from '../../../tradingSchemas/QuoteResultsSerialized'; @@ -10,7 +12,16 @@ export const getQuoteBodySchema = { additionalProperties: false, properties: { trader: QuoterParametersSchema, - params: TradeParametersSchema + params: { + ...TradeParametersSchema, + properties: omit(TradeParametersSchema.properties, ['sellTokenDecimals', 'buyTokenDecimals']), + required: [ + 'amount', + 'kind', + 'sellToken', + 'buyToken', + ] + } } } as const satisfies JSONSchema; diff --git a/libs/repositories/src/const.ts b/libs/repositories/src/const.ts index c58ce563..b9445ada 100644 --- a/libs/repositories/src/const.ts +++ b/libs/repositories/src/const.ts @@ -1,5 +1,5 @@ import BigNumber from 'bignumber.js'; -import { SupportedChainId } from '../../shared/src/types'; +import { SupportedChainId } from '@cowprotocol/shared'; interface TokenAddressAndDecimals { address: string; diff --git a/libs/services/src/TradingService/TradingService.ts b/libs/services/src/TradingService/TradingService.ts index 5b7d4d7e..387b820b 100644 --- a/libs/services/src/TradingService/TradingService.ts +++ b/libs/services/src/TradingService/TradingService.ts @@ -1,4 +1,4 @@ -import { injectable } from 'inversify'; +import { inject, injectable } from 'inversify'; import { getQuote, TradeParameters, @@ -8,6 +8,7 @@ import { SupportedChainId, CowEnv } from '@cowprotocol/cow-sdk'; +import { Erc20Repository, erc20RepositorySymbol } from '@cowprotocol/repositories'; export const tradingServiceSymbol = Symbol.for('TradingServiceSymbol'); @@ -19,13 +20,30 @@ interface TraderParams { @injectable() export class TradingService { + constructor( + @inject(erc20RepositorySymbol) + private erc20Repository: Erc20Repository + ) { + } async getQuote( trader: Parameters[1], - params: TradeParameters, + params: Omit, advancedSettings?: SwapAdvancedSettings ): Promise { - return getQuote(params, trader, advancedSettings).then(({result}) => result); + const chainId = trader.chainId as number + const sellToken = await this.erc20Repository.get(chainId, params.sellToken); + const buyToken = await this.erc20Repository.get(chainId, params.buyToken); + + if (typeof sellToken?.decimals !== 'number' || typeof buyToken?.decimals !== 'number') { + throw new Error('[TradingService.getQuote] Cannot find tokens decimals') + } + + const sellTokenDecimals = sellToken.decimals + const buyTokenDecimals = buyToken.decimals + + return getQuote({ ...params, sellTokenDecimals, buyTokenDecimals }, trader, advancedSettings) + .then(({result}) => result); } async postOrder( diff --git a/libs/shared/src/utils.ts b/libs/shared/src/utils.ts index 7cfc9aba..57f1d425 100644 --- a/libs/shared/src/utils.ts +++ b/libs/shared/src/utils.ts @@ -41,3 +41,14 @@ export function toSupportedChainId(chain: string | number): SupportedChainId { return chain; } + + +export function omit(object: T, omitKeys: K[]): Omit { + const result = { ...object }; + + for (const key of omitKeys) { + delete result[key]; + } + + return result; +} \ No newline at end of file