From 410b2fb120037021f594edb44d1cfeadd3a7f2be Mon Sep 17 00:00:00 2001 From: Koh Wei Jie Date: Mon, 23 Feb 2026 13:32:49 -0800 Subject: [PATCH] etheruem mainnet v2 boilerplate --- packages/core/src/chains/defaults.ts | 37 +++++++++++ packages/core/src/constants.ts | 17 +++++ packages/external-match/src/client.ts | 28 +++++++++ packages/node/src/clients/renegade/base.ts | 72 ++++++++++++++++++++++ wasm/src/common/types.rs | 6 ++ wasm/src/signature.rs | 2 +- 6 files changed, 161 insertions(+), 1 deletion(-) diff --git a/packages/core/src/chains/defaults.ts b/packages/core/src/chains/defaults.ts index 6a350c3c..757dc5a1 100644 --- a/packages/core/src/chains/defaults.ts +++ b/packages/core/src/chains/defaults.ts @@ -3,6 +3,8 @@ import { AUTH_SERVER_URL_ARBITRUM_SEPOLIA, AUTH_SERVER_URL_BASE_MAINNET, AUTH_SERVER_URL_BASE_SEPOLIA, + AUTH_SERVER_URL_ETHEREUM_MAINNET, + AUTH_SERVER_URL_ETHEREUM_SEPOLIA, CHAIN_ID_TO_ENVIRONMENT, CHAIN_IDS, CHAIN_SPECIFIERS, @@ -11,6 +13,8 @@ import { DARKPOOL_ADDRESS_ARBITRUM_SEPOLIA, DARKPOOL_ADDRESS_BASE_MAINNET, DARKPOOL_ADDRESS_BASE_SEPOLIA, + DARKPOOL_ADDRESS_ETHEREUM_MAINNET, + DARKPOOL_ADDRESS_ETHEREUM_SEPOLIA, ENV_AGNOSTIC_CHAINS, ENVIRONMENT, type EnvAgnosticChain, @@ -21,12 +25,16 @@ import { PERMIT2_ADDRESS_ARBITRUM_SEPOLIA, PERMIT2_ADDRESS_BASE_MAINNET, PERMIT2_ADDRESS_BASE_SEPOLIA, + PERMIT2_ADDRESS_ETHEREUM_MAINNET, + PERMIT2_ADDRESS_ETHEREUM_SEPOLIA, PRICE_REPORTER_URL_MAINNET, PRICE_REPORTER_URL_TESTNET, RELAYER_URL_ARBITRUM_ONE, RELAYER_URL_ARBITRUM_SEPOLIA, RELAYER_URL_BASE_MAINNET, RELAYER_URL_BASE_SEPOLIA, + RELAYER_URL_ETHEREUM_MAINNET, + RELAYER_URL_ETHEREUM_SEPOLIA, } from "../constants.js"; export interface SDKConfig { @@ -86,6 +94,28 @@ export const CONFIGS: Record = { permit2Address: PERMIT2_ADDRESS_BASE_SEPOLIA, authServerUrl: AUTH_SERVER_URL_BASE_SEPOLIA, }, + [CHAIN_IDS.EthereumMainnet]: { + id: CHAIN_IDS.EthereumMainnet, + chainSpecifier: CHAIN_SPECIFIERS[CHAIN_IDS.EthereumMainnet], + hseBaseUrl: HSE_URL_MAINNET, + darkpoolAddress: DARKPOOL_ADDRESS_ETHEREUM_MAINNET, + relayerUrl: RELAYER_URL_ETHEREUM_MAINNET, + websocketUrl: `wss://${RELAYER_URL_ETHEREUM_MAINNET}:4000`, + priceReporterUrl: PRICE_REPORTER_URL_MAINNET, + permit2Address: PERMIT2_ADDRESS_ETHEREUM_MAINNET, + authServerUrl: AUTH_SERVER_URL_ETHEREUM_MAINNET, + }, + [CHAIN_IDS.EthereumSepolia]: { + id: CHAIN_IDS.EthereumSepolia, + chainSpecifier: CHAIN_SPECIFIERS[CHAIN_IDS.EthereumSepolia], + hseBaseUrl: HSE_URL_TESTNET, + darkpoolAddress: DARKPOOL_ADDRESS_ETHEREUM_SEPOLIA, + relayerUrl: RELAYER_URL_ETHEREUM_SEPOLIA, + websocketUrl: `wss://${RELAYER_URL_ETHEREUM_SEPOLIA}:4000`, + priceReporterUrl: PRICE_REPORTER_URL_TESTNET, + permit2Address: PERMIT2_ADDRESS_ETHEREUM_SEPOLIA, + authServerUrl: AUTH_SERVER_URL_ETHEREUM_SEPOLIA, + }, }; /** Returns true if the chain ID is supported */ @@ -123,6 +153,8 @@ export function chainIdFromEnvAndName(env: Environment, name: EnvAgnosticChain): return CHAIN_IDS.ArbitrumOne; case ENV_AGNOSTIC_CHAINS.Base: return CHAIN_IDS.BaseMainnet; + case ENV_AGNOSTIC_CHAINS.Ethereum: + return CHAIN_IDS.EthereumMainnet; default: throw new Error(`Unsupported env / chain: ${env} / ${name}`); } @@ -133,6 +165,8 @@ export function chainIdFromEnvAndName(env: Environment, name: EnvAgnosticChain): return CHAIN_IDS.ArbitrumSepolia; case ENV_AGNOSTIC_CHAINS.Base: return CHAIN_IDS.BaseSepolia; + case ENV_AGNOSTIC_CHAINS.Ethereum: + return CHAIN_IDS.EthereumSepolia; default: throw new Error(`Unsupported env / chain: ${env} / ${name}`); } @@ -148,6 +182,9 @@ export function getEnvAgnosticChain(chainId: ChainId): EnvAgnosticChain { case CHAIN_IDS.BaseSepolia: case CHAIN_IDS.BaseMainnet: return ENV_AGNOSTIC_CHAINS.Base; + case CHAIN_IDS.EthereumMainnet: + case CHAIN_IDS.EthereumSepolia: + return ENV_AGNOSTIC_CHAINS.Ethereum; } } diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index d9f044a9..a883eba5 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -20,6 +20,8 @@ export const CHAIN_IDS = { ArbitrumSepolia: 421614, BaseSepolia: 84532, BaseMainnet: 8453, + EthereumMainnet: 1, + EthereumSepolia: 11155111, } as const; export type ChainId = (typeof CHAIN_IDS)[keyof typeof CHAIN_IDS]; @@ -29,6 +31,8 @@ export const CHAIN_SPECIFIERS = { [CHAIN_IDS.ArbitrumSepolia]: "arbitrum-sepolia", [CHAIN_IDS.BaseMainnet]: "base-mainnet", [CHAIN_IDS.BaseSepolia]: "base-sepolia", + [CHAIN_IDS.EthereumMainnet]: "ethereum-mainnet", + [CHAIN_IDS.EthereumSepolia]: "ethereum-sepolia", } as const; export type ChainSpecifier = (typeof CHAIN_SPECIFIERS)[keyof typeof CHAIN_SPECIFIERS]; @@ -43,11 +47,14 @@ export const CHAIN_ID_TO_ENVIRONMENT: Record = { [CHAIN_IDS.ArbitrumSepolia]: "testnet", [CHAIN_IDS.BaseMainnet]: "mainnet", [CHAIN_IDS.BaseSepolia]: "testnet", + [CHAIN_IDS.EthereumMainnet]: "mainnet", + [CHAIN_IDS.EthereumSepolia]: "testnet", }; export const ENV_AGNOSTIC_CHAINS = { Arbitrum: "arbitrum", Base: "base", + Ethereum: "ethereum", } as const; export type EnvAgnosticChain = (typeof ENV_AGNOSTIC_CHAINS)[keyof typeof ENV_AGNOSTIC_CHAINS]; @@ -69,12 +76,18 @@ export const RELAYER_URL_ARBITRUM_ONE = "arbitrum-one.relayer.renegade.fi"; export const RELAYER_URL_ARBITRUM_SEPOLIA = "arbitrum-sepolia.relayer.renegade.fi"; export const RELAYER_URL_BASE_MAINNET = "base-mainnet.relayer.renegade.fi"; export const RELAYER_URL_BASE_SEPOLIA = "base-sepolia.relayer.renegade.fi"; +export const RELAYER_URL_ETHEREUM_MAINNET = "ethereum-mainnet.relayer.renegade.fi"; +export const RELAYER_URL_ETHEREUM_SEPOLIA = "ethereum-sepolia.relayer.renegade.fi"; export const AUTH_SERVER_URL_ARBITRUM_ONE = "https://arbitrum-one.auth-server.renegade.fi:3000"; export const AUTH_SERVER_URL_ARBITRUM_SEPOLIA = "https://arbitrum-sepolia.auth-server.renegade.fi:3000"; export const AUTH_SERVER_URL_BASE_MAINNET = "https://base-mainnet.auth-server.renegade.fi:3000"; export const AUTH_SERVER_URL_BASE_SEPOLIA = "https://base-sepolia.auth-server.renegade.fi:3000"; +export const AUTH_SERVER_URL_ETHEREUM_MAINNET = + "https://ethereum-mainnet.auth-server.renegade.fi:3000"; +export const AUTH_SERVER_URL_ETHEREUM_SEPOLIA = + "https://ethereum-sepolia.auth-server.renegade.fi:3000"; //////////////////////////////////////////////////////////////////////////////// // Deployed Contracts @@ -84,11 +97,15 @@ export const DARKPOOL_ADDRESS_ARBITRUM_ONE = "0x30bD8eAb29181F790D7e495786d4B96d export const DARKPOOL_ADDRESS_ARBITRUM_SEPOLIA = "0x9af58f1ff20ab22e819e40b57ffd784d115a9ef5"; export const DARKPOOL_ADDRESS_BASE_MAINNET = "0xb4a96068577141749CC8859f586fE29016C935dB"; export const DARKPOOL_ADDRESS_BASE_SEPOLIA = "0x653C95391644EEE16E4975a7ef1f46e0B8276695"; +export const DARKPOOL_ADDRESS_ETHEREUM_MAINNET = "0x0000000000000000000000000000000000000000"; // TODO: Update after deployment +export const DARKPOOL_ADDRESS_ETHEREUM_SEPOLIA = "0x0000000000000000000000000000000000000000"; // TODO: Update after deployment export const PERMIT2_ADDRESS_ARBITRUM_ONE = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; export const PERMIT2_ADDRESS_ARBITRUM_SEPOLIA = "0x9458198bcc289c42e460cb8ca143e5854f734442"; export const PERMIT2_ADDRESS_BASE_MAINNET = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; export const PERMIT2_ADDRESS_BASE_SEPOLIA = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; +export const PERMIT2_ADDRESS_ETHEREUM_MAINNET = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; +export const PERMIT2_ADDRESS_ETHEREUM_SEPOLIA = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; //////////////////////////////////////////////////////////////////////////////// // System-Wide Constants diff --git a/packages/external-match/src/client.ts b/packages/external-match/src/client.ts index 6e57ab35..3cdced28 100644 --- a/packages/external-match/src/client.ts +++ b/packages/external-match/src/client.ts @@ -50,12 +50,16 @@ const ARBITRUM_SEPOLIA_BASE_URL = "https://arbitrum-sepolia.v2.auth-server.reneg const ARBITRUM_ONE_BASE_URL = "https://arbitrum-one.v2.auth-server.renegade.fi"; const BASE_SEPOLIA_BASE_URL = "https://base-sepolia.v2.auth-server.renegade.fi"; const BASE_MAINNET_BASE_URL = "https://base-mainnet.v2.auth-server.renegade.fi"; +const ETHEREUM_MAINNET_BASE_URL = "https://ethereum-mainnet.v2.auth-server.renegade.fi"; +const ETHEREUM_SEPOLIA_BASE_URL = "https://ethereum-sepolia.v2.auth-server.renegade.fi"; // Constants for relayer URLs const ARBITRUM_SEPOLIA_RELAYER_URL = "https://arbitrum-sepolia.v2.relayer.renegade.fi"; const ARBITRUM_ONE_RELAYER_URL = "https://arbitrum-one.v2.relayer.renegade.fi"; const BASE_SEPOLIA_RELAYER_URL = "https://base-sepolia.v2.relayer.renegade.fi"; const BASE_MAINNET_RELAYER_URL = "https://base-mainnet.v2.relayer.renegade.fi"; +const ETHEREUM_MAINNET_RELAYER_URL = "https://ethereum-mainnet.v2.relayer.renegade.fi"; +const ETHEREUM_SEPOLIA_RELAYER_URL = "https://ethereum-sepolia.v2.relayer.renegade.fi"; // Header constants const RENEGADE_API_KEY_HEADER = "x-renegade-api-key"; @@ -357,6 +361,30 @@ export class ExternalMatchClient { ); } + /** + * Create a new client configured for the Ethereum mainnet. + */ + static newEthereumMainnetClient(apiKey: string, apiSecret: string): ExternalMatchClient { + return new ExternalMatchClient( + apiKey, + apiSecret, + ETHEREUM_MAINNET_BASE_URL, + ETHEREUM_MAINNET_RELAYER_URL, + ); + } + + /** + * Create a new client configured for the Ethereum Sepolia testnet. + */ + static newEthereumSepoliaClient(apiKey: string, apiSecret: string): ExternalMatchClient { + return new ExternalMatchClient( + apiKey, + apiSecret, + ETHEREUM_SEPOLIA_BASE_URL, + ETHEREUM_SEPOLIA_RELAYER_URL, + ); + } + // --- Quote methods (v1 signature, v2 internally) --- /** diff --git a/packages/node/src/clients/renegade/base.ts b/packages/node/src/clients/renegade/base.ts index e9ef31e4..9ac2c795 100644 --- a/packages/node/src/clients/renegade/base.ts +++ b/packages/node/src/clients/renegade/base.ts @@ -305,6 +305,78 @@ export class RenegadeClient { }); } + /** + * Ethereum Mainnet client via seed. + * + * @param params.seed your 0x… seed + */ + static newEthereumMainnetClient({ seed, logger }: { seed: `0x${string}`; logger?: Logger }) { + return RenegadeClient.new({ chainId: CHAIN_IDS.EthereumMainnet, seed, logger }); + } + + /** + * Ethereum Mainnet client with external keychain. + * + * @param params.walletSecrets symmetric key + wallet ID + * @param params.signMessage callback to sign auth messages + * @param params.publicKey your public key + */ + static newEthereumMainnetClientWithKeychain({ + walletSecrets, + signMessage, + publicKey, + logger, + }: { + walletSecrets: GeneratedSecrets; + signMessage: (message: string) => Promise<`0x${string}`>; + publicKey: `0x${string}`; + logger?: Logger; + }) { + return RenegadeClient.newWithExternalKeychain({ + chainId: CHAIN_IDS.EthereumMainnet, + walletSecrets, + signMessage, + publicKey, + logger, + }); + } + + /** + * Ethereum Sepolia client via seed. + * + * @param params.seed your 0x… seed + */ + static newEthereumSepoliaClient({ seed, logger }: { seed: `0x${string}`; logger?: Logger }) { + return RenegadeClient.new({ chainId: CHAIN_IDS.EthereumSepolia, seed, logger }); + } + + /** + * Ethereum Sepolia client with external keychain. + * + * @param params.walletSecrets symmetric key + wallet ID + * @param params.signMessage callback to sign auth messages + * @param params.publicKey your public key + */ + static newEthereumSepoliaClientWithKeychain({ + walletSecrets, + signMessage, + publicKey, + logger, + }: { + walletSecrets: GeneratedSecrets; + signMessage: (message: string) => Promise<`0x${string}`>; + publicKey: `0x${string}`; + logger?: Logger; + }) { + return RenegadeClient.newWithExternalKeychain({ + chainId: CHAIN_IDS.EthereumSepolia, + walletSecrets, + signMessage, + publicKey, + logger, + }); + } + // -- Wallet Operations -- // async getWallet( diff --git a/wasm/src/common/types.rs b/wasm/src/common/types.rs index a0d135b4..150c1dc7 100644 --- a/wasm/src/common/types.rs +++ b/wasm/src/common/types.rs @@ -177,6 +177,10 @@ pub enum Chain { BaseSepolia, /// The Base Mainnet chain BaseMainnet, + /// The Ethereum Sepolia chain + EthereumSepolia, + /// The Ethereum Mainnet chain + EthereumMainnet, /// Any local devnet chain Devnet, } @@ -190,6 +194,8 @@ impl FromStr for Chain { "arbitrum-one" => Ok(Chain::ArbitrumOne), "base-sepolia" => Ok(Chain::BaseSepolia), "base-mainnet" => Ok(Chain::BaseMainnet), + "ethereum-sepolia" => Ok(Chain::EthereumSepolia), + "ethereum-mainnet" => Ok(Chain::EthereumMainnet), "devnet" => Ok(Chain::Devnet), _ => Err(JsError::new(&format!("Invalid chain: {s}"))), } diff --git a/wasm/src/signature.rs b/wasm/src/signature.rs index da94545d..82b3661c 100644 --- a/wasm/src/signature.rs +++ b/wasm/src/signature.rs @@ -55,7 +55,7 @@ pub async fn sign_withdrawal_authorization( postcard::to_allocvec(&contract_transfer) .map_err(map_js_error!("Failed to serialize transfer: {}"))? } - &Chain::BaseMainnet | &Chain::BaseSepolia => { + &Chain::BaseMainnet | &Chain::BaseSepolia | &Chain::EthereumMainnet | &Chain::EthereumSepolia => { let contract_transfer = to_base_external_transfer(&transfer) .map_err(map_js_error!("Failed to convert transfer: {}"))?;