diff --git a/README.md b/README.md index c3f914e..f147d22 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This repository is a monorepo consisting of 4 packages and 1 app: - [`@zkchainhub/shared`](./packages/shared): A library for shared configurations, constants, types, etc. - [`@zkchainhub/chain-providers`](./packages/chain-providers): A library that provides abstracted services over Viem providers to query blockchain data - [`@zkchainhub/pricing`](./packages/pricing): An extensible library that provides Pricing services to fetch token prices. Currently, only Coingecko provider is developed +- [`@zkchainhub/metadata`](./packages/metadata): A library that exposes different providers for fetching chains and tokens metadata. - [`@zkchainhub/metrics`](./packages/metrics): A library that provides different aggregated metrics from the ZKsync ecosystem and ZK chains. - [`@zkchainhub/api`](./apps/api): An Express server that exposes an API where you can fetch information about ZKsync ecosystem and their chains, using the before mentioned libraries @@ -48,16 +49,7 @@ $ pnpm build ## ⚙️ Setting up env variables -- Inside `apps/api` folder, create `.env` file and copy paste `.env.example` content in there. - -``` -$ cd apps/api && cp .env.example .env -``` - -- Set up `L1_RPC_URLS` as CSV list of RPC URLs. For example, `https://eth.llamarpc.com,https://rpc.flashbots.net/fast`. You can check [Chainlist](https://chainlist.org/) for a list of public RPCs -- Set up `L2_RPC_URLS` as CSV list of RPC URLs. For example, `https://mainnet.era.zksync.io`. You can check [Chainlist](https://chainlist.org/) for a list of public RPCs -- Set `COINGECKO_API_KEY`, `COINGECKO_BASE_URL` and `COINGECKO_API_KEY` depending on your API plan. You can get an API Key creating an account on [Coingecko's site](https://www.coingecko.com/en/api) -- (Optionally) Set `PORT` on which API is made available. By default is port 3000 +- Follow the instructions for `apps/api` on [API's README](./apps/api/README.md) ## Running the app @@ -116,3 +108,7 @@ ZKchainHub was built with ❤️ by [Wonderland](https://defi.sucks). Wonderland is a team of top Web3 researchers, developers, and operators who believe that the future needs to be open-source, permissionless, and decentralized. [DeFi sucks](https://defi.sucks), but Wonderland is here to make it better. + +## License + +This project is licensed under the MIT License. See the [`LICENSE`](./LICENSE) file for details. diff --git a/apps/api/README.md b/apps/api/README.md new file mode 100644 index 0000000..1e942d7 --- /dev/null +++ b/apps/api/README.md @@ -0,0 +1,82 @@ +# ZKchainHub API + +## Overview + +The `@zkchainhub/api` app is an Express server that exposes an API where you can fetch information about ZKsync ecosystem and their chains. + +## 📋 Prerequisites + +- Ensure you have `node >= 20.0.0` and `pnpm >= 9.5.0` installed. + +## Installation + +```bash +$ pnpm install +``` + +## Building + +To build the monorepo packages, run: + +```bash +$ pnpm build +``` + +## ⚙️ Setting up env variables + +- Create `.env` file and copy paste `.env.example` content in there. + +``` +$ cp .env.example .env +``` + +Available options: + +- (optional) `PORT` on which API is made available. By default is port 3000 +- (optional) `ENVIRONMENT` which environment we are using ( 'mainnet' | 'testnet' | 'local'). By default is 'mainnet' +- `BRIDGE_HUB_ADDRESS` +- `SHARED_BRIDGE_ADDRESS` +- `STATE_MANAGER_ADDRESSES` CSV list of State managers addresses +- `L1_RPC_URLS` as CSV list of RPC URLs. For example, `https://eth.llamarpc.com,https://rpc.flashbots.net/fast`. You can check [Chainlist](https://chainlist.org/) for a list of public RPCs +- (optional) `PRICING_SOURCE` which pricing source to use ('dummy' | 'coingecko'). By default is dummy +- (optional) `DUMMY_PRICE` for dummy pricing source. Default is undefined +- (required if 'coingecko' is selected)`COINGECKO_API_KEY`, `COINGECKO_BASE_URL` and `COINGECKO_API_KEY` depending on your API plan. You can get an API Key creating an account on [Coingecko's site](https://www.coingecko.com/en/api) +- `METADATA_SOURCE` which metadata source to use ('github' | 'local' | 'static') +- (required if METADATA_SOURCE is 'github') `METADATA_TOKEN_URL` Metadata tokens URL +- (required if METADATA_SOURCE is 'github') `METADATA_CHAIN_URL` Metadata chains URL +- (required if METADATA_SOURCE is 'local') `METADATA_TOKEN_JSON_PATH` Metadata tokens JSON file path (see examples on `packages/metadata`) +- (required if METADATA_SOURCE is 'local') `METADATA_CHAIN_JSON_PATH` Metadata chain JSON file path (see examples on `packages/metadata`) + +## Running the app + +```bash +# development watch mode +$ pnpm run dev + +# production mode +$ pnpm run start + +``` + +Verify that ZKchainHub API is running on http://localhost:3000 (or the port specified) + +## Test + +```bash +# unit tests +$ pnpm run test + +# test coverage +$ pnpm run test:cov +``` + +## API + +### Metrics routes + +- `GET /metrics/ecosystem`: Retrieves overall ecosystem metrics +- `GET /metrics/zkchain/:chainId`: Retrieves chain specific metrics + +## Docs + +Locally Swagger docs are available at http://localhost:3000/docs diff --git a/packages/chain-providers/README.md b/packages/chain-providers/README.md new file mode 100644 index 0000000..8423cff --- /dev/null +++ b/packages/chain-providers/README.md @@ -0,0 +1,90 @@ +# ZKchainHub Chain Providers package + +## Overview + +The `@zkchainhub/chain-providers` package provides wrappers of the `Viem` library to interact with EVM-based blockchains and ZK chains of the ZKsync ecosystem. + +## 📋 Prerequisites + +- Ensure you have `node >= 20.0.0` and `pnpm >= 9.5.0` installed. + +## Installation + +```bash +$ pnpm install +``` + +## Building + +To build the monorepo packages, run: + +```bash +$ pnpm build +``` + +## Test + +```bash +# unit tests +$ pnpm run test + +# test coverage +$ pnpm run test:cov +``` + +## Usage + +### Importing the Package + +You can import the package in your TypeScript or JavaScript files as follows: + +```typescript +import { EvmProvider } from "@zkchainhub/chain-providers"; +``` + +### Example + +```typescript +// EVM-provider +const rpcUrls = [...]; //non-empty +const chain = mainnet; // from viem/chains + +const evmProvider = new EvmProvider(rpcUrls, chain, logger); + +const gasPrice = await evmProvider.getGasPrice(); + +const result = await evmProvider.readContract(address, abi, "myfunction", [arg1, arg2]); + +// ZK-chain provider +const zkChainProvider = new ZKChainProvider(rpcUrls, chain, logger); + +const l2Tps = await zkChainProvider.tps(); +``` + +## API + +### [EvmProvider](./src/providers/evmProvider.service.ts) + +Available methods + +- `getMulticall3Address()` +- `getBalance(address: Address)` +- `getBlockNumber()` +- `getBlockByNumber(blockNumber: number)` +- `getGasPrice()` +- `estimateGas(args: EstimateGasParameters)` +- `getStorageAt(address: Address, slot: number | Hex)` +- `readContract(contractAddress: Address, abi: TAbi functionName: TFunctionName, args?: TArgs)` +- `batchRequest(abi: AbiWithConstructor,bytecode: Hex, args: ContractConstructorArgs, constructorReturnParams: ReturnType)` +- `multicall(args: MulticallParameters)` + +### [ZKChainProvider](./src/providers/zkChainProvider.service.ts) + +Available methods + +- `getL1BatchDetails(batchNumber: number)` +- `getL1BatchNumber()` +- `avgBlockTime(range: number = 1000)` +- `tps()` + +For more details on both providers, refer to their implementations. diff --git a/packages/metadata/README.md b/packages/metadata/README.md index 47369c9..c04028b 100644 --- a/packages/metadata/README.md +++ b/packages/metadata/README.md @@ -87,6 +87,43 @@ $ pnpm run test $ pnpm run test:cov ``` +## Usage + +### Importing the Package + +You can import the package in your TypeScript or JavaScript files as follows: + +```typescript +import { MetadataProviderFactory } from "@zkchainhub/metadata"; +``` + +### Example + +You can manually instantiate any of the available providers or use the factory + +```typescript +// manual +const metadataProvider = new LocalFileMetadataProvider(tokenJson, chainsJson, logger); + +// factory +const metadataFromFactory = MetadataProviderFactory.create(providerOptions, additionalDependencies); + +const chainsMap = await metadataProvider.getChainsMetadata(); +const tokensArray = await metadataProvider.getTokensMetadata(); +``` + +## API + +### IMetadataProvider + +#### `getChainsMetadata(): Promise` + +Retrieves the metadata for ZK chains of the ecosystem + +#### `getTokensMetadata(): Promise[]>` + +Retrieves metadata for tokens of the ecosystem + ## Contributing To create a new provider, create it inside [`providers`](./src/providers/) folder and implement the [`IMetadataProvider`](./src/interfaces/metadata.interface.ts) interface. diff --git a/packages/metrics/README.md b/packages/metrics/README.md new file mode 100644 index 0000000..45094e2 --- /dev/null +++ b/packages/metrics/README.md @@ -0,0 +1,84 @@ +# ZKchainHub Metrics package + +## Overview + +The `@zkchainhub/metrics` package exposes services with different aggregated metrics from the ZKsync ecosystem and ZK chains. + +## 📋 Prerequisites + +- Ensure you have `node >= 20.0.0` and `pnpm >= 9.5.0` installed. + +## Installation + +```bash +$ pnpm install +``` + +## Building + +To build the monorepo packages, run: + +```bash +$ pnpm build +``` + +## Test + +```bash +# unit tests +$ pnpm run test + +# test coverage +$ pnpm run test:cov +``` + +## Usage + +### Importing the Package + +You can import the package in your TypeScript or JavaScript files as follows: + +```typescript +import { L1MetricsService } from "@zkchainhub/metrics"; +``` + +### Example + +This packages requires that user injects instances of: + +- EvmProvider +- IPricingProvider +- IMetadataProvider + +```typescript +// ... define needed dependencies + +const l1MetricsService = new L1MetricsService( + bridgeHubAddress, + sharedBridgeAddress, + stateTransitionManagerAddresses, + evmProvider, + pricingProvider, + metadataProvider, + logger, +); + +await l1MetricsService.l1Tvl(); +``` + +## API + +### [L1MetricsService](./src/l1/l1MetricsService.ts) + +Available methods + +- `l1Tvl()` +- `getBatchesInfo(chainId: ChainId)` +- `tvl(chainId: ChainId)` +- `chainType(chainId: ChainId)` +- `ethGasInfo()` +- `getChainIds()` +- `getBaseTokens(chainIds: ChainId[])` +- `feeParams(chainId: ChainId)` + +For more details on services, refer to their implementations. diff --git a/packages/pricing/README.md b/packages/pricing/README.md new file mode 100644 index 0000000..aa098c7 --- /dev/null +++ b/packages/pricing/README.md @@ -0,0 +1,96 @@ +# ZKchainHub Pricing package + +## Overview + +The `@zkchainhub/pricing` package exposes different providers for retrieving token prices. + +Currently, there are two different providers: + +- `CoingeckoProvider` +- `DummyPricingProvider` + +## 📋 Prerequisites + +- Ensure you have `node >= 20.0.0` and `pnpm >= 9.5.0` installed. + +## Installation + +```bash +$ pnpm install +``` + +## Building + +To build the monorepo packages, run: + +```bash +$ pnpm build +``` + +## Test + +```bash +# unit tests +$ pnpm run test + +# test coverage +$ pnpm run test:cov +``` + +## Usage + +### Importing the Package + +You can import the package in your TypeScript or JavaScript files as follows: + +```typescript +import { PricingProviderFactory } from "@zkchainhub/pricing"; +``` + +### Example + +You can manually instantiate any of the available providers or use the factory + +```typescript +// manual +const pricingProvider = new CoingeckoProvider({ ...options }, cache, logger); + +// factory +const pricingFromFactory = PricingProviderFactory.create(providerOptions, additionalDependencies); + +const tokenAddresses = [ + "0xE41d2489571d322189246DaFA5ebDe1F4699F498", + "0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1", + "0x0000000000000000000000000000000000000001", //convention to fetch ETH price +]; + +const response = await pricingProvider.getTokenPrices(tokenAddresses); + +for (let [address, price] of response) { + console.log(`The price of ${address} is ${price ? price.toString() : "not found"}`); +} +``` + +## API + +### IPricingProvider + +#### `getTokenPrices(addresses: Address[]): Promise` + +Retrieves the price for the list of token. + +- **Parameters:** + - `addresses` (Address[]): array of token addresses that we want to fetch +- **Returns:** `Promise`: A promise that resolves to a map of Address to price or undefined if not found + +## Contributing + +1. To create a new provider, create it inside [`providers`](./src/providers/) folder and implement the [`IPricingProvider`](./src/interfaces/pricing.interface.ts) interface. + +> Note 1: is provider implementation responsibility to map token addresses to their internal id if needed. + +> Note 2: for native token (eg. ETH), use the one address + +2. Then, write the configuration interface inside [`pricingConfig.interface.ts`](./src/interfaces/pricingConfig.interface.ts) and add the provider to the [`PricingProviderFactory`](./src/factory/index.ts) class. + +3. Finally, export the provider and required files in [`external.ts`](./src/external.ts). diff --git a/packages/shared/README.md b/packages/shared/README.md new file mode 100644 index 0000000..1d61f7e --- /dev/null +++ b/packages/shared/README.md @@ -0,0 +1,13 @@ +# ZKchainHub Shared package + +The `@zkchainhub/shared` package provides shared utilities, types, constants and logger. This package is designed to be used across the packages of this monorepo to ensure consistency and reusability. + +## Usage + +### Importing the Package + +You can import the package in your TypeScript files as follows: + +```typescript +import { IMetadataProvider, Token, TokenType, ZKChainMetadata } from "@zkchainhub/shared"; +```