0
# Signer Management
1
2
Access and manage signers for transactions, including account impersonation for testing.
3
4
## Capabilities
5
6
### Get All Signers
7
8
Returns an array of all available signers from the Hardhat network configuration.
9
10
```typescript { .api }
11
/**
12
* Get all available signers from network configuration
13
* @returns Promise resolving to array of HardhatEthersSigner instances
14
*/
15
function getSigners(): Promise<HardhatEthersSigner[]>;
16
17
interface HardhatEthersSigner extends ethers.Signer {
18
/** The signer's address as a string */
19
address: string;
20
/** The provider this signer is connected to */
21
provider: ethers.JsonRpcProvider | HardhatEthersProvider;
22
/** Connect this signer to a different provider */
23
connect(provider: ethers.JsonRpcProvider | HardhatEthersProvider): ethers.Signer;
24
}
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import { network } from "hardhat";
31
32
const { ethers } = await network.connect();
33
34
// Get all signers
35
const signers = await ethers.getSigners();
36
console.log(`Found ${signers.length} signers`);
37
38
// Access first signer (common pattern)
39
const [deployer] = await ethers.getSigners();
40
console.log(`Deployer address: ${deployer.address}`);
41
42
// Access multiple signers
43
const [deployer, user1, user2] = await ethers.getSigners();
44
45
// Use signers for transactions
46
const counter = await ethers.deployContract("Counter", [], deployer);
47
await counter.connect(user1).increment();
48
```
49
50
### Get Specific Signer
51
52
Returns a specific signer by its address.
53
54
```typescript { .api }
55
/**
56
* Get a specific signer by address
57
* @param address - The address of the signer to retrieve
58
* @returns Promise resolving to HardhatEthersSigner instance
59
*/
60
function getSigner(address: string): Promise<HardhatEthersSigner>;
61
```
62
63
**Usage Examples:**
64
65
```typescript
66
// Get signer by specific address
67
const signer = await ethers.getSigner("0x1234...abcd");
68
console.log(`Signer address: ${signer.address}`);
69
70
// Use specific signer for deployment
71
const counter = await ethers.deployContract("Counter", [], signer);
72
73
// Get signer and use for contract interaction
74
const userSigner = await ethers.getSigner("0x5678...ef01");
75
const tx = await counter.connect(userSigner).increment();
76
```
77
78
### Get Impersonated Signer
79
80
Creates a signer that impersonates any address, useful for testing with arbitrary accounts.
81
82
```typescript { .api }
83
/**
84
* Get an impersonated signer for testing purposes
85
* @param address - The address to impersonate
86
* @returns Promise resolving to HardhatEthersSigner that can act as the specified address
87
*/
88
function getImpersonatedSigner(address: string): Promise<HardhatEthersSigner>;
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
// Impersonate a specific address for testing
95
const whaleAddress = "0x1234...abcd"; // Some address with tokens
96
const impersonatedSigner = await ethers.getImpersonatedSigner(whaleAddress);
97
98
// Use impersonated signer for transactions
99
const token = await ethers.getContractAt("ERC20", tokenAddress);
100
await token.connect(impersonatedSigner).transfer(recipient, amount);
101
102
// Test contract behavior as different users
103
const governance = await ethers.getContractAt("GovernanceContract", govAddress);
104
const proposer = await ethers.getImpersonatedSigner("0x5678...ef01");
105
await governance.connect(proposer).propose(proposalData);
106
```
107
108
### Signer Properties and Methods
109
110
HardhatEthersSigner extends ethers.Signer with additional properties:
111
112
```typescript
113
const signer = await ethers.getSigner("0x1234...abcd");
114
115
// Direct access to address (no async needed)
116
console.log(signer.address); // "0x1234...abcd"
117
118
// Standard ethers.Signer methods
119
const balance = await signer.getBalance();
120
const nonce = await signer.getNonce();
121
const gasPrice = await signer.getGasPrice();
122
123
// Sign messages and transactions
124
const message = "Hello, world!";
125
const signature = await signer.signMessage(message);
126
127
const tx = {
128
to: "0x5678...ef01",
129
value: ethers.parseEther("1.0"),
130
};
131
const signedTx = await signer.signTransaction(tx);
132
```
133
134
### Working with Network Configurations
135
136
Signers are created based on your Hardhat network configuration:
137
138
```typescript
139
// hardhat.config.ts
140
export default {
141
networks: {
142
hardhat: {
143
accounts: [
144
{
145
privateKey: "0x1234...",
146
balance: "10000000000000000000000", // 10000 ETH
147
},
148
],
149
},
150
localhost: {
151
url: "http://127.0.0.1:8545",
152
},
153
mainnet: {
154
url: "https://mainnet.infura.io/v3/...",
155
accounts: ["0x5678..."], // Private keys
156
},
157
},
158
};
159
160
// When connected to different networks, getSigners() returns different accounts
161
const { ethers } = await network.connect("mainnet");
162
const signers = await ethers.getSigners(); // Returns mainnet accounts
163
```
164
165
### Common Usage Patterns
166
167
```typescript
168
// Deployment pattern
169
const [deployer, ...users] = await ethers.getSigners();
170
const contract = await ethers.deployContract("MyContract", [], deployer);
171
172
// Multi-user testing
173
const [owner, user1, user2, user3] = await ethers.getSigners();
174
await contract.connect(user1).someFunction();
175
await contract.connect(user2).anotherFunction();
176
177
// Role-based access testing
178
const adminSigner = await ethers.getSigner(adminAddress);
179
const userSigner = await ethers.getSigner(userAddress);
180
181
await contract.connect(adminSigner).setConfig(newConfig);
182
await expect(
183
contract.connect(userSigner).setConfig(newConfig)
184
).to.be.revertedWith("Only admin");
185
186
// Impersonation for fork testing
187
const { ethers } = await network.connect("mainnet-fork");
188
const richUser = await ethers.getImpersonatedSigner("0x...");
189
await token.connect(richUser).transfer(testAddress, largeAmount);
190
```
191
192
### Error Handling
193
194
```typescript
195
try {
196
const signer = await ethers.getSigner("0xinvalid");
197
} catch (error) {
198
console.error("Invalid address:", error.message);
199
}
200
201
try {
202
const signers = await ethers.getSigners();
203
if (signers.length === 0) {
204
console.log("No signers available on this network");
205
}
206
} catch (error) {
207
console.error("Failed to get signers:", error.message);
208
}
209
```