Skip to content
Merged
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
54 changes: 54 additions & 0 deletions solana/devnet/2025-10-23-deploy-bridge/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
RUST_TOOLCHAIN=1.87.0
SOLANA_VERSION=2.1.21
ANCHOR_VERSION=0.31.0

# Variables for cloning Bridge repo
BRIDGE_REPO=https://github.com/base/bridge.git
BRIDGE_COMMIT=24b6bcaec94eac34524bcd0774dd6ec14dc3bf21

# Variables for deploying and sending transactions
DEPLOY_ENV=testnet-alpha
DEPLOYER_KP=~/.config/solana/id.json

GAS_FEE_RECEIVER=AFs1LCbodhvwpgX3u3URLsud6R1XMSaMiQ5LtXw4GKYT

# Variables for initializing the Bridge Solana program
BRIDGE_PROGRAM_ID=7c6mteAcTXaQ1MFBCrnuzoZVTTAEfZwa6wgy4bqX3KXC
GUARDIAN=2N9nKVFPHsBVazniiYNxECB2nPLcwjk3dHAJH9tkr2xQ # MCM Authority
SOL_REMOTE_TOKEN=0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC
BRIDGE_EIP1559_TARGET=5_000_000
BRIDGE_EIP1559_DENOMINATOR=2
BRIDGE_EIP1559_WINDOW_DURATION_SECONDS=1
BRIDGE_EIP1559_MINIMUM_BASE_FEE=1
BRIDGE_GAS_PER_CALL=125_000
BRIDGE_GAS_COST_SCALER=1_000_000
BRIDGE_GAS_COST_SCALER_DP=1_000_000
BRIDGE_GAS_FEE_RECEIVER=$(GAS_FEE_RECEIVER)
BRIDGE_PROTOCOL_BLOCK_INTERVAL_REQUIREMENT=300
BRIDGE_BUFFER_MAX_CALL_BUFFER_SIZE=8192 # 8KB
BRIDGE_BASE_ORACLE_THRESHOLD=2
BRIDGE_BASE_ORACLE_SIGNER_COUNT=2
BRIDGE_BASE_ORACLE_SIGNERS=0xb03FAB6DEd1867a927Cd3E7026Aa0fe95dDb9715,0x7f7a481926dc754f5768691a17022c3fa548ed8b
BRIDGE_PARTNER_ORACLE_REQUIRED_THRESHOLD=0

# Variables for initializing the Base Relayer Solana program
BASE_RELAYER_PROGRAM_ID=56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H
GUARDIAN=2N9nKVFPHsBVazniiYNxECB2nPLcwjk3dHAJH9tkr2xQ # MCM Authority
BASE_RELAYER_EIP1559_TARGET=5_000_000
BASE_RELAYER_EIP1559_DENOMINATOR=2
BASE_RELAYER_EIP1559_WINDOW_DURATION_SECONDS=1
BASE_RELAYER_EIP1559_MINIMUM_BASE_FEE=1
BASE_RELAYER_MIN_GAS_LIMIT_PER_MESSAGE=100_000
BASE_RELAYER_MAX_GAS_LIMIT_PER_MESSAGE=5_000_000
BASE_RELAYER_GAS_COST_SCALER=1_000_000
BASE_RELAYER_GAS_COST_SCALER_DP=1_000_000
BASE_RELAYER_GAS_FEE_RECEIVER=$(GAS_FEE_RECEIVER)

# Variables for funding the SOL vault and the gas fee receiver
AUTHORITY=$(DEPLOYER_KP)
SOL_VAULT=4LS6xgoSn5Ed1UcJKJbwNSsyBQY2NX7H6nJcdt979c1A
SOL_AMOUNT=0.1

