Skip to content

Commit 78a248d

Browse files
authored
fix: standardize evm env in scripts (#803)
* fix: standardize evm providers in scripts Signed-off-by: Reinis Martinsons <[email protected]> * fix: require env Signed-off-by: Reinis Martinsons <[email protected]> --------- Signed-off-by: Reinis Martinsons <[email protected]>
1 parent 6d189e6 commit 78a248d

8 files changed

+96
-145
lines changed

scripts/svm/bridgeLiabilityToHubPool.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@
66
* updates the Hub Pool’s USDC balance.
77
*
88
* Required Environment Variables:
9-
* - TESTNET: (Optional) Set to "true" to use Sepolia; defaults to mainnet.
109
* - MNEMONIC: Wallet mnemonic to sign the Ethereum transaction.
1110
* - HUB_POOL_ADDRESS: Ethereum address of the Hub Pool.
12-
* - NODE_URL_1: Ethereum RPC URL for mainnet (ignored if TESTNET=true).
13-
* - NODE_URL_11155111: Ethereum RPC URL for Sepolia (ignored if TESTNET=false).
11+
* - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
1412
*
1513
* Example Usage:
16-
* TESTNET=true \
1714
* NODE_URL_11155111=$NODE_URL_11155111 \
1815
* MNEMONIC=$MNEMONIC \
1916
* HUB_POOL_ADDRESS=$HUB_POOL_ADDRESS \
@@ -50,7 +47,7 @@ import { BigNumber, ethers } from "ethers";
5047
import { TokenMessengerMinter } from "../../target/types/token_messenger_minter";
5148
import { getMessages } from "../../test/svm/cctpHelpers";
5249
import { BondToken__factory } from "../../typechain";
53-
import { formatUsdc, requireEnv } from "./utils/helpers";
50+
import { formatUsdc, requireEnv, isSolanaDevnet } from "./utils/helpers";
5451

5552
// Set up Solana provider.
5653
const provider = AnchorProvider.env();
@@ -67,7 +64,8 @@ const ethereumDomain = 0; // Ethereum
6764
const solanaDomain = 5; // Solana
6865

6966
// Set up Ethereum provider and signer.
70-
const nodeURL = process.env.TESTNET === "true" ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
67+
const isDevnet = isSolanaDevnet(provider);
68+
const nodeURL = isDevnet ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
7169
const ethersProvider = new ethers.providers.JsonRpcProvider(nodeURL);
7270
const ethersSigner = ethers.Wallet.fromMnemonic(requireEnv("MNEMONIC")).connect(ethersProvider);
7371

@@ -123,13 +121,7 @@ const messageTransmitterAbi = [
123121
async function bridgeLiabilityToHubPool(): Promise<void> {
124122
const seed = SOLANA_SPOKE_STATE_SEED; // Seed is always 0 for the state account PDA in public networks.
125123

126-
// Resolve Solana cluster, EVM chain ID, Iris API URL and USDC addresses.
127-
let isDevnet: boolean;
128-
const solanaRpcEndpoint = provider.connection.rpcEndpoint;
129-
if (solanaRpcEndpoint.includes("devnet")) isDevnet = true;
130-
else if (solanaRpcEndpoint.includes("mainnet")) isDevnet = false;
131-
else throw new Error(`Unsupported solanaCluster endpoint: ${solanaRpcEndpoint}`);
132-
124+
// Resolve Solana USDC addresses.
133125
const svmUsdc = isDevnet ? SOLANA_USDC_DEVNET : SOLANA_USDC_MAINNET;
134126

135127
const [statePda, _] = PublicKey.findProgramAddressSync(
@@ -152,7 +144,7 @@ async function bridgeLiabilityToHubPool(): Promise<void> {
152144

153145
console.log("Receiving liability from Solana Spoke Pool to Ethereum Hub Pool...");
154146
console.table([
155-
{ Property: "isTestnet", Value: process.env.TESTNET === "true" },
147+
{ Property: "isTestnet", Value: isDevnet },
156148
{ Property: "hubPoolAddress", Value: hubPoolAddress },
157149
{ Property: "svmSpokeProgramProgramId", Value: svmSpokeProgram.programId.toString() },
158150
{ Property: "providerPublicKey", Value: provider.wallet.publicKey.toString() },

scripts/svm/executeRebalanceToHubPool.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,15 @@
66
* liabilities for bridging back to the Hub Pool.
77
*
88
* Required Environment Variables:
9-
* - TESTNET: (Optional) Set to "true" to use Sepolia; defaults to mainnet.
109
* - MNEMONIC: Wallet mnemonic to sign the Ethereum transaction.
1110
* - HUB_POOL_ADDRESS: Ethereum address of the Hub Pool.
12-
* - NODE_URL_1: Ethereum RPC URL for mainnet (ignored if TESTNET=true).
13-
* - NODE_URL_11155111: Ethereum RPC URL for Sepolia (ignored if TESTNET=false).
11+
* - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
1412
*
1513
* Required Arguments:
1614
* - `--netSendAmount`: The unscaled amount of USDC to rebalance (e.g., for USDC with 6 decimals, 1 = 0.000001 USDC).
1715
* - `--resumeRemoteTx`: (Optional) Hash of a previously submitted remote transaction to resume.
1816
*
1917
* Example Usage:
20-
* TESTNET=true \
2118
* NODE_URL_11155111=$NODE_URL_11155111 \
2219
* MNEMONIC=$MNEMONIC \
2320
* HUB_POOL_ADDRESS=$HUB_POOL_ADDRESS \
@@ -64,6 +61,7 @@ import {
6461
formatUsdc,
6562
getSolanaChainId,
6663
requireEnv,
64+
isSolanaDevnet,
6765
} from "./utils/helpers";
6866

6967
import { getNodeUrl, MerkleTree } from "@uma/common";
@@ -96,7 +94,8 @@ const [eventAuthority] = PublicKey.findProgramAddressSync(
9694
);
9795

9896
// Set up Ethereum provider and signer.
99-
const nodeURL = process.env.TESTNET === "true" ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
97+
const isDevnet = isSolanaDevnet(provider);
98+
const nodeURL = isDevnet ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
10099
const ethersProvider = new ethers.providers.JsonRpcProvider(nodeURL);
101100
const ethersSigner = ethers.Wallet.fromMnemonic(requireEnv("MNEMONIC")).connect(ethersProvider);
102101

@@ -120,11 +119,6 @@ async function executeRebalanceToHubPool(): Promise<void> {
120119
const resumeRemoteTx = resolvedArgv.resumeRemoteTx;
121120

122121
// Resolve Solana cluster, EVM chain ID, Iris API URL and USDC addresses.
123-
let isDevnet: boolean;
124-
const solanaRpcEndpoint = provider.connection.rpcEndpoint;
125-
if (solanaRpcEndpoint.includes("devnet")) isDevnet = true;
126-
else if (solanaRpcEndpoint.includes("mainnet")) isDevnet = false;
127-
else throw new Error(`Unsupported solanaCluster endpoint: ${solanaRpcEndpoint}`);
128122
const solanaCluster = isDevnet ? "devnet" : "mainnet";
129123
const solanaChainId = getSolanaChainId(solanaCluster);
130124
const irisApiUrl = isDevnet ? CIRCLE_IRIS_API_URL_DEVNET : CIRCLE_IRIS_API_URL_MAINNET;
@@ -147,7 +141,7 @@ async function executeRebalanceToHubPool(): Promise<void> {
147141

148142
console.log("Executing rebalance to hub pool...");
149143
console.table([
150-
{ Property: "isTestnet", Value: process.env.TESTNET === "true" },
144+
{ Property: "isTestnet", Value: isDevnet },
151145
{ Property: "originChainId", Value: evmChainId.toString() },
152146
{ Property: "targetChainId", Value: solanaChainId.toString() },
153147
{ Property: "hubPoolAddress", Value: hubPool.address },

scripts/svm/executeRebalanceToSpokePool.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// This script executes root bundle on HubPool that rebalances tokens to Solana Spoke Pool. Required environment:
2-
// - ETHERS_PROVIDER_URL: Ethereum RPC provider URL.
3-
// - ETHERS_MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
2+
// - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
3+
// - MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
44
// - HUB_POOL_ADDRESS: Hub Pool address
55

66
import * as anchor from "@coral-xyz/anchor";
77
import { BN, Program, AnchorProvider } from "@coral-xyz/anchor";
88
import { AccountMeta, PublicKey, SystemProgram } from "@solana/web3.js";
99
import { TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from "@solana/spl-token";
10+
import { getNodeUrl } from "@uma/common";
1011
// eslint-disable-next-line camelcase
1112
import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../../utils/constants";
1213
import { SvmSpoke } from "../../target/types/svm_spoke";
@@ -26,6 +27,7 @@ import {
2627
} from "./utils/constants";
2728
import { constructSimpleRebalanceTree } from "./utils/poolRebalanceTree";
2829
import { decodeMessageHeader, getMessages } from "../../test/svm/cctpHelpers";
30+
import { getSolanaChainId, isSolanaDevnet, requireEnv } from "./utils/helpers";
2931

3032
// Set up Solana provider.
3133
const provider = AnchorProvider.env();
@@ -39,21 +41,14 @@ const messageTransmitterProgram = new Program<MessageTransmitter>(messageTransmi
3941
const tokenMessengerMinterIdl = require("../../target/idl/token_messenger_minter.json");
4042
const tokenMessengerMinterProgram = new Program<TokenMessengerMinter>(tokenMessengerMinterIdl, provider);
4143

42-
// Set up Ethereum provider.
43-
if (!process.env.ETHERS_PROVIDER_URL) {
44-
throw new Error("Environment variable ETHERS_PROVIDER_URL is not set");
45-
}
46-
const ethersProvider = new ethers.providers.JsonRpcProvider(process.env.ETHERS_PROVIDER_URL);
47-
if (!process.env.ETHERS_MNEMONIC) {
48-
throw new Error("Environment variable ETHERS_MNEMONIC is not set");
49-
}
50-
const ethersSigner = ethers.Wallet.fromMnemonic(process.env.ETHERS_MNEMONIC).connect(ethersProvider);
44+
// Set up Ethereum provider and signer.
45+
const isDevnet = isSolanaDevnet(provider);
46+
const nodeURL = isDevnet ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
47+
const ethersProvider = new ethers.providers.JsonRpcProvider(nodeURL);
48+
const ethersSigner = ethers.Wallet.fromMnemonic(requireEnv("MNEMONIC")).connect(ethersProvider);
5149

5250
// Get the HubPool contract instance.
53-
if (!process.env.HUB_POOL_ADDRESS) {
54-
throw new Error("Environment variable HUB_POOL_ADDRESS is not set");
55-
}
56-
const hubPoolAddress = ethers.utils.getAddress(process.env.HUB_POOL_ADDRESS);
51+
const hubPoolAddress = ethers.utils.getAddress(requireEnv("HUB_POOL_ADDRESS"));
5752
const hubPool = HubPool__factory.connect(hubPoolAddress, ethersProvider);
5853

5954
// CCTP domains.
@@ -79,16 +74,9 @@ async function executeRebalanceToSpokePool(): Promise<void> {
7974
const netSendAmount = resolvedArgv.netSendAmount ? BigNumber.from(resolvedArgv.netSendAmount) : BigNumber.from(0);
8075
const resumeRemoteTx = resolvedArgv.resumeRemoteTx;
8176

82-
// Resolve Solana cluster, EVM chain ID, Iris API URL and USDC addresses.
83-
let isDevnet: boolean;
84-
const solanaRpcEndpoint = provider.connection.rpcEndpoint;
85-
if (solanaRpcEndpoint.includes("devnet")) isDevnet = true;
86-
else if (solanaRpcEndpoint.includes("mainnet")) isDevnet = false;
87-
else throw new Error(`Unsupported solanaCluster endpoint: ${solanaRpcEndpoint}`);
77+
// Resolve chain IDs, Iris API URL and USDC addresses.
8878
const solanaCluster = isDevnet ? "devnet" : "mainnet";
89-
const solanaChainId = BigNumber.from(
90-
BigInt(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`solana-${solanaCluster}`))) & BigInt("0xFFFFFFFFFFFFFFFF")
91-
);
79+
const solanaChainId = getSolanaChainId(solanaCluster);
9280
const irisApiUrl = isDevnet ? CIRCLE_IRIS_API_URL_DEVNET : CIRCLE_IRIS_API_URL_MAINNET;
9381
const supportedEvmChainId = isDevnet ? CHAIN_IDs.SEPOLIA : CHAIN_IDs.MAINNET; // Sepolia is bridged to devnet, Ethereum to mainnet in CCTP.
9482
const evmChainId = (await ethersProvider.getNetwork()).chainId;

scripts/svm/proposeRebalanceToSpokePool.ts

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
11
// This script proposes root bundle on HubPool that would rebalance tokens to Solana Spoke Pool once executed.
22
// Required environment:
3-
// - ETHERS_PROVIDER_URL: Ethereum RPC provider URL.
4-
// - ETHERS_MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
3+
// - TESTNET: (Optional) Set to "true" to use Sepolia; defaults to mainnet.
4+
// - MNEMONIC: Wallet mnemonic to sign the Ethereum transaction.
55
// - HUB_POOL_ADDRESS: Hub Pool address
6+
// - NODE_URL_1: Ethereum RPC URL for mainnet (ignored if TESTNET=true).
7+
// - NODE_URL_11155111: Ethereum RPC URL for Sepolia (ignored if TESTNET=false).
68

79
// eslint-disable-next-line camelcase
810
import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../../utils/constants";
911
import yargs from "yargs";
1012
import { hideBin } from "yargs/helpers";
1113
import { ethers, BigNumber } from "ethers";
14+
import { getNodeUrl } from "@uma/common";
1215
// eslint-disable-next-line camelcase
1316
import { BondToken__factory, HubPool__factory } from "../../typechain";
1417
import { constructSimpleRebalanceTree } from "./utils/poolRebalanceTree";
18+
import { getSolanaChainId, requireEnv } from "./utils/helpers";
1519

1620
// Set up Ethereum provider.
17-
if (!process.env.ETHERS_PROVIDER_URL) {
18-
throw new Error("Environment variable ETHERS_PROVIDER_URL is not set");
19-
}
20-
const ethersProvider = new ethers.providers.JsonRpcProvider(process.env.ETHERS_PROVIDER_URL);
21-
if (!process.env.ETHERS_MNEMONIC) {
22-
throw new Error("Environment variable ETHERS_MNEMONIC is not set");
23-
}
24-
const ethersSigner = ethers.Wallet.fromMnemonic(process.env.ETHERS_MNEMONIC).connect(ethersProvider);
21+
const nodeURL = process.env.TESTNET === "true" ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
22+
const ethersProvider = new ethers.providers.JsonRpcProvider(nodeURL);
23+
const ethersSigner = ethers.Wallet.fromMnemonic(requireEnv("MNEMONIC")).connect(ethersProvider);
2524

2625
// Get the HubPool contract instance.
27-
if (!process.env.HUB_POOL_ADDRESS) {
28-
throw new Error("Environment variable HUB_POOL_ADDRESS is not set");
29-
}
30-
const hubPoolAddress = ethers.utils.getAddress(process.env.HUB_POOL_ADDRESS);
26+
const hubPoolAddress = ethers.utils.getAddress(requireEnv("HUB_POOL_ADDRESS"));
3127
const hubPool = HubPool__factory.connect(hubPoolAddress, ethersProvider);
3228

3329
// Parse arguments
@@ -45,9 +41,7 @@ async function proposeRebalanceToSpokePool(): Promise<void> {
4541
const evmChainId = (await ethersProvider.getNetwork()).chainId;
4642
if (evmChainId !== CHAIN_IDs.MAINNET && evmChainId !== CHAIN_IDs.SEPOLIA) throw new Error("Unsupported EVM chain ID");
4743
const solanaCluster = evmChainId === CHAIN_IDs.MAINNET ? "mainnet" : "devnet";
48-
const solanaChainId = BigNumber.from(
49-
BigInt(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`solana-${solanaCluster}`))) & BigInt("0xFFFFFFFFFFFFFFFF")
50-
);
44+
const solanaChainId = getSolanaChainId(solanaCluster);
5145
const l1TokenAddress = TOKEN_SYMBOLS_MAP.USDC.addresses[evmChainId];
5246

5347
// Construct simple merkle tree for the pool rebalance.

scripts/svm/remoteHubPoolPauseDeposits.ts

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// This script bridges remote call to pause deposits on Solana Spoke Pool. Required environment:
2-
// - ETHERS_PROVIDER_URL: Ethereum RPC provider URL.
3-
// - ETHERS_MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
2+
// - NODE_URL_${CHAIN_ID}: Ethereum RPC URL (must point to the Mainnet or Sepolia depending on Solana cluster).
3+
// - MNEMONIC: Mnemonic of the wallet that will sign the sending transaction on Ethereum
44
// - HUB_POOL_ADDRESS: Hub Pool address
55

66
import * as anchor from "@coral-xyz/anchor";
@@ -10,11 +10,13 @@ import "dotenv/config";
1010
import { ethers } from "ethers";
1111
import yargs from "yargs";
1212
import { hideBin } from "yargs/helpers";
13+
import { getNodeUrl } from "@uma/common";
1314
import { MessageTransmitter } from "../../target/types/message_transmitter";
1415
import { SvmSpoke } from "../../target/types/svm_spoke";
1516
import { decodeMessageHeader, getMessages } from "../../test/svm/cctpHelpers";
1617
import { HubPool__factory } from "../../typechain";
1718
import { CIRCLE_IRIS_API_URL_DEVNET, CIRCLE_IRIS_API_URL_MAINNET } from "./utils/constants";
19+
import { isSolanaDevnet, requireEnv } from "./utils/helpers";
1820

1921
// Set up Solana provider.
2022
const provider = AnchorProvider.env();
@@ -34,27 +36,13 @@ async function remoteHubPoolPauseDeposit(): Promise<void> {
3436
const resumeRemoteTx = resolvedArgv.resumeRemoteTx;
3537
const pause = resolvedArgv.pause;
3638

37-
// Set up Ethereum provider.
38-
if (!process.env.ETHERS_PROVIDER_URL) {
39-
throw new Error("Environment variable ETHERS_PROVIDER_URL is not set");
40-
}
41-
const ethersProvider = new ethers.providers.JsonRpcProvider(process.env.ETHERS_PROVIDER_URL);
42-
if (!process.env.ETHERS_MNEMONIC) {
43-
throw new Error("Environment variable ETHERS_MNEMONIC is not set");
44-
}
45-
const ethersSigner = ethers.Wallet.fromMnemonic(process.env.ETHERS_MNEMONIC).connect(ethersProvider);
46-
47-
if (!process.env.HUB_POOL_ADDRESS) {
48-
throw new Error("Environment variable HUB_POOL_ADDRESS is not set");
49-
}
50-
const hubPoolAddress = process.env.HUB_POOL_ADDRESS;
51-
52-
let cluster: "devnet" | "mainnet";
53-
const rpcEndpoint = provider.connection.rpcEndpoint;
54-
if (rpcEndpoint.includes("devnet")) cluster = "devnet";
55-
else if (rpcEndpoint.includes("mainnet")) cluster = "mainnet";
56-
else throw new Error(`Unsupported cluster endpoint: ${rpcEndpoint}`);
57-
const isDevnet = cluster == "devnet";
39+
// Set up Ethereum provider and signer.
40+
const isDevnet = isSolanaDevnet(provider);
41+
const nodeURL = isDevnet ? getNodeUrl("sepolia", true) : getNodeUrl("mainnet", true);
42+
const ethersProvider = new ethers.providers.JsonRpcProvider(nodeURL);
43+
const ethersSigner = ethers.Wallet.fromMnemonic(requireEnv("MNEMONIC")).connect(ethersProvider);
44+
45+
const hubPoolAddress = requireEnv("HUB_POOL_ADDRESS");
5846

5947
// CCTP domains.
6048
const remoteDomain = 0; // Ethereum

0 commit comments

Comments
 (0)