Skip to content

Commit

Permalink
fix: add l2 eth token configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
vasyl-ivanchuk committed Jul 31, 2024
1 parent 8d366d8 commit 81890ab
Show file tree
Hide file tree
Showing 17 changed files with 296 additions and 127 deletions.
10 changes: 9 additions & 1 deletion packages/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ CONTRACT_VERIFICATION_API_URL=http://127.0.0.1:3070
NETWORK_NAME=testnet-sepolia
BASE_TOKEN_SYMBOL=ETH
BASE_TOKEN_DECIMALS=18
BASE_TOKEN_L1_ADDRESS=0x8E9C82509488eD471A83824d20Dd474b8F534a0b
BASE_TOKEN_L1_ADDRESS=0x0000000000000000000000000000000000000000
BASE_TOKEN_ICON_URL=https://assets.coingecko.com/coins/images/279/large/ethereum.png?1698873266
BASE_TOKEN_NAME=Ether
BASE_TOKEN_LIQUIDITY=220000000000
BASE_TOKEN_USDPRICE=1800

ETH_TOKEN_SYMBOL=ETH
ETH_TOKEN_DECIMALS=18
ETH_TOKEN_L2_ADDRESS=0x000000000000000000000000000000000000800A
ETH_TOKEN_ICON_URL=https://assets.coingecko.com/coins/images/279/large/ethereum.png?1698873266
ETH_TOKEN_NAME=Ether
ETH_TOKEN_LIQUIDITY=220000000000
ETH_TOKEN_USDPRICE=1800
8 changes: 8 additions & 0 deletions packages/api/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ PORT=3007
LIMITED_PAGINATION_MAX_ITEMS=15
API_LIMITED_PAGINATION_MAX_ITEMS=15
CONTRACT_VERIFICATION_API_URL=http://verification.api
BASE_TOKEN_SYMBOL=ETH
BASE_TOKEN_DECIMALS=18
BASE_TOKEN_L1_ADDRESS=0x0000000000000000000000000000000000000000
BASE_TOKEN_ICON_URL=https://assets.coingecko.com/coins/images/279/large/ethereum.png?1698873266
BASE_TOKEN_NAME=Ether
BASE_TOKEN_LIQUIDITY=220000000000
BASE_TOKEN_USDPRICE=1800
ETH_TOKEN_L2_ADDRESS=0x000000000000000000000000000000000000800A
17 changes: 14 additions & 3 deletions packages/api/src/api/stats/stats.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { Test } from "@nestjs/testing";
import { mock } from "jest-mock-extended";
import { ConfigService } from "@nestjs/config";
import { Logger } from "@nestjs/common";
import { TokenService } from "../../token/token.service";
import { Token } from "../../token/token.entity";
import { StatsController } from "./stats.controller";
import { baseTokenData } from "../../config";
import { BASE_TOKEN_L2_ADDRESS } from "../../common/constants";

