mm-apt 0.4.2__tar.gz → 0.5.0__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_apt-0.5.0/.claude/settings.local.json +15 -0
- mm_apt-0.5.0/.env.example +1 -0
- mm_apt-0.5.0/.pre-commit-config.yaml +10 -0
- mm_apt-0.5.0/CLAUDE.md +13 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/PKG-INFO +2 -2
- mm_apt-0.5.0/README.txt +2 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/justfile +7 -1
- mm_apt-0.5.0/pyproject.toml +73 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/src/mm_apt/ans.py +2 -2
- mm_apt-0.5.0/src/mm_apt/balance.py +32 -0
- mm_apt-0.5.0/src/mm_apt/coin.py +5 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/tests/test_account.py +1 -1
- mm_apt-0.5.0/tests/test_balance.py +12 -0
- mm_apt-0.5.0/uv.lock +1311 -0
- mm_apt-0.4.2/.env.example +0 -1
- mm_apt-0.4.2/README.txt +0 -2
- mm_apt-0.4.2/dict.dic +0 -1
- mm_apt-0.4.2/pyproject.toml +0 -74
- mm_apt-0.4.2/src/mm_apt/balance.py +0 -14
- mm_apt-0.4.2/src/mm_apt/coin.py +0 -2
- mm_apt-0.4.2/tests/test_balance.py +0 -7
- mm_apt-0.4.2/uv.lock +0 -1005
- {mm_apt-0.4.2 → mm_apt-0.5.0}/.gitignore +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/src/mm_apt/__init__.py +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/src/mm_apt/account.py +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/src/mm_apt/py.typed +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/src/mm_apt/retry.py +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/tests/__init__.py +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/tests/conftest.py +0 -0
- {mm_apt-0.4.2 → mm_apt-0.5.0}/tests/test_ans.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"WebSearch",
|
|
5
|
+
"Bash(curl:*)",
|
|
6
|
+
"Bash(just test:*)",
|
|
7
|
+
"Bash(just lint:*)",
|
|
8
|
+
"WebFetch(domain:aptoscan.com)",
|
|
9
|
+
"WebFetch(domain:github.com)",
|
|
10
|
+
"WebFetch(domain:aptos.dev)"
|
|
11
|
+
],
|
|
12
|
+
"deny": [],
|
|
13
|
+
"ask": []
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MAINNET_RPC_URL=https://api.mainnet.aptoslabs.com/v1
|
mm_apt-0.5.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Claude Guidelines
|
|
2
|
+
|
|
3
|
+
## Critical Guidelines
|
|
4
|
+
|
|
5
|
+
1. **Always communicate in English** - Regardless of the language the user speaks, always respond in English. All code, comments, and documentation must be in English.
|
|
6
|
+
|
|
7
|
+
2. **Minimal documentation** - Only add comments/documentation when it simplifies understanding and isn't obvious from the code itself. Keep it strictly relevant and concise.
|
|
8
|
+
|
|
9
|
+
3. **Critical thinking** - Always critically evaluate user ideas. Users can make mistakes. Think first about whether the user's idea is good before implementing.
|
|
10
|
+
|
|
11
|
+
4. **Lint after changes** - After making code changes, always run `just lint` to verify code quality and fix any linter issues.
|
|
12
|
+
|
|
13
|
+
5. **No disabling linter rules** - Never use special disabling comments (like `# noqa`, `# type: ignore`, `# ruff: noqa`, etc.) to turn off linter rules without explicit permission. If you believe a rule should be disabled, ask first.
|
mm_apt-0.5.0/README.txt
ADDED
|
@@ -15,7 +15,7 @@ format:
|
|
|
15
15
|
test:
|
|
16
16
|
uv run pytest -n auto tests
|
|
17
17
|
|
|
18
|
-
lint: format
|
|
18
|
+
lint: format pre-commit
|
|
19
19
|
uv run ruff check src tests
|
|
20
20
|
uv run mypy src
|
|
21
21
|
|
|
@@ -33,3 +33,9 @@ publish: build
|
|
|
33
33
|
|
|
34
34
|
sync:
|
|
35
35
|
uv sync
|
|
36
|
+
|
|
37
|
+
pre-commit:
|
|
38
|
+
uv run pre-commit run --all-files
|
|
39
|
+
|
|
40
|
+
pre-commit-autoupdate:
|
|
41
|
+
uv run pre-commit autoupdate
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mm-apt"
|
|
3
|
+
version = "0.5.0"
|
|
4
|
+
description = ""
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = ["mm-web3~=0.5.4"]
|
|
7
|
+
|
|
8
|
+
[build-system]
|
|
9
|
+
requires = ["hatchling"]
|
|
10
|
+
build-backend = "hatchling.build"
|
|
11
|
+
|
|
12
|
+
[dependency-groups]
|
|
13
|
+
dev = [
|
|
14
|
+
"pytest~=8.4.2",
|
|
15
|
+
"pytest-asyncio~=1.2.0",
|
|
16
|
+
"pytest-xdist~=3.8.0",
|
|
17
|
+
"ruff~=0.14.2",
|
|
18
|
+
"pip-audit~=2.9.0",
|
|
19
|
+
"bandit~=1.8.6",
|
|
20
|
+
"mypy~=1.18.2",
|
|
21
|
+
"pre-commit~=4.3.0",
|
|
22
|
+
"python-dotenv~=1.2.1",
|
|
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_mode = "auto"
|
|
73
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
@@ -7,7 +7,7 @@ async def address_to_name(address: str, timeout: float = 5, proxy: str | None =
|
|
|
7
7
|
res = await http_request(url, proxy=proxy, timeout=timeout)
|
|
8
8
|
if res.is_err():
|
|
9
9
|
return res.to_result_err()
|
|
10
|
-
json_res = res.
|
|
10
|
+
json_res = res.parse_json()
|
|
11
11
|
if res.status_code == 200 and json_res == {}:
|
|
12
12
|
return res.to_result_ok(None)
|
|
13
13
|
if "name" in json_res:
|
|
@@ -20,7 +20,7 @@ async def address_to_primary_name(address: str, timeout: float = 5, proxy: str |
|
|
|
20
20
|
res = await http_request(url, proxy=proxy, timeout=timeout)
|
|
21
21
|
if res.is_err():
|
|
22
22
|
return res.to_result_err()
|
|
23
|
-
json_res = res.
|
|
23
|
+
json_res = res.parse_json()
|
|
24
24
|
if res.status_code == 200 and json_res == {}:
|
|
25
25
|
return res.to_result_ok(None)
|
|
26
26
|
if "name" in json_res:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from mm_http import http_request
|
|
2
|
+
from mm_result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def get_balance(node: str, account: str, coin_type: str, timeout: float = 5, proxy: str | None = None) -> Result[int]:
|
|
6
|
+
url = f"{node}/view"
|
|
7
|
+
|
|
8
|
+
if "::" in coin_type:
|
|
9
|
+
# Coin type (e.g., 0x1::aptos_coin::AptosCoin)
|
|
10
|
+
body = {
|
|
11
|
+
"function": "0x1::coin::balance",
|
|
12
|
+
"type_arguments": [coin_type],
|
|
13
|
+
"arguments": [account],
|
|
14
|
+
}
|
|
15
|
+
else:
|
|
16
|
+
# Fungible Asset metadata address
|
|
17
|
+
body = {
|
|
18
|
+
"function": "0x1::primary_fungible_store::balance",
|
|
19
|
+
"type_arguments": ["0x1::fungible_asset::Metadata"],
|
|
20
|
+
"arguments": [account, coin_type],
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
res = await http_request(url, method="POST", json=body, proxy=proxy, timeout=timeout)
|
|
24
|
+
try:
|
|
25
|
+
json_res = res.parse_json()
|
|
26
|
+
if isinstance(json_res, list) and len(json_res) > 0:
|
|
27
|
+
return res.to_result_ok(int(json_res[0]))
|
|
28
|
+
if isinstance(json_res, dict) and json_res.get("error_code") == "resource_not_found":
|
|
29
|
+
return res.to_result_ok(0)
|
|
30
|
+
return res.to_result_err(f"Unexpected response format: {json_res}")
|
|
31
|
+
except Exception as e:
|
|
32
|
+
return res.to_result_err(e)
|
|
@@ -32,7 +32,7 @@ def test_invalid_full_length_addresses():
|
|
|
32
32
|
bad_char = "0x" + "g" + "0" * 63
|
|
33
33
|
assert is_valid_address(bad_char) is False
|
|
34
34
|
# Numeric type
|
|
35
|
-
assert is_valid_address(123) is False
|
|
35
|
+
assert is_valid_address(123) is False # pyright: ignore[reportArgumentType]
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def test_address_out_of_range():
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from mm_apt.balance import get_balance
|
|
2
|
+
from mm_apt.coin import APTOS_COIN_TYPE, USDT_METADATA
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def test_get_balance(mainnet_rpc_url, okx_address):
|
|
6
|
+
res = await get_balance(mainnet_rpc_url, okx_address, APTOS_COIN_TYPE)
|
|
7
|
+
assert res.unwrap() > 1000
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def test_get_balance_usdt(mainnet_rpc_url, okx_address):
|
|
11
|
+
res = await get_balance(mainnet_rpc_url, okx_address, USDT_METADATA)
|
|
12
|
+
assert res.unwrap() > 0
|