Add Oracle Aggregator and CCIP Integration
- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
This commit is contained in:
85
scripts/ccip-deployment/deploy-all-ccip-mainnet.sh
Executable file
85
scripts/ccip-deployment/deploy-all-ccip-mainnet.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Deploy all CCIP contracts to Ethereum Mainnet
|
||||
# This script deploys CCIPLogger which receives Chain-138 transactions
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/../lib/init.sh"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
|
||||
# Load environment variables
|
||||
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||
source "$PROJECT_ROOT/.env"
|
||||
else
|
||||
log_error "Error: .env file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "=== Deploying CCIP Contracts to Ethereum Mainnet ==="
|
||||
|
||||
# Check prerequisites
|
||||
if [ -z "$PRIVATE_KEY" ]; then
|
||||
log_error "Error: PRIVATE_KEY not set in .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$ETHEREUM_MAINNET_RPC" ]; then
|
||||
log_warn "Warning: ETHEREUM_MAINNET_RPC not set, using default"
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
CCIP_ETH_ROUTER="${CCIP_ETH_ROUTER:-0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D}"
|
||||
AUTHORIZED_SIGNER="${AUTHORIZED_SIGNER:-}"
|
||||
CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-0x000000000000008a}"
|
||||
|
||||
echo "Configuration:"
|
||||
echo " CCIP Router (Ethereum): $CCIP_ETH_ROUTER"
|
||||
echo " Authorized Signer: ${AUTHORIZED_SIGNER:-Not set (optional)}"
|
||||
echo " Chain-138 Selector: $CHAIN138_SELECTOR"
|
||||
|
||||
# Deploy CCIPLogger
|
||||
log_warn "Deploying CCIPLogger..."
|
||||
export CCIP_ETH_ROUTER
|
||||
export AUTHORIZED_SIGNER
|
||||
export CHAIN138_SELECTOR
|
||||
|
||||
npx hardhat run scripts/ccip-deployment/deploy-ccip-logger.js --network mainnet
|
||||
|
||||
CCIP_LOGGER_ADDRESS=$(grep "CCIPLogger deployed to:" <<< "$(npx hardhat run scripts/ccip-deployment/deploy-ccip-logger.js --network mainnet 2>&1)" | awk '{print $NF}')
|
||||
|
||||
if [ -z "$CCIP_LOGGER_ADDRESS" ]; then
|
||||
log_error "Error: Failed to extract CCIPLogger address"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "✅ CCIPLogger deployed: $CCIP_LOGGER_ADDRESS"
|
||||
|
||||
# Update .env
|
||||
log_warn "Updating .env file..."
|
||||
if grep -q "CCIP_LOGGER_ETH_ADDRESS=" "$PROJECT_ROOT/.env"; then
|
||||
sed -i "s|CCIP_LOGGER_ETH_ADDRESS=.*|CCIP_LOGGER_ETH_ADDRESS=$CCIP_LOGGER_ADDRESS|" "$PROJECT_ROOT/.env"
|
||||
else
|
||||
echo "CCIP_LOGGER_ETH_ADDRESS=$CCIP_LOGGER_ADDRESS" >> "$PROJECT_ROOT/.env"
|
||||
fi
|
||||
|
||||
if ! grep -q "CCIP_ETH_ROUTER=" "$PROJECT_ROOT/.env"; then
|
||||
echo "CCIP_ETH_ROUTER=$CCIP_ETH_ROUTER" >> "$PROJECT_ROOT/.env"
|
||||
fi
|
||||
|
||||
if ! grep -q "CHAIN138_SELECTOR=" "$PROJECT_ROOT/.env"; then
|
||||
echo "CHAIN138_SELECTOR=$CHAIN138_SELECTOR" >> "$PROJECT_ROOT/.env"
|
||||
fi
|
||||
|
||||
log_success "✅ .env file updated"
|
||||
|
||||
log_info "=== Deployment Summary ==="
|
||||
echo "Deployed Contracts:"
|
||||
echo " CCIPLogger: $CCIP_LOGGER_ADDRESS"
|
||||
echo "Next Steps:"
|
||||
echo " 1. Verify contract on Etherscan"
|
||||
echo " 2. Deploy CCIPTxReporter to Chain-138"
|
||||
echo " 3. Configure watcher/relayer service"
|
||||
echo " 4. Start monitoring"
|
||||
55
scripts/ccip-deployment/deploy-ccip-logger.js
Executable file
55
scripts/ccip-deployment/deploy-ccip-logger.js
Executable file
@@ -0,0 +1,55 @@
|
||||
const { ethers } = require("hardhat");
|
||||
require("dotenv").config();
|
||||
|
||||
/**
|
||||
* Deploy CCIPLogger to Ethereum Mainnet
|
||||
* This contract receives and logs Chain-138 transactions via CCIP
|
||||
*/
|
||||
async function main() {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log("Deploying CCIPLogger with account:", deployer.address);
|
||||
console.log("Account balance:", (await ethers.provider.getBalance(deployer.address)).toString());
|
||||
|
||||
// Get configuration from environment
|
||||
const routerAddress = process.env.CCIP_ETH_ROUTER || "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D"; // Official Chainlink CCIP Router on Mainnet
|
||||
const authorizedSigner = process.env.AUTHORIZED_SIGNER || ethers.ZeroAddress;
|
||||
const sourceChainSelector = process.env.CHAIN138_SELECTOR || "0x000000000000008a"; // Chain-138 selector (update with actual value from CCIP Directory)
|
||||
|
||||
console.log("\nConfiguration:");
|
||||
console.log(" Router:", routerAddress);
|
||||
console.log(" Authorized Signer:", authorizedSigner);
|
||||
console.log(" Source Chain Selector:", sourceChainSelector);
|
||||
|
||||
// Deploy CCIPLogger
|
||||
const CCIPLogger = await ethers.getContractFactory("CCIPLogger");
|
||||
console.log("\nDeploying CCIPLogger...");
|
||||
|
||||
const logger = await CCIPLogger.deploy(
|
||||
routerAddress,
|
||||
authorizedSigner,
|
||||
sourceChainSelector
|
||||
);
|
||||
|
||||
await logger.waitForDeployment();
|
||||
const loggerAddress = await logger.getAddress();
|
||||
|
||||
console.log("\n✅ CCIPLogger deployed to:", loggerAddress);
|
||||
console.log("\nDeployment details:");
|
||||
console.log(" Router:", await logger.getRouter());
|
||||
console.log(" Authorized Signer:", await logger.authorizedSigner());
|
||||
console.log(" Source Chain Selector:", await logger.expectedSourceChainSelector());
|
||||
console.log(" Owner:", await logger.owner());
|
||||
|
||||
console.log("\n📝 Next steps:");
|
||||
console.log(" 1. Verify contract on Etherscan:");
|
||||
console.log(` npx hardhat verify --network mainnet ${loggerAddress} "${routerAddress}" "${authorizedSigner}" "${sourceChainSelector}"`);
|
||||
console.log(" 2. Update .env with CCIP_LOGGER_ETH_ADDRESS=" + loggerAddress);
|
||||
console.log(" 3. Deploy CCIPTxReporter to Chain-138 with this address as destination");
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
63
scripts/ccip-deployment/deploy-ccip-reporter.js
Executable file
63
scripts/ccip-deployment/deploy-ccip-reporter.js
Executable file
@@ -0,0 +1,63 @@
|
||||
const { ethers } = require("hardhat");
|
||||
require("dotenv").config();
|
||||
|
||||
/**
|
||||
* Deploy CCIPTxReporter to Chain-138
|
||||
* This contract reports Chain-138 transactions to Ethereum Mainnet via CCIP
|
||||
*/
|
||||
async function main() {
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log("Deploying CCIPTxReporter with account:", deployer.address);
|
||||
console.log("Account balance:", (await ethers.provider.getBalance(deployer.address)).toString());
|
||||
|
||||
// Get configuration from environment
|
||||
const routerAddress = process.env.CCIP_CHAIN138_ROUTER || process.env.CCIP_ROUTER || ethers.ZeroAddress;
|
||||
const destChainSelector = process.env.ETH_MAINNET_SELECTOR || "0x500147"; // Ethereum Mainnet selector (update with actual value from CCIP Directory)
|
||||
const destReceiver = process.env.CCIP_LOGGER_ETH_ADDRESS || ethers.ZeroAddress;
|
||||
|
||||
if (routerAddress === ethers.ZeroAddress) {
|
||||
throw new Error("CCIP_ROUTER or CCIP_CHAIN138_ROUTER must be set in .env");
|
||||
}
|
||||
if (destReceiver === ethers.ZeroAddress) {
|
||||
throw new Error("CCIP_LOGGER_ETH_ADDRESS must be set in .env (deploy CCIPLogger first)");
|
||||
}
|
||||
|
||||
console.log("\nConfiguration:");
|
||||
console.log(" Router (Chain-138):", routerAddress);
|
||||
console.log(" Destination Chain Selector (Ethereum):", destChainSelector);
|
||||
console.log(" Destination Receiver (CCIPLogger):", destReceiver);
|
||||
|
||||
// Deploy CCIPTxReporter
|
||||
const CCIPTxReporter = await ethers.getContractFactory("CCIPTxReporter");
|
||||
console.log("\nDeploying CCIPTxReporter...");
|
||||
|
||||
const reporter = await CCIPTxReporter.deploy(
|
||||
routerAddress,
|
||||
destChainSelector,
|
||||
destReceiver
|
||||
);
|
||||
|
||||
await reporter.waitForDeployment();
|
||||
const reporterAddress = await reporter.getAddress();
|
||||
|
||||
console.log("\n✅ CCIPTxReporter deployed to:", reporterAddress);
|
||||
console.log("\nDeployment details:");
|
||||
console.log(" Router:", await reporter.router());
|
||||
console.log(" Destination Chain Selector:", await reporter.destChainSelector());
|
||||
console.log(" Destination Receiver:", await reporter.destReceiver());
|
||||
console.log(" Owner:", await reporter.owner());
|
||||
|
||||
console.log("\n📝 Next steps:");
|
||||
console.log(" 1. Verify contract on Chain-138 explorer (if available)");
|
||||
console.log(" 2. Update .env with CCIP_REPORTER_CHAIN138_ADDRESS=" + reporterAddress);
|
||||
console.log(" 3. Fund the contract with ETH for CCIP fees");
|
||||
console.log(" 4. Start the watcher/relayer service");
|
||||
console.log(" 5. Test with a sample transaction report");
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await hre.ethers.getSigners();
|
||||
console.log("Deploying CCIPWETH10Bridge to Chain-138 with account:", deployer.address);
|
||||
|
||||
const CCIPRouter = process.env.CCIP_CHAIN138_ROUTER || "";
|
||||
const WETH10 = process.env.WETH10_ADDRESS || "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f";
|
||||
const MainnetSelector = process.env.MAINNET_SELECTOR || "5009297550715157269";
|
||||
|
||||
if (!CCIPRouter) {
|
||||
throw new Error("CCIP_CHAIN138_ROUTER environment variable not set");
|
||||
}
|
||||
|
||||
const CCIPWETH10Bridge = await hre.ethers.getContractFactory("CCIPWETH10Bridge");
|
||||
const bridge = await CCIPWETH10Bridge.deploy(CCIPRouter, WETH10, MainnetSelector);
|
||||
|
||||
await bridge.waitForDeployment();
|
||||
const address = await bridge.getAddress();
|
||||
console.log("CCIPWETH10Bridge deployed to Chain-138 at:", address);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
31
scripts/ccip-deployment/deploy-ccip-weth10-bridge-mainnet.js
Normal file
31
scripts/ccip-deployment/deploy-ccip-weth10-bridge-mainnet.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await hre.ethers.getSigners();
|
||||
console.log("Deploying CCIPWETH10Bridge to Mainnet with account:", deployer.address);
|
||||
|
||||
const CCIPRouter = process.env.CCIP_ETH_ROUTER || "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D";
|
||||
const WETH10 = process.env.WETH10_ADDRESS || "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f";
|
||||
const Chain138Selector = process.env.CHAIN138_SELECTOR || "0x000000000000000000000000000000000000008A";
|
||||
|
||||
const CCIPWETH10Bridge = await hre.ethers.getContractFactory("CCIPWETH10Bridge");
|
||||
const bridge = await CCIPWETH10Bridge.deploy(CCIPRouter, WETH10, Chain138Selector);
|
||||
|
||||
await bridge.waitForDeployment();
|
||||
const address = await bridge.getAddress();
|
||||
console.log("CCIPWETH10Bridge deployed to:", address);
|
||||
|
||||
// Verify on Etherscan
|
||||
if (process.env.ETHERSCAN_API_KEY) {
|
||||
console.log("Verifying on Etherscan...");
|
||||
await hre.run("verify:verify", {
|
||||
address: address,
|
||||
constructorArguments: [CCIPRouter, WETH10, Chain138Selector],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
26
scripts/ccip-deployment/deploy-ccip-weth9-bridge-chain138.js
Normal file
26
scripts/ccip-deployment/deploy-ccip-weth9-bridge-chain138.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await hre.ethers.getSigners();
|
||||
console.log("Deploying CCIPWETH9Bridge to Chain-138 with account:", deployer.address);
|
||||
|
||||
const CCIPRouter = process.env.CCIP_CHAIN138_ROUTER || "";
|
||||
const WETH9 = process.env.WETH9_ADDRESS || "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
|
||||
const MainnetSelector = process.env.MAINNET_SELECTOR || "5009297550715157269";
|
||||
|
||||
if (!CCIPRouter) {
|
||||
throw new Error("CCIP_CHAIN138_ROUTER environment variable not set");
|
||||
}
|
||||
|
||||
const CCIPWETH9Bridge = await hre.ethers.getContractFactory("CCIPWETH9Bridge");
|
||||
const bridge = await CCIPWETH9Bridge.deploy(CCIPRouter, WETH9, MainnetSelector);
|
||||
|
||||
await bridge.waitForDeployment();
|
||||
const address = await bridge.getAddress();
|
||||
console.log("CCIPWETH9Bridge deployed to Chain-138 at:", address);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
31
scripts/ccip-deployment/deploy-ccip-weth9-bridge-mainnet.js
Normal file
31
scripts/ccip-deployment/deploy-ccip-weth9-bridge-mainnet.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
const [deployer] = await hre.ethers.getSigners();
|
||||
console.log("Deploying CCIPWETH9Bridge to Mainnet with account:", deployer.address);
|
||||
|
||||
const CCIPRouter = process.env.CCIP_ETH_ROUTER || "0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D";
|
||||
const WETH9 = process.env.WETH9_ADDRESS || "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
|
||||
const Chain138Selector = process.env.CHAIN138_SELECTOR || "0x000000000000000000000000000000000000008A";
|
||||
|
||||
const CCIPWETH9Bridge = await hre.ethers.getContractFactory("CCIPWETH9Bridge");
|
||||
const bridge = await CCIPWETH9Bridge.deploy(CCIPRouter, WETH9, Chain138Selector);
|
||||
|
||||
await bridge.waitForDeployment();
|
||||
const address = await bridge.getAddress();
|
||||
console.log("CCIPWETH9Bridge deployed to:", address);
|
||||
|
||||
// Verify on Etherscan
|
||||
if (process.env.ETHERSCAN_API_KEY) {
|
||||
console.log("Verifying on Etherscan...");
|
||||
await hre.run("verify:verify", {
|
||||
address: address,
|
||||
constructorArguments: [CCIPRouter, WETH9, Chain138Selector],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in New Issue
Block a user