Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 87 additions & 5 deletions config/bigBlocksConfig.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { CHAIN_IDS } from './chainIds';
const { HYPE_EVM_PRIVATE_KEY } = process.env;
const { PRIVATE_KEY_FOR_BATCHER_CONTRACT_DEPLOYMENT } = process.env;
const { PRIVATE_KEY_FOR_V4_CONTRACT_DEPLOYMENT } = process.env;

/**
* Configuration for a chain that supports BigBlocks
*/
Expand All @@ -10,38 +12,117 @@ export interface BigBlocksChainConfig {
isTestnet: boolean;
/** API URL for BigBlocks service */
apiUrl: string;
/** RPC URL for the network */
rpcUrl: string;
/** Chain ID for BigBlocks service */
bigBlocksChainId: number;
/** Environment variable key for private key */
envKey: string | undefined;
}

/**
* Map of chain IDs to their BigBlocks configuration
* Map of chain IDs to their BigBlocks configuration for V4 contracts deployment
* Currently only supported on HypeEVM networks
*/
export const BIGBLOCKS_SUPPORTED_CHAINS: Record<number, BigBlocksChainConfig> =
export const BIGBLOCKS_SUPPORTED_CHAINS_V4_CONTRACTS: Record<number, BigBlocksChainConfig> =
{
[CHAIN_IDS.HYPEEVM]: {
name: 'HypeEVM mainnet',
isTestnet: false,
apiUrl: 'https://api.hyperliquid.xyz/exchange',
rpcUrl: 'https://spectrum-01.simplystaking.xyz/hyperliquid-tn-rpc/evm',
bigBlocksChainId: 1337,
envKey: PRIVATE_KEY_FOR_V4_CONTRACT_DEPLOYMENT
},
[CHAIN_IDS.HYPEEVM_TESTNET]: {
name: 'HypeEVM Testnet',
isTestnet: true,
apiUrl: 'https://api.hyperliquid-testnet.xyz/exchange',
rpcUrl: 'https://spectrum-01.simplystaking.xyz/hyperliquid-tn-rpc/evm',
bigBlocksChainId: 1337,
envKey: PRIVATE_KEY_FOR_V4_CONTRACT_DEPLOYMENT
}
};

/**
* Map of chain IDs to their BigBlocks configuration for Batcher contract deployment
* Currently only supported on HypeEVM networks
*/
export const BIGBLOCKS_SUPPORTED_CHAINS_BATCHER: Record<number, BigBlocksChainConfig> =
{
[CHAIN_IDS.HYPEEVM]: {
name: 'HypeEVM mainnet',
isTestnet: false,
apiUrl: 'https://api.hyperliquid.xyz/exchange',
rpcUrl: 'https://spectrum-01.simplystaking.xyz/hyperliquid-tn-rpc/evm',
bigBlocksChainId: 1337,
envKey: HYPE_EVM_PRIVATE_KEY
envKey: PRIVATE_KEY_FOR_BATCHER_CONTRACT_DEPLOYMENT
},
[CHAIN_IDS.HYPEEVM_TESTNET]: {
name: 'HypeEVM Testnet',
isTestnet: true,
apiUrl: 'https://api.hyperliquid-testnet.xyz/exchange',
rpcUrl: 'https://spectrum-01.simplystaking.xyz/hyperliquid-tn-rpc/evm',
bigBlocksChainId: 1337,
envKey: HYPE_EVM_PRIVATE_KEY
envKey: PRIVATE_KEY_FOR_BATCHER_CONTRACT_DEPLOYMENT
}
};

/**
* Legacy configuration - deprecated, use specific configurations above
* @deprecated Use BIGBLOCKS_SUPPORTED_CHAINS_V4_CONTRACTS or BIGBLOCKS_SUPPORTED_CHAINS_BATCHER instead
*/
export const BIGBLOCKS_SUPPORTED_CHAINS: Record<number, BigBlocksChainConfig> =
BIGBLOCKS_SUPPORTED_CHAINS_V4_CONTRACTS;

// V4 Contracts specific functions
/**
* Check if a given chain ID supports BigBlocks for V4 contracts
* @param chainId The chain ID to check
* @returns true if the chain supports BigBlocks for V4 contracts, false otherwise
*/
export const isBigBlocksSupportedV4Contracts = (chainId: number): boolean => {
return chainId in BIGBLOCKS_SUPPORTED_CHAINS_V4_CONTRACTS;
};

/**
* Get the BigBlocks configuration for V4 contracts deployment
* @param chainId The chain ID to get configuration for
* @returns The chain's BigBlocks configuration for V4 contracts, or undefined if not supported
*/
export const getBigBlocksConfigV4Contracts = (
chainId: number
): BigBlocksChainConfig | undefined => {
return BIGBLOCKS_SUPPORTED_CHAINS_V4_CONTRACTS[chainId];
};

