Skip to content

Commit

Permalink
feat: support query rsETH
Browse files Browse the repository at this point in the history
  • Loading branch information
xsteadybcgo committed Oct 23, 2024
1 parent 249e255 commit e75244c
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 1 deletion.
75 changes: 74 additions & 1 deletion src/positions/positions.controller.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import { Controller, Get, Param, Query } from "@nestjs/common";
import { Controller, Get, Logger, Param, Query } from "@nestjs/common";
import {
ApiBadRequestResponse,
ApiExcludeController,
ApiNotFoundResponse,
ApiOkResponse,
ApiOperation,
ApiParam,
ApiTags,
} from "@nestjs/swagger";
import {
BalanceQueryDto,
BalanceReturnDto,
GetAGXPositionDto,
GetUserPositionsDto,
UserPositionsResponseDto,
} from "./positions.dto";
import { PositionsService } from "./positions.service";
import { PaginationUtil } from "src/common/pagination.util";
import { ParseAddressPipe } from "src/common/pipes/parseAddress.pipe";
import { SERVICE_EXCEPTION } from "src/puffer/tokenPointsWithoutDecimals.dto";

@ApiTags("positions")
@ApiExcludeController(false)
@Controller("positions")
export class PositionsController {
private readonly logger = new Logger(PositionsController.name);
constructor(private positionsService: PositionsService) {}

@Get(":projectName")
Expand Down Expand Up @@ -57,4 +65,69 @@ export class PositionsController {

return data;
}

@Get("/balance/:token")
@ApiOperation({
summary: "Get balance list by block",
})
@ApiOkResponse({
description: "Return all users' balance.",
type: BalanceReturnDto,
})
@ApiBadRequestResponse({
description: '{ "errno": 1, "errmsg": "Service exception" }',
})
@ApiNotFoundResponse({
description: '{ "errno": 1, "errmsg": "not found" }',
})
public async getRsethBalance(
@Param("token", new ParseAddressPipe()) token: string,
@Query() rsethQueryDto: BalanceQueryDto,
): Promise<Partial<BalanceReturnDto>> {
const { block, page = 1, limit = 500 } = rsethQueryDto;
try {
// If more tokens need to be supported, please modify the subgraph.
// Currently, only rsETH.eth and rsETH.arb are supported.
const userPositions = await this.positionsService.getUserPositionByToken({
token,
block,
page,
limit,
});
const data = userPositions.map((position) => {
const account = position.id;
const liquidityPosition = position.liquidityPositions.reduce(
(acc, cur) =>
acc +
(BigInt(cur.supplied) * BigInt(cur.balance)) /
BigInt(cur.totalSupplied),
BigInt(0),
);
const balancePosition = position.balances[0]
? BigInt(position.balances[0].balance)
: BigInt(0);
const balance = (balancePosition + liquidityPosition).toString();

return { account, balance };
});
console.log(
data.reduce((acc, cur) => BigInt(cur.balance) + acc, BigInt(0)),
);
const paging = PaginationUtil.paginate(data, page, limit);
const list = paging.items;
const meta = paging.meta;
return {
errno: 0,
errmsg: "no error",
data: list,
meta,
};
} catch (err) {
this.logger.error(
`Get balance ${token} on block ${block} failed`,
err.stack,
);
return SERVICE_EXCEPTION;
}
}
}
44 changes: 44 additions & 0 deletions src/positions/positions.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,47 @@ export class UserPositionsResponseDto {
})
public readonly data?: UserPositionsDto[];
}

export class BalanceQueryDto extends PagingOptionsDto {
@ApiProperty({
required: true,
description: "block number on nova network",
})
block: number;
}

export class BalanceReturnDto {
@ApiProperty({
type: Number,
description: "error code",
example: 0,
})
public readonly errno: number;

@ApiProperty({
type: String,
description: "error message",
example: "no error",
})
public readonly errmsg: string;

@ApiProperty({
type: Array<{ account: string; balance: string }>,
description: "user's balance",
example: [
{
balance: "10000000000",
account: "0x22723cc5ae5a1b4514ca41f2466e2ade15cf529b",
},
],
required: false,
})
public readonly data?: Array<{ account: string; balance: string }>;

@ApiProperty({
type: PagingMetaDto,
description: "page meta",
example: 0,
})
public readonly meta?: PagingMetaDto;
}
74 changes: 74 additions & 0 deletions src/positions/positions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BalanceOfLpRepository } from "src/repositories/balanceOfLp.repository";
import { GetUserPositionsDto } from "./positions.dto";
import { ethers } from "ethers";
import { PaginationUtil } from "src/common/pagination.util";
import { fetchGraphQLData } from "src/utils/fetchDataFromGraph";

@Injectable()
export class PositionsService {
Expand Down Expand Up @@ -46,4 +47,77 @@ export class PositionsService {
Result: result,
};
}

async getUserPositionByToken(params: {
token: string;
limit: number;
page: number;
block: number;
}) {
const { token, block, limit, page } = params;
const data = await fetchGraphQLData<{ userPositions: any[] }>(
"https://graph.zklink.io/subgraphs/name/rseth-balance", // If more tokens need to be supported, please modify the subgraph
`query MyQuery($token: Bytes = \"${token}\") {
userPositions(
first: ${limit},
skip: ${(page - 1) * limit},
block: {number: ${block}}
where: {
and: [
{
valid: true
},
{
or: [
{
balances_: {
tokenAddress: $token,
balance_gt: 0
}
},
{
liquidityPositions_: {
token: $token,
supplied_gt: 0
}
}
]
}
]
}
) {
id
valid
balances(
where: {
tokenAddress: $token
}
) {
symbol
id
decimals
balance
tokenAddress
}
liquidityPositions(
where: {
token: $token
}
) {
id
supplied
token
pool {
balance
totalSupplied
symbol
}
}
}
}
`,
);

return data.userPositions;
}
}

0 comments on commit e75244c

Please sign in to comment.