Skip to content

Commit

Permalink
feat(base): add support for Base (#96)
Browse files Browse the repository at this point in the history
* feat: add base support

* chore: update generated types

* fix: unit tests

* chore: skip goldrush tests since the free trial is over and a paid plan is required

* chore: limit moralis owners to only 2

* chore: bump cow-sdk to latest

* Add comment for skipped test

* docs: update the auto-generated types

---------

Co-authored-by: Anxo Rodriguez <[email protected]>
  • Loading branch information
alfetopito and anxolin authored Nov 26, 2024
1 parent 78d10de commit bb2bdb9
Show file tree
Hide file tree
Showing 23 changed files with 1,392 additions and 1,323 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
# RPC urls (http or websocket)
# RPC_URL_1=https://mainnet.infura.io/v3/your-infura-key
# RPC_URL_100=https://rpc.gnosischain.com
# RPC_URL_8453=wss://base-mainnet.io/ws/v3/your-infura-key
# RPC_URL_42161=wss://arbitrum-mainnet.io/ws/v3/your-infura-key
# RPC_URL_11155111=https://sepolia.infura.io/v3/your-infura-key

# CoW API
# COW_API_BASE_URL=https://api.cow.fi
# COW_API_URL_1=https://api.cow.fi/mainnet
# COW_API_URL_100=https://api.cow.fi/xdai
# COW_API_URL_8453=https://api.cow.fi/base
# COW_API_URL_42161=https://api.cow.fi/arbitrum_one
# COW_API_URL_11155111=https://api.cow.fi/sepolia

Expand Down
8 changes: 5 additions & 3 deletions apps/twap/src/app/utils/getApiBaseUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { SupportedChainId } from '@cowprotocol/cow-sdk';
const COW_API_BASE_URL = 'https://api.cow.fi';

const CHAIN_ID_TO_NAME: Record<SupportedChainId, string> = {
1: 'mainnet',
100: 'xdai',
'11155111': 'sepolia',
[SupportedChainId.MAINNET]: 'mainnet',
[SupportedChainId.GNOSIS_CHAIN]: 'xdai',
[SupportedChainId.SEPOLIA]: 'sepolia',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum-one',
[SupportedChainId.BASE]: 'base',
};

export function getApiBaseUrl(chainId: SupportedChainId): string {
Expand Down
11 changes: 6 additions & 5 deletions apps/twap/src/app/utils/getConditionalOrderId.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { SupportedChainId } from '@cowprotocol/cow-sdk';
import { CurrencyAmount, Token } from '@uniswap/sdk-core';
import { hexZeroPad } from '@ethersproject/bytes';
import { defaultAbiCoder } from '@ethersproject/abi';
import { keccak256 } from '@ethersproject/keccak256';
import { CurrencyAmount, Token } from '@uniswap/sdk-core';

interface ConditionalOrderParams {
staticInput: string;
Expand Down Expand Up @@ -42,9 +41,11 @@ export const TWAP_ORDER_STRUCT =

const twapHandlerAddress = '0x910d00a310f7Dc5B29FE73458F47f519be547D3d';
export const TWAP_HANDLER_ADDRESS: Record<SupportedChainId, string> = {
1: twapHandlerAddress,
100: twapHandlerAddress,
'11155111': twapHandlerAddress,
[SupportedChainId.MAINNET]: twapHandlerAddress,
[SupportedChainId.GNOSIS_CHAIN]: twapHandlerAddress,
[SupportedChainId.ARBITRUM_ONE]: twapHandlerAddress,
[SupportedChainId.BASE]: twapHandlerAddress,
[SupportedChainId.SEPOLIA]: twapHandlerAddress,
};

export function twapOrderToStruct(order: TWAPOrder): TWAPOrderStruct {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Erc20RepositoryViem } from './Erc20RepositoryViem';
import { SupportedChainId } from '@cowprotocol/shared';
import { PublicClient } from 'viem';
import { erc20Abi } from 'viem';
import { erc20Abi, PublicClient } from 'viem';
import { Erc20 } from './Erc20Repository';
import { Erc20RepositoryViem } from './Erc20RepositoryViem';

const multicallMock = jest.fn();

Expand Down Expand Up @@ -39,6 +38,7 @@ describe('Erc20RepositoryViem', () => {
[SupportedChainId.MAINNET]: mockPublicClient,
[SupportedChainId.GNOSIS_CHAIN]: mockPublicClient,
[SupportedChainId.ARBITRUM_ONE]: mockPublicClient,
[SupportedChainId.BASE]: mockPublicClient,
[SupportedChainId.SEPOLIA]: mockPublicClient,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Container } from 'inversify';
import { TokenHolderRepositoryGoldRush } from './TokenHolderRepositoryGoldRush';
import { SupportedChainId } from '@cowprotocol/shared';
import { WETH, NULL_ADDRESS } from '../../test/mock';
import { Container } from 'inversify';
import { NULL_ADDRESS, WETH } from '../../test/mock';
import { GOLD_RUSH_API_KEY } from '../datasources/goldRush';
import { TokenHolderRepositoryGoldRush } from './TokenHolderRepositoryGoldRush';

describe('TokenHolderRepositoryGoldRush', () => {
// Skip this test as it requires an https://goldrush.dev API key. Enable it locally when needed
describe.skip('TokenHolderRepositoryGoldRush', () => {
let tokenHolderRepositoryGoldRush: TokenHolderRepositoryGoldRush;

beforeAll(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Container } from 'inversify';
import { TokenHolderRepositoryMoralis } from './TokenHolderRepositoryMoralis';
import { SupportedChainId } from '@cowprotocol/shared';
import { WETH, NULL_ADDRESS } from '../../test/mock';
import { Container } from 'inversify';
import { NULL_ADDRESS, WETH } from '../../test/mock';
import { MORALIS_API_KEY } from '../datasources/moralis';
import { TokenHolderRepositoryMoralis } from './TokenHolderRepositoryMoralis';

describe('TokenHolderRepositoryMoralis', () => {
let tokenHolderRepositoryMoralis: TokenHolderRepositoryMoralis;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { injectable } from 'inversify';
import {
TokenHolderPoint,
TokenHolderRepository,
} from './TokenHolderRepository';
import { SupportedChainId } from '@cowprotocol/shared';
import { injectable } from 'inversify';
import {
MORALIS_API_BASE_URL,
MORALIS_API_KEY,
MORALIS_CLIENT_NETWORK_MAPPING,
} from '../datasources/moralis';
import {
TokenHolderPoint,
TokenHolderRepository,
} from './TokenHolderRepository';

interface MoralisTokenHolderItem {
balance: string;
Expand Down Expand Up @@ -36,7 +36,7 @@ export class TokenHolderRepositoryMoralis implements TokenHolderRepository {
tokenAddress: string
): Promise<TokenHolderPoint[] | null> {
const response = (await fetch(
`${MORALIS_API_BASE_URL}/v2.2/erc20/${tokenAddress}/owners?chain=${MORALIS_CLIENT_NETWORK_MAPPING[chainId]}&order=DESC`,
`${MORALIS_API_BASE_URL}/v2.2/erc20/${tokenAddress}/owners?chain=${MORALIS_CLIENT_NETWORK_MAPPING[chainId]}&order=DESC&limit=2`,
{
method: 'GET',
headers: {
Expand Down
13 changes: 7 additions & 6 deletions libs/repositories/src/UsdRepository/UsdRepositoryCow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { UsdRepositoryCow } from './UsdRepositoryCow';

import { NULL_ADDRESS, WETH, errorResponse, okResponse } from '../../test/mock';
import { USDC } from '../const';
import { Erc20Repository, Erc20 } from '../Erc20Repository/Erc20Repository';
import { CowApiClient } from '../datasources/cowApi';
import { Erc20, Erc20Repository } from '../Erc20Repository/Erc20Repository';

const mockApiGet = jest.fn();

Expand Down Expand Up @@ -35,6 +35,7 @@ const cowApiClients = {
[SupportedChainId.MAINNET]: mockApi,
[SupportedChainId.GNOSIS_CHAIN]: mockApi,
[SupportedChainId.ARBITRUM_ONE]: mockApi,
[SupportedChainId.BASE]: mockApi,
[SupportedChainId.SEPOLIA]: mockApi,
};
const usdRepositoryCow = new UsdRepositoryCow(
Expand Down Expand Up @@ -68,7 +69,7 @@ describe('UsdRepositoryCow', () => {
});

// Get USD price for WETH
let price = await usdRepositoryCow.getUsdPrice(
const price = await usdRepositoryCow.getUsdPrice(
SupportedChainId.MAINNET,
WETH
);
Expand Down Expand Up @@ -102,7 +103,7 @@ describe('UsdRepositoryCow', () => {
);

// Get USD price for a not supported token
let price = await usdRepositoryCow.getUsdPrice(
const price = await usdRepositoryCow.getUsdPrice(
SupportedChainId.MAINNET,
NULL_ADDRESS // See https://api.cow.fi/mainnet/api/v1/token/0x0000000000000000000000000000000000000000/native_price
);
Expand All @@ -126,7 +127,7 @@ describe('UsdRepositoryCow', () => {
);

// Get USD price for a not supported token
let pricePromise = usdRepositoryCow.getUsdPrice(
const pricePromise = usdRepositoryCow.getUsdPrice(
SupportedChainId.MAINNET,
WETH
);
Expand All @@ -148,7 +149,7 @@ describe('UsdRepositoryCow', () => {
);

// Get USD price for something is not even an address
let price = await usdRepositoryCow.getUsdPrice(
const price = await usdRepositoryCow.getUsdPrice(
SupportedChainId.MAINNET,
'this-is-not-a-token' // See https://api.cow.fi/mainnet/api/v1/token/this-is-not-a-token/native_price
);
Expand All @@ -171,7 +172,7 @@ describe('UsdRepositoryCow', () => {
);

// Get USD price for something is not even an address
let priceResult = usdRepositoryCow.getUsdPrice(
const priceResult = usdRepositoryCow.getUsdPrice(
SupportedChainId.MAINNET,
'this-is-not-a-token'
);
Expand Down
6 changes: 5 additions & 1 deletion libs/repositories/src/const.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SupportedChainId } from '@cowprotocol/shared';
import BigNumber from 'bignumber.js';
import { SupportedChainId } from '../../shared/src/types';

interface TokenAddressAndDecimals {
address: string;
Expand All @@ -19,6 +19,10 @@ export const USDC: Record<SupportedChainId, TokenAddressAndDecimals> = {
address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
decimals: 6,
},
[SupportedChainId.BASE]: {
address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
decimals: 6,
},
[SupportedChainId.SEPOLIA]: {
address: '0xbe72E441BF55620febc26715db68d3494213D8Cb',
decimals: 18,
Expand Down
3 changes: 2 additions & 1 deletion libs/repositories/src/datasources/coingecko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { SupportedChainId } from '@cowprotocol/shared';

import createClient from 'openapi-fetch';

import type { paths, components } from '../gen/coingecko/coingecko-pro-types';
import type { components, paths } from '../gen/coingecko/coingecko-pro-types';

export const COINGECKO_PRO_BASE_URL = 'https://pro-api.coingecko.com';

Expand All @@ -11,6 +11,7 @@ export const COINGECKO_PLATFORMS: Record<SupportedChainId, string | undefined> =
[SupportedChainId.MAINNET]: 'ethereum',
[SupportedChainId.GNOSIS_CHAIN]: 'xdai',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum-one',
[SupportedChainId.BASE]: 'base',
[SupportedChainId.SEPOLIA]: undefined,
};

Expand Down
3 changes: 2 additions & 1 deletion libs/repositories/src/datasources/cowApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import createClient from 'openapi-fetch';

const COW_API_BASE_URL = process.env.COW_API_BASE_URL || 'https://api.cow.fi';

import type { paths } from '../gen/cow/cow-api-types';
import { AllChainIds, SupportedChainId } from '@cowprotocol/shared';
import type { paths } from '../gen/cow/cow-api-types';

export type CowApiClient = ReturnType<typeof createClient<paths>>;

const COW_API_NETWORK_NAMES: Record<SupportedChainId, string> = {
[SupportedChainId.MAINNET]: 'mainnet',
[SupportedChainId.GNOSIS_CHAIN]: 'xdai',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum_one',
[SupportedChainId.BASE]: 'base',
[SupportedChainId.SEPOLIA]: 'sepolia',
};

Expand Down
1 change: 1 addition & 0 deletions libs/repositories/src/datasources/ethplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const ETHPLORER_BASE_URL: Record<SupportedChainId, string | null> = {
[SupportedChainId.SEPOLIA]: 'https://sepolia-api.ethplorer.io',
[SupportedChainId.GNOSIS_CHAIN]: null,
[SupportedChainId.ARBITRUM_ONE]: null,
[SupportedChainId.BASE]: null,
};
1 change: 1 addition & 0 deletions libs/repositories/src/datasources/goldRush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export const GOLD_RUSH_CLIENT_NETWORK_MAPPING: Record<
[SupportedChainId.SEPOLIA]: 'eth-sepolia',
[SupportedChainId.GNOSIS_CHAIN]: 'gnosis-mainnet',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum-mainnet',
[SupportedChainId.BASE]: 'base-mainnet',
};
1 change: 1 addition & 0 deletions libs/repositories/src/datasources/moralis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export const MORALIS_CLIENT_NETWORK_MAPPING: Record<SupportedChainId, string> =
[SupportedChainId.SEPOLIA]: 'sepolia',
[SupportedChainId.GNOSIS_CHAIN]: 'gnosis',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum',
[SupportedChainId.BASE]: 'base',
};
12 changes: 3 additions & 9 deletions libs/repositories/src/datasources/viem.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import {
createPublicClient,
http,
Client,
Chain,
PublicClient,
webSocket,
} from 'viem';
import { arbitrum, gnosis, mainnet, sepolia } from 'viem/chains';
import { AllChainIds, SupportedChainId } from '@cowprotocol/shared';
import { Chain, createPublicClient, http, PublicClient, webSocket } from 'viem';
import { arbitrum, base, gnosis, mainnet, sepolia } from 'viem/chains';

const NETWORKS: Record<SupportedChainId, Chain> = {
[SupportedChainId.MAINNET]: mainnet,
[SupportedChainId.GNOSIS_CHAIN]: gnosis,
[SupportedChainId.ARBITRUM_ONE]: arbitrum,
[SupportedChainId.BASE]: base,
[SupportedChainId.SEPOLIA]: sepolia,
};

Expand Down
22 changes: 12 additions & 10 deletions libs/repositories/src/gen/coingecko/coingecko-dex-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ export interface paths {
};
/**
* Most Recently Updated Tokens List
* @description This endpoint allows you to **query 100 most recently updated tokens info across all networks on GeckoTerminal**
* @description This endpoint allows you to **query 100 most recently updated tokens info of a specific network or across all networks on GeckoTerminal**
*/
get: operations["tokens-info-recent-updated"];
put?: never;
Expand Down Expand Up @@ -954,7 +954,7 @@ export interface components {
* "https://tether.to/"
* ],
* "description": "Tether (USDT) is a cryptocurrency with a value meant to mirror the value of the U.S. dollar...",
* "gt_score": 92.66055045871559,
* "gt_score": 92.6605504587156,
* "discord_url": null,
* "telegram_handle": null,
* "twitter_handle": "Tether_to"
Expand Down Expand Up @@ -995,7 +995,7 @@ export interface components {
* "https://weth.io/"
* ],
* "description": "WETH is the tokenized/packaged form of ETH that you use to pay for items when you interact with Ethereum dApps...",
* "gt_score": 92.66055045871559,
* "gt_score": 92.6605504587156,
* "discord_url": null,
* "telegram_handle": null,
* "twitter_handle": null
Expand All @@ -1014,7 +1014,7 @@ export interface components {
* "https://tether.to/"
* ],
* "description": "Tether (USDT) is a cryptocurrency with a value meant to mirror the value of the U.S. dollar. ...",
* "gt_score": 92.66055045871559,
* "gt_score": 92.6605504587156,
* "discord_url": null,
* "telegram_handle": null,
* "twitter_handle": "Tether_to"
Expand All @@ -1036,7 +1036,7 @@ export interface components {
* "coingecko_coin_id": "tensor",
* "websites": [],
* "description": "TNSR is the native token for the Tensor NFT marketplace on Solana.",
* "gt_score": 41.284403669724774,
* "gt_score": 41.2844036697248,
* "metadata_updated_at": "2024-04-08T15:59:04Z",
* "discord_url": null,
* "telegram_handle": null,
Expand Down Expand Up @@ -1066,23 +1066,23 @@ export interface components {
* 3660.85954963415,
* 3417.91885296256,
* 3660.85954963415,
* 306823.2770311613
* 306823.277031161
* ],
* [
* 1712448000,
* 3362.60273217873,
* 3455.28884490954,
* 3352.95305060685,
* 3454.61590249189,
* 242144.86478418365
* 242144.864784184
* ],
* [
* 1712361600,
* 3323.05578706056,
* 3391.19811016133,
* 3317.73497182435,
* 3362.60273217873,
* 273323.66168293066
* 273323.661682931
* ]
* ]
* }
Expand Down Expand Up @@ -1187,7 +1187,7 @@ export interface operations {
path: {
/** @description network id <br> *refers to [/networks](/reference/networks-list) */
network: string;
/** @description token contract address, comma-separated if more than one token contract address, max 30 addresses */
/** @description token contract address, comma-separated if more than one token contract address,100 addresses */
addresses: string;
};
cookie?: never;
Expand Down Expand Up @@ -1648,8 +1648,10 @@ export interface operations {
"tokens-info-recent-updated": {
parameters: {
query?: {
/** @description attributes to include */
/** @description Attributes for related resources to include, which will be returned under the top-level 'included' key */
include?: "network";
/** @description Filter tokens by provided network <br> *refers to [/networks](/reference/networks-list) */
network?: string;
};
header?: never;
path?: never;
Expand Down
Loading

0 comments on commit bb2bdb9

Please sign in to comment.