Skip to content

Commit 4799228

Browse files
authored
Merge pull request #1094 from graphprotocol/tmigone/tooling-improvements
2 parents c3c94ca + ea21739 commit 4799228

File tree

17 files changed

+184
-113
lines changed

17 files changed

+184
-113
lines changed

packages/hardhat-graph-protocol/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"json5": "^2.2.3"
4848
},
4949
"devDependencies": {
50+
"@nomicfoundation/hardhat-verify": "^2.0.12",
5051
"@types/chai": "^4.0.0",
5152
"@types/debug": "^4.1.12",
5253
"@types/mocha": "^10.0.9",
@@ -55,6 +56,7 @@
5556
"eslint-graph-config": "workspace:^0.0.1",
5657
"ethers": "^6.13.4",
5758
"hardhat": "^2.22.16",
59+
"hardhat-secure-accounts": "^1.0.4",
5860
"mocha": "^10.8.2",
5961
"ts-node": "^8.0.0",
6062
"typescript": "^5.6.3"
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { vars } from 'hardhat/config'
2+
3+
import type { HardhatUserConfig, NetworksUserConfig, ProjectPathsUserConfig, SolidityUserConfig } from 'hardhat/types'
4+
import type { EtherscanConfig } from '@nomicfoundation/hardhat-verify/types'
5+
6+
// This next import ensures secure accounts config is correctly typed
7+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8+
import type { SecureAccountsOptions } from 'hardhat-secure-accounts/src/type-extensions'
9+
10+
// Environment variables
11+
const ARBISCAN_API_KEY = vars.get('ARBISCAN_API_KEY', undefined)
12+
13+
// RPCs
14+
const VIRTUAL_ARBITRUM_SEPOLIA_RPC = vars.has('VIRTUAL_ARBITRUM_SEPOLIA_RPC') ? vars.get('VIRTUAL_ARBITRUM_SEPOLIA_RPC') : undefined
15+
const ARBITRUM_SEPOLIA_RPC = vars.get('ARBITRUM_SEPOLIA_RPC', 'https://sepolia-rollup.arbitrum.io/rpc')
16+
17+
// Accounts
18+
const DEPLOYER_PRIVATE_KEY = vars.get('DEPLOYER_PRIVATE_KEY', undefined)
19+
const GOVERNOR_PRIVATE_KEY = vars.get('GOVERNOR_PRIVATE_KEY', undefined)
20+
const getTestnetAccounts = () => {
21+
const accounts: string[] = []
22+
if (DEPLOYER_PRIVATE_KEY) accounts.push(DEPLOYER_PRIVATE_KEY)
23+
if (GOVERNOR_PRIVATE_KEY) accounts.push(GOVERNOR_PRIVATE_KEY)
24+
return accounts.length > 0 ? accounts : undefined
25+
}
26+
const getHardhatAccounts = () => {
27+
return {
28+
mnemonic: 'myth like bonus scare over problem client lizard pioneer submit female collect',
29+
}
30+
}
31+
32+
export const solidityUserConfig: SolidityUserConfig = {
33+
version: '0.8.27',
34+
settings: {
35+
optimizer: {
36+
enabled: true,
37+
runs: 1,
38+
},
39+
},
40+
}
41+
42+
export const projectPathsUserConfig: ProjectPathsUserConfig = {
43+
artifacts: './build/contracts',
44+
sources: './contracts',
45+
}
46+
47+
export const etherscanUserConfig: Partial<EtherscanConfig> = {
48+
apiKey: {
49+
arbitrumSepolia: ARBISCAN_API_KEY,
50+
},
51+
customChains: [
52+
{
53+
network: 'arbitrumSepolia',
54+
chainId: 421614,
55+
urls: { apiURL: 'https://api-sepolia.arbiscan.io/api', browserURL: 'https://sepolia.arbiscan.io/' },
56+
},
57+
],
58+
}
59+
60+
// In general:
61+
// - hardhat is used for unit tests
62+
// - localhost is used for local development on a hardhat network or fork
63+
// - virtualArbitrumSepolia is for Tenderly Virtual Testnet
64+
export const networksUserConfig: NetworksUserConfig = {
65+
hardhat: {
66+
chainId: 31337,
67+
accounts: getHardhatAccounts(),
68+
},
69+
localhost: {
70+
chainId: 31337,
71+
url: 'http://localhost:8545',
72+
accounts: getTestnetAccounts(),
73+
},
74+
arbitrumSepolia: {
75+
chainId: 421614,
76+
url: ARBITRUM_SEPOLIA_RPC,
77+
secureAccounts: {
78+
enabled: true,
79+
},
80+
},
81+
...(VIRTUAL_ARBITRUM_SEPOLIA_RPC && {
82+
virtualArbitrumSepolia: {
83+
chainId: 421615,
84+
url: VIRTUAL_ARBITRUM_SEPOLIA_RPC,
85+
accounts: getTestnetAccounts(),
86+
},
87+
}),
88+
}
89+
90+
export const hardhatBaseConfig: HardhatUserConfig & { etherscan: Partial<EtherscanConfig> } = {
91+
solidity: solidityUserConfig,
92+
paths: projectPathsUserConfig,
93+
secureAccounts: {
94+
enabled: false,
95+
},
96+
networks: networksUserConfig,
97+
graph: {
98+
deployments: {
99+
horizon: {
100+
addressBook: 'addresses.json',
101+
},
102+
},
103+
},
104+
etherscan: etherscanUserConfig,
105+
}
106+
107+
export default hardhatBaseConfig

packages/hardhat-graph-protocol/src/sdk/ignition/ignition.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import path from 'path'
66

77
export function loadConfig(configPath: string, prefix: string, networkName: string): any {
88
const configFileCandidates = [
9-
path.join(require.main?.path ?? '', configPath, `${prefix}.${networkName}.json5`),
10-
path.join(require.main?.path ?? '', configPath, `${prefix}.default.json5`),
9+
path.resolve(process.cwd(), configPath, `${prefix}.${networkName}.json5`),
10+
path.resolve(process.cwd(), configPath, `${prefix}.default.json5`),
1111
]
1212

1313
const configFile = configFileCandidates.find(file => fs.existsSync(file))
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import { loadConfig, saveAddressBook } from './ignition/ignition'
2+
import { hardhatBaseConfig } from './hardhat.base.config'
23

3-
export const IgnitionHelper = { saveAddressBook, loadConfig }
4+
const IgnitionHelper = { saveAddressBook, loadConfig }
5+
export { hardhatBaseConfig, IgnitionHelper }

packages/horizon/README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ Graph Horizon is the next evolution of the Graph Protocol.
66

77
The following environment variables might be required:
88

9-
- `ETHERSCAN_API_KEY`: Etherscan API key
9+
| Variable | Description |
10+
|----------|-------------|
11+
| `ARBISCAN_API_KEY` | Arbiscan API key |
12+
| `DEPLOYER_PRIVATE_KEY` | Deployer private key - for testnet deployments |
13+
| `GOVERNOR_PRIVATE_KEY` | Governor private key - for testnet deployments |
14+
| `ARBITRUM_SEPOLIA_RPC` | Arbitrum Sepolia RPC URL |
15+
| `VIRTUAL_ARBITRUM_SEPOLIA_RPC` | Virtual Arbitrum Sepolia RPC URL |
1016

1117
You can set them using Hardhat:
1218

1319
```bash
14-
npx hardhat vars set ETHERSCAN_API_KEY
20+
npx hardhat vars set <variable>
1521
```
1622

1723
## Build
@@ -23,20 +29,20 @@ yarn build
2329

2430
## Deploy
2531

32+
Note that this instructions will help you deploy Graph Horizon contracts, but no data service will be deployed. If you want to deploy the Subgraph Service please refer to the [Subgraph Service README](../subgraph-service/README.md) for deploy instructions.
33+
2634
### New deployment
2735
To deploy Graph Horizon from scratch run the following command:
2836

2937
```bash
3038
npx hardhat run scripts/deploy.ts --network hardhat
3139
```
3240

33-
Note that this will deploy a standalone version of Graph Horizon contracts, meaning the Subgraph Service or any other data service will not be deployed. If you want to deploy the Subgraph Service please refer to the [Subgraph Service README](../subgraph-service/README.md) for deploy instructions.
34-
3541
### Upgrade deployment
3642
To upgrade an existing deployment of the original Graph Protocol to Graph Horizon, run the following command:
3743

3844
```bash
39-
npx hardhat run scripts/migrate.ts --network hardhat
45+
npx hardhat run scripts/migrate.ts --network localhost
4046
```
4147

42-
Note that this will deploy a standalone version of Graph Horizon contracts, meaning the Subgraph Service or any other data service will not be deployed. If you want to deploy the Subgraph Service please refer to the [Subgraph Service README](../subgraph-service/README.md) for deploy instructions.
48+
Usually you would run this against a network (or a fork) where the original Graph Protocol was previously deployed.

packages/horizon/hardhat.config.ts

Lines changed: 2 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,15 @@
1-
import { vars } from 'hardhat/config'
2-
3-
import type { HardhatUserConfig } from 'hardhat/config'
1+
import { hardhatBaseConfig } from 'hardhat-graph-protocol/sdk'
42

53
// Hardhat plugins
64
import '@nomicfoundation/hardhat-foundry'
75
import '@nomicfoundation/hardhat-toolbox'
86
import '@nomicfoundation/hardhat-ignition-ethers'
9-
import '@tenderly/hardhat-tenderly'
107
import 'hardhat-storage-layout'
118
import 'hardhat-contract-sizer'
129
import 'hardhat-secure-accounts'
1310

14-
// Environment variables
15-
const ETHERSCAN_API_KEY = vars.get('ETHERSCAN_API_KEY', '')
16-
const ARBITRUM_VIRTUAL_TESTNET_URL = vars.get('ARBITRUM_VIRTUAL_TESTNET_URL', '')
17-
const DEPLOYER_PRIVATE_KEY = vars.get('DEPLOYER_PRIVATE_KEY')
18-
const GOVERNOR_PRIVATE_KEY = vars.get('GOVERNOR_PRIVATE_KEY')
19-
20-
const getNetworkAccounts = () => {
21-
const accounts: string[] = []
22-
if (vars.has('DEPLOYER_PRIVATE_KEY')) accounts.push(DEPLOYER_PRIVATE_KEY)
23-
if (vars.has('GOVERNOR_PRIVATE_KEY')) accounts.push(GOVERNOR_PRIVATE_KEY)
24-
return accounts.length > 0 ? accounts : undefined
25-
}
26-
2711
if (process.env.BUILD_RUN !== 'true') {
2812
require('hardhat-graph-protocol')
2913
}
3014

31-
const config: HardhatUserConfig = {
32-
solidity: {
33-
version: '0.8.27',
34-
settings: {
35-
optimizer: {
36-
enabled: true,
37-
runs: 1,
38-
},
39-
},
40-
},
41-
paths: {
42-
artifacts: './build/contracts',
43-
sources: './contracts',
44-
},
45-
secureAccounts: {
46-
enabled: false,
47-
},
48-
networks: {
49-
hardhat: {
50-
chainId: 31337,
51-
accounts: {
52-
mnemonic: 'myth like bonus scare over problem client lizard pioneer submit female collect',
53-
},
54-
},
55-
localhost: {
56-
chainId: 31337,
57-
url: 'http://localhost:8545',
58-
accounts: getNetworkAccounts(),
59-
},
60-
arbitrumSepolia: {
61-
chainId: 421614,
62-
secureAccounts: {
63-
enabled: true,
64-
},
65-
url: 'https://sepolia-rollup.arbitrum.io/rpc',
66-
},
67-
arbitrumVirtualTestnet: {
68-
chainId: 421615,
69-
url: ARBITRUM_VIRTUAL_TESTNET_URL,
70-
accounts: getNetworkAccounts(),
71-
},
72-
},
73-
tenderly: {
74-
project: 'graph-network',
75-
username: 'graphprotocol',
76-
},
77-
graph: {
78-
deployments: {
79-
horizon: {
80-
addressBook: 'addresses.json',
81-
},
82-
},
83-
},
84-
etherscan: {
85-
apiKey: {
86-
arbitrumSepolia: ETHERSCAN_API_KEY,
87-
},
88-
customChains: [
89-
{
90-
network: 'arbitrumSepolia',
91-
chainId: 421614,
92-
urls: {
93-
apiURL: 'https://api-sepolia.arbiscan.io/api',
94-
browserURL: 'https://sepolia.arbiscan.io/',
95-
},
96-
},
97-
],
98-
},
99-
}
100-
101-
export default config
15+
export default hardhatBaseConfig

packages/horizon/ignition/configs/horizon.hardhat.json5 renamed to packages/horizon/ignition/configs/horizon.default.json5

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
{
22
"$global": {
3-
"governor": "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0",
43
"pauseGuardian": "0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC",
5-
"subgraphAvailabilityOracle": "0xd03ea8624C8C5987235048901fB614fDcA89b117",
64
// Placeholder address for a standalone Horizon deployment, see README.md for more details
75
"subgraphServiceAddress": "0x0000000000000000000000000000000000000000"
86
},
97
"RewardsManager": {
8+
"subgraphAvailabilityOracle": "0xd03ea8624C8C5987235048901fB614fDcA89b117",
109
"issuancePerBlock": "114155251141552511415n"
1110
},
1211
"EpochManager": {

packages/horizon/ignition/modules/core/GraphPayments.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default buildModule('GraphPayments', (m) => {
1111
const { Controller } = m.useModule(GraphPeripheryModule)
1212
const { GraphPaymentsProxyAdmin, GraphPaymentsProxy } = m.useModule(HorizonProxiesModule)
1313

14+
const governor = m.getAccount(1)
1415
const protocolPaymentCut = m.getParameter('protocolPaymentCut')
1516

1617
// Deploy GraphPayments implementation - requires periphery and proxies to be registered in the controller
@@ -30,13 +31,16 @@ export default buildModule('GraphPayments', (m) => {
3031
initArgs: [],
3132
})
3233

34+
m.call(GraphPaymentsProxyAdmin, 'transferOwnership', [governor], { after: [GraphPayments] })
35+
3336
return { GraphPayments, GraphPaymentsProxyAdmin }
3437
})
3538

3639
export const MigrateGraphPaymentsModule = buildModule('GraphPayments', (m) => {
3740
const { GraphPaymentsProxyAdmin, GraphPaymentsProxy } = m.useModule(MigrateHorizonProxiesModule)
3841
const { Controller } = m.useModule(MigratePeripheryModule)
3942

43+
const governor = m.getAccount(1)
4044
const protocolPaymentCut = m.getParameter('protocolPaymentCut')
4145

4246
// Deploy GraphPayments implementation
@@ -56,5 +60,7 @@ export const MigrateGraphPaymentsModule = buildModule('GraphPayments', (m) => {
5660
initArgs: [],
5761
})
5862

63+
m.call(GraphPaymentsProxyAdmin, 'transferOwnership', [governor], { after: [GraphPayments] })
64+
5965
return { GraphPayments, GraphPaymentsProxyAdmin }
6066
})

packages/horizon/ignition/modules/core/PaymentsEscrow.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default buildModule('PaymentsEscrow', (m) => {
1111
const { Controller } = m.useModule(GraphPeripheryModule)
1212
const { PaymentsEscrowProxyAdmin, PaymentsEscrowProxy } = m.useModule(HorizonProxiesModule)
1313

14+
const governor = m.getAccount(1)
1415
const withdrawEscrowThawingPeriod = m.getParameter('withdrawEscrowThawingPeriod')
1516

1617
// Deploy PaymentsEscrow implementation - requires periphery and proxies to be registered in the controller
@@ -30,13 +31,16 @@ export default buildModule('PaymentsEscrow', (m) => {
3031
initArgs: [],
3132
})
3233

34+
m.call(PaymentsEscrowProxyAdmin, 'transferOwnership', [governor], { after: [PaymentsEscrow] })
35+
3336
return { PaymentsEscrow, PaymentsEscrowProxyAdmin }
3437
})
3538

3639
export const MigratePaymentsEscrowModule = buildModule('PaymentsEscrow', (m) => {
3740
const { PaymentsEscrowProxyAdmin, PaymentsEscrowProxy } = m.useModule(MigrateHorizonProxiesModule)
3841
const { Controller } = m.useModule(MigratePeripheryModule)
3942

43+
const governor = m.getAccount(1)
4044
const withdrawEscrowThawingPeriod = m.getParameter('withdrawEscrowThawingPeriod')
4145

4246
// Deploy PaymentsEscrow implementation
@@ -56,5 +60,7 @@ export const MigratePaymentsEscrowModule = buildModule('PaymentsEscrow', (m) =>
5660
initArgs: [],
5761
})
5862

63+
m.call(PaymentsEscrowProxyAdmin, 'transferOwnership', [governor], { after: [PaymentsEscrow] })
64+
5965
return { PaymentsEscrow, PaymentsEscrowProxyAdmin }
6066
})

packages/horizon/ignition/modules/deploy.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ export default buildModule('GraphHorizon_Deploy', (m) => {
2020
TAPCollector,
2121
} = m.useModule(GraphHorizonCoreModule)
2222

23+
const governor = m.getAccount(1)
24+
25+
// BUG?: acceptOwnership should be called after everything in GraphHorizonCoreModule and GraphPeripheryModule is resolved
26+
// but it seems that it's not waiting for interal calls. Waiting on HorizonStaking seems to fix the issue for some reason
27+
// Removing HorizonStaking from the after list will trigger the bug
28+
29+
// Accept ownership of Graph Governed based contracts
30+
m.call(Controller, 'acceptOwnership', [], { from: governor, after: [GraphPeripheryModule, GraphHorizonCoreModule, HorizonStaking] })
31+
m.call(GraphProxyAdmin, 'acceptOwnership', [], { from: governor, after: [GraphPeripheryModule, GraphHorizonCoreModule, HorizonStaking] })
32+
2333
return {
2434
Controller,
2535
L2Curation,

0 commit comments

Comments
 (0)