aiosend 0.1.14__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.
- aiosend-0.1.14/LICENSE.txt +21 -0
- aiosend-0.1.14/PKG-INFO +104 -0
- aiosend-0.1.14/README.md +70 -0
- aiosend-0.1.14/aiosend/__init__.py +12 -0
- aiosend-0.1.14/aiosend/__meta__.py +2 -0
- aiosend-0.1.14/aiosend/client/__init__.py +13 -0
- aiosend-0.1.14/aiosend/client/api_server.py +54 -0
- aiosend-0.1.14/aiosend/client/client.py +85 -0
- aiosend-0.1.14/aiosend/client/client.pyi +212 -0
- aiosend-0.1.14/aiosend/client/session/__init__.py +7 -0
- aiosend-0.1.14/aiosend/client/session/aiohttp.py +69 -0
- aiosend-0.1.14/aiosend/client/session/base.py +82 -0
- aiosend-0.1.14/aiosend/enums/__init__.py +24 -0
- aiosend-0.1.14/aiosend/enums/asset.py +53 -0
- aiosend-0.1.14/aiosend/enums/check_status.py +15 -0
- aiosend-0.1.14/aiosend/enums/currency_type.py +15 -0
- aiosend-0.1.14/aiosend/enums/fiat.py +55 -0
- aiosend-0.1.14/aiosend/enums/invoice_status.py +17 -0
- aiosend-0.1.14/aiosend/enums/paid_btn_name.py +24 -0
- aiosend-0.1.14/aiosend/enums/update_type.py +11 -0
- aiosend-0.1.14/aiosend/exceptions.py +54 -0
- aiosend-0.1.14/aiosend/loggers.py +5 -0
- aiosend-0.1.14/aiosend/methods/__init__.py +50 -0
- aiosend-0.1.14/aiosend/methods/base.py +18 -0
- aiosend-0.1.14/aiosend/methods/create_check.py +45 -0
- aiosend-0.1.14/aiosend/methods/create_invoice.py +100 -0
- aiosend-0.1.14/aiosend/methods/delete_check.py +33 -0
- aiosend-0.1.14/aiosend/methods/delete_invoice.py +33 -0
- aiosend-0.1.14/aiosend/methods/get_balance.py +30 -0
- aiosend-0.1.14/aiosend/methods/get_checks.py +48 -0
- aiosend-0.1.14/aiosend/methods/get_currencies.py +32 -0
- aiosend-0.1.14/aiosend/methods/get_exchange_rates.py +32 -0
- aiosend-0.1.14/aiosend/methods/get_invoices.py +60 -0
- aiosend-0.1.14/aiosend/methods/get_me.py +30 -0
- aiosend-0.1.14/aiosend/methods/get_stats.py +39 -0
- aiosend-0.1.14/aiosend/methods/get_transfers.py +50 -0
- aiosend-0.1.14/aiosend/methods/transfer.py +61 -0
- aiosend-0.1.14/aiosend/polling/__init__.py +7 -0
- aiosend-0.1.14/aiosend/polling/manager.py +206 -0
- aiosend-0.1.14/aiosend/py.typed +0 -0
- aiosend-0.1.14/aiosend/tools/__init__.py +23 -0
- aiosend-0.1.14/aiosend/tools/delete_all_checks.py +28 -0
- aiosend-0.1.14/aiosend/tools/delete_all_invoices.py +28 -0
- aiosend-0.1.14/aiosend/tools/exchange.py +38 -0
- aiosend-0.1.14/aiosend/tools/get_balance_by_asset.py +33 -0
- aiosend-0.1.14/aiosend/tools/get_invoice.py +34 -0
- aiosend-0.1.14/aiosend/types/__init__.py +35 -0
- aiosend-0.1.14/aiosend/types/app.py +16 -0
- aiosend-0.1.14/aiosend/types/app_stats.py +26 -0
- aiosend-0.1.14/aiosend/types/balance.py +18 -0
- aiosend-0.1.14/aiosend/types/base.py +61 -0
- aiosend-0.1.14/aiosend/types/base.pyi +31 -0
- aiosend-0.1.14/aiosend/types/check.py +71 -0
- aiosend-0.1.14/aiosend/types/check.pyi +25 -0
- aiosend-0.1.14/aiosend/types/currency.py +26 -0
- aiosend-0.1.14/aiosend/types/exchange_rate.py +24 -0
- aiosend-0.1.14/aiosend/types/invoice.py +133 -0
- aiosend-0.1.14/aiosend/types/invoice.pyi +56 -0
- aiosend-0.1.14/aiosend/types/transfer.py +31 -0
- aiosend-0.1.14/aiosend/types/update.py +19 -0
- aiosend-0.1.14/aiosend/utils/__init__.py +7 -0
- aiosend-0.1.14/aiosend/utils/list_serializer.py +18 -0
- aiosend-0.1.14/aiosend/utils/propagating_thread.py +34 -0
- aiosend-0.1.14/aiosend/utils/sync.py +49 -0
- aiosend-0.1.14/aiosend/webhook/__init__.py +13 -0
- aiosend-0.1.14/aiosend/webhook/aiohttp_manager.py +35 -0
- aiosend-0.1.14/aiosend/webhook/base.py +131 -0
- aiosend-0.1.14/aiosend/webhook/fastapi_manager.py +37 -0
- aiosend-0.1.14/aiosend/webhook/flask_manager.py +37 -0
- aiosend-0.1.14/pyproject.toml +88 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 - present VoVcHiC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
aiosend-0.1.14/PKG-INFO
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aiosend
|
|
3
|
+
Version: 0.1.14
|
|
4
|
+
Summary: sync & async Crypto Pay API client.
|
|
5
|
+
Home-page: https://github.com/vovchic17/
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: crypto pay,CryptoBot,Crypto Pay API
|
|
8
|
+
Author: VoVcHiC
|
|
9
|
+
Author-email: tsvetkovvova17@gmail.com
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Provides-Extra: docs
|
|
18
|
+
Provides-Extra: fastapi
|
|
19
|
+
Provides-Extra: flask
|
|
20
|
+
Requires-Dist: aiohttp (>=3.9,<4.0)
|
|
21
|
+
Requires-Dist: certifi (>=2024.8.30,<2025.0.0)
|
|
22
|
+
Requires-Dist: fastapi[standard] (>=0.115.0,<0.116.0) ; extra == "fastapi"
|
|
23
|
+
Requires-Dist: flask[async] (>=3.0.3,<4.0.0) ; extra == "flask"
|
|
24
|
+
Requires-Dist: furo (>=2024.0.0,<2025.0.0) ; extra == "docs"
|
|
25
|
+
Requires-Dist: matplotlib (>=3.9.2,<4.0.0) ; extra == "docs"
|
|
26
|
+
Requires-Dist: pydantic (>=2.4,<3.0)
|
|
27
|
+
Requires-Dist: sphinx-autodoc-typehints (>=2.3.0,<3.0.0) ; extra == "docs"
|
|
28
|
+
Requires-Dist: sphinx-copybutton (>=0.5.2,<0.6.0) ; extra == "docs"
|
|
29
|
+
Requires-Dist: sphinxext-opengraph (>=0.9.1,<0.10.0) ; extra == "docs"
|
|
30
|
+
Project-URL: Documentation, https://aiocp.rtfd.io/en/latest/
|
|
31
|
+
Project-URL: Repository, https://github.com/vovchic17/
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<img src="docs/_static/logo.png" align="center"/>
|
|
36
|
+
<h1 align="center">aiocp</h1>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
[](https://www.python.org/)
|
|
40
|
+
[](https://help.crypt.bot/crypto-pay-api)
|
|
41
|
+
[](https://aiocp.readthedocs.io/en/latest/?badge=latest)
|
|
42
|
+
[](https://pydantic.dev)
|
|
43
|
+
[](https://docs.aiohttp.org/en/stable/)
|
|
44
|
+
[](https://github.com/charliermarsh/ruff)
|
|
45
|
+
[](https://mypy-lang.org/)
|
|
46
|
+
|
|
47
|
+
**aiocp** is a syncronous & asynchronous [Crypto Pay API](https://help.crypt.bot/crypto-pay-api) client.
|
|
48
|
+
|
|
49
|
+
> ## [Official documentation](https://aiocp.readthedocs.io/en/latest/)
|
|
50
|
+
> ## [<img src="https://raw.githubusercontent.com/vovchic17/static/2cae16d0c4289f9556dacc13322dd4a2fcca214f/src/telegram_logo.svg" width="30" align="top"> Telegram chat](https://aiocp.t.me/)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
```python
|
|
55
|
+
import asyncio
|
|
56
|
+
from aiocp import CryptoPay
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
async def main():
|
|
60
|
+
cp = CryptoPay(token="TOKEN")
|
|
61
|
+
app = await cp.get_me()
|
|
62
|
+
print(app.name) # Your App Name
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
asyncio.run(main())
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## aiogram 3.x integration example
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import asyncio
|
|
73
|
+
from aiogram import Bot, Dispatcher
|
|
74
|
+
from aiocp import CryptoPay
|
|
75
|
+
|
|
76
|
+
cp = CryptoPay("TOKEN")
|
|
77
|
+
bot = Bot("TOKEN")
|
|
78
|
+
dp = Dispatcher()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dp.message()
|
|
82
|
+
async def get_invoice(message):
|
|
83
|
+
invoice = await cp.create_invoice(1, "USDT")
|
|
84
|
+
await message.answer(f"pay: {invoice.bot_invoice_url}")
|
|
85
|
+
invoice.await_payment(message=message)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@cp.polling_handler()
|
|
89
|
+
async def handle_payment(invoice, message):
|
|
90
|
+
await message.answer(f"invoice #{invoice.invoice_id} has been paid")
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
async def main():
|
|
94
|
+
await asyncio.gather(
|
|
95
|
+
dp.start_polling(bot),
|
|
96
|
+
cp.start_polling(),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
asyncio.run(main())
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
aiosend-0.1.14/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/_static/logo.png" align="center"/>
|
|
3
|
+
<h1 align="center">aiocp</h1>
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
[](https://help.crypt.bot/crypto-pay-api)
|
|
8
|
+
[](https://aiocp.readthedocs.io/en/latest/?badge=latest)
|
|
9
|
+
[](https://pydantic.dev)
|
|
10
|
+
[](https://docs.aiohttp.org/en/stable/)
|
|
11
|
+
[](https://github.com/charliermarsh/ruff)
|
|
12
|
+
[](https://mypy-lang.org/)
|
|
13
|
+
|
|
14
|
+
**aiocp** is a syncronous & asynchronous [Crypto Pay API](https://help.crypt.bot/crypto-pay-api) client.
|
|
15
|
+
|
|
16
|
+
> ## [Official documentation](https://aiocp.readthedocs.io/en/latest/)
|
|
17
|
+
> ## [<img src="https://raw.githubusercontent.com/vovchic17/static/2cae16d0c4289f9556dacc13322dd4a2fcca214f/src/telegram_logo.svg" width="30" align="top"> Telegram chat](https://aiocp.t.me/)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
```python
|
|
22
|
+
import asyncio
|
|
23
|
+
from aiocp import CryptoPay
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def main():
|
|
27
|
+
cp = CryptoPay(token="TOKEN")
|
|
28
|
+
app = await cp.get_me()
|
|
29
|
+
print(app.name) # Your App Name
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
asyncio.run(main())
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## aiogram 3.x integration example
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import asyncio
|
|
40
|
+
from aiogram import Bot, Dispatcher
|
|
41
|
+
from aiocp import CryptoPay
|
|
42
|
+
|
|
43
|
+
cp = CryptoPay("TOKEN")
|
|
44
|
+
bot = Bot("TOKEN")
|
|
45
|
+
dp = Dispatcher()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dp.message()
|
|
49
|
+
async def get_invoice(message):
|
|
50
|
+
invoice = await cp.create_invoice(1, "USDT")
|
|
51
|
+
await message.answer(f"pay: {invoice.bot_invoice_url}")
|
|
52
|
+
invoice.await_payment(message=message)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@cp.polling_handler()
|
|
56
|
+
async def handle_payment(invoice, message):
|
|
57
|
+
await message.answer(f"invoice #{invoice.invoice_id} has been paid")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def main():
|
|
61
|
+
await asyncio.gather(
|
|
62
|
+
dp.start_polling(bot),
|
|
63
|
+
cp.start_polling(),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .api_server import MAINNET, TESTNET, APIServer
|
|
2
|
+
from .client import CryptoPay
|
|
3
|
+
from .session.aiohttp import AiohttpSession
|
|
4
|
+
from .session.base import BaseSession
|
|
5
|
+
|
|
6
|
+
__all__ = (
|
|
7
|
+
"MAINNET",
|
|
8
|
+
"TESTNET",
|
|
9
|
+
"APIServer",
|
|
10
|
+
"AiohttpSession",
|
|
11
|
+
"BaseSession",
|
|
12
|
+
"CryptoPay",
|
|
13
|
+
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from aiosend.enums import Asset, Fiat
|
|
8
|
+
from aiosend.methods import CryptoPayMethod
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class APIServer:
|
|
13
|
+
"""Configuration for endpoints."""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
"""Net name"""
|
|
17
|
+
base: str
|
|
18
|
+
"""Base URL"""
|
|
19
|
+
|
|
20
|
+
def url(self, method: "CryptoPayMethod") -> str:
|
|
21
|
+
"""Return URL for method."""
|
|
22
|
+
return self.base.format(method=method.__method__)
|
|
23
|
+
|
|
24
|
+
def get_qr(self, link: str) -> str:
|
|
25
|
+
"""Return qr code link."""
|
|
26
|
+
return f"https://qr.crypt.bot/?url={link}"
|
|
27
|
+
|
|
28
|
+
def get_image(
|
|
29
|
+
self,
|
|
30
|
+
asset: "Asset | str",
|
|
31
|
+
asset_amount: float,
|
|
32
|
+
fiat: "Fiat | str",
|
|
33
|
+
fiat_amount: float,
|
|
34
|
+
main: "Literal['asset', 'fiat']",
|
|
35
|
+
) -> str:
|
|
36
|
+
"""Return check image url."""
|
|
37
|
+
return (
|
|
38
|
+
"https://imggen.send.tg/checks/image?"
|
|
39
|
+
f"asset={asset}"
|
|
40
|
+
f"&asset_amount={asset_amount}"
|
|
41
|
+
f"&fiat={fiat}"
|
|
42
|
+
f"&fiat_amount={fiat_amount}"
|
|
43
|
+
f"&main={main}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
MAINNET = APIServer(
|
|
48
|
+
name="MAINNET",
|
|
49
|
+
base="https://pay.crypt.bot/api/{method}",
|
|
50
|
+
)
|
|
51
|
+
TESTNET = APIServer(
|
|
52
|
+
name="TESTNET",
|
|
53
|
+
base="https://testnet-pay.crypt.bot/api/{method}",
|
|
54
|
+
)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from aiosend import loggers
|
|
4
|
+
from aiosend.client import MAINNET, TESTNET
|
|
5
|
+
from aiosend.exceptions import APIError, WrongNetworkError
|
|
6
|
+
from aiosend.methods import Methods
|
|
7
|
+
from aiosend.polling import PollingConfig, PollingManager
|
|
8
|
+
from aiosend.tools import Tools
|
|
9
|
+
from aiosend.utils import PropagatingThread
|
|
10
|
+
from aiosend.webhook import AiohttpManager, RequestHandler
|
|
11
|
+
|
|
12
|
+
from .session import AiohttpSession
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from aiosend.client import APIServer
|
|
16
|
+
from aiosend.methods import CryptoPayMethod
|
|
17
|
+
from aiosend.types import _CryptoPayType
|
|
18
|
+
from aiosend.webhook import _APP, WebhookManager
|
|
19
|
+
|
|
20
|
+
from .session import BaseSession
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class CryptoPay(Methods, Tools, RequestHandler, PollingManager):
|
|
24
|
+
"""
|
|
25
|
+
Client class providing API methods.
|
|
26
|
+
|
|
27
|
+
:param token: Crypto Bot API token
|
|
28
|
+
:param session: HTTP Session
|
|
29
|
+
:param api_server: Crypto Bot API server
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
token: str,
|
|
35
|
+
api_server: "APIServer" = MAINNET,
|
|
36
|
+
session: "type[BaseSession]" = AiohttpSession,
|
|
37
|
+
manager: "WebhookManager[_APP] | None" = None,
|
|
38
|
+
polling_config: "PollingConfig | None" = None,
|
|
39
|
+
) -> None:
|
|
40
|
+
self._token = token
|
|
41
|
+
self.session = session(api_server)
|
|
42
|
+
RequestHandler.__init__(self, manager or AiohttpManager())
|
|
43
|
+
PollingManager.__init__(self, polling_config or PollingConfig())
|
|
44
|
+
thread = PropagatingThread(target=self.__auth)
|
|
45
|
+
thread.start()
|
|
46
|
+
thread.join()
|
|
47
|
+
|
|
48
|
+
async def __call__(
|
|
49
|
+
self,
|
|
50
|
+
method: "CryptoPayMethod[_CryptoPayType]",
|
|
51
|
+
) -> "_CryptoPayType":
|
|
52
|
+
"""
|
|
53
|
+
Request method.
|
|
54
|
+
|
|
55
|
+
Use this method to make an API request.
|
|
56
|
+
|
|
57
|
+
:param method: CryptoPayMethod object.
|
|
58
|
+
:return: :class:`CryptoPayType` object.
|
|
59
|
+
"""
|
|
60
|
+
async with self.session as session:
|
|
61
|
+
loggers.client.debug("Requesting: %s", method.__method__)
|
|
62
|
+
return await session.request(self._token, self, method)
|
|
63
|
+
|
|
64
|
+
def __auth(self) -> None:
|
|
65
|
+
try:
|
|
66
|
+
me = self.get_me()
|
|
67
|
+
loggers.client.info(
|
|
68
|
+
"Authorized as '%s' id=%d on %s",
|
|
69
|
+
me.name,
|
|
70
|
+
me.app_id,
|
|
71
|
+
self.session.api_server.name,
|
|
72
|
+
)
|
|
73
|
+
except APIError:
|
|
74
|
+
current_net = self.session.api_server
|
|
75
|
+
if current_net == MAINNET:
|
|
76
|
+
self.session = self.session.__class__(TESTNET)
|
|
77
|
+
else:
|
|
78
|
+
self.session = self.session.__class__(MAINNET)
|
|
79
|
+
self.get_me()
|
|
80
|
+
net = self.session.api_server
|
|
81
|
+
msg = (
|
|
82
|
+
"Authorization failed. Token is served by the "
|
|
83
|
+
f"{net.name}, you are using {current_net.name}"
|
|
84
|
+
)
|
|
85
|
+
raise WrongNetworkError(msg) from None
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from builtins import bool as _bool
|
|
2
|
+
from builtins import float as _float
|
|
3
|
+
from builtins import list as _list
|
|
4
|
+
from builtins import str as _str
|
|
5
|
+
from collections.abc import Awaitable, Callable, Generator
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from types import NoneType as _NoneType
|
|
8
|
+
from typing import Any, TypeVar
|
|
9
|
+
|
|
10
|
+
from typing_extensions import Self
|
|
11
|
+
|
|
12
|
+
from aiosend.client import APIServer
|
|
13
|
+
from aiosend.enums import (
|
|
14
|
+
Asset,
|
|
15
|
+
CheckStatus,
|
|
16
|
+
CurrencyType,
|
|
17
|
+
Fiat,
|
|
18
|
+
InvoiceStatus,
|
|
19
|
+
LiteralAsset,
|
|
20
|
+
LiteralCheckStatus,
|
|
21
|
+
LiteralCurrencyType,
|
|
22
|
+
LiteralFiat,
|
|
23
|
+
LiteralInvoiceStatus,
|
|
24
|
+
LiteralPaidBtnName,
|
|
25
|
+
PaidBtnName,
|
|
26
|
+
)
|
|
27
|
+
from aiosend.methods import CryptoPayMethod
|
|
28
|
+
from aiosend.polling import PollingConfig
|
|
29
|
+
from aiosend.polling.manager import Handler, PollingTask
|
|
30
|
+
from aiosend.types import (
|
|
31
|
+
App,
|
|
32
|
+
AppStats,
|
|
33
|
+
Balance,
|
|
34
|
+
Check,
|
|
35
|
+
Currency,
|
|
36
|
+
ExchangeRate,
|
|
37
|
+
Invoice,
|
|
38
|
+
Transfer,
|
|
39
|
+
_CryptoPayType,
|
|
40
|
+
)
|
|
41
|
+
from aiosend.webhook import (
|
|
42
|
+
_APP,
|
|
43
|
+
WebhookManager,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
from .session import BaseSession
|
|
47
|
+
|
|
48
|
+
_T = TypeVar("_T")
|
|
49
|
+
|
|
50
|
+
# These classes are needed for syncronous type hinting.
|
|
51
|
+
# Stub file annotates the methods as syncronous, but
|
|
52
|
+
# while using this lib asynchronously, the actual return type
|
|
53
|
+
# is a coroutine that returns an annotated type, so these classes
|
|
54
|
+
# will annotate awaited object as return type.
|
|
55
|
+
|
|
56
|
+
class list(_list[_T]): # noqa: A001, N801
|
|
57
|
+
def __await__(self) -> Generator[None, None, Self]: ...
|
|
58
|
+
|
|
59
|
+
class bool(_bool): # type: ignore[misc] # noqa: A001, N801
|
|
60
|
+
def __await__(self) -> Generator[None, None, Self]: ...
|
|
61
|
+
|
|
62
|
+
class str(_str): # noqa: A001, N801
|
|
63
|
+
def __await__(self) -> Generator[None, None, Self]: ...
|
|
64
|
+
|
|
65
|
+
class float(_float): # noqa: A001, N801
|
|
66
|
+
def __await__(self) -> Generator[None, None, Self]: ...
|
|
67
|
+
|
|
68
|
+
class NoneType(_NoneType): # type: ignore[misc, valid-type]
|
|
69
|
+
def __await__(self) -> Generator[None, None, None]: ...
|
|
70
|
+
|
|
71
|
+
class CryptoPay:
|
|
72
|
+
_token: _str
|
|
73
|
+
session: BaseSession
|
|
74
|
+
_timeout: int
|
|
75
|
+
_delay: int
|
|
76
|
+
_tasks: dict[int, PollingTask]
|
|
77
|
+
_handler: Handler | None
|
|
78
|
+
_exp_handler: Handler | None
|
|
79
|
+
_webhook_manager: WebhookManager
|
|
80
|
+
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
token: _str,
|
|
84
|
+
api_server: APIServer = ...,
|
|
85
|
+
session: type[BaseSession] = ...,
|
|
86
|
+
manager: WebhookManager[_APP] | None = None,
|
|
87
|
+
polling_config: PollingConfig | None = None,
|
|
88
|
+
) -> None: ...
|
|
89
|
+
async def __call__(
|
|
90
|
+
self,
|
|
91
|
+
method: CryptoPayMethod[_CryptoPayType],
|
|
92
|
+
) -> _CryptoPayType: ...
|
|
93
|
+
def get_me(self) -> App: ...
|
|
94
|
+
def create_invoice(
|
|
95
|
+
self,
|
|
96
|
+
amount: _float,
|
|
97
|
+
asset: Asset | LiteralAsset | _str | None = None,
|
|
98
|
+
*,
|
|
99
|
+
currency_type: CurrencyType | LiteralCurrencyType | _str | None = None,
|
|
100
|
+
fiat: Fiat | LiteralFiat | _str | None = None,
|
|
101
|
+
accepted_assets: _list[Asset | LiteralAsset | _str] | None = None,
|
|
102
|
+
description: _str | None = None,
|
|
103
|
+
hidden_message: _str | None = None,
|
|
104
|
+
paid_btn_name: PaidBtnName | LiteralPaidBtnName | _str | None = None,
|
|
105
|
+
paid_btn_url: _str | None = None,
|
|
106
|
+
payload: _str | None = None,
|
|
107
|
+
allow_comments: bool | None = None,
|
|
108
|
+
allow_anonymous: bool | None = None,
|
|
109
|
+
expires_in: int | None = None,
|
|
110
|
+
) -> Invoice: ...
|
|
111
|
+
def delete_invoice(
|
|
112
|
+
self,
|
|
113
|
+
invoice_id: int,
|
|
114
|
+
) -> bool: ...
|
|
115
|
+
def create_check(
|
|
116
|
+
self,
|
|
117
|
+
amount: _float,
|
|
118
|
+
asset: Asset | LiteralAsset | _str,
|
|
119
|
+
pin_to_user_id: int | None = None,
|
|
120
|
+
pin_to_username: _str | None = None,
|
|
121
|
+
) -> Check: ...
|
|
122
|
+
def delete_check(
|
|
123
|
+
self,
|
|
124
|
+
check_id: int,
|
|
125
|
+
) -> bool: ...
|
|
126
|
+
def transfer(
|
|
127
|
+
self,
|
|
128
|
+
user_id: int,
|
|
129
|
+
asset: Asset | LiteralAsset | _str,
|
|
130
|
+
amount: _float,
|
|
131
|
+
spend_id: _str | None = None,
|
|
132
|
+
comment: _str | None = None,
|
|
133
|
+
disable_send_notification: bool | None = None,
|
|
134
|
+
) -> Transfer: ...
|
|
135
|
+
def get_invoices(
|
|
136
|
+
self,
|
|
137
|
+
asset: Asset | LiteralAsset | _str | None = None,
|
|
138
|
+
fiat: Fiat | LiteralFiat | _str | None = None,
|
|
139
|
+
invoice_ids: _list[int] | None = None,
|
|
140
|
+
status: InvoiceStatus | LiteralInvoiceStatus | _str | None = None,
|
|
141
|
+
offset: int | None = None,
|
|
142
|
+
count: int | None = None,
|
|
143
|
+
) -> list[Invoice]: ...
|
|
144
|
+
def get_checks(
|
|
145
|
+
self,
|
|
146
|
+
asset: Asset | LiteralAsset | _str | None = None,
|
|
147
|
+
check_ids: _list[int] | None = None,
|
|
148
|
+
status: CheckStatus | LiteralCheckStatus | _str | None = None,
|
|
149
|
+
offset: int | None = None,
|
|
150
|
+
count: int | None = None,
|
|
151
|
+
) -> list[Check]: ...
|
|
152
|
+
def get_transfers(
|
|
153
|
+
self,
|
|
154
|
+
asset: Asset | LiteralAsset | _str | None = None,
|
|
155
|
+
transfer_ids: _list[int] | None = None,
|
|
156
|
+
spend_id: _str | None = None,
|
|
157
|
+
offset: int | None = None,
|
|
158
|
+
count: int | None = None,
|
|
159
|
+
) -> list[Transfer]: ...
|
|
160
|
+
def get_balance(self) -> list[Balance]: ...
|
|
161
|
+
def get_exchange_rates(self) -> list[ExchangeRate]: ...
|
|
162
|
+
def get_currencies(self) -> list[Currency]: ...
|
|
163
|
+
def get_stats(
|
|
164
|
+
self,
|
|
165
|
+
start_at: datetime | None = None,
|
|
166
|
+
end_at: datetime | None = None,
|
|
167
|
+
) -> AppStats: ...
|
|
168
|
+
def delete_all_checks(self) -> NoneType: ...
|
|
169
|
+
def delete_all_invoices(self) -> NoneType: ...
|
|
170
|
+
def exchange(
|
|
171
|
+
self,
|
|
172
|
+
amount: _float,
|
|
173
|
+
source: Asset | LiteralAsset | Fiat | LiteralFiat | _str,
|
|
174
|
+
target: Asset | LiteralAsset | Fiat | LiteralFiat | _str,
|
|
175
|
+
) -> float: ...
|
|
176
|
+
def get_balance_by_asset(
|
|
177
|
+
self,
|
|
178
|
+
asset: Asset | LiteralAsset | _str,
|
|
179
|
+
) -> float: ...
|
|
180
|
+
def polling_handler(self) -> Callable[[Handler], Handler]: ...
|
|
181
|
+
def expired_handler(self) -> Callable[[Handler], Handler]: ...
|
|
182
|
+
def webhook_handler(
|
|
183
|
+
self,
|
|
184
|
+
app: _APP,
|
|
185
|
+
path: _str,
|
|
186
|
+
) -> Callable[
|
|
187
|
+
[Callable[[Invoice], Awaitable]],
|
|
188
|
+
Callable[[Invoice], Awaitable],
|
|
189
|
+
]: ...
|
|
190
|
+
def feed_update(
|
|
191
|
+
self,
|
|
192
|
+
handler: Callable[[Invoice], Awaitable],
|
|
193
|
+
body: dict[_str, Any],
|
|
194
|
+
headers: dict[_str, _str],
|
|
195
|
+
) -> NoneType: ...
|
|
196
|
+
async def __process_invoice(
|
|
197
|
+
self,
|
|
198
|
+
invoice: Invoice,
|
|
199
|
+
) -> NoneType: ...
|
|
200
|
+
def _add_invoice(
|
|
201
|
+
self,
|
|
202
|
+
invoice: Invoice,
|
|
203
|
+
data: dict[_str, Any],
|
|
204
|
+
) -> NoneType: ...
|
|
205
|
+
def start_polling(
|
|
206
|
+
self,
|
|
207
|
+
parallel: Callable[[], Any] | None = None,
|
|
208
|
+
) -> NoneType: ...
|
|
209
|
+
def get_invoice(
|
|
210
|
+
self,
|
|
211
|
+
invoice: int | Invoice,
|
|
212
|
+
) -> Invoice | NoneType: ...
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import ssl
|
|
2
|
+
from typing import TYPE_CHECKING, cast
|
|
3
|
+
|
|
4
|
+
import certifi
|
|
5
|
+
from aiohttp import ClientSession, TCPConnector
|
|
6
|
+
from aiohttp.http import SERVER_SOFTWARE
|
|
7
|
+
|
|
8
|
+
from aiosend.__meta__ import __version__
|
|
9
|
+
|
|
10
|
+
from .base import BaseSession
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
import aiosend
|
|
14
|
+
from aiosend.client import APIServer
|
|
15
|
+
from aiosend.methods import CryptoPayMethod
|
|
16
|
+
from aiosend.types import _CryptoPayType
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AiohttpSession(BaseSession):
|
|
20
|
+
"""
|
|
21
|
+
Http session based on aiohttp.
|
|
22
|
+
|
|
23
|
+
This class is a wrapper of `aiohttp.ClientSession`.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, api_server: "APIServer") -> None:
|
|
27
|
+
super().__init__(api_server)
|
|
28
|
+
self._session: ClientSession | None = None
|
|
29
|
+
|
|
30
|
+
async def request(
|
|
31
|
+
self,
|
|
32
|
+
token: str,
|
|
33
|
+
client: "aiosend.CryptoPay",
|
|
34
|
+
method: "CryptoPayMethod[_CryptoPayType]",
|
|
35
|
+
) -> "_CryptoPayType":
|
|
36
|
+
"""Make http request."""
|
|
37
|
+
ssl_context = ssl.create_default_context(cafile=certifi.where())
|
|
38
|
+
self._session = ClientSession(
|
|
39
|
+
connector=TCPConnector(
|
|
40
|
+
ssl_context=ssl_context,
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
async with self._session as session:
|
|
44
|
+
resp = await session.post(
|
|
45
|
+
url=self.api_server.url(method),
|
|
46
|
+
data=method.model_dump_json(exclude_none=True),
|
|
47
|
+
headers={
|
|
48
|
+
"Crypto-Pay-API-Token": token,
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
"User-Agent": f"{SERVER_SOFTWARE} aiosend/{__version__}",
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
response = self._check_response(client, method, await resp.text())
|
|
54
|
+
return cast("_CryptoPayType", response.result)
|
|
55
|
+
|
|
56
|
+
async def close(self) -> None:
|
|
57
|
+
"""Close http session."""
|
|
58
|
+
if self._session is not None and not self._session.closed:
|
|
59
|
+
await self._session.close()
|
|
60
|
+
|
|
61
|
+
def __del__(self) -> None:
|
|
62
|
+
"""Close session connector."""
|
|
63
|
+
if (
|
|
64
|
+
self._session is not None
|
|
65
|
+
and not self._session.closed
|
|
66
|
+
and self._session.connector is not None
|
|
67
|
+
and self._session.connector_owner
|
|
68
|
+
):
|
|
69
|
+
self._session.connector.close()
|