diff --git a/apps/api/src/app/routes/chains/__chainId/markets/__sellToken-__buyToken/slippageTolerance.ts b/apps/api/src/app/routes/chains/__chainId/markets/__sellToken-__buyToken/slippageTolerance.ts index 5d02c4f..869968a 100644 --- a/apps/api/src/app/routes/chains/__chainId/markets/__sellToken-__buyToken/slippageTolerance.ts +++ b/apps/api/src/app/routes/chains/__chainId/markets/__sellToken-__buyToken/slippageTolerance.ts @@ -4,6 +4,10 @@ import { } from '../../../../../schemas'; import { FastifyPluginAsync } from 'fastify'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; +import { getSlippageService } from '@cowprotocol/services'; + +// TODO: Add this in a follow up PR +// import { ALL_SUPPORTED_CHAIN_IDS } from '@cowprotocol/cow-sdk'; interface Result { slippageBps: number; @@ -38,7 +42,7 @@ const responseSchema = { description: 'Slippage tolerance in basis points. One basis point is equivalent to 0.01% (1/100th of a percent)', type: 'number', - examples: [50, 100, 200], + examples: [50, 100, 200], // [ALL_SUPPORTED_CHAIN_IDS], minimum: 0, maximum: 10000, }, @@ -47,6 +51,8 @@ const responseSchema = { type RouteSchema = FromSchema; +const slippageService = getSlippageService(); + const root: FastifyPluginAsync = async (fastify): Promise => { // example: http://localhost:3010/chains/1/markets/0x6b175474e89094c44da98b954eedeac495271d0f-0x2260fac5e5542a773aa44fbcfedf7c193bc2c599/slippageTolerance fastify.get<{ @@ -67,7 +73,11 @@ const root: FastifyPluginAsync = async (fastify): Promise => { fastify.log.info( `Get default slippage for market ${baseTokenAddress}-${quoteTokenAddress} on chain ${chainId}` ); - reply.send({ slippageBps: 50 }); + const slippageBps = slippageService.getSlippageBps( + baseTokenAddress, + quoteTokenAddress + ); + reply.send({ slippageBps }); } ); }; diff --git a/libs/repositories/.eslintrc.json b/libs/repositories/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/libs/repositories/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/repositories/README.md b/libs/repositories/README.md new file mode 100644 index 0000000..b985950 --- /dev/null +++ b/libs/repositories/README.md @@ -0,0 +1,7 @@ +# repositories + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test repositories` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/repositories/jest.config.ts b/libs/repositories/jest.config.ts new file mode 100644 index 0000000..089124a --- /dev/null +++ b/libs/repositories/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'repositories', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/libs/repositories', +}; diff --git a/libs/repositories/project.json b/libs/repositories/project.json new file mode 100644 index 0000000..6d5ac33 --- /dev/null +++ b/libs/repositories/project.json @@ -0,0 +1,30 @@ +{ + "name": "repositories", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/repositories/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/repositories/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/repositories/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/libs/repositories/src/UsdRepository.ts b/libs/repositories/src/UsdRepository.ts new file mode 100644 index 0000000..f7a3d21 --- /dev/null +++ b/libs/repositories/src/UsdRepository.ts @@ -0,0 +1,16 @@ +import { get } from 'http'; + +export interface UsdRepository { + getDailyUsdPrice(tokenAddress: string, date: Date): Promise; +} + +export class UsdRepositoryMock implements UsdRepository { + async getDailyUsdPrice(tokenAddress: string, date: Date): Promise { + return 1234; + } +} + +// TODO: Remove once we have IoC +export function getUsdRepository(): UsdRepository { + return new UsdRepositoryMock(); +} diff --git a/libs/repositories/src/index.ts b/libs/repositories/src/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/libs/repositories/tsconfig.json b/libs/repositories/tsconfig.json new file mode 100644 index 0000000..19b9eec --- /dev/null +++ b/libs/repositories/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs" + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/repositories/tsconfig.lib.json b/libs/repositories/tsconfig.lib.json new file mode 100644 index 0000000..3f06e80 --- /dev/null +++ b/libs/repositories/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/libs/repositories/tsconfig.spec.json b/libs/repositories/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/libs/repositories/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/libs/services/.eslintrc.json b/libs/services/.eslintrc.json new file mode 100644 index 0000000..9d9c0db --- /dev/null +++ b/libs/services/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/services/README.md b/libs/services/README.md new file mode 100644 index 0000000..678238c --- /dev/null +++ b/libs/services/README.md @@ -0,0 +1,7 @@ +# services + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test services` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/services/jest.config.ts b/libs/services/jest.config.ts new file mode 100644 index 0000000..972e461 --- /dev/null +++ b/libs/services/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'services', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/libs/services', +}; diff --git a/libs/services/project.json b/libs/services/project.json new file mode 100644 index 0000000..f6ae697 --- /dev/null +++ b/libs/services/project.json @@ -0,0 +1,30 @@ +{ + "name": "services", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/services/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/services/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/services/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/libs/services/src/SlippageService/SlippageService.spec.ts b/libs/services/src/SlippageService/SlippageService.spec.ts new file mode 100644 index 0000000..1c9b2e7 --- /dev/null +++ b/libs/services/src/SlippageService/SlippageService.spec.ts @@ -0,0 +1,9 @@ +import { getSlippageService } from './SlippageService'; + +const slippageService = getSlippageService(); + +describe('SlippageService', () => { + it('should return always 50', () => { + expect(slippageService.getSlippageBps('0x0', '0x0')).toEqual(50); + }); +}); diff --git a/libs/services/src/SlippageService/SlippageService.ts b/libs/services/src/SlippageService/SlippageService.ts new file mode 100644 index 0000000..e23f614 --- /dev/null +++ b/libs/services/src/SlippageService/SlippageService.ts @@ -0,0 +1,20 @@ +/** + * BPS (Basis Points) + */ +export type Bps = number; + +export interface SlippageService { + getSlippageBps(quoteTokenAddress: string, baseTokenAddress: string): Bps; +} + +// TODO: Find good name for the implementation, as Leandro don't like "Impl" suffix, just don't want to couple it to add Coingecko in its name (as that would couple it to the data-source, and the adding a name to specify the algorithm might complicate the name, as this will use some custom logic based on standard deviation, so for now as we plan to have just one implementation, I want to keep it simple. But happy to get ideas here) +export class SlippageServiceImpl implements SlippageService { + getSlippageBps(_quoteTokenAddress: string, _baseTokenAddress: string): Bps { + return 50; + } +} + +// TODO: This is just temporal! I will introduce a IoC framework in a follow up +export function getSlippageService(): SlippageService { + return new SlippageServiceImpl(); +} diff --git a/libs/services/src/index.ts b/libs/services/src/index.ts new file mode 100644 index 0000000..4e078ee --- /dev/null +++ b/libs/services/src/index.ts @@ -0,0 +1 @@ +export * from './SlippageService/SlippageService'; diff --git a/libs/services/tsconfig.json b/libs/services/tsconfig.json new file mode 100644 index 0000000..19b9eec --- /dev/null +++ b/libs/services/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs" + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/services/tsconfig.lib.json b/libs/services/tsconfig.lib.json new file mode 100644 index 0000000..3f06e80 --- /dev/null +++ b/libs/services/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/libs/services/tsconfig.spec.json b/libs/services/tsconfig.spec.json new file mode 100644 index 0000000..9b2a121 --- /dev/null +++ b/libs/services/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index b21255c..07b321f 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,10 +10,7 @@ "importHelpers": true, "target": "es2015", "module": "esnext", - "lib": [ - "es2020", - "dom" - ], + "lib": ["es2020", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", @@ -21,19 +18,12 @@ "esModuleInterop": true, "allowJs": true, "paths": { - "@cowprotocol/abis": [ - "libs/abis/src/index.ts" - ], - "@cowprotocol/cms-api": [ - "libs/cms-api/src/index.ts" - ], - "@cowprotocol/notifications": [ - "libs/notifications/src/index.ts" - ] + "@cowprotocol/abis": ["libs/abis/src/index.ts"], + "@cowprotocol/cms-api": ["libs/cms-api/src/index.ts"], + "@cowprotocol/notifications": ["libs/notifications/src/index.ts"], + "@cowprotocol/repositories": ["libs/repositories/src/index.ts"], + "@cowprotocol/services": ["libs/services/src/index.ts"] } }, - "exclude": [ - "node_modules", - "tmp" - ] -} \ No newline at end of file + "exclude": ["node_modules", "tmp"] +} diff --git a/yarn.lock b/yarn.lock index 7e320b8..44fd87f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6602,7 +6602,7 @@ node-fetch@^2.6.12: node-fetch@^3.3.2: version "3.3.2" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== dependencies: data-uri-to-buffer "^4.0.0"