Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: initial changes to show erc20 as native token in explorer #2

Open
wants to merge 74 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
69a1a03
feat: initial changes to show erc20 as native token in explorer
fkrause98 Jan 22, 2024
fb8e1dd
feat: use nativechain instead of eth
fkrause98 Jan 24, 2024
93000f8
feat: finishing touches to show ERC20 as native token
fkrause98 Jan 26, 2024
afc4368
chore: rename .png
fkrause98 Jan 26, 2024
8729286
chore: rename png asset
fkrause98 Jan 29, 2024
48a887a
feat: default to ethereum when rpc method is missing
fkrause98 Jan 29, 2024
8c47644
fix: for error of missing method
fkrause98 Jan 29, 2024
9047c93
fix: worker tests
fkrause98 Jan 29, 2024
bbfd6ee
fix: worker tests
fkrause98 Jan 29, 2024
edaff40
fix: api tests and some e2e imports
fkrause98 Jan 30, 2024
30d422c
fix: move token.ts file to work for imports
fkrause98 Jan 30, 2024
703cfb1
fix: common imports
fkrause98 Jan 31, 2024
3db2ebe
feat: adapt to base-token-addr-endpoint
fkrause98 Feb 2, 2024
2b89e32
fix: worker tests
fkrause98 Feb 6, 2024
8292786
Merge branch 'main' into show-native-erc20token-info
fkrause98 Feb 14, 2024
3882989
fix: fix data-fetcher tests
fkrause98 Feb 14, 2024
1ce5552
chore: remove unused png
fkrause98 Feb 14, 2024
06d69a4
chore: replace "Native Token" with "Base Token"
fkrause98 Mar 1, 2024
80523d8
chore: rename chainNative to baseToken
fkrause98 Mar 1, 2024
222c479
feat: move base token fetching to separate module
fkrause98 Mar 7, 2024
373b2f1
chore: remove old, unused code
fkrause98 Mar 7, 2024
09b7b14
fix: use base token instead of base token
fkrause98 Mar 8, 2024
db59ca2
fix: rename native token to base token
fkrause98 Mar 8, 2024
27c2da7
chore: remove old, unused code
fkrause98 Mar 9, 2024
bc683c2
fix: fix build, add comment
fkrause98 Mar 9, 2024
370b07c
fix: restore postgres default password on config
fkrause98 Mar 9, 2024
2f6807d
feat: use base token from config in more places
fkrause98 Mar 12, 2024
e945af2
chore: update .env.example
fkrause98 Mar 12, 2024
d28c184
feat: move base-token fetching to a script
fkrause98 Mar 12, 2024
c3b210a
fix: data-fetcher unit tests
fkrause98 Mar 13, 2024
48c10f0
fix: api unit tests
fkrause98 Mar 13, 2024
f79a787
fix: worker tests
fkrause98 Mar 13, 2024
a075201
fix: more tests
fkrause98 Mar 13, 2024
4e79b7c
chore: properly import config
fkrause98 Mar 14, 2024
3d156db
feat: rename to BaseToken
fkrause98 Mar 14, 2024
191c230
feat: remove baseTokenData function
fkrause98 Mar 14, 2024
557ade6
feat: add base token address to configs
fkrause98 Mar 18, 2024
6475157
feat: use base token from config instead of constant
fkrause98 Mar 19, 2024
82337a0
chore: remove unused scriped script
fkrause98 Apr 3, 2024
a3fbfd8
Merge branch 'main' into show-native-erc20token-info
fkrause98 Apr 3, 2024
b35d489
fix: update baseToken to baseTokenData in E2E tests
Apr 9, 2024
b05d179
fix(e2e tests): fix end-to-end test to use base token, modify eth add…
Apr 10, 2024
2b0cdcc
fix(e2e tests): fix eth address in address e2e tests
Apr 10, 2024
2d864fb
fix(e2e tests): change missing apparences of l1 address
Apr 10, 2024
c10c183
fix(e2e tests): non existing var name
Apr 10, 2024
bc94960
fix: increase default timeout settings (#228)
vasyl-ivanchuk Apr 12, 2024
8e892ac
Merge branch 'main' into show-native-erc20token-info
SantiagoPittella Apr 12, 2024
7fa6341
fix(e2e tests): valid address format
Apr 15, 2024
d3916ed
fix(e2e tests): add missing fields in select
Apr 15, 2024
2c98553
fix(e2e tests): remove unused modules
SantiagoPittella Apr 15, 2024
fbbdcc9
fix(e2e tests): typecheck
SantiagoPittella Apr 15, 2024
037533f
fix(e2e tests): increase amount of selects in test
SantiagoPittella Apr 15, 2024
2af72cf
fix(e2e tests): add missing values in tests
SantiagoPittella Apr 15, 2024
0ac3a04
test(coverage): api config with base token
SantiagoPittella Apr 16, 2024
60d1196
test: uncomment tests
SantiagoPittella Apr 19, 2024
1fa1b11
fix: remove non existing script
SantiagoPittella Apr 19, 2024
2a03395
fix: address PR comments
SantiagoPittella Apr 19, 2024
4820fcf
fix: lint errors
SantiagoPittella Apr 19, 2024
053f71b
fix: rpc method name
SantiagoPittella Apr 19, 2024
cef3484
fix: rollback address capitalization
SantiagoPittella Apr 22, 2024
c094d99
fix: rename root hash to block hash (#249)
vasyl-ivanchuk Apr 23, 2024
a711fc7
fix: use checksum address
SantiagoPittella Apr 23, 2024
7d28e3d
Merge branch 'main' into show-native-erc20token-info
SantiagoPittella Apr 23, 2024
b60f5c2
Merge branch 'show-native-erc20token-info' of github.com:lambdaclass/…
SantiagoPittella Apr 23, 2024
d237471
fix: use both version of the rpc response for getBridgeContract method
SantiagoPittella Apr 23, 2024
b9d74a2
Revert "fix(e2e tests): add missing fields in select"
fkrause98 Apr 23, 2024
0203281
Revert "fix(e2e tests): add missing fields in select"
SantiagoPittella Apr 23, 2024
a1d1b4e
fix(e2e): account tests
fkrause98 Apr 23, 2024
41d4189
Merge branch 'show-native-erc20token-info' of github.com:lambdaclass/…
SantiagoPittella Apr 23, 2024
288ff55
fix: use correct amount of selects
SantiagoPittella Apr 23, 2024
ffac23c
test: add tests for old response
SantiagoPittella Apr 24, 2024
3c38e15
chore: fix docker compose (#256)
vasyl-ivanchuk May 23, 2024
146e2d9
fix: explorer doesn't require defined bridge address (#257)
vasyl-ivanchuk May 24, 2024
1d88c0b
Merge branch 'main' into show-native-erc20token-info
SantiagoPittella May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,18 @@ services:
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=block-explorer

geth:
image: "matterlabs/geth:latest"
logging:
driver: none
ports:
- "8545:8545"
- "8546:8546"
reth:
restart: always
image: "ghcr.io/paradigmxyz/reth:v0.2.0-beta.2"
volumes:
- geth:/var/lib/geth/data
- type: bind
source: ./reth_chaindata
target: /chaindata
command: node --dev --datadir /rethdata --http --http.addr 0.0.0.0 --http.port 8545 --dev.block-time 300ms --chain /chaindata/reth_config
environment:
- RUST_LOG=warn
ports:
- 127.0.0.1:8545:8545

zksync:
stdin_open: true
Expand All @@ -96,28 +99,30 @@ services:
depends_on:
postgres:
condition: service_healthy
geth:
reth:
condition: service_started
ports:
- "3050:3050" # JSON RPC HTTP port
- "3051:3051" # JSON RPC WS port
- 127.0.0.1:3050:3050 # JSON RPC HTTP port
- 127.0.0.1:3051:3051 # JSON RPC WS port
volumes:
# Configs folder bind
- zksync-config:/etc/env/
# Storage folder bind
- zksync-data:/var/lib/zksync/data
environment:
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/zksync_local
- ETH_CLIENT_WEB3_URL=http://geth:8545
- DATABASE_PROVER_URL=postgres://postgres:postgres@postgres/prover_local
- DATABASE_URL=postgres://postgres:postgres@postgres/zksync_local
- ETH_CLIENT_WEB3_URL=http://reth:8545
healthcheck:
test: "curl -H \"Content-Type: application/json\" -X POST --data '{\"jsonrpc\":\"2.0\",\"method\":\"web3_clientVersion\",\"params\":[],\"id\":67}' 127.0.0.1:3050 || exit 1"
interval: 5s
test: curl --fail http://localhost:3071/health || exit 1
interval: 10s
timeout: 5s
retries: 300
retries: 60
start_period: 30s
restart: unless-stopped

volumes:
geth:
reth:
postgres:
zksync-config:
zksync-data:
7 changes: 7 additions & 0 deletions packages/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ DISABLE_EXTERNAL_API=false
DATABASE_STATEMENT_TIMEOUT_MS=90000
CONTRACT_VERIFICATION_API_URL=http://127.0.0.1:3070
NETWORK_NAME=testnet-sepolia
BASE_TOKEN_SYMBOL=wETH
BASE_TOKEN_DECIMALS=18
BASE_TOKEN_L1_ADDRESS=0x8E9C82509488eD471A83824d20Dd474b8F534a0b
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
6 changes: 3 additions & 3 deletions packages/api/src/api/account/account.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Test } from "@nestjs/testing";
import { mock } from "jest-mock-extended";
import { BadRequestException, Logger } from "@nestjs/common";
import { L2_ETH_TOKEN_ADDRESS } from "../../common/constants";
import { BASE_TOKEN_L2_ADDRESS } from "../../common/constants";
import { BlockService } from "../../block/block.service";
import { BlockDetails } from "../../block/blockDetails.entity";
import { TransactionService } from "../../transaction/transaction.service";
Expand Down Expand Up @@ -557,7 +557,7 @@ describe("AccountController", () => {
describe("getAccountEtherBalance", () => {
it("calls balanceService.getBalance and returns account ether balance", async () => {
const response = await controller.getAccountEtherBalance(address);
expect(balanceServiceMock.getBalance).toBeCalledWith(address, L2_ETH_TOKEN_ADDRESS);
expect(balanceServiceMock.getBalance).toBeCalledWith(address, BASE_TOKEN_L2_ADDRESS);
expect(response).toEqual({
status: ResponseStatus.OK,
message: ResponseMessage.OK,
Expand Down Expand Up @@ -588,7 +588,7 @@ describe("AccountController", () => {

it("calls balanceService.getBalancesByAddresses and returns accounts ether balances", async () => {
const response = await controller.getAccountsEtherBalances([address, "address2"]);
expect(balanceServiceMock.getBalancesByAddresses).toBeCalledWith([address, "address2"], L2_ETH_TOKEN_ADDRESS);
expect(balanceServiceMock.getBalancesByAddresses).toBeCalledWith([address, "address2"], BASE_TOKEN_L2_ADDRESS);
expect(response).toEqual({
status: ResponseStatus.OK,
message: ResponseMessage.OK,
Expand Down
6 changes: 3 additions & 3 deletions packages/api/src/api/account/account.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Controller, Get, Query, Logger, UseFilters, ParseArrayPipe, BadRequestException } from "@nestjs/common";
import { ApiTags, ApiExcludeController } from "@nestjs/swagger";
import { L2_ETH_TOKEN_ADDRESS } from "../../common/constants";
import { BASE_TOKEN_L2_ADDRESS } from "../../common/constants";
import { TokenType } from "../../token/token.entity";
import { dateToTimestamp } from "../../common/utils";
import { BlockService } from "../../block/block.service";
Expand Down Expand Up @@ -176,7 +176,7 @@ export class AccountController {
public async getAccountEtherBalance(
@Query("address", new ParseAddressPipe()) address: string
): Promise<AccountEtherBalanceResponseDto> {
const balance = await this.balanceService.getBalance(address, L2_ETH_TOKEN_ADDRESS);
const balance = await this.balanceService.getBalance(address, BASE_TOKEN_L2_ADDRESS);
return {
status: ResponseStatus.OK,
message: ResponseMessage.OK,
Expand All @@ -201,7 +201,7 @@ export class AccountController {
if (uniqueAddresses.length > 20) {
throw new BadRequestException("Maximum 20 addresses per request");
}
const balances = await this.balanceService.getBalancesByAddresses(addresses, L2_ETH_TOKEN_ADDRESS);
const balances = await this.balanceService.getBalancesByAddresses(addresses, BASE_TOKEN_L2_ADDRESS);
const result = addresses.map((address) => ({
account: address,
balance: balances.find((balance) => balance.address.toLowerCase() === address.toLowerCase())?.balance || "0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Transfer } from "../../transfer/transfer.entity";
import { TransactionStatus } from "../../transaction/entities/transaction.entity";
import { L2_ETH_TOKEN_ADDRESS } from "../../common/constants";
import { BASE_TOKEN_L2_ADDRESS } from "../../common/constants";
import { mapInternalTransactionListItem } from "./internalTransactionMapper";

describe("internalTransactionMapper", () => {
Expand All @@ -11,7 +11,7 @@ describe("internalTransactionMapper", () => {
from: "0xc7e0220d02d549c4846A6EC31D89C3B670Ebe35C",
to: "0xc7e0220d02d549c4846A6EC31D89C3B670Ebe35D",
amount: "1000000",
tokenAddress: L2_ETH_TOKEN_ADDRESS,
tokenAddress: BASE_TOKEN_L2_ADDRESS,
transaction: {
blockNumber: 20,
receivedAt: new Date("2023-01-01"),
Expand Down
7 changes: 4 additions & 3 deletions packages/api/src/api/stats/stats.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Test } from "@nestjs/testing";
import { mock } from "jest-mock-extended";
import { Logger } from "@nestjs/common";
import { TokenService } from "../../token/token.service";
import { Token, ETH_TOKEN } from "../../token/token.entity";
import { Token } from "../../token/token.entity";
import { StatsController } from "./stats.controller";
import { baseTokenData } from "../../config";

describe("StatsController", () => {
let controller: StatsController;
Expand Down Expand Up @@ -31,7 +32,7 @@ describe("StatsController", () => {
describe("ethPrice", () => {
it("returns ok response and ETH price when ETH token is found", async () => {
jest.spyOn(tokenServiceMock, "findOne").mockResolvedValueOnce({
usdPrice: ETH_TOKEN.usdPrice,
usdPrice: baseTokenData.usdPrice,
offChainDataUpdatedAt: new Date("2023-03-03"),
} as Token);

Expand All @@ -40,7 +41,7 @@ describe("StatsController", () => {
status: "1",
message: "OK",
result: {
ethusd: ETH_TOKEN.usdPrice.toString(),
ethusd: baseTokenData.usdPrice.toString(),
ethusd_timestamp: Math.floor(new Date("2023-03-03").getTime() / 1000).toString(),
},
});
Expand Down
7 changes: 5 additions & 2 deletions packages/api/src/api/stats/stats.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ 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 { ETH_TOKEN } from "../../token/token.entity";
import { dateToTimestamp } from "../../common/utils";
import { baseTokenData } from "../../config";

const entityName = "stats";

Expand All @@ -18,7 +18,10 @@ export class StatsController {

@Get("/ethprice")
public async ethPrice(): Promise<EthPriceResponseDto> {
const token = await this.tokenService.findOne(ETH_TOKEN.l2Address, { usdPrice: true, offChainDataUpdatedAt: true });
const token = await this.tokenService.findOne(baseTokenData.l2Address, {
usdPrice: true,
offChainDataUpdatedAt: true,
});
return {
status: token ? ResponseStatus.OK : ResponseStatus.NOTOK,
message: token ? ResponseMessage.OK : ResponseMessage.NO_DATA_FOUND,
Expand Down
25 changes: 13 additions & 12 deletions packages/api/src/api/token/token.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Test } from "@nestjs/testing";
import { mock } from "jest-mock-extended";
import { Logger } from "@nestjs/common";
import { TokenService } from "../../token/token.service";
import { Token, ETH_TOKEN } from "../../token/token.entity";
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 @@ -32,22 +33,22 @@ describe("TokenController", () => {

describe("tokenInfo", () => {
it("returns ok response and token info when token is found", async () => {
jest.spyOn(tokenServiceMock, "findOne").mockResolvedValueOnce(ETH_TOKEN);

const baseToken = baseTokenData as Token;
jest.spyOn(tokenServiceMock, "findOne").mockResolvedValueOnce(baseToken);
const response = await controller.tokenInfo(contractAddress);
expect(response).toEqual({
status: "1",
message: "OK",
result: [
{
contractAddress: ETH_TOKEN.l2Address,
iconURL: ETH_TOKEN.iconURL,
l1Address: ETH_TOKEN.l1Address,
liquidity: ETH_TOKEN.liquidity.toString(),
symbol: ETH_TOKEN.symbol,
tokenDecimal: ETH_TOKEN.decimals.toString(),
tokenName: ETH_TOKEN.name,
tokenPriceUSD: ETH_TOKEN.usdPrice.toString(),
contractAddress: baseToken.l2Address,
iconURL: baseToken.iconURL,
l1Address: baseToken.l1Address,
liquidity: baseToken.liquidity.toString(),
symbol: baseToken.symbol,
tokenDecimal: baseToken.decimals.toString(),
tokenName: baseToken.name,
tokenPriceUSD: baseToken.usdPrice.toString(),
},
],
});
Expand Down
1 change: 0 additions & 1 deletion packages/api/src/api/token/token.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { ResponseStatus, ResponseMessage } from "../dtos/common/responseBase.dto
import { ApiExceptionFilter } from "../exceptionFilter";
import { TokenInfoResponseDto } from "../dtos/token/tokenInfo.dto";
import { TokenService } from "../../token/token.service";

const entityName = "token";

@ApiExcludeController()
Expand Down
13 changes: 8 additions & 5 deletions packages/api/src/balance/balance.entity.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Entity, Column, PrimaryColumn, Index, ManyToOne, JoinColumn, AfterLoad } from "typeorm";
import { BaseEntity } from "../common/entities/base.entity";
import { Token, ETH_TOKEN } from "../token/token.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";
@Entity({ name: "balances" })
export class Balance extends BaseEntity {
@PrimaryColumn({ type: "bytea", transformer: normalizeAddressTransformer })
Expand All @@ -24,9 +24,12 @@ export class Balance extends BaseEntity {
public readonly balance: string;

@AfterLoad()
populateEthToken() {
if (this.tokenAddress === ETH_TOKEN.l2Address && !this.token) {
this.token = ETH_TOKEN;
populateBaseToken() {
if (
!this.token &&
(this.tokenAddress === undefined || this.tokenAddress.toLowerCase() === baseTokenData.l2Address.toLowerCase())
) {
this.token = baseTokenData as Token;
}
}
}
2 changes: 1 addition & 1 deletion packages/api/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const L2_ETH_TOKEN_ADDRESS = "0x000000000000000000000000000000000000800a";
export const BASE_TOKEN_L2_ADDRESS = "0x000000000000000000000000000000000000800A";
68 changes: 66 additions & 2 deletions packages/api/src/config/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import config from "../config";

jest.mock("./featureFlags", () => ({
feature1Enabled: true,
feature2Enabled: false,
Expand All @@ -20,6 +19,71 @@ describe("config", () => {

it("sets default values", () => {
expect(config()).toEqual({
baseTokenData: {
l2Address: "0x000000000000000000000000000000000000800A",
l1Address: "0x0000000000000000000000000000000000000001",
symbol: "ETH",
name: "Ether",
decimals: 18,
// Fallback data in case ETH token is not in the DB
iconURL: "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1698873266",
liquidity: 220000000000,
usdPrice: 1800,
},
NODE_ENV: "test",
port: 3020,
metrics: {
port: 3005,
collectDbConnectionPoolMetricsInterval: 10000,
},
typeORM: {
type: "postgres",
url: "postgres://postgres:[email protected]:5432/block-explorer",
poolSize: 300,
extra: {
idleTimeoutMillis: 60000,
statement_timeout: 90000,
},
synchronize: true,
logging: false,
autoLoadEntities: true,
retryAttempts: 10,
retryDelay: 3000,
applicationName: "block-explorer-api",
},
contractVerificationApiUrl: "http://127.0.0.1:3070",
featureFlags: {
feature1Enabled: true,
feature2Enabled: false,
},
gracefulShutdownTimeoutMs: 0,
});
});

it("sets default values with base ERC20", () => {
process.env = {
BASE_TOKEN_SYMBOL: "MTTL",
BASE_TOKEN_DECIMALS: "18",
BASE_TOKEN_L1_ADDRESS: "0xSomeAddress",
BASE_TOKEN_ICON_URL: "https://matter-labs.io",
BASE_TOKEN_NAME: "MatterLabs",
BASE_TOKEN_LIQUIDITY: "999999999999",
BASE_TOKEN_USDPRICE: "19",
NODE_ENV: "test",
};

expect(config()).toEqual({
baseTokenData: {
l2Address: "0x000000000000000000000000000000000000800A",
l1Address: "0xSomeAddress",
symbol: "MTTL",
name: "MatterLabs",
decimals: 18,
// Fallback data in case ETH token is not in the DB
iconURL: "https://matter-labs.io",
liquidity: 999999999999,
usdPrice: 19,
},
NODE_ENV: "test",
port: 3020,
metrics: {
Expand All @@ -28,7 +92,7 @@ describe("config", () => {
},
typeORM: {
type: "postgres",
url: "postgres://postgres:postgres@localhost:5432/block-explorer",
url: "postgres://postgres:postgres@127.0.0.1:5432/block-explorer",
poolSize: 300,
extra: {
idleTimeoutMillis: 60000,
Expand Down
Loading