mm-apt 0.3.1__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.
@@ -0,0 +1 @@
1
+ MAINNET_RPC_URL=https://fullnode.mainnet.aptoslabs.com/v1
@@ -0,0 +1,14 @@
1
+ .idea
2
+ .venv
3
+ .env
4
+ .coverage
5
+ /htmlcov
6
+ __pycache__
7
+ *.egg-info
8
+ pip-wheel-metadata
9
+ .pytest_cache
10
+ .mypy_cache
11
+ .ruff_cache
12
+ /dist
13
+ /build
14
+ /tmp
mm_apt-0.3.1/PKG-INFO ADDED
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.4
2
+ Name: mm-apt
3
+ Version: 0.3.1
4
+ Requires-Python: >=3.12
5
+ Requires-Dist: mm-crypto-utils>=0.3.1
@@ -0,0 +1,2 @@
1
+ https://aptos.dev/
2
+ https://aptoscan.com/
mm_apt-0.3.1/dict.dic ADDED
@@ -0,0 +1 @@
1
+ ndigits
mm_apt-0.3.1/justfile ADDED
@@ -0,0 +1,33 @@
1
+ set dotenv-load
2
+ version := `uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])'`
3
+
4
+
5
+ clean:
6
+ rm -rf .pytest_cache .mypy_cache .ruff_cache .coverage dist build src/*.egg-info
7
+
8
+ build: clean lint audit test
9
+ uv build
10
+
11
+ format:
12
+ uv run ruff check --select I --fix src tests
13
+ uv run ruff format src tests
14
+
15
+ test:
16
+ uv run pytest -n auto tests
17
+
18
+ lint: format
19
+ uv run ruff check src tests
20
+ uv run mypy src
21
+
22
+ audit:
23
+ uv run pip-audit
24
+ uv run bandit -r -c "pyproject.toml" src
25
+
26
+ publish: build
27
+ git diff-index --quiet HEAD
28
+ uvx twine upload dist/**
29
+ git tag -a 'v{{version}}' -m 'v{{version}}'
30
+ git push origin v{{version}}
31
+
32
+ sync:
33
+ uv sync
@@ -0,0 +1,72 @@
1
+ [project]
2
+ name = "mm-apt"
3
+ version = "0.3.1"
4
+ description = ""
5
+ requires-python = ">=3.12"
6
+ dependencies = [
7
+ "mm-crypto-utils>=0.3.1",
8
+ ]
9
+
10
+ [build-system]
11
+ requires = ["hatchling"]
12
+ build-backend = "hatchling.build"
13
+
14
+ [tool.uv]
15
+ dev-dependencies = [
16
+ "pytest~=8.3.5",
17
+ "pytest-xdist~=3.6.1",
18
+ "ruff~=0.11.5",
19
+ "pip-audit~=2.9.0",
20
+ "bandit~=1.8.3",
21
+ "mypy~=1.15.0",
22
+ "pytest-asyncio>=0.26.0",
23
+ ]
24
+
25
+ [tool.mypy]
26
+ python_version = "3.13"
27
+ warn_no_return = false
28
+ strict = true
29
+ exclude = ["^tests/", "^tmp/"]
30
+
31
+ [tool.ruff]
32
+ line-length = 130
33
+ target-version = "py313"
34
+ [tool.ruff.lint]
35
+ select = ["ALL"]
36
+ ignore = [
37
+ "TC", # flake8-type-checking, TYPE_CHECKING is dangerous, for example it doesn't work with pydantic
38
+ "A005", # flake8-builtins: stdlib-module-shadowing
39
+ "ERA001", # eradicate: commented-out-code
40
+ "PT", # flake8-pytest-style
41
+ "D", # pydocstyle
42
+ "FIX", # flake8-fixme
43
+ "PLR0911", # pylint: too-many-return-statements
44
+ "PLR0912", # pylint: too-many-branches
45
+ "PLR0913", # pylint: too-many-arguments
46
+ "PLR2004", # pylint: magic-value-comparison
47
+ "PLC0414", # pylint: useless-import-alias
48
+ "FBT", # flake8-boolean-trap
49
+ "EM", # flake8-errmsg
50
+ "TRY003", # tryceratops: raise-vanilla-args
51
+ "C901", # mccabe: complex-structure,
52
+ "BLE001", # flake8-blind-except
53
+ "S311", # bandit: suspicious-non-cryptographic-random-usage
54
+ "TD002", # flake8-todos: missing-todo-author
55
+ "TD003", # flake8-todos: missing-todo-link
56
+ "RET503", # flake8-return: implicit-return
57
+ "COM812", # it's used in ruff formatter
58
+ "ASYNC109",
59
+ "G004"
60
+ ]
61
+ [tool.ruff.lint.per-file-ignores]
62
+ "tests/*.py" = ["ANN", "S"]
63
+ [tool.ruff.format]
64
+ quote-style = "double"
65
+ indent-style = "space"
66
+
67
+ [tool.bandit]
68
+ exclude_dirs = ["tests"]
69
+ skips = ["B311"]
70
+
71
+ [tool.pytest.ini_options]
72
+ asyncio_default_fixture_loop_scope = "function"
File without changes
@@ -0,0 +1,27 @@
1
+ from mm_std import Result, http_request
2
+
3
+
4
+ async def address_to_name(address: str, timeout: float = 5, proxy: str | None = None) -> Result[str | None]:
5
+ url = f"https://www.aptosnames.com/api/mainnet/v1/name/{address}"
6
+ res = await http_request(url, proxy=proxy, timeout=timeout)
7
+ if res.is_error():
8
+ return res.to_result_failure()
9
+ json_res = res.parse_json_body()
10
+ if res.status_code == 200 and json_res == {}:
11
+ return res.to_result_success(None)
12
+ if "name" in json_res:
13
+ return res.to_result_success(json_res["name"])
14
+ return res.to_result_failure("unknown_response")
15
+
16
+
17
+ async def address_to_primary_name(address: str, timeout: float = 5, proxy: str | None = None) -> Result[str | None]:
18
+ url = f"https://www.aptosnames.com/api/mainnet/v1/primary-name/{address}"
19
+ res = await http_request(url, proxy=proxy, timeout=timeout)
20
+ if res.is_error():
21
+ return res.to_result_failure()
22
+ json_res = res.parse_json_body()
23
+ if res.status_code == 200 and json_res == {}:
24
+ return res.to_result_success(None)
25
+ if "name" in json_res:
26
+ return res.to_result_success(json_res["name"])
27
+ return res.to_result_failure("unknown_response")
@@ -0,0 +1,13 @@
1
+ from mm_std import Result, http_request
2
+
3
+
4
+ async def get_balance(node: str, account: str, coin_type: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
5
+ url = f"{node}/accounts/{account}/resource/0x1::coin::CoinStore%3C{coin_type}%3E"
6
+ res = await http_request(url, proxy=proxy, timeout=timeout)
7
+ try:
8
+ json_res = res.parse_json_body()
9
+ if json_res.get("error_code") == "resource_not_found":
10
+ return res.to_result_success(0)
11
+ return res.to_result_success(int(json_res["data"]["coin"]["value"]))
12
+ except Exception as e:
13
+ return res.to_result_failure(e)
@@ -0,0 +1,2 @@
1
+ APTOS_COIN_TYPE = "0x1::aptos_coin::AptosCoin"
2
+ APTOS_COIN_DECIMALS = 8
File without changes
File without changes
@@ -0,0 +1,17 @@
1
+ import pytest
2
+ from mm_std import get_dotenv
3
+
4
+
5
+ @pytest.fixture
6
+ def anyio_backend() -> str:
7
+ return "asyncio"
8
+
9
+
10
+ @pytest.fixture
11
+ def mainnet_rpc_url() -> str:
12
+ return get_dotenv("MAINNET_RPC_URL")
13
+
14
+
15
+ @pytest.fixture
16
+ def okx_address() -> str:
17
+ return "0x834d639b10d20dcb894728aa4b9b572b2ea2d97073b10eacb111f338b20ea5d7"
@@ -0,0 +1,21 @@
1
+ import pytest
2
+
3
+ from mm_apt import ans
4
+
5
+ pytestmark = pytest.mark.asyncio
6
+
7
+
8
+ async def test_address_to_primary_name():
9
+ address = "0x68e6982c788b50e3caccc834a4764763381d7201be996914e1310139a35854ed"
10
+ assert (await ans.address_to_primary_name(address)).unwrap() == "vitalik"
11
+
12
+ address = "0xabfabdec0732564bd906fb94e467410a131c6e6040f7bca860458e2026e3b14e"
13
+ assert (await ans.address_to_primary_name(address)).unwrap() is None
14
+
15
+
16
+ async def test_address_to_name_async():
17
+ address = "0x68e6982c788b50e3caccc834a4764763381d7201be996914e1310139a35854ed"
18
+ assert (await ans.address_to_name(address)).ok == "vitalik"
19
+
20
+ address = "0xabfabdec0732564bd906fb94e467410a131c6e6040f7bca860458e2026e3b14e"
21
+ assert (await ans.address_to_primary_name(address)).ok is None
@@ -0,0 +1,11 @@
1
+ import pytest
2
+
3
+ from mm_apt.balance import get_balance
4
+ from mm_apt.coin import APTOS_COIN_TYPE
5
+
6
+ pytestmark = pytest.mark.asyncio
7
+
8
+
9
+ async def test_get_balance(mainnet_rpc_url, okx_address):
10
+ res = await get_balance(mainnet_rpc_url, okx_address, APTOS_COIN_TYPE)
11
+ assert res.unwrap() > 1000