Coverage for silkaj/cli.py: 100%
85 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
1# Copyright 2016-2025 Maël Azimi <m.a@moul.re>
2#
3# Silkaj is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Affero General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# Silkaj is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Affero General Public License for more details.
12#
13# You should have received a copy of the GNU Affero General Public License
14# along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
16import contextlib
17import sys
18from pathlib import Path
20import rich_click as click
21from duniterpy.api.endpoint import endpoint as du_endpoint
23from silkaj import tools, tui
24from silkaj.about import about
25from silkaj.auth import generate_auth_file
26from silkaj.blockchain.blocks import list_blocks
27from silkaj.blockchain.difficulty import difficulties
28from silkaj.blockchain.information import currency_info
29from silkaj.checksum import checksum_command
30from silkaj.constants import (
31 G1_DEFAULT_ENDPOINT,
32 G1_TEST_DEFAULT_ENDPOINT,
33 SILKAJ_VERSION,
34)
35from silkaj.g1_monetary_license import license_command
36from silkaj.money.balance import balance_cmd
37from silkaj.money.history import transaction_history
38from silkaj.money.transfer import transfer_money
39from silkaj.wot import revocation
40from silkaj.wot.certification import certify
41from silkaj.wot.lookup import lookup_cmd
42from silkaj.wot.membership import send_membership
43from silkaj.wot.status import status
45click.rich_click.SHOW_ARGUMENTS = True
46click.rich_click.OPTION_GROUPS = {
47 "silkaj": [
48 {
49 "name": "Basic options",
50 "options": ["--help", "--version"],
51 },
52 {
53 "name": "Endpoint and currency specification",
54 "options": ["--endpoint", "--gtest"],
55 },
56 {
57 "name": "Authentication",
58 "options": [
59 "--auth-scrypt",
60 "--nrp",
61 "--auth-file",
62 "--auth-seed",
63 "--auth-wif",
64 ],
65 },
66 ],
67}
70@click.group()
71@click.help_option("-h", "--help")
72@click.version_option(SILKAJ_VERSION, "-v", "--version")
73@click.option(
74 "--endpoint",
75 "-ep",
76 help=f"Default endpoint reaches Ğ1 currency on its official endpoint: \
77{tui.endpoint_link(du_endpoint(G1_DEFAULT_ENDPOINT).host)}. \
78--endpoint allows to specify a custom endpoint following the format: <host>:<port>/<path>. \
79<port> and <path> are optional. In case no port is specified, it defaults to 443.",
80 cls=tools.MutuallyExclusiveOption,
81 mutually_exclusive=["gtest"],
82)
83@click.option(
84 "--gtest",
85 "-gt",
86 is_flag=True,
87 help=f"Uses official ĞTest currency endpoint: \
88{tui.endpoint_link(du_endpoint(G1_TEST_DEFAULT_ENDPOINT).host)}. \
89Note that --endpoint has precedence over --gtest.",
90 cls=tools.MutuallyExclusiveOption,
91 mutually_exclusive=["endpoint"],
92)
93@click.option(
94 "--auth-scrypt",
95 "--scrypt",
96 is_flag=True,
97 help="Scrypt authentication: default method",
98)
99@click.option("--nrp", help='Scrypt parameters: defaults N,r,p: "4096,16,1"')
100@click.option(
101 "--auth-file",
102 "-af",
103 type=click.Path(exists=True, dir_okay=False, path_type=Path),
104 help="Authentication file path",
105)
106@click.option(
107 "--auth-seed",
108 "--seed",
109 is_flag=True,
110 help="Seed hexadecimal authentication",
111)
112@click.option(
113 "--auth-wif",
114 "--wif",
115 is_flag=True,
116 help="WIF and EWIF authentication methods",
117)
118@click.option(
119 "--display",
120 "-d",
121 is_flag=True,
122 help="Display the generated document before sending it",
123)
124@click.option(
125 "--dry-run",
126 "-n",
127 is_flag=True,
128 help="By-pass licence, confirmation. \
129Do not send the document, but display it instead",
130)
131@click.pass_context
132def cli(
133 ctx: click.Context,
134 endpoint: str,
135 gtest: bool,
136 auth_scrypt: bool,
137 nrp: str,
138 auth_file: Path,
139 auth_seed: bool,
140 auth_wif: bool,
141 display: bool,
142 dry_run: bool,
143) -> None:
144 if display and dry_run:
145 sys.exit("ERROR: display and dry-run options can not be used together")
147 ctx.obj = {}
148 ctx.ensure_object(dict)
149 ctx.obj["ENDPOINT"] = endpoint
150 ctx.obj["GTEST"] = gtest
151 ctx.obj["AUTH_SCRYPT"] = auth_scrypt
152 ctx.obj["AUTH_SCRYPT_PARAMS"] = nrp
153 ctx.obj["AUTH_FILE_PATH"] = auth_file
154 ctx.obj["AUTH_SEED"] = auth_seed
155 ctx.obj["AUTH_WIF"] = auth_wif
156 ctx.obj["DISPLAY_DOCUMENT"] = display
157 ctx.obj["DRY_RUN"] = dry_run
158 ctx.help_option_names = ["-h", "--help"]
161cli.add_command(about)
162cli.add_command(generate_auth_file)
163cli.add_command(checksum_command)
164cli.add_command(license_command)
167@cli.group("blockchain", help="Blockchain related commands")
168def blockchain_group() -> None:
169 pass
172blockchain_group.add_command(list_blocks)
173blockchain_group.add_command(difficulties)
174blockchain_group.add_command(currency_info)
177@cli.group("money", help="Money management related commands")
178def money_group() -> None:
179 pass
182money_group.add_command(balance_cmd)
183money_group.add_command(transaction_history)
184money_group.add_command(transfer_money)
187@cli.group("wot", help="Web-of-Trust related commands")
188def wot_group() -> None:
189 pass
192wot_group.add_command(certify)
193with contextlib.suppress(ModuleNotFoundError):
194 from silkaj.wot.exclusions import exclusions_command
196 wot_group.add_command(exclusions_command)
198wot_group.add_command(lookup_cmd)
199wot_group.add_command(send_membership)
200wot_group.add_command(status)
203@wot_group.group(
204 "revocation",
205 help="Create, save, verify or publish revocation document.\n\
206Subcommands optionally take the path to the revocation document.",
207)
208def revocation_group() -> None:
209 pass
212revocation_group.add_command(revocation.create)
213revocation_group.add_command(revocation.verify)
214revocation_group.add_command(revocation.publish)
215revocation_group.add_command(revocation.revoke_now)