Skip to content

build(hub-contracts): fully automated deploy script #1029

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 19, 2025
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
31 changes: 31 additions & 0 deletions packages/network-contracts/scripts/hub/deployHubContracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euxo pipefail

if declare -p KEY >/dev/null 2>&1; then
echo "Using deployer private key from environment variable KEY"
else
read -p "Enter deployer private key: " KEY
export KEY="$KEY"
fi

if declare -p CHAIN >/dev/null 2>&1; then
echo "Using chain from environment variable CHAIN"
else
read -p "Enter chain: " CHAIN
export CHAIN="$CHAIN"
fi

OUTPUT_FILE=project-registry-address.txt npx hardhat run --network $CHAIN scripts/hub/deployProjectRegistry.ts
export PROJECT_REGISTRY_ADDRESS=$(cat project-registry-address.txt)
OUTPUT_FILE=project-staking-address.txt npx hardhat run --network $CHAIN scripts/hub/deployProjectStakingV1.ts
OUTPUT_FILE=marketplace-address.txt npx hardhat run --network $CHAIN scripts/hub/deployMarketplaceV4.ts
set +x
echo "{"
echo " \"ProjectRegistryV1\": \"$PROJECT_REGISTRY_ADDRESS\","
echo " \"MarketplaceV4\": \"$(cat marketplace-address.txt)\","
echo " \"ProjectStakingV1\": \"$(cat project-staking-address.txt)\""
echo "}"

rm project-registry-address.txt
rm project-staking-address.txt
rm marketplace-address.txt
29 changes: 22 additions & 7 deletions packages/network-contracts/scripts/hub/deployMarketplaceV4.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable quotes */
import { writeFileSync } from "fs"
import { ethers as hardhatEthers, upgrades } from "hardhat"
import { config } from "@streamr/config"
import { utils } from "ethers"
Expand All @@ -10,15 +11,21 @@ const { log } = console

const {
CHAIN = 'dev1',
PROJECT_REGISTRY_ADDRESS,
OUTPUT_FILE,
} = process.env

const {
id: CHAIN_ID,
contracts: {
ProjectRegistryV1: PROJECT_REGISTRY_ADDRESS,
ProjectRegistryV1: PROJECT_REGISTRY_ADDRESS_FROM_CONFIG,
}
} = (config as any)[CHAIN]
if (!PROJECT_REGISTRY_ADDRESS) { throw new Error(`No ProjectRegistryV1 found in chain "${CHAIN}"`) }

const projectRegistryAddress = PROJECT_REGISTRY_ADDRESS || PROJECT_REGISTRY_ADDRESS_FROM_CONFIG
if (!projectRegistryAddress) {
throw new Error(`No ProjectRegistryV1 found in chain "${CHAIN}", please supply it in env variable PROJECT_REGISTRY_ADDRESS`)
}

const interchainMailbox = chainToMailboxAddress(CHAIN)

