1use crate::error::config::GetSharedWalletConfigPathError;
2use crate::error::fs::{
3 ReadFileError, ReadPermissionsError, RemoveDirectoryAndContentsError, RemoveDirectoryError,
4 RemoveFileError, RenameError, SetPermissionsError, WriteFileError,
5};
6use crate::error::keyring::KeyringMaintenanceError;
7use crate::error::{
8 config::ConfigError,
9 encryption::EncryptionError,
10 fs::{CopyFileError, CreateDirAllError, EnsureParentDirExistsError, NoParentPathError},
11 get_user_home::GetUserHomeError,
12 keyring::KeyringError,
13 structured_file::StructuredFileError,
14 wallet_config::{SaveWalletConfigError, WalletConfigError},
15};
16use candid::types::principal::PrincipalError;
17use ic_agent::identity::PemError;
18use ic_identity_hsm::HardwareIdentityError;
19use std::path::PathBuf;
20use std::string::FromUtf8Error;
21use thiserror::Error;
22
23#[derive(Error, Debug)]
24pub enum CallSenderFromWalletError {
25 #[error("Failed to read principal from id '{0}', and did not find a wallet for that identity")]
26 ParsePrincipalFromIdFailedAndNoWallet(String, #[source] PrincipalError),
27
28 #[error(
29 "Failed to read principal from id '{0}' ({1}), and failed to load the wallet for that identity"
30 )]
31 ParsePrincipalFromIdFailedAndGetWalletCanisterIdFailed(
32 String,
33 PrincipalError,
34 #[source] WalletConfigError,
35 ),
36}
37
38#[derive(Error, Debug)]
39pub enum ConvertMnemonicToKeyError {
40 #[error("Failed to derive extended secret key from path")]
41 DeriveExtendedKeyFromPathFailed(#[source] bip32::Error),
42}
43
44#[derive(Error, Debug)]
45pub enum CreateIdentityConfigError {
46 #[error("Failed to generate a fresh encryption configuration")]
47 GenerateFreshEncryptionConfigurationFailed(#[source] EncryptionError),
48
49 #[error("Failed to check for keyring availability")]
50 KeyringAvailabilityCheckFailed(#[source] KeyringMaintenanceError),
51}
52
53#[derive(Error, Debug)]
54pub enum CreateNewIdentityError {
55 #[error("Cannot create an anonymous identity.")]
56 CannotCreateAnonymousIdentity(),
57
58 #[error("Failed to clean up previous creation attempts")]
59 CleanupPreviousCreationAttemptsFailed(#[from] RemoveDirectoryAndContentsError),
60
61 #[error("Failed to create identity config")]
62 ConvertMnemonicToKeyFailed(#[source] ConvertMnemonicToKeyError),
63
64 #[error("Convert secret key to sec1 Pem failed")]
65 ConvertSecretKeyToSec1PemFailed(#[source] Box<sec1::Error>),
66
67 #[error("Failed to create identity config")]
68 CreateIdentityConfigFailed(#[source] CreateIdentityConfigError),
69
70 #[error("Failed to create mnemonic from phrase: {0}")]
71 CreateMnemonicFromPhraseFailed(String),
72
73 #[error("failed to create temporary identity directory")]
74 CreateTemporaryIdentityDirectoryFailed(#[source] CreateDirAllError),
75
76 #[error("Failed to generate key")]
77 GenerateKeyFailed(#[source] GenerateKeyError),
78
79 #[error("Identity already exists.")]
80 IdentityAlreadyExists(),
81
82 #[error("Failed to load pem file")]
83 LoadPemFromFileFailed(#[source] LoadPemFromFileError),
84
85 #[error("Failed to remove identity")]
86 RemoveIdentityFailed(#[source] RemoveIdentityError),
87
88 #[error("Failed to rename temporary directory to permanent identity directory")]
89 RenameTemporaryIdentityDirectoryFailed(#[from] RenameError),
90
91 #[error("Failed to save identity configuration")]
92 SaveIdentityConfigurationFailed(#[source] SaveIdentityConfigurationError),
93
94 #[error("Failed to save pem")]
95 SavePemFailed(#[source] SavePemError),
96
97 #[error("Failed to switch back over to the identity you're replacing")]
98 SwitchBackToIdentityFailed(#[source] UseIdentityByNameError),
99
100 #[error("Failed to temporarily switch over to anonymous identity")]
101 SwitchToAnonymousIdentityFailed(#[source] UseIdentityByNameError),
102
103 #[error("Failed to validate pem file")]
104 ValidatePemFileFailed(#[source] ValidatePemFileError),
105}
106
107#[derive(Error, Debug)]
108pub enum ExportIdentityError {
109 #[error("Failed to get identity config")]
110 GetIdentityConfigFailed(#[source] GetIdentityConfigOrDefaultError),
111
112 #[error("The specified identity does not exist")]
113 IdentityDoesNotExist(#[source] RequireIdentityExistsError),
114
115 #[error("Failed to load pem file")]
116 LoadPemFailed(#[source] LoadPemError),
117
118 #[error("Could not translate pem file to text")]
119 TranslatePemContentToTextFailed(#[source] FromUtf8Error),
120
121 #[error("Failed to validate pem file")]
122 ValidatePemFileFailed(#[source] ValidatePemFileError),
123}
124
125#[derive(Error, Debug)]
126pub enum GenerateKeyError {
127 #[error("Failed to convert mnemonic to key")]
128 ConvertMnemonicToKeyFailed(#[source] ConvertMnemonicToKeyError),
129
130 #[error("Failed to generate a fresh secp256k1 key")]
131 GenerateFreshSecp256k1KeyFailed(#[source] Box<sec1::Error>),
132}
133
134#[derive(Error, Debug)]
135pub enum GetIdentityConfigOrDefaultError {
136 #[error("Failed to load configuration for identity '{0}'")]
137 LoadIdentityConfigurationFailed(String, #[source] StructuredFileError),
138}
139
140#[derive(Error, Debug)]
141pub enum GetLegacyCredentialsPemPathError {
142 #[error("Failed to get legacy pem path")]
143 GetLegacyPemPathFailed(#[source] GetUserHomeError),
144}
145
146#[derive(Error, Debug)]
147pub enum InitializeIdentityManagerError {
148 #[error("Cannot create identity directory")]
149 CreateIdentityDirectoryFailed(#[source] CreateDirAllError),
150
151 #[error("Failed to generate key")]
152 GenerateKeyFailed(#[source] GenerateKeyError),
153
154 #[error(transparent)]
155 GetLegacyCredentialsPemPathFailed(#[from] GetLegacyCredentialsPemPathError),
156
157 #[error("failed to migrate legacy identity")]
158 MigrateLegacyIdentityFailed(#[source] CopyFileError),
159
160 #[error("Failed to save configuration")]
161 SaveConfigurationFailed(#[source] StructuredFileError),
162
163 #[error("Failed to write pem to file")]
164 WritePemToFileFailed(#[source] WritePemToFileError),
165}
166
167#[derive(Error, Debug)]
168pub enum InstantiateIdentityFromNameError {
169 #[error("Failed to get principal of identity: {0}")]
170 GetIdentityPrincipalFailed(String),
171
172 #[error("Failed to load identity")]
173 LoadIdentityFailed(#[source] LoadIdentityError),
174
175 #[error("Identity must exist")]
176 RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
177}
178
179#[derive(Error, Debug)]
180pub enum LoadIdentityError {
181 #[error("Failed to get identity config")]
182 GetIdentityConfigOrDefaultFailed(#[source] GetIdentityConfigOrDefaultError),
183
184 #[error("Failed to instantiate identity")]
185 NewIdentityFailed(#[source] NewIdentityError),
186}
187
188#[derive(Error, Debug)]
189pub enum LoadPemError {
190 #[error("Failed to load PEM file from file")]
191 LoadFromFileFailed(#[source] LoadPemFromFileError),
192
193 #[error("Failed to load PEM file from keyring for identity '{0}'")]
194 LoadFromKeyringFailed(Box<String>, #[source] KeyringError),
195}
196
197#[derive(Error, Debug)]
198pub enum LoadPemFromFileError {
199 #[error("Failed to decrypt PEM file at {0}")]
200 DecryptPemFileFailed(PathBuf, #[source] EncryptionError),
201
202 #[error("failed to read pem file")]
203 ReadPemFileFailed(#[from] ReadFileError),
204}
205
206#[derive(Error, Debug)]
207pub enum LoadPemIdentityError {
208 #[error("Cannot read identity file '{0}'")]
209 ReadIdentityFileFailed(String, #[source] Box<PemError>),
210}
211
212#[derive(Error, Debug)]
213pub enum MapWalletsToRenamedIdentityError {
214 #[error("Failed to get config directory for identity manager")]
215 GetConfigDirectoryFailed(#[source] ConfigError),
216
217 #[error(transparent)]
218 GetSharedNetworkDataDirectoryFailed(#[from] GetSharedWalletConfigPathError),
219
220 #[error(transparent)]
221 LoadNetworkMetadata(#[from] StructuredFileError),
222
223 #[error("Failed to rename wallet global config key")]
224 RenameWalletGlobalConfigKeyFailed(#[source] RenameWalletGlobalConfigKeyError),
225}
226
227#[derive(Error, Debug)]
228pub enum NewHardwareIdentityError {
229 #[error("Failed to instantiate hardware identity for identity '{0}'")]
230 InstantiateHardwareIdentityFailed(String, #[source] Box<HardwareIdentityError>),
231}
232
233#[derive(Error, Debug)]
234pub enum NewIdentityError {
235 #[error("Failed to load PEM")]
236 LoadPemFailed(#[source] LoadPemError),
237
238 #[error("Failed to load PEM identity")]
239 LoadPemIdentityFailed(#[source] LoadPemIdentityError),
240
241 #[error("Failed to instantiate hardware identity")]
242 NewHardwareIdentityFailed(#[source] NewHardwareIdentityError),
243}
244
245#[derive(Error, Debug)]
246pub enum NewIdentityManagerError {
247 #[error("Failed to get config directory for identity manager")]
248 GetConfigDirectoryFailed(#[source] ConfigError),
249
250 #[error("Failed to load identity manager configuration")]
251 LoadIdentityManagerConfigurationFailed(#[source] StructuredFileError),
252
253 #[error("Failed to initialize identity manager")]
254 InitializeFailed(#[source] InitializeIdentityManagerError),
255
256 #[error("The specified identity must exist")]
257 OverrideIdentityMustExist(#[source] RequireIdentityExistsError),
258
259 #[error(r#"No identity configuration found. Please run "dfx identity get-principal" or "dfx identity new <identity name>" to create a new identity."#)]
260 NoIdentityConfigurationFound,
261}
262
263#[derive(Error, Debug)]
264pub enum RemoveIdentityError {
265 #[error("Cannot delete the anonymous identity.")]
266 CannotDeleteAnonymousIdentity(),
267
268 #[error("Cannot delete the default identity.")]
269 CannotDeleteDefaultIdentity(),
270
271 #[error("Failed to display linked wallets")]
272 DisplayLinkedWalletsFailed(#[source] WalletConfigError),
273
274 #[error(
275 "If you want to remove an identity with configured wallets, please use the --drop-wallets flag."
276 )]
277 DropWalletsFlagRequiredToRemoveIdentityWithWallets(),
278
279 #[error("failed to remove identity directory")]
280 RemoveIdentityDirectoryFailed(#[source] RemoveDirectoryError),
281
282 #[error("Failed to remove identity file")]
283 RemoveIdentityFileFailed(#[from] RemoveFileError),
284
285 #[error("Failed to remove identity from keyring")]
286 RemoveIdentityFromKeyringFailed(#[source] KeyringError),
287
288 #[error("Identity must exist")]
289 RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
290}
291
292#[derive(Error, Debug)]
293pub enum RenameIdentityError {
294 #[error("Cannot create an anonymous identity.")]
295 CannotCreateAnonymousIdentity(),
296
297 #[error("Failed to get identity config")]
298 GetIdentityConfigFailed(#[source] GetIdentityConfigOrDefaultError),
299
300 #[error("Identity already exists.")]
301 IdentityAlreadyExists(),
302
303 #[error("Identity does not exist")]
304 IdentityDoesNotExist(#[source] RequireIdentityExistsError),
305
306 #[error("Failed to load pem")]
307 LoadPemFailed(#[source] LoadPemError),
308
309 #[error("Failed to map wallets to renamed identity")]
310 MapWalletsToRenamedIdentityFailed(#[source] MapWalletsToRenamedIdentityError),
311
312 #[error("Failed to remove identity from keyring")]
313 RemoveIdentityFromKeyringFailed(#[source] KeyringError),
314
315 #[error("failed to rename identity directory")]
316 RenameIdentityDirectoryFailed(#[from] RenameError),
317
318 #[error("Failed to save identity configuration")]
319 SaveIdentityConfigurationFailed(#[source] SaveIdentityConfigurationError),
320
321 #[error("Failed to save pem")]
322 SavePemFailed(#[source] SavePemError),
323
324 #[error("Failed to switch over default identity settings")]
325 SwitchDefaultIdentitySettingsFailed(#[source] WriteDefaultIdentityError),
326}
327
328#[derive(Error, Debug)]
329pub enum RenameWalletGlobalConfigKeyError {
330 #[error("Failed to rename '{0}' to '{1}' in the global wallet config")]
331 RenameWalletFailed(Box<String>, Box<String>, #[source] WalletConfigError),
332
333 #[error(transparent)]
334 SaveWalletConfig(#[from] SaveWalletConfigError),
335}
336
337#[derive(Error, Debug)]
338pub enum RequireIdentityExistsError {
339 #[error("Identity {0} does not exist at '{1}'.")]
340 IdentityDoesNotExist(String, PathBuf),
341
342 #[error("An Identity named {0} cannot be created as it is reserved for internal use.")]
343 ReservedIdentityName(String),
344}
345
346#[derive(Error, Debug)]
347pub enum SaveIdentityConfigurationError {
348 #[error("failed to ensure identity configuration directory exists")]
349 EnsureIdentityConfigurationDirExistsFailed(#[source] EnsureParentDirExistsError),
350
351 #[error("Failed to save identity configuration")]
352 SaveIdentityConfigurationFailed(#[source] StructuredFileError),
353}
354
355#[derive(Error, Debug)]
356pub enum SavePemError {
357 #[error("Cannot save PEM content for an HSM.")]
358 CannotSavePemContentForHsm(),
359
360 #[error("Failed to write PEM to file")]
361 WritePemToFileFailed(#[source] WritePemToFileError),
362
363 #[error("Failed to write PEM to keyring")]
364 WritePemToKeyringFailed(#[source] KeyringError),
365}
366
367#[derive(Error, Debug)]
368pub enum UseIdentityByNameError {
369 #[error("Identity must exist")]
370 RequireIdentityExistsFailed(#[source] RequireIdentityExistsError),
371
372 #[error("Failed to write default identity")]
373 WriteDefaultIdentityFailed(#[source] WriteDefaultIdentityError),
374}
375
376#[derive(Error, Debug)]
377pub enum ValidatePemFileError {
378 #[error(transparent)]
379 PemError(#[from] ic_agent::identity::PemError),
380
381 #[error(
382 "Ed25519 v1 keys (those generated by OpenSSL) are not supported. Try again with a v2 key"
383 )]
384 UnsupportedKeyVersion(),
385
386 #[error("Failed to validate PEM content")]
387 ValidatePemContentFailed(#[source] Box<PemError>),
388}
389
390#[derive(Error, Debug)]
391pub enum WriteDefaultIdentityError {
392 #[error("Failed to save identity manager configuration")]
393 SaveIdentityManagerConfigurationFailed(#[source] StructuredFileError),
394}
395
396#[derive(Error, Debug)]
397pub enum WritePemContentError {
398 #[error(transparent)]
399 CreateDirAll(#[from] CreateDirAllError),
400
401 #[error(transparent)]
402 NoParent(#[from] NoParentPathError),
403
404 #[error(transparent)]
405 ReadPermissions(#[from] ReadPermissionsError),
406
407 #[error(transparent)]
408 SetPermissions(#[from] SetPermissionsError),
409
410 #[error(transparent)]
411 Write(#[from] WriteFileError),
412}
413
414#[derive(Error, Debug)]
415pub enum WritePemToFileError {
416 #[error("Failed to encrypt PEM file")]
417 EncryptPemFileFailed(PathBuf, #[source] EncryptionError),
418
419 #[error("failed to write PEM content")]
420 WritePemContentFailed(#[source] WritePemContentError),
421}