// Batcher specific functions
/**
* Check if a given chain ID supports BigBlocks for Batcher contract
* @param chainId The chain ID to check
* @returns true if the chain supports BigBlocks for Batcher contract, false otherwise
*/
export const isBigBlocksSupportedBatcher = (chainId: number): boolean => {
return chainId in BIGBLOCKS_SUPPORTED_CHAINS_BATCHER;
};

/**
* Get the BigBlocks configuration for Batcher contract deployment
* @param chainId The chain ID to get configuration for
* @returns The chain's BigBlocks configuration for Batcher contract, or undefined if not supported
*/
export const getBigBlocksConfigBatcher = (
chainId: number
): BigBlocksChainConfig | undefined => {
return BIGBLOCKS_SUPPORTED_CHAINS_BATCHER[chainId];
};

// Legacy functions - deprecated but kept for backward compatibility
/**
* Check if a given chain ID supports BigBlocks
* @param chainId The chain ID to check
* @returns true if the chain supports BigBlocks, false otherwise
* @deprecated Use isBigBlocksSupportedV4Contracts or isBigBlocksSupportedBatcher instead
*/
export const isBigBlocksSupported = (chainId: number): boolean => {
return chainId in BIGBLOCKS_SUPPORTED_CHAINS;
Expand All @@ -51,6 +132,7 @@ export const isBigBlocksSupported = (chainId: number): boolean => {
* Get the BigBlocks configuration for a chain
* @param chainId The chain ID to get configuration for
* @returns The chain's BigBlocks configuration, or undefined if not supported
* @deprecated Use getBigBlocksConfigV4Contracts or getBigBlocksConfigBatcher instead
*/
export const getBigBlocksConfig = (
chainId: number
Expand Down
13 changes: 10 additions & 3 deletions scripts/chainConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ export async function getChainConfig(chainId: number): Promise<ChainConfig> {
case CHAIN_IDS.IRYS_TESTNET:
case CHAIN_IDS.PHAROS:
case CHAIN_IDS.PHAROS_TESTNET:
case CHAIN_IDS.HYPEEVM:
case CHAIN_IDS.HYPEEVM_TESTNET:
case CHAIN_IDS.APECHAIN:
case CHAIN_IDS.APECHAIN_TESTNET:
case CHAIN_IDS.CORE_DAO:
Expand All @@ -117,7 +115,16 @@ export async function getChainConfig(chainId: number): Promise<ChainConfig> {
forwarderContractName = 'ForwarderV4';
forwarderFactoryContractName = 'ForwarderFactoryV4';
break;

case CHAIN_IDS.HYPEEVM:
case CHAIN_IDS.HYPEEVM_TESTNET:
gasParams = {
maxFeePerGas: 30_000_000_000n,
maxPriorityFeePerGas: 30_000_000_000n,
gasLimit: 3_000_000
};
forwarderContractName = 'ForwarderV4';
forwarderFactoryContractName = 'ForwarderFactoryV4';
break;
case CHAIN_IDS.WORLD:
case CHAIN_IDS.WORLD_TESTNET:
gasParams = {
Expand Down
159 changes: 142 additions & 17 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
} from '../deployUtils';
import { enableBigBlocks } from './enableBigBlocks';
import {
getBigBlocksConfig,
isBigBlocksSupported
getBigBlocksConfigV4Contracts,
isBigBlocksSupportedV4Contracts
} from '../config/bigBlocksConfig';

const NONCE = {
Expand All @@ -20,25 +20,149 @@ const NONCE = {
FORWARDER_FACTORY: 3
};

// Add interface for JSON RPC response
interface JsonRpcResponse {
jsonrpc: string;
id: number;
result?: boolean;
error?: {
code: number;
message: string;
};
}

/**
* Check if BigBlocks is already enabled using RPC call
*/
async function checkBigBlocksStatus(
userAddress: string,
chainId: number
): Promise<boolean> {
const config = getBigBlocksConfigV4Contracts(chainId);
if (!config) {
throw new Error(`Chain with ID ${chainId} is not supported for BigBlocks.`);
}
console.log('Useradd' + userAddress);
console.log(
`Checking BigBlocks status for ${userAddress} on ${config.name}...`
);
console.log(`Making RPC call to: ${config.rpcUrl}`);
try {
const requestBody = {
jsonrpc: '2.0',
id: 0,
method: 'eth_usingBigBlocks',
params: [userAddress]
};

const res = await fetch(config.rpcUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});

if (!res.ok) {
throw new Error(`HTTP Error: ${res.status} ${await res.text()}`);
}

const result = (await res.json()) as JsonRpcResponse;

console.log(result);

if (result.error) {
throw new Error(
`RPC Error: ${result.error.code} - ${result.error.message}`
);
}

return result.result || false;
} catch (err) {
console.error('Failed to fetch BigBlocks status.');
throw err;
}
}

/**
* Enable BigBlocks with retry mechanism
*/
async function enableBigBlocksWithRetry(
config: any,
chainId: number,
maxRetries: number = 3
): Promise<void> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(
` Attempt ${attempt}/${maxRetries}: Enabling BigBlocks on ${config.name}`
);
await enableBigBlocks(config.envKey, true, chainId);
console.log(` BigBlocks enabled on ${config.name} (attempt ${attempt})`);
return;
} catch (error) {
console.log(
`Attempt ${attempt}/${maxRetries} failed:`,
(error as Error).message
);

if (attempt === maxRetries) {
throw new Error(
`Failed to enable BigBlocks on ${
config.name
} after ${maxRetries} attempts: ${(error as Error).message}`
);
}

// Wait 2 seconds before retry
console.log(' Waiting 2 seconds before retry...');
await new Promise((resolve) => setTimeout(resolve, 2000));
}
}
}

/**
* Configure BigBlocks for HypeEVM network
* Setup BigBlocks for a specific chain
*/
async function setupBigBlocks(chainId: number): Promise<void> {
const config = getBigBlocksConfig(chainId);
async function setupBigBlocks(
chainId: number,
deployerAddress: string
): Promise<void> {
const config = getBigBlocksConfigV4Contracts(chainId);
if (!config) return;

if (!config.envKey) {
throw new Error(`Please set the private key for ${config.name}.`);
}

console.log(`Using BigBlocks on ${config.name}`);
try {
await enableBigBlocks(config.envKey, true, chainId);
} catch (error) {
console.log(` Checking BigBlocks status on ${config.name}...`);

// Check if BigBlocks is already enabled
const isEnabled = await checkBigBlocksStatus(deployerAddress, chainId);

if (isEnabled) {
console.log(`BigBlocks already enabled on ${config.name}`);
return;
}

console.log(
` BigBlocks not enabled on ${config.name}, attempting to enable...`
);

// Try to enable BigBlocks with retry mechanism
await enableBigBlocksWithRetry(config, chainId, 3);

// Verify it was enabled successfully
console.log(`Verifying BigBlocks was enabled...`);
const isEnabledAfter = await checkBigBlocksStatus(deployerAddress, chainId);

if (!isEnabledAfter) {
throw new Error(
`Failed to setup BigBlocks on ${config.name}: ${(error as Error).message}`
`BigBlocks enable command succeeded but verification failed on ${config.name}`
);
}

console.log(`BigBlocks successfully verified as enabled on ${config.name}`);
}

async function main() {
Expand All @@ -47,15 +171,16 @@ async function main() {
const currentNonce = await ethers.provider.getTransactionCount(
deployerAddress
);
const { chainId } = await ethers.provider.getNetwork(); // More direct way to get chainId
const { chainId } = await ethers.provider.getNetwork();
const chainConfig = await getChainConfig(Number(chainId));
const output: DeploymentAddresses = loadOutput();

const gasOverrides = chainConfig.gasParams;

if (isBigBlocksSupported(Number(chainId))) {
console.log('🔄 Setting up BigBlocks...');
await setupBigBlocks(Number(chainId));
// Handle BigBlocks setup automatically if supported
if (isBigBlocksSupportedV4Contracts(Number(chainId))) {
console.log('🔍 BigBlocks supported on this chain, checking status...');
await setupBigBlocks(Number(chainId), deployerAddress);
}

console.log(
Expand Down Expand Up @@ -105,7 +230,7 @@ async function main() {
const WalletFactory = await ethers.getContractFactory(
chainConfig.walletFactoryContractName
);
const contract = await WalletFactory.deploy(walletAddress, gasOverrides); // constructor args + overrides
const contract = await WalletFactory.deploy(walletAddress, gasOverrides);
await contract.waitForDeployment();
console.log(
`✅ ${chainConfig.walletFactoryContractName} deployed at ${contract.target}`
Expand All @@ -132,7 +257,7 @@ async function main() {
const Forwarder = await ethers.getContractFactory(
chainConfig.forwarderContractName
);
const contract = await Forwarder.deploy(gasOverrides); // overrides only
const contract = await Forwarder.deploy(gasOverrides);
await contract.waitForDeployment();
console.log(
`✅ ${chainConfig.forwarderContractName} deployed at ${contract.target}`
Expand All @@ -157,7 +282,7 @@ async function main() {
const contract = await ForwarderFactory.deploy(
forwarderAddress,
gasOverrides
); // constructor args + overrides
);
await contract.waitForDeployment();
console.log(
`✅ ${chainConfig.forwarderFactoryContractName} deployed at ${contract.target}`
Expand Down
Loading
Loading