mm-sol 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mm_sol-0.3.1 → mm_sol-0.3.3}/PKG-INFO +2 -1
- {mm_sol-0.3.1 → mm_sol-0.3.3}/pyproject.toml +4 -2
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/account.py +41 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cli.py +12 -6
- mm_sol-0.3.3/src/mm_sol/cli/cmd/wallet/mnemonic_cmd.py +19 -0
- mm_sol-0.3.3/tests/cli/cmd/wallet/test_mnemonic_cmd.py +38 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_account.py +23 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/uv.lock +29 -18
- mm_sol-0.3.1/src/mm_sol/cli/cmd/wallet/new_cmd.py +0 -14
- mm_sol-0.3.1/tests/cli/cmd/wallet/test_new_cmd.py +0 -24
- {mm_sol-0.3.1 → mm_sol-0.3.3}/.env.example +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/.gitignore +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/README.txt +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/dict.dic +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/justfile +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/balance.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/block.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/calcs.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cli_utils.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/balance_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/balances_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/example_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/node_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/transfer_sol_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/transfer_token_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/wallet/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/cmd/wallet/keypair_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/examples/balances.toml +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/examples/transfer-sol.toml +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/examples/transfer-token.toml +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/cli/validators.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/constants.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/converters.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/py.typed +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/rpc.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/solana_cli.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/token.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/transfer.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/src/mm_sol/utils.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/cli/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/cli/cmd/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/cli/cmd/wallet/__init__.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/cli/cmd/wallet/test_keypair_cmd.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/conftest.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_balance.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_client.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_converters.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_rpc.py +0 -0
- {mm_sol-0.3.1 → mm_sol-0.3.3}/tests/test_token.py +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mm-sol
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Requires-Python: >=3.12
|
|
5
5
|
Requires-Dist: base58~=2.1.1
|
|
6
6
|
Requires-Dist: jinja2>=3.1.5
|
|
7
7
|
Requires-Dist: mm-crypto-utils>=0.1.4
|
|
8
|
+
Requires-Dist: mnemonic==0.21
|
|
8
9
|
Requires-Dist: solana~=0.36.3
|
|
9
10
|
Requires-Dist: typer>=0.15.1
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mm-sol"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
4
4
|
description = ""
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
dependencies = [
|
|
7
7
|
"mm-crypto-utils>=0.1.4",
|
|
8
8
|
"solana~=0.36.3",
|
|
9
9
|
"base58~=2.1.1",
|
|
10
|
+
"mnemonic==0.21",
|
|
10
11
|
"typer>=0.15.1",
|
|
11
12
|
"jinja2>=3.1.5",
|
|
13
|
+
|
|
12
14
|
]
|
|
13
15
|
[project.scripts]
|
|
14
16
|
mm-sol = "mm_sol.cli.cli:app"
|
|
@@ -24,7 +26,7 @@ dev-dependencies = [
|
|
|
24
26
|
"ruff~=0.9.4",
|
|
25
27
|
"pip-audit~=2.7.3",
|
|
26
28
|
"bandit~=1.8.2",
|
|
27
|
-
"mypy~=1.
|
|
29
|
+
"mypy~=1.15.0",
|
|
28
30
|
]
|
|
29
31
|
|
|
30
32
|
[tool.mypy]
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import contextlib
|
|
2
2
|
import random
|
|
3
|
+
from dataclasses import dataclass
|
|
3
4
|
|
|
4
5
|
import base58
|
|
5
6
|
import pydash
|
|
6
7
|
from mm_std import Err, Ok, Result
|
|
8
|
+
from mnemonic import Mnemonic
|
|
7
9
|
from pydantic import BaseModel
|
|
8
10
|
from solana.rpc.api import Client
|
|
9
11
|
from solders.keypair import Keypair
|
|
10
12
|
from solders.pubkey import Pubkey
|
|
11
13
|
from solders.rpc.responses import GetAccountInfoResp
|
|
12
14
|
|
|
15
|
+
PHANTOM_DERIVATION_PATH = "m/44'/501'/{i}'/0'"
|
|
16
|
+
WORD_STRENGTH = {12: 128, 15: 160, 18: 192, 21: 224, 24: 256}
|
|
17
|
+
|
|
13
18
|
|
|
14
19
|
class NewAccount(BaseModel):
|
|
15
20
|
public_key: str
|
|
@@ -17,6 +22,42 @@ class NewAccount(BaseModel):
|
|
|
17
22
|
private_key_arr: list[int]
|
|
18
23
|
|
|
19
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class DerivedAccount:
|
|
27
|
+
index: int
|
|
28
|
+
path: str
|
|
29
|
+
address: str
|
|
30
|
+
private_key: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def generate_mnemonic(num_words: int = 24) -> str:
|
|
34
|
+
if num_words not in WORD_STRENGTH:
|
|
35
|
+
raise ValueError(f"num_words must be one of {list(WORD_STRENGTH.keys())}")
|
|
36
|
+
mnemonic = Mnemonic("english")
|
|
37
|
+
return mnemonic.generate(strength=WORD_STRENGTH[num_words])
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def derive_accounts(mnemonic: str, passphrase: str, derivation_path: str, limit: int) -> list[DerivedAccount]:
|
|
41
|
+
if "{i}" not in derivation_path:
|
|
42
|
+
raise ValueError("derivation_path must contain {i}, for example: m/44'/501'/{i}'/0'")
|
|
43
|
+
|
|
44
|
+
result: list[DerivedAccount] = []
|
|
45
|
+
seed = Mnemonic.to_seed(mnemonic, passphrase)
|
|
46
|
+
for i in range(limit):
|
|
47
|
+
path = derivation_path.replace("{i}", str(i))
|
|
48
|
+
keypair = Keypair.from_seed_and_derivation_path(seed, path)
|
|
49
|
+
result.append(
|
|
50
|
+
DerivedAccount(
|
|
51
|
+
index=i,
|
|
52
|
+
path=path,
|
|
53
|
+
address=str(keypair.pubkey()),
|
|
54
|
+
private_key=base58.b58encode(bytes(keypair.to_bytes_array())).decode("utf-8"),
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return result
|
|
59
|
+
|
|
60
|
+
|
|
20
61
|
def generate_account() -> NewAccount:
|
|
21
62
|
keypair = Keypair()
|
|
22
63
|
public_key = str(keypair.pubkey())
|
|
@@ -5,9 +5,11 @@ from typing import Annotated
|
|
|
5
5
|
import typer
|
|
6
6
|
from mm_std import print_plain
|
|
7
7
|
|
|
8
|
+
from mm_sol.account import PHANTOM_DERIVATION_PATH
|
|
9
|
+
|
|
8
10
|
from . import cli_utils
|
|
9
11
|
from .cmd import balance_cmd, balances_cmd, example_cmd, node_cmd, transfer_sol_cmd, transfer_token_cmd
|
|
10
|
-
from .cmd.wallet import keypair_cmd,
|
|
12
|
+
from .cmd.wallet import keypair_cmd, mnemonic_cmd
|
|
11
13
|
|
|
12
14
|
app = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=False, add_completion=False)
|
|
13
15
|
|
|
@@ -102,12 +104,16 @@ def node_command(
|
|
|
102
104
|
node_cmd.run(urls, proxy)
|
|
103
105
|
|
|
104
106
|
|
|
105
|
-
@wallet_app.command(name="
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
@wallet_app.command(name="mnemonic", help="Derive accounts from a mnemonic")
|
|
108
|
+
@wallet_app.command(name="m", hidden=True)
|
|
109
|
+
def wallet_mnemonic_command( # nosec
|
|
110
|
+
mnemonic: Annotated[str, typer.Option("--mnemonic", "-m")] = "",
|
|
111
|
+
passphrase: Annotated[str, typer.Option("--passphrase", "-p")] = "",
|
|
112
|
+
derivation_path: Annotated[str, typer.Option("--path")] = PHANTOM_DERIVATION_PATH,
|
|
113
|
+
words: int = typer.Option(12, "--words", "-w", help="Number of mnemonic words"),
|
|
114
|
+
limit: int = typer.Option(5, "--limit", "-l"),
|
|
109
115
|
) -> None:
|
|
110
|
-
|
|
116
|
+
mnemonic_cmd.run(mnemonic, passphrase, words, derivation_path, limit)
|
|
111
117
|
|
|
112
118
|
|
|
113
119
|
@wallet_app.command(name="keypair", help="Print public, private_base58, private_arr by a private key")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from dataclasses import asdict
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from mm_std import print_json
|
|
5
|
+
|
|
6
|
+
from mm_sol.account import derive_accounts, generate_mnemonic
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def run(mnemonic: str, passphrase: str, words: int, derivation_path: str, limit: int) -> None: # nosec
|
|
10
|
+
result: dict[str, Any] = {}
|
|
11
|
+
if not mnemonic:
|
|
12
|
+
mnemonic = generate_mnemonic(words)
|
|
13
|
+
result["mnemonic"] = mnemonic
|
|
14
|
+
if passphrase:
|
|
15
|
+
result["passphrase"] = passphrase
|
|
16
|
+
accounts = derive_accounts(mnemonic=mnemonic, passphrase=passphrase, derivation_path=derivation_path, limit=limit)
|
|
17
|
+
|
|
18
|
+
result["accounts"] = [asdict(acc) for acc in accounts]
|
|
19
|
+
print_json(result)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from mm_sol.account import PHANTOM_DERIVATION_PATH
|
|
4
|
+
from mm_sol.cli.cli import app
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_mnemonic_cmd(cli_runner):
|
|
8
|
+
mnemonic = "cotton limit tube replace sister flight double muffin health neutral hill maid"
|
|
9
|
+
passphrase = "my-secret"
|
|
10
|
+
path = PHANTOM_DERIVATION_PATH
|
|
11
|
+
|
|
12
|
+
res = cli_runner.invoke(app, f"wallet mnemonic -m '{mnemonic}' -p '{passphrase}' --path '{path}' -l 11")
|
|
13
|
+
assert res.exit_code == 0
|
|
14
|
+
|
|
15
|
+
data = json.loads(res.stdout)
|
|
16
|
+
assert len(data["accounts"]) == 11
|
|
17
|
+
|
|
18
|
+
# pprint(data["accounts"][2])
|
|
19
|
+
|
|
20
|
+
assert data["accounts"][2]["address"] == "Gdfo64rJK6eZBNaN1pRMM6u2aBdpTmuSSzwNNvN8wrbC"
|
|
21
|
+
assert (
|
|
22
|
+
data["accounts"][2]["private_key"]
|
|
23
|
+
== "39YAWGyPPQBuzoCFNndZGqwHciLYPajfq3f9L37TxSrryvDB4cHKfJRWWQPx3shWAjojhayhvq8wfnf4fRrpqz2N"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_mnemonic_cmd_generates_different_result(cli_runner):
|
|
28
|
+
res1 = cli_runner.invoke(app, "wallet mnemonic -l 2")
|
|
29
|
+
data1 = json.loads(res1.stdout)
|
|
30
|
+
assert res1.exit_code == 0
|
|
31
|
+
|
|
32
|
+
res2 = cli_runner.invoke(app, "wallet mnemonic -l 2")
|
|
33
|
+
data2 = json.loads(res2.stdout)
|
|
34
|
+
assert res2.exit_code == 0
|
|
35
|
+
|
|
36
|
+
assert res1.stdout != res2.stdout
|
|
37
|
+
assert data1["accounts"][1]["address"] != data2["accounts"][1]["address"]
|
|
38
|
+
assert data1["accounts"][1]["private_key"] != data2["accounts"][1]["private_key"]
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
from mm_sol.account import (
|
|
2
|
+
PHANTOM_DERIVATION_PATH,
|
|
3
|
+
DerivedAccount,
|
|
2
4
|
check_private_key,
|
|
5
|
+
derive_accounts,
|
|
3
6
|
generate_account,
|
|
7
|
+
generate_mnemonic,
|
|
4
8
|
get_keypair,
|
|
5
9
|
get_private_key_arr_str,
|
|
6
10
|
get_private_key_base58,
|
|
@@ -127,3 +131,22 @@ def test_is_valid_pubkey():
|
|
|
127
131
|
assert is_address("9nmjQrSpmf51BxcQu6spWD8w4jUzPVrtmtPbDGLyDuan")
|
|
128
132
|
assert is_address("9nmjQrSpmf51BxcQu6spWD8w4jUzPVrtmtPbDGLyDuaN")
|
|
129
133
|
assert not is_address("9nmjQrSpmf51BxcQu6spWD8w4jUzPVrtmtPbDGLyDuama")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_generate_mnemonic():
|
|
137
|
+
assert len(generate_mnemonic().split()) == 24
|
|
138
|
+
assert len(generate_mnemonic(12).split()) == 12
|
|
139
|
+
assert generate_mnemonic() != generate_mnemonic()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_derive_accounts():
|
|
143
|
+
mnemonic = "cotton limit tube replace sister flight double muffin health neutral hill maid"
|
|
144
|
+
passphrase = "my-secret"
|
|
145
|
+
res = derive_accounts(mnemonic=mnemonic, passphrase=passphrase, derivation_path=PHANTOM_DERIVATION_PATH, limit=10)
|
|
146
|
+
assert len(res) == 10
|
|
147
|
+
assert res[2] == DerivedAccount(
|
|
148
|
+
index=2,
|
|
149
|
+
path="m/44'/501'/2'/0'",
|
|
150
|
+
address="Gdfo64rJK6eZBNaN1pRMM6u2aBdpTmuSSzwNNvN8wrbC",
|
|
151
|
+
private_key="39YAWGyPPQBuzoCFNndZGqwHciLYPajfq3f9L37TxSrryvDB4cHKfJRWWQPx3shWAjojhayhvq8wfnf4fRrpqz2N",
|
|
152
|
+
)
|
|
@@ -493,12 +493,13 @@ wheels = [
|
|
|
493
493
|
|
|
494
494
|
[[package]]
|
|
495
495
|
name = "mm-sol"
|
|
496
|
-
version = "0.3.
|
|
496
|
+
version = "0.3.3"
|
|
497
497
|
source = { editable = "." }
|
|
498
498
|
dependencies = [
|
|
499
499
|
{ name = "base58" },
|
|
500
500
|
{ name = "jinja2" },
|
|
501
501
|
{ name = "mm-crypto-utils" },
|
|
502
|
+
{ name = "mnemonic" },
|
|
502
503
|
{ name = "solana" },
|
|
503
504
|
{ name = "typer" },
|
|
504
505
|
]
|
|
@@ -518,6 +519,7 @@ requires-dist = [
|
|
|
518
519
|
{ name = "base58", specifier = "~=2.1.1" },
|
|
519
520
|
{ name = "jinja2", specifier = ">=3.1.5" },
|
|
520
521
|
{ name = "mm-crypto-utils", specifier = ">=0.1.4" },
|
|
522
|
+
{ name = "mnemonic", specifier = "==0.21" },
|
|
521
523
|
{ name = "solana", specifier = "~=0.36.3" },
|
|
522
524
|
{ name = "typer", specifier = ">=0.15.1" },
|
|
523
525
|
]
|
|
@@ -525,7 +527,7 @@ requires-dist = [
|
|
|
525
527
|
[package.metadata.requires-dev]
|
|
526
528
|
dev = [
|
|
527
529
|
{ name = "bandit", specifier = "~=1.8.2" },
|
|
528
|
-
{ name = "mypy", specifier = "~=1.
|
|
530
|
+
{ name = "mypy", specifier = "~=1.15.0" },
|
|
529
531
|
{ name = "pip-audit", specifier = "~=2.7.3" },
|
|
530
532
|
{ name = "pytest", specifier = "~=8.3.4" },
|
|
531
533
|
{ name = "pytest-xdist", specifier = "~=3.6.1" },
|
|
@@ -549,6 +551,15 @@ wheels = [
|
|
|
549
551
|
{ url = "https://files.pythonhosted.org/packages/f3/ef/cb423cc357cc116313fcd97e9d0ff673234f5f1725f4a73929ced27b1d00/mm_std-0.2.1-py3-none-any.whl", hash = "sha256:71fa84f2fa897901c925614327123e8d0bc6ae61ff7873479dc9a53889442237", size = 14620 },
|
|
550
552
|
]
|
|
551
553
|
|
|
554
|
+
[[package]]
|
|
555
|
+
name = "mnemonic"
|
|
556
|
+
version = "0.21"
|
|
557
|
+
source = { registry = "https://pypi.org/simple" }
|
|
558
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ff/77/e6232ed59fbd7b90208bb8d4f89ed5aabcf30a524bc2fb8f0dafbe8e7df9/mnemonic-0.21.tar.gz", hash = "sha256:1fe496356820984f45559b1540c80ff10de448368929b9c60a2b55744cc88acf", size = 152462 }
|
|
559
|
+
wheels = [
|
|
560
|
+
{ url = "https://files.pythonhosted.org/packages/57/48/5abb16ce7f9d97b728e6b97c704ceaa614362e0847651f379ed0511942a0/mnemonic-0.21-py3-none-any.whl", hash = "sha256:72dc9de16ec5ef47287237b9b6943da11647a03fe7cf1f139fc3d7c4a7439288", size = 92701 },
|
|
561
|
+
]
|
|
562
|
+
|
|
552
563
|
[[package]]
|
|
553
564
|
name = "msgpack"
|
|
554
565
|
version = "1.1.0"
|
|
@@ -581,27 +592,27 @@ wheels = [
|
|
|
581
592
|
|
|
582
593
|
[[package]]
|
|
583
594
|
name = "mypy"
|
|
584
|
-
version = "1.
|
|
595
|
+
version = "1.15.0"
|
|
585
596
|
source = { registry = "https://pypi.org/simple" }
|
|
586
597
|
dependencies = [
|
|
587
598
|
{ name = "mypy-extensions" },
|
|
588
599
|
{ name = "typing-extensions" },
|
|
589
600
|
]
|
|
590
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
591
|
-
wheels = [
|
|
592
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
593
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
594
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
595
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
596
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
597
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
598
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
599
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
600
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
601
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
602
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
603
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
604
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
601
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 }
|
|
602
|
+
wheels = [
|
|
603
|
+
{ url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 },
|
|
604
|
+
{ url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 },
|
|
605
|
+
{ url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 },
|
|
606
|
+
{ url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 },
|
|
607
|
+
{ url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 },
|
|
608
|
+
{ url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 },
|
|
609
|
+
{ url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 },
|
|
610
|
+
{ url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 },
|
|
611
|
+
{ url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 },
|
|
612
|
+
{ url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 },
|
|
613
|
+
{ url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 },
|
|
614
|
+
{ url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 },
|
|
615
|
+
{ url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 },
|
|
605
616
|
]
|
|
606
617
|
|
|
607
618
|
[[package]]
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from mm_std import print_json
|
|
2
|
-
|
|
3
|
-
from mm_sol.account import generate_account, get_private_key_arr_str
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def run(limit: int, array: bool) -> None:
|
|
7
|
-
result = {}
|
|
8
|
-
for _ in range(limit):
|
|
9
|
-
acc = generate_account()
|
|
10
|
-
private_key = acc.private_key_base58
|
|
11
|
-
if array:
|
|
12
|
-
private_key = get_private_key_arr_str(acc.private_key_base58)
|
|
13
|
-
result[acc.public_key] = private_key
|
|
14
|
-
print_json(result)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
|
-
from mm_sol.account import get_public_key
|
|
4
|
-
from mm_sol.cli.cli import app
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def test_new_cmd(cli_runner):
|
|
8
|
-
res = cli_runner.invoke(app, "wallet new -l 11")
|
|
9
|
-
assert res.exit_code == 0
|
|
10
|
-
|
|
11
|
-
accounts = json.loads(res.stdout)
|
|
12
|
-
assert len(accounts) == 11
|
|
13
|
-
for address, private in accounts.items():
|
|
14
|
-
assert address == get_public_key(private)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def test_new_generates_different_keys(cli_runner):
|
|
18
|
-
res1 = cli_runner.invoke(app, "wallet new -l 2")
|
|
19
|
-
assert res1.exit_code == 0
|
|
20
|
-
|
|
21
|
-
res2 = cli_runner.invoke(app, "wallet new -l 2")
|
|
22
|
-
assert res2.exit_code == 0
|
|
23
|
-
|
|
24
|
-
assert res1.stdout != res2.stdout
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|