# Signatures of the set-upgrade-authority txs (used to generate the set-upgrade-authority artifacts)
SET_BRIDGE_UPGRADE_AUTHORITY_SIGNATURE=5i1CYwJDo9jFVLsBM2aQMkzwbr41QD68kFL5CBZru7cSr7AeXGyaF52PQnWjLX6oT2VLREuV4Pv5dPdNAM2EhLrB
SET_BASE_RELAYER_UPGRADE_AUTHORITY_SIGNATURE=2f3bUQpBaZjSjmLiThv5rTSqu9QXVtweitUJXHuDd2LREjm59HuBiNWrJAJQLsyy73Dbq7cfFLdAd2Dd2nJGXkXi
2 changes: 2 additions & 0 deletions solana/devnet/2025-10-23-deploy-bridge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bridge/
*keypair.json
163 changes: 163 additions & 0 deletions solana/devnet/2025-10-23-deploy-bridge/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
include ../.env
include .env

include ../../Makefile

.PHONY: install-rust
install-rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
rustup toolchain install $(RUST_TOOLCHAIN) && \
rustup default $(RUST_TOOLCHAIN)

.PHONY: install-solana-cli
install-solana-cli:
curl -sSfL https://release.anza.xyz/v$(SOLANA_VERSION)/install | sh

.PHONY: install-anchor
install-anchor:
cargo install --git https://github.com/coral-xyz/anchor --tag v$(ANCHOR_VERSION) anchor-cli --force

.PHONY: install-bun
install-bun:
curl -fsSL https://bun.sh/install | bash

.PHONY: setup-deps
setup-deps: install-rust install-solana-cli install-anchor install-bun

##
# Deployment Workflow
##

# Step 1: Clone and build bridge programs
.PHONY: step1-clone-bridge
step1-clone-bridge:
@echo "==> Step 1: Cloning and building bridge programs..."
rm -rf bridge
git clone --filter=blob:none $(BRIDGE_REPO) bridge
cd bridge && \
git checkout $(BRIDGE_COMMIT)
cd bridge/clients/ts && \
bun install && \
bun run build
cd bridge/scripts && \
bun install

# Step 2: Build programs
.PHONY: step2-build-programs
step2-build-programs:
@echo "==> Step 2: Building bridge programs..."
cd bridge/solana && \
anchor keys sync && \
cp target/deploy/bridge-keypair.json ../../bridge-keypair.json && \
cp target/deploy/base_relayer-keypair.json ../../base_relayer-keypair.json
cd bridge/scripts && \
bun cli sol build \
--deploy-env $(DEPLOY_ENV) \
--bridge-program-kp ../../bridge-keypair.json \
--base-relayer-program-kp ../../base_relayer-keypair.json

# Step 3: Deploy programs
.PHONY: step3-deploy-programs
step3-deploy-programs:
@echo "==> Step 3: Deploying programs..."
make sol-confirm-cmd \
cmd="cd bridge/scripts && \
bun cli sol deploy \
--deploy-env $(DEPLOY_ENV) \
--program bridge \
--program-kp ../../bridge-keypair.json \
--deployer-kp $(DEPLOYER_KP)" \
output=artifacts/bridge-deploy-artifacts.json
make sol-confirm-cmd \
cmd="cd bridge/scripts && \
bun cli sol deploy \
--deploy-env $(DEPLOY_ENV) \
--program base-relayer \
--program-kp ../../base_relayer-keypair.json \
--deployer-kp $(DEPLOYER_KP)" \
output=artifacts/base-relayer-deploy-artifacts.json

