-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(backend): implement eth mainnet uniswap v3 resolver (#2)
Adds new positions controller. Adds Uniswap V3 resolver. Adds resolver registry for future resolver implementations. --------- Signed-off-by: Luca Georges Francois <[email protected]>
- Loading branch information
1 parent
c398596
commit eb8b728
Showing
18 changed files
with
2,958 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Contributing to lipso backend | ||
|
||
_Coming soon!_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
import { NestFactory } from '@nestjs/core'; | ||
import { AppModule } from './app.module'; | ||
import { ValidationPipe } from '@nestjs/common'; | ||
|
||
async function bootstrap() { | ||
const app = await NestFactory.create(AppModule); | ||
app.useGlobalPipes(new ValidationPipe()); | ||
await app.listen(3000); | ||
} | ||
bootstrap(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { IsNotEmpty } from 'class-validator'; | ||
|
||
/** | ||
* Parameters for the `/positions` endpoint, used to specify: | ||
* | ||
* - The Ethereum Address of the owner of the positions. | ||
*/ | ||
export class ListPositionsDTO { | ||
// TODO: Validate that the owner is a valid Ethereum Address. | ||
@IsNotEmpty() | ||
owner: string; | ||
|
||
// TODO: Add a field to specify the list of chains. | ||
// TODO: Add a field to specify the list of protocols. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* A liquidity position on a DEX. | ||
* | ||
* As the goal of this project is to provide insights to the user about their liquidity positions, this entity helps to understand if their position is in range or not. | ||
* Depending on the DEX, the extra field can be used to store additional information about the position. | ||
* For example, in UniswapV3, the extra field stores the position ID can be used to create a link to the position on the official UniswapV3 interface. | ||
*/ | ||
export class Position<T> { | ||
inRange: boolean; | ||
extra: T; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { PositionsController } from './positions.controller'; | ||
import { PositionsService } from './positions.service'; | ||
import { ResolverRegistryService } from './resolver-registry/resolver-registry.service'; | ||
|
||
describe('PositionsController', () => { | ||
let controller: PositionsController; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
controllers: [PositionsController], | ||
providers: [PositionsService, ResolverRegistryService], | ||
}).compile(); | ||
|
||
controller = module.get<PositionsController>(PositionsController); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(controller).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { Controller, Get, Query } from '@nestjs/common'; | ||
import { PositionsService } from './positions.service'; | ||
import { ListPositionsDTO } from './dto/list-positions.dto'; | ||
import { Position } from './entities/position.entity'; | ||
import { ResolverRegistryService } from './resolver-registry/resolver-registry.service'; | ||
import { mainnet } from 'viem/chains'; | ||
import { createPublicClient, getAddress, http } from 'viem'; | ||
import { ResolverPositionExtra } from './resolver-registry/resolver.entity'; | ||
|
||
@Controller('positions') | ||
export class PositionsController { | ||
constructor( | ||
private readonly positionsService: PositionsService, | ||
private resolverRegistryService: ResolverRegistryService, | ||
) { | ||
// TODO: Get HTTP endpoint from config. | ||
const ethMainnetClient = createPublicClient({ | ||
chain: mainnet, | ||
transport: http(undefined, { | ||
batch: { | ||
batchSize: 10, | ||
}, | ||
}), | ||
}); | ||
|
||
// TODO: Get UniswapV3 mainnet deployment addresses from config. | ||
this.resolverRegistryService.registerUniswapV3Resolver( | ||
ethMainnetClient, | ||
getAddress('0x1F98431c8aD98523631AE4a59f267346ea31F984'), | ||
getAddress('0xC36442b4a4522E871399CD717aBDD847Ab11FE88'), | ||
); | ||
} | ||
|
||
@Get() | ||
async findAll( | ||
@Query() query: ListPositionsDTO, | ||
): Promise<Position<ResolverPositionExtra>[]> { | ||
return this.positionsService.findAll(query, this.resolverRegistryService); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { PositionsService } from './positions.service'; | ||
import { PositionsController } from './positions.controller'; | ||
import { ResolverRegistryService } from './resolver-registry/resolver-registry.service'; | ||
|
||
@Module({ | ||
controllers: [PositionsController], | ||
providers: [PositionsService, ResolverRegistryService], | ||
}) | ||
export class PositionsModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { PositionsService } from './positions.service'; | ||
|
||
describe('PositionsService', () => { | ||
let service: PositionsService; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
providers: [PositionsService], | ||
}).compile(); | ||
|
||
service = module.get<PositionsService>(PositionsService); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(service).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { ListPositionsDTO } from './dto/list-positions.dto'; | ||
import { Position } from './entities/position.entity'; | ||
import { ResolverRegistryService } from './resolver-registry/resolver-registry.service'; | ||
import { getAddress } from 'viem'; | ||
import { ResolverPositionExtra } from './resolver-registry/resolver.entity'; | ||
|
||
@Injectable() | ||
export class PositionsService { | ||
async findAll( | ||
query: ListPositionsDTO, | ||
resolverRegistryService: ResolverRegistryService, | ||
): Promise<Position<ResolverPositionExtra>[]> { | ||
const owner = getAddress(query.owner); | ||
const store = resolverRegistryService.getStore(); | ||
|
||
const positions = ( | ||
await Promise.all( | ||
Array.from(store.values()).map((resolver) => { | ||
return Promise.all( | ||
resolver.map((r) => | ||
r.findAllPositions<ResolverPositionExtra>(owner), | ||
), | ||
); | ||
}), | ||
) | ||
) | ||
.flat() | ||
.flat(); | ||
|
||
return positions; | ||
} | ||
} |
Oops, something went wrong.