|
2 | 2 |
|
3 | 3 | import logging |
4 | 4 | import pathlib as pl |
| 5 | +import typing as tp |
5 | 6 |
|
6 | 7 | from cardano_clusterlib import clusterlib_helpers |
| 8 | +from cardano_clusterlib import consts |
7 | 9 | from cardano_clusterlib import helpers |
8 | 10 | from cardano_clusterlib import types as itp |
9 | 11 |
|
@@ -82,5 +84,112 @@ def gen_non_extended_verification_key( |
82 | 84 | helpers._check_outfiles(out_file) |
83 | 85 | return out_file |
84 | 86 |
|
| 87 | + def gen_mnemonic( |
| 88 | + self, |
| 89 | + size: tp.Literal[12, 15, 18, 21, 24], |
| 90 | + out_file: itp.FileType = "", |
| 91 | + ) -> list[str]: |
| 92 | + """Generate a mnemonic sentence that can be used for key derivation. |
| 93 | +
|
| 94 | + Args: |
| 95 | + size: Number of words in the mnemonic (12, 15, 18, 21, or 24). |
| 96 | + out_file: A path to a file where the mnemonic will be stored (optional). |
| 97 | +
|
| 98 | + Returns: |
| 99 | + list[str]: A list of words in the generated mnemonic. |
| 100 | + """ |
| 101 | + out_args = [] |
| 102 | + if out_file: |
| 103 | + clusterlib_helpers._check_files_exist(out_file, clusterlib_obj=self._clusterlib_obj) |
| 104 | + out_args = ["--out-file", str(out_file)] |
| 105 | + |
| 106 | + out = ( |
| 107 | + self._clusterlib_obj.cli( |
| 108 | + [ |
| 109 | + "key", |
| 110 | + "generate-mnemonic", |
| 111 | + *out_args, |
| 112 | + "--size", |
| 113 | + str(size), |
| 114 | + ] |
| 115 | + ) |
| 116 | + .stdout.strip() |
| 117 | + .decode("ascii") |
| 118 | + ) |
| 119 | + |
| 120 | + if out_file: |
| 121 | + helpers._check_outfiles(out_file) |
| 122 | + words = helpers.read_from_file(file=out_file).strip().split() |
| 123 | + else: |
| 124 | + words = out.split() |
| 125 | + |
| 126 | + return words |
| 127 | + |
| 128 | + def derive_from_mnemonic( |
| 129 | + self, |
| 130 | + key_name: str, |
| 131 | + key_type: consts.KeyType, |
| 132 | + mnemonic_file: itp.FileType, |
| 133 | + account_number: int = 0, |
| 134 | + key_number: int | None = None, |
| 135 | + out_format: consts.OutputFormat = consts.OutputFormat.TEXT_ENVELOPE, |
| 136 | + destination_dir: itp.FileType = ".", |
| 137 | + ) -> pl.Path: |
| 138 | + """Derive an extended signing key from a mnemonic sentence. |
| 139 | +
|
| 140 | + Args: |
| 141 | + key_name: A name of the key. |
| 142 | + key_type: A type of the key. |
| 143 | + mnemonic_file: A path to a file containing the mnemonic sentence. |
| 144 | + account_number: An account number (default is 0). |
| 145 | + key_number: A key number (optional, required for payment and stake keys). |
| 146 | + out_format: An output format (default is text-envelope). |
| 147 | + destination_dir: A path to directory for storing artifacts (optional). |
| 148 | +
|
| 149 | + Returns: |
| 150 | + Path: A path to the generated extended signing key file. |
| 151 | + """ |
| 152 | + destination_dir = pl.Path(destination_dir).expanduser() |
| 153 | + out_file = destination_dir / f"{key_name}.skey" |
| 154 | + clusterlib_helpers._check_files_exist(out_file, clusterlib_obj=self._clusterlib_obj) |
| 155 | + |
| 156 | + key_args = [] |
| 157 | + key_number_err = f"`key_number` must be specified when key_type is '{key_type.value}'" |
| 158 | + if key_type == consts.KeyType.DREP: |
| 159 | + key_args.append("--drep-key") |
| 160 | + elif key_type == consts.KeyType.CC_COLD: |
| 161 | + key_args.append("--cc-cold-key") |
| 162 | + elif key_type == consts.KeyType.CC_HOT: |
| 163 | + key_args.append("--cc-hot-key") |
| 164 | + elif key_type == consts.KeyType.PAYMENT: |
| 165 | + if key_number is None: |
| 166 | + raise ValueError(key_number_err) |
| 167 | + key_args.extend(["--payment-key-with-number", str(key_number)]) |
| 168 | + elif key_type == consts.KeyType.STAKE: |
| 169 | + if key_number is None: |
| 170 | + raise ValueError(key_number_err) |
| 171 | + key_args.extend(["--stake-key-with-number", str(key_number)]) |
| 172 | + else: |
| 173 | + err = f"Unsupported key_type: {key_type}" |
| 174 | + raise ValueError(err) |
| 175 | + |
| 176 | + self._clusterlib_obj.cli( |
| 177 | + [ |
| 178 | + "key", |
| 179 | + "derive-from-mnemonic", |
| 180 | + f"--key-output-{out_format.value}", |
| 181 | + *key_args, |
| 182 | + "--account-number", |
| 183 | + str(account_number), |
| 184 | + "--mnemonic-from-file", |
| 185 | + str(mnemonic_file), |
| 186 | + "--signing-key-file", |
| 187 | + str(out_file), |
| 188 | + ] |
| 189 | + ) |
| 190 | + |
| 191 | + helpers._check_outfiles(out_file) |
| 192 | + return out_file |
| 193 | + |
85 | 194 | def __repr__(self) -> str: |
86 | 195 | return f"<{self.__class__.__name__}: clusterlib_obj={id(self._clusterlib_obj)}>" |
0 commit comments