# Step 4: Initialize programs
.PHONY: step4-init-programs
step4-init-programs:
@echo "==> Step 4: Initializing programs..."
make sol-confirm-cmd \
cmd="cd bridge/scripts && \
bun cli sol bridge initialize \
--program-id $(BRIDGE_PROGRAM_ID) \
--rpc-url $(SOL_RPC_URL) \
--payer-kp $(DEPLOYER_KP) \
--guardian $(GUARDIAN) \
--remote-sol-address $(SOL_REMOTE_TOKEN) \
--eip1559-target $(BRIDGE_EIP1559_TARGET) \
--eip1559-denominator $(BRIDGE_EIP1559_DENOMINATOR) \
--eip1559-window-duration-seconds $(BRIDGE_EIP1559_WINDOW_DURATION_SECONDS) \
--eip1559-minimum-base-fee $(BRIDGE_EIP1559_MINIMUM_BASE_FEE) \
--gas-per-call $(BRIDGE_GAS_PER_CALL) \
--gas-cost-scaler $(BRIDGE_GAS_COST_SCALER) \
--gas-cost-scaler-dp $(BRIDGE_GAS_COST_SCALER_DP) \
--gas-fee-receiver $(BRIDGE_GAS_FEE_RECEIVER) \
--protocol-block-interval-requirement $(BRIDGE_PROTOCOL_BLOCK_INTERVAL_REQUIREMENT) \
--buffer-max-call-buffer-size $(BRIDGE_BUFFER_MAX_CALL_BUFFER_SIZE) \
--base-oracle-threshold $(BRIDGE_BASE_ORACLE_THRESHOLD) \
--base-oracle-signer-count $(BRIDGE_BASE_ORACLE_SIGNER_COUNT) \
--base-oracle-signers $(BRIDGE_BASE_ORACLE_SIGNERS) \
--partner-oracle-required-threshold $(BRIDGE_PARTNER_ORACLE_REQUIRED_THRESHOLD)" \
output=artifacts/init-bridge.json
make sol-confirm-cmd \
cmd="cd bridge/scripts && \
bun cli sol base-relayer initialize \
--program-id $(BASE_RELAYER_PROGRAM_ID) \
--rpc-url $(SOL_RPC_URL) \
--payer-kp $(DEPLOYER_KP) \
--guardian $(GUARDIAN) \
--eip1559-target $(BASE_RELAYER_EIP1559_TARGET) \
--eip1559-denominator $(BASE_RELAYER_EIP1559_DENOMINATOR) \
--eip1559-window-duration-seconds $(BASE_RELAYER_EIP1559_WINDOW_DURATION_SECONDS) \
--eip1559-minimum-base-fee $(BASE_RELAYER_EIP1559_MINIMUM_BASE_FEE) \
--min-gas-limit-per-message $(BASE_RELAYER_MIN_GAS_LIMIT_PER_MESSAGE) \
--max-gas-limit-per-message $(BASE_RELAYER_MAX_GAS_LIMIT_PER_MESSAGE) \
--gas-cost-scaler $(BASE_RELAYER_GAS_COST_SCALER) \
--gas-cost-scaler-dp $(BASE_RELAYER_GAS_COST_SCALER_DP) \
--gas-fee-receiver $(BASE_RELAYER_GAS_FEE_RECEIVER)" \
output=artifacts/init-base-relayer.json

# Step 5: Print SOL vault
.PHONY: step5-print-sol-vault
step5-print-sol-vault:
@echo "==> Step 5: Printing SOL vault..."
cd bridge/scripts && \
bun cli sol bridge sol-vault \
--bridge-program $(BRIDGE_PROGRAM_ID)

# Step 6: Fund SOL vault
.PHONY: step6-fund-sol-vault
step6-fund-sol-vault:
@echo "==> Step 6: Funding SOL vault..."
make sol-transfer SOL_RECIPIENT=$(SOL_VAULT) output=artifacts/fund-sol-vault.json

# Step 7: Fund the gas fee receiver
.PHONY: step7-fund-gas-fee-receiver
step7-fund-gas-fee-receiver:
@echo "==> Step 7: Funding gas fee receiver..."
make sol-transfer SOL_RECIPIENT=$(GAS_FEE_RECEIVER) output=artifacts/fund-gas-fee-receiver.json

# Step 8: Transfer upgrade authorities of the bridge and base relayer programs
.PHONY: step8-transfer-upgrade-authorities
step8-transfer-upgrade-authorities:
@echo "==> Step 8: Transferring upgrade authorities of the bridge and base relayer programs..."
make sol-program-set-upgrade-authority \
SOL_PROGRAM_ID=$(BRIDGE_PROGRAM_ID) \
NEW_UPGRADE_AUTHORITY=$(GUARDIAN)
make sol-program-show SOL_PROGRAM_ID=$(BRIDGE_PROGRAM_ID)
make sol-program-set-upgrade-authority \
SOL_PROGRAM_ID=$(BASE_RELAYER_PROGRAM_ID) \
NEW_UPGRADE_AUTHORITY=$(GUARDIAN)
make sol-program-show SOL_PROGRAM_ID=$(BASE_RELAYER_PROGRAM_ID)