describe("StatsController", () => {
let controller: StatsController;
let tokenServiceMock: TokenService;
let configServiceMock: ConfigService;

beforeEach(async () => {
tokenServiceMock = mock<TokenService>({
findOne: jest.fn().mockResolvedValue(null),
});
configServiceMock = mock<ConfigService>({
get: jest.fn().mockResolvedValue({
l2Address: BASE_TOKEN_L2_ADDRESS,
}),
});

const module = await Test.createTestingModule({
controllers: [StatsController],
Expand All @@ -22,6 +29,10 @@ describe("StatsController", () => {
provide: TokenService,
useValue: tokenServiceMock,
},
{
provide: ConfigService,
useValue: configServiceMock,
},
],
}).compile();
module.useLogger(mock<Logger>());
Expand All @@ -32,7 +43,7 @@ describe("StatsController", () => {
describe("ethPrice", () => {
it("returns ok response and ETH price when ETH token is found", async () => {
jest.spyOn(tokenServiceMock, "findOne").mockResolvedValueOnce({
usdPrice: baseTokenData.usdPrice,
usdPrice: 1000,
offChainDataUpdatedAt: new Date("2023-03-03"),
} as Token);

Expand All @@ -41,7 +52,7 @@ describe("StatsController", () => {
status: "1",
message: "OK",
result: {
ethusd: baseTokenData.usdPrice.toString(),
ethusd: "1000",
ethusd_timestamp: Math.floor(new Date("2023-03-03").getTime() / 1000).toString(),
},
});
Expand Down
11 changes: 8 additions & 3 deletions packages/api/src/api/stats/stats.controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Controller, Get, UseFilters } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { ApiTags, ApiExcludeController } from "@nestjs/swagger";
import { ResponseStatus, ResponseMessage } from "../dtos/common/responseBase.dto";
import { ApiExceptionFilter } from "../exceptionFilter";
import { EthPriceResponseDto } from "../dtos/stats/ethPrice.dto";
import { TokenService } from "../../token/token.service";
import { dateToTimestamp } from "../../common/utils";
import { baseTokenData } from "../../config";
import { type BaseToken } from "../../config";

const entityName = "stats";

Expand All @@ -14,11 +15,15 @@ const entityName = "stats";
@Controller(`api/${entityName}`)
@UseFilters(ApiExceptionFilter)
export class StatsController {
constructor(private readonly tokenService: TokenService) {}
private readonly ethTokenAddress: string;

constructor(private readonly tokenService: TokenService, private readonly configService: ConfigService) {
this.ethTokenAddress = this.configService.get<BaseToken>("ethToken").l2Address;
}

@Get("/ethprice")
public async ethPrice(): Promise<EthPriceResponseDto> {
const token = await this.tokenService.findOne(baseTokenData.l2Address, {
const token = await this.tokenService.findOne(this.ethTokenAddress, {
usdPrice: true,
offChainDataUpdatedAt: true,
});
Expand Down
14 changes: 11 additions & 3 deletions packages/api/src/api/token/token.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { Logger } from "@nestjs/common";
import { TokenService } from "../../token/token.service";
import { Token } from "../../token/token.entity";
import { TokenController } from "./token.controller";
import config from "../../config/index";
const { baseTokenData } = config();

describe("TokenController", () => {
let controller: TokenController;
let tokenServiceMock: TokenService;
Expand Down Expand Up @@ -33,7 +32,16 @@ describe("TokenController", () => {

describe("tokenInfo", () => {
it("returns ok response and token info when token is found", async () => {
const baseToken = baseTokenData as Token;
const baseToken = {
l2Address: "l2Address",
l1Address: "l1Address",
symbol: "ETH",
name: "Ether",
decimals: 18,
liquidity: 10,
iconURL: "iconURL",
usdPrice: 20,
} as Token;
jest.spyOn(tokenServiceMock, "findOne").mockResolvedValueOnce(baseToken);
const response = await controller.tokenInfo(contractAddress);
expect(response).toEqual({
Expand Down
16 changes: 10 additions & 6 deletions packages/api/src/balance/balance.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { BaseEntity } from "../common/entities/base.entity";
import { Token } from "../token/token.entity";
import { normalizeAddressTransformer } from "../common/transformers/normalizeAddress.transformer";
import { bigIntNumberTransformer } from "../common/transformers/bigIntNumber.transformer";
import { baseTokenData } from "../config/index";
import { baseToken, ethToken } from "../config";

@Entity({ name: "balances" })
export class Balance extends BaseEntity {
@PrimaryColumn({ type: "bytea", transformer: normalizeAddressTransformer })
Expand All @@ -25,11 +26,14 @@ export class Balance extends BaseEntity {

@AfterLoad()
populateBaseToken() {
if (
!this.token &&
(this.tokenAddress === undefined || this.tokenAddress.toLowerCase() === baseTokenData.l2Address.toLowerCase())
) {
this.token = baseTokenData as Token;
// tokenAddress might be empty when not all entity fields are requested from the DB
if (this.tokenAddress && !this.token) {
const tokenAddress = this.tokenAddress.toLowerCase();
if (tokenAddress === baseToken.l2Address.toLowerCase()) {
this.token = baseToken as Token;
} else if (tokenAddress === ethToken.l2Address.toLowerCase()) {
this.token = ethToken as Token;
}
}
}
}
Loading

0 comments on commit 81890ab

Please sign in to comment.