Expand All @@ -28,10 +35,10 @@ const interchainMailbox = chainToMailboxAddress(CHAIN)
*/
async function main() {
log(`Deploying MarketplaceV4 to ${CHAIN}:`)
log(` - project registry address: ${PROJECT_REGISTRY_ADDRESS}`)
log(` - project registry address: ${projectRegistryAddress}`)

const projectRegistryFactory = await getContractFactory("ProjectRegistryV1")
const projectRegistryFactoryTx = await projectRegistryFactory.attach(PROJECT_REGISTRY_ADDRESS)
const projectRegistryFactoryTx = await projectRegistryFactory.attach(projectRegistryAddress)
const projectRegistry = await projectRegistryFactoryTx.deployed()
log("ProjectRegistryV1 attached at: ", projectRegistry.address)

Expand All @@ -41,11 +48,19 @@ async function main() {
await marketplace.deployed()
log(`MarketplaceV4 deployed on ${CHAIN} at: ${marketplace.address}`)

await marketplace.addMailbox(interchainMailbox)
log(`MarketplaceV4 added interchain mailbox: ${interchainMailbox}`)

try {
await (await marketplace.addMailbox(interchainMailbox)).wait()
log(`MarketplaceV4 added interchain mailbox: ${interchainMailbox}`)
} catch (error) {
log(`Error when setting interchain mailbox: ${error}`)
}
await projectRegistry.grantRole(id("TRUSTED_ROLE"), marketplace.address)
log(`ProjectRegistry granted trusted role to MarketplaceV4.`)

if (OUTPUT_FILE) {
writeFileSync(OUTPUT_FILE, marketplace.address)
log(`MarketplaceV4 address written to ${OUTPUT_FILE}`)
}
}

main().catch((error) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
/* eslint-disable quotes */
import { writeFileSync } from "fs"

import { ethers as hhEthers, upgrades } from "hardhat"
import { config } from "@streamr/config"

const { log } = console

const {
CHAIN = 'dev1',
OUTPUT_FILE,
} = process.env

const {
Expand All @@ -28,6 +31,11 @@ async function main() {
const projectRegistryFactoryTx = await upgrades.deployProxy(projectRegistryFactory, [STREAM_REGISTRY_ADDRESS], { kind: 'uups' })
const projectRegistry = await projectRegistryFactoryTx.deployed()
log(`ProjectRegistryV1 deployed at: ${projectRegistry.address}`)

if (OUTPUT_FILE) {
writeFileSync(OUTPUT_FILE, projectRegistry.address)
log(`ProjectRegistryV1 address written to ${OUTPUT_FILE}`)
}
}

main().catch((error) => {
Expand Down
21 changes: 17 additions & 4 deletions packages/network-contracts/scripts/hub/deployProjectStakingV1.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,50 @@
/* eslint-disable quotes */
import { writeFileSync } from "fs"

import { ethers as hhEthers, upgrades } from "hardhat"
import { config } from "@streamr/config"

const { log } = console

const {
CHAIN = 'dev1',
PROJECT_REGISTRY_ADDRESS,
OUTPUT_FILE,
} = process.env

const {
contracts: {
DATA: STAKING_TOKEN_ADDRESS, // LINK dev1 - 0x3387F44140ea19100232873a5aAf9E46608c791E
ProjectRegistryV1: PROJECT_REGISTRY_ADDRESS,
ProjectRegistryV1: PROJECT_REGISTRY_ADDRESS_FROM_CONFIG,
}
} = (config as any)[CHAIN]

if (!PROJECT_REGISTRY_ADDRESS) { throw new Error(`No ProjectRegistryV1 found in chain "${CHAIN}"`) }
const projectRegistryAddress = PROJECT_REGISTRY_ADDRESS || PROJECT_REGISTRY_ADDRESS_FROM_CONFIG

if (!projectRegistryAddress) {
throw new Error(`No ProjectRegistryV1 found in chain "${CHAIN}", please supply it in env variable PROJECT_REGISTRY_ADDRESS`)
}

/**
* npx hardhat run --network dev1 scripts/deployProjectStakingV1.ts
* npx hardhat flatten contracts/ProjectStaking/ProjectStakingV1.sol > ps.sol
*/
async function main() {
log(`ProjectRegistryV1 address: ${PROJECT_REGISTRY_ADDRESS}`)
log(`ProjectRegistryV1 address: ${projectRegistryAddress}`)
log(`Staking token address: ${STAKING_TOKEN_ADDRESS}`)
log(`Deploying ProjectStakingV1 to "${CHAIN}" chain:`)
const projectStakingFactory = await hhEthers.getContractFactory("ProjectStakingV1")
const projectStakingFactoryTx = await upgrades.deployProxy(projectStakingFactory, [
PROJECT_REGISTRY_ADDRESS,
projectRegistryAddress,
STAKING_TOKEN_ADDRESS
], { kind: 'uups' })
const projectStaking = await projectStakingFactoryTx.deployed()
log(`ProjectStakingV1 deployed at: ${projectStaking.address}`)

if (OUTPUT_FILE) {
writeFileSync(OUTPUT_FILE, projectStaking.address)
log(`ProjectStakingV1 address written to ${OUTPUT_FILE}`)
}
}

main().catch((error) => {
Expand Down
12 changes: 10 additions & 2 deletions packages/network-contracts/scripts/hub/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable quotes */
const testnet = ['alfajores', 'fuji', 'goerli', 'optGoerli', 'arbGoerli', 'polygonAmoy', 'peaq']
const mainnet = ['celo', 'avalanche', 'polygon', 'gnosis', 'ethereum', 'optimism', 'arbitrum']
const testnet = ['alfajores', 'fuji', 'goerli', 'optGoerli', 'arbGoerli', 'polygonAmoy', 'dev2']
const mainnet = ['celo', 'avalanche', 'polygon', 'gnosis', 'ethereum', 'optimism', 'arbitrum', 'peaq', 'iotex']

/**
* Maps the chain name to a unique hyperlane domain id
Expand All @@ -27,6 +27,12 @@ export function chainToDomainId(name: string): number {
return 8995
case 'dev1':
return 8997
case 'dev2':
return 31337
case 'iotex':
return 4689
case 'peaq':
return 3338
default:
throw new Error(`Unknown domain id for the given chain name (${name}).`)
}
Expand Down Expand Up @@ -103,6 +109,8 @@ export function chainToEthereumRpcUrl(name: string): string {
return `https://avalanche-fuji.infura.io/v3/${process.env.FUJI_API_KEY}`
case 'dev1':
return 'http://10.200.10.1:8546'
case 'dev2':
return 'http://10.200.10.1:8547'

default:
throw new Error('Unknown ethereum RPC URL for the given chain name.')
Expand Down