# Step 9: Generate set-upgrade-authority artifacts (use solana explorer to get the signature of the set-upgrade-authority tx)
.PHONY: step9-generate-set-upgrade-authorities-artifacts
step9-generate-set-upgrade-authorities-artifacts:
@echo "==> Step 8: Generating set-upgrade-authorities artifacts..."
make sol-confirm SIG=$(SET_BRIDGE_UPGRADE_AUTHORITY_SIGNATURE) output=artifacts/set-bridge-upgrade-authority-artifacts.json
make sol-confirm SIG=$(SET_BASE_RELAYER_UPGRADE_AUTHORITY_SIGNATURE) output=artifacts/set-base-relayer-upgrade-authority-artifacts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"confirmationStatus": "confirmed",
"transaction": {
"signatures": [
"2k59UnU4dQkXGdebaSrPX95QzXZNqbHEqqC7qzLitrydi1MYw5NbV9q1xdMTe976wTistASd6Lvn8ccHXbDnaKRL",
"4V15b7Bf28HwhU5WKnkPSnzVACQ9E1KdxcgXxNC9C91mjcUGDnsXbQbCfBK9HnTcfEQpRFN14NdadZn9iX68HQHY"
],
"message": {
"header": {
"numRequiredSignatures": 2,
"numReadonlySignedAccounts": 0,
"numReadonlyUnsignedAccounts": 4
},
"accountKeys": [
"2aWsUTRfJu2hPNUYHaYJjm6C3SVPqXjtoxu2VgBXsd72",
"56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H",
"9mUcnyK4TVwHoMkyVCTiVFqWDUuRqHoAJP32pxSXCTjP",
"De6pBEXUw4DiJ9zFzfdM69BDxU8F7rVrcV3tRVhDSWc4",
"11111111111111111111111111111111",
"BPFLoaderUpgradeab1e11111111111111111111111",
"SysvarC1ock11111111111111111111111111111111",
"SysvarRent111111111111111111111111111111111"
],
"recentBlockhash": "FAh2wWUXeWPnuMKPi7L2DdKxrxBrbJaZndoeCZuxz6mb",
"instructions": [
{
"programIdIndex": 4,
"accounts": [
0,
1
],
"data": "111184NuZo7gmbjwda8fGAim94roEJcdbYKd7Gdtpi6CbBByeanCr8u4EAFXLjnY2U8bjD",
"stackHeight": null
},
{
"programIdIndex": 5,
"accounts": [
0,
2,
1,
3,
7,
6,
4,
0
],
"data": "3Bxs42J4x6iEtSZM",
"stackHeight": null
}
]
}
},
"meta": {
"err": null,
"status": {
"Ok": null
},
"fee": 10000,
"preBalances": [
169019364280,
0,
0,
2098391280,
1,
1,
1169280,
1009200
],
"postBalances": [
169018212840,
1141440,
2098391280,
0,
1,
1,
1169280,
1009200
],
"innerInstructions": [
{
"index": 1,
"instructions": [
{
"programIdIndex": 4,
"accounts": [
0,
2,
3
],
"data": "11119qYqhtqT5NHTm27UYqYVeF4Lm2dwfwCnPkVvZ6nWdk5kZP2tzGt1VBLLyRd9W8hoWf",
"stackHeight": 2
}
]
}
],
"logMessages": [
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success",
"Program BPFLoaderUpgradeab1e11111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Deployed program 56MBBEYAtQAdjT4e1NzHD8XaoyRSTvfgbSVVcEcHj51H",
"Program BPFLoaderUpgradeab1e11111111111111111111111 success"
],
"preTokenBalances": [],
"postTokenBalances": [],
"rewards": [],
"loadedAddresses": {
"writable": [],
"readonly": []
},
"computeUnitsConsumed": 2670
},
"blockTime": 1761256231,
"slot": 416638064
}
Loading