Skip to content

Commit 9b05de4

Browse files
committed
feat: auto fund test accounts on local networks
Signed-off-by: Tomás Migone <[email protected]>
1 parent 0f9690d commit 9b05de4

File tree

4 files changed

+72
-37
lines changed

4 files changed

+72
-37
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ tx-*.log
4848
addresses-fork.json
4949
addresses-hardhat.json
5050
addresses-localhost.json
51-
51+
addresses-local-network.json
5252
# Keys
5353
.keystore
5454

packages/hardhat-graph-protocol/src/gre.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,25 @@ export const greExtendEnvironment = (hre: HardhatRuntimeEnvironment) => {
7676
}
7777
}
7878

79+
// Accounts
80+
const grtTokenAddress = greDeployments?.horizon?.contracts?.GraphToken?.target
81+
const accounts = {
82+
getAccounts: async () => getAccounts(provider, grtTokenAddress),
83+
getDeployer: async (accountIndex?: number) => getDeployer(provider, accountIndex, grtTokenAddress),
84+
getGovernor: async (accountIndex?: number) => getGovernor(provider, accountIndex, grtTokenAddress),
85+
getArbitrator: async (accountIndex?: number) => getArbitrator(provider, accountIndex, grtTokenAddress),
86+
getPauseGuardian: async (accountIndex?: number) => getPauseGuardian(provider, accountIndex, grtTokenAddress),
87+
getSubgraphAvailabilityOracle: async (accountIndex?: number) => getSubgraphAvailabilityOracle(provider, accountIndex, grtTokenAddress),
88+
getGateway: async (accountIndex?: number) => getGateway(provider, accountIndex, grtTokenAddress),
89+
getTestAccounts: async () => getTestAccounts(provider, grtTokenAddress),
90+
}
91+
7992
logDebug('GRE initialized successfully!')
8093
return {
8194
...greDeployments,
8295
provider,
8396
chainId,
84-
accounts: {
85-
getAccounts: async () => getAccounts(provider),
86-
getDeployer: async (accountIndex?: number) => getDeployer(provider, accountIndex),
87-
getGovernor: async (accountIndex?: number) => getGovernor(provider, accountIndex),
88-
getArbitrator: async (accountIndex?: number) => getArbitrator(provider, accountIndex),
89-
getPauseGuardian: async (accountIndex?: number) => getPauseGuardian(provider, accountIndex),
90-
getSubgraphAvailabilityOracle: async (accountIndex?: number) => getSubgraphAvailabilityOracle(provider, accountIndex),
91-
getGateway: async (accountIndex?: number) => getGateway(provider, accountIndex),
92-
getTestAccounts: async () => getTestAccounts(provider),
93-
},
97+
accounts: accounts,
9498
}
9599
})
96100
}
Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { setGRTBalance } from '../hardhat'
2+
import { toBeHex } from 'ethers'
3+
4+
import type { Addressable } from 'ethers'
15
import type { HardhatEthersProvider } from '@nomicfoundation/hardhat-ethers/internal/hardhat-ethers-provider'
2-
import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'
6+
import type { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'
37

48
// The Graph convention for account derivation is:
59
// 0: Deployer
@@ -10,6 +14,15 @@ import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers'
1014
// 5: Gateway/payer
1115
// 6+: Test accounts
1216

17+
enum GraphAccountIndex {
18+
Deployer = 0,
19+
Governor = 1,
20+
Arbitrator = 2,
21+
PauseGuardian = 3,
22+
SubgraphAvailabilityOracle = 4,
23+
Gateway = 5,
24+
}
25+
1326
export type GraphAccounts = {
1427
deployer: HardhatEthersSigner
1528
governor: HardhatEthersSigner
@@ -20,46 +33,64 @@ export type GraphAccounts = {
2033
test: HardhatEthersSigner[]
2134
}
2235

23-
export async function getAccounts(provider: HardhatEthersProvider): Promise<GraphAccounts> {
36+
export async function getAccounts(provider: HardhatEthersProvider, grtTokenAddress?: string | Addressable): Promise<GraphAccounts> {
2437
return {
25-
deployer: await getDeployer(provider),
26-
governor: await getGovernor(provider),
27-
arbitrator: await getArbitrator(provider),
28-
pauseGuardian: await getPauseGuardian(provider),
29-
subgraphAvailabilityOracle: await getSubgraphAvailabilityOracle(provider),
30-
gateway: await getGateway(provider),
31-
test: await getTestAccounts(provider),
38+
deployer: await getDeployer(provider, GraphAccountIndex.Deployer, grtTokenAddress),
39+
governor: await getGovernor(provider, GraphAccountIndex.Governor, grtTokenAddress),
40+
arbitrator: await getArbitrator(provider, GraphAccountIndex.Arbitrator, grtTokenAddress),
41+
pauseGuardian: await getPauseGuardian(provider, GraphAccountIndex.PauseGuardian, grtTokenAddress),
42+
subgraphAvailabilityOracle: await getSubgraphAvailabilityOracle(provider, GraphAccountIndex.SubgraphAvailabilityOracle, grtTokenAddress),
43+
gateway: await getGateway(provider, GraphAccountIndex.Gateway, grtTokenAddress),
44+
test: await getTestAccounts(provider, grtTokenAddress),
3245
}
3346
}
3447

35-
export async function getDeployer(provider: HardhatEthersProvider, accountIndex = 0) {
36-
return provider.getSigner(accountIndex)
48+
export async function getDeployer(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.Deployer, grtTokenAddress?: string | Addressable) {
49+
return _getAccount(provider, accountIndex, grtTokenAddress)
3750
}
3851

39-
export async function getGovernor(provider: HardhatEthersProvider, accountIndex = 1) {
40-
return provider.getSigner(accountIndex)
52+
export async function getGovernor(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.Governor, grtTokenAddress?: string | Addressable) {
53+
return _getAccount(provider, accountIndex, grtTokenAddress)
4154
}
4255

43-
export async function getArbitrator(provider: HardhatEthersProvider, accountIndex = 2) {
44-
return provider.getSigner(accountIndex)
56+
export async function getArbitrator(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.Arbitrator, grtTokenAddress?: string | Addressable) {
57+
return _getAccount(provider, accountIndex, grtTokenAddress)
4558
}
4659

47-
export async function getPauseGuardian(provider: HardhatEthersProvider, accountIndex = 3) {
48-
return provider.getSigner(accountIndex)
60+
export async function getPauseGuardian(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.PauseGuardian, grtTokenAddress?: string | Addressable) {
61+
return _getAccount(provider, accountIndex, grtTokenAddress)
4962
}
5063

51-
export async function getSubgraphAvailabilityOracle(provider: HardhatEthersProvider, accountIndex = 4) {
52-
return provider.getSigner(accountIndex)
64+
export async function getSubgraphAvailabilityOracle(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.SubgraphAvailabilityOracle, grtTokenAddress?: string | Addressable) {
65+
return _getAccount(provider, accountIndex, grtTokenAddress)
5366
}
5467

55-
export async function getGateway(provider: HardhatEthersProvider, accountIndex = 5) {
56-
return provider.getSigner(accountIndex)
68+
export async function getGateway(provider: HardhatEthersProvider, accountIndex = GraphAccountIndex.Gateway, grtTokenAddress?: string | Addressable) {
69+
return _getAccount(provider, accountIndex, grtTokenAddress)
5770
}
5871

59-
export async function getTestAccounts(provider: HardhatEthersProvider) {
72+
export async function getTestAccounts(provider: HardhatEthersProvider, grtTokenAddress?: string | Addressable) {
6073
const accounts = await provider.send('eth_accounts', []) as string[]
61-
if (accounts.length < 6) {
74+
const numReservedAccounts = Object.values(GraphAccountIndex).filter(v => typeof v === 'number').length
75+
if (accounts.length < numReservedAccounts) {
6276
return []
6377
}
64-
return await Promise.all(accounts.slice(6).map(async account => await provider.getSigner(account)))
78+
return await Promise.all(
79+
accounts
80+
.slice(numReservedAccounts)
81+
.map(async account => await _getAccount(provider, account, grtTokenAddress)),
82+
)
83+
}
84+
85+
async function _getAccount(provider: HardhatEthersProvider, accountIndex: number | string, grtTokenAddress?: string | Addressable) {
86+
const account = await provider.getSigner(accountIndex)
87+
88+
// If the chain is local, send 10M GRT to the account
89+
const chainId = await provider.send('eth_chainId', []) as string
90+
const isLocal = [toBeHex(1337), toBeHex(31337)].includes(toBeHex(BigInt(chainId)))
91+
if (grtTokenAddress && isLocal) {
92+
await setGRTBalance(provider, grtTokenAddress, account.address, 10_000_000n)
93+
}
94+
95+
return account
6596
}

packages/toolshed/src/hardhat/hardhat.base.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ export const networksUserConfig: BaseNetworksUserConfig = {
9191
localNetwork: {
9292
chainId: 1337,
9393
url: LOCAL_NETWORK_RPC,
94-
secureAccounts: {
95-
enabled: false,
94+
accounts: {
95+
mnemonic: 'myth like bonus scare over problem client lizard pioneer submit female collect',
9696
},
9797
deployments: {
9898
horizon: resolveNodeModulesPath('@graphprotocol/horizon/addresses-local-network.json'),

0 commit comments

Comments
 (0)