26 Commits
1.0.1 ... docs

Author SHA1 Message Date
deesiigneer
b4ddd1fd93 update example 2022-07-18 22:27:58 +03:00
deesiigneer
5449659566 update example 2022-07-18 22:15:43 +03:00
deesiigneer
85ef993011 update example and add get_uuids() example 2022-07-18 22:15:05 +03:00
deesiigneer
8e6664bc51 new feature get_uuids() 2022-07-18 22:14:06 +03:00
deesiigneer
0d46f0a126 version bump 2022-07-18 22:12:48 +03:00
Aleksey
f5484d3900 version fix 2022-07-18 05:59:29 +03:00
Aleksey
1c35daf142 Delete 68747470733a2f2f692e696d6775722e636f6d2f6d656c685768552e706e67.png 2022-07-18 05:47:29 +03:00
deesiigneer
91ed017ac6 Merge remote-tracking branch 'origin/main' 2022-07-18 05:47:10 +03:00
deesiigneer
1806ba7929 logo asset 2022-07-18 05:47:00 +03:00
deesiigneer
f4623e9204 typo pypi fix 2022-07-18 05:45:05 +03:00
Aleksey
906060a4b7 Add files via upload 2022-07-18 04:58:01 +03:00
Aleksey
6bf342a9f1 update
translate to English
2022-07-18 04:49:47 +03:00
Aleksey
a6cbf2adcc fix 2022-07-18 04:25:31 +03:00
Aleksey
59d43736c0 Update python-publish.yml 2022-07-18 03:44:58 +03:00
Aleksey
9429c443c4 Merge pull request #5 from deesiigneer/v2.0.x
v2.0.0!
2022-07-18 03:17:19 +03:00
Aleksey
152b5272c1 Update README.rst 2022-07-18 03:15:38 +03:00
deesiigneer
81d8b1de35 v2.0.0 2022-07-18 03:12:27 +03:00
Aleksey
0667922c8c Update and rename README.md to README.rst 2022-07-08 11:26:54 +03:00
Aleksey
9a61797253 Update README.md 2022-06-22 11:59:41 +03:00
Aleksey
c9c1bc8e81 Update README.md 2022-06-09 14:46:41 +03:00
Aleksey
f551a860bc Update setup.py 2022-06-08 10:53:05 +03:00
Aleksey
1065b5748b Merge pull request #3 from deesiigneer/feature/webhook_verify
Добавление webhook_verify
2022-06-08 10:50:20 +03:00
Aleksey
1d6af2b8ec Update README.md
Немного исправлено описание библиотеки и добавлено описание функции webhook_veify()
2022-06-08 10:24:55 +03:00
deesiigneer
f244e3f4db new feature webhook_verify 2022-06-08 10:00:38 +03:00
deesiigneer
76dc15a332 Merge remote-tracking branch 'origin/main' 2022-06-06 14:52:00 +03:00
deesiigneer
a2a4ac9fab fix #1 2022-06-06 14:51:38 +03:00
20 changed files with 509 additions and 192 deletions

View File

@@ -12,28 +12,27 @@ on:
release: release:
types: [published] types: [published]
permissions:
contents: read
jobs: jobs:
deploy: regular:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ 3.9 ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3 uses: actions/setup-python@v2
with: with:
python-version: '3.x' python-version: ${{ matrix.python-version }}
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install build pip install twine
- name: Build package - name: Compile package
run: python -m build run: |
python3 setup.py sdist
- name: Publish package - name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 uses: pypa/gh-action-pypi-publish@release/v1
with: with:
user: __token__ user: __token__
password: ${{ secrets.PYPI_API_TOKEN }} password: ${{ secrets.PYPI_API_TOKEN }}

View File

@@ -1,87 +0,0 @@
# pyspapi
Фреймворк [API](https://github.com/sp-worlds/api-docs) для серверов СП
## Установка
**Требуется *Python 3.7* или выше**
*Windows*
```commandline
pip install pyspapi
```
*Linux*
```commandline
sudo apt pip3 install pyspapi
```
## Примеры
### [Оплата](https://github.com/sp-worlds/api-docs/blob/main/PAYMENTS.md)
```Python
import spapi
api = spapi.Api(card_id='CARD_ID',
token='TOKEN')
print(api.payment(amount=1,
redirecturl='https://www.google.com/',
webhookurl='https://www.yourwebhook.com/',
data='Какие-то данные'
)
)
```
- `amount` - Стоимость покупки в АРах
- `redirectUrl` - URL страницы, на которую попадет пользователь после оплаты
- `webhookUrl` - URL, куда наш сервер направит запрос, чтобы оповестить ваш сервер об успешной оплате
- `data` - Строка до 100 символов, сюда можно поместить любые полезные данных.
#### Получение данных об успешной оплате
После успешной оплаты на URL указанный в `webhookUrl` придет POST запрос.
*Тело запроса будет в формате JSON:*
- `payer` - Ник игрока, который совершил оплату
- `amount` - Стоимость покупки
- `data` - Данные, которые вы отдали при создании запроса на оплату
### [Переводы](https://github.com/sp-worlds/api-docs/blob/main/TRANSACTIONS.md)
```Python
import spapi
api = spapi.Api(card_id='CARD_ID',
token='TOKEN')
print(api.transaction(receiver='12345',
amount=1,
comment="test"
)
)
```
- `receiver` - Номер карты получателя
- `amount` - Количество АР для перевода
- `comment` - Комментарий к переводу
-
### [Проверка наличия проходки](https://github.com/sp-worlds/api-docs/blob/main/USERS.md)
```Python
import spapi
api = spapi.Api(card_id='CARD_ID',
token='TOKEN')
print(api.check_user(discord_user_id=123456789012345678)
)
```
- `discord_user_id` - ID пользователя в Discord.
*В ответ вы получите JSON:*
- `username` - Ник пользователя или null, если у пользователя нет входа на сервер.
## Ссылки
- [Discord сервер разработчика](https://discord.gg/sJYtYnhN)
- [Документация API сайтов СП](https://github.com/sp-worlds/api-docs)

61
README.rst Normal file
View File

@@ -0,0 +1,61 @@
.. image:: https://i.imgur.com/melhWhU.png
:alt: pyspapi
.. image:: https://img.shields.io/discord/850091193190973472?color=5865F2&label=discord
:target: https://discord.gg/VbyHaKRAaN
:alt: Discord server invite
.. image:: https://img.shields.io/github/v/release/deesiigneer/pyspapi?include_prereleases&label=github%20release
:target: https://github.com/deesiigneer/pyspapi/
:alt: GitHub release (latest by date including pre-releases)
.. image:: https://img.shields.io/pypi/v/pyspapi.svg
:target: https://pypi.org/project/pyspapi/
:alt: PyPI downloads info
.. image:: https://img.shields.io/pypi/dm/pyspapi?color=informational&label=pypi%20downloads
:target: https://pypi.org/project/pyspapi/
:alt: PyPI version info
.. image:: https://img.shields.io/readthedocs/pyspapi
:target: https://pyspapi.readthedocs.io/
:alt: pyspapi documentation
pyspapi
========
`API <https://github.com/sp-worlds/api-docs>`_ wrapper for SP servers written in Python.
Installation
-------------
**Requires Python 3.9 or higher**
*Windows*
.. code:: sh
pip install pyspapi
*Linux/macOS*
.. code:: sh
sudo apt pip3 install pyspapi
Quick example
--------------
Checking the balance
~~~~~~~~~~~~~~~~~~~~~
.. code:: py
import pyspapi
print(pyspapi.SPAPI(card_id='card_id', token='token').balance)
More examples can be found in the `examples <https://github.com/deesiigneer/pyspapi/tree/main/examples>`_
Links
------
- `Discord server <https://discord.gg/VbyHaKRAaN>`_
- `pyspapi documentation <https://pyspapi.readthedocs.io/>`_
- `PyPi <https://pypi.org/project/pyspapi/>`_
- `API documentation for SP sites <https://github.com/sp-worlds/api-docs>`_

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,3 @@
import pyspapi
print(pyspapi.MojangAPI.get_name_history(uuid='63ed47877aa3470fbfc46c5356c3d797'))

View File

@@ -0,0 +1,20 @@
import pyspapi
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797'))
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').timestamp)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').id)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').name)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').is_legacy_profile)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').cape_url)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').skin_url)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').skin_model)
print(pyspapi.MojangAPI.get_profile(uuid='63ed47877aa3470fbfc46c5356c3d797').skin)

View File

@@ -0,0 +1,3 @@
import pyspapi
print(pyspapi.MojangAPI.get_username(uuid='63ed47877aa3470fbfc46c5356c3d797'))

View File

@@ -0,0 +1,5 @@
import pyspapi
print(pyspapi.MojangAPI.get_uuid(username='deesiigneer'))
print(pyspapi.MojangAPI.get_uuids(['deesiigneer', '5opka', 'OsterMiner']))

View File

@@ -0,0 +1,5 @@
import pyspapi
spapi = pyspapi.SPAPI(card_id='card_id', token='token').balance
print(spapi.check_users_access([262632724928397312, 264329096920563714]))

View File

@@ -0,0 +1,11 @@
import pyspapi
spapi = pyspapi.SPAPI(card_id='card_id', token='token')
print(spapi.get_user(262632724928397312))
print(spapi.get_user(262632724928397312).username)
print(spapi.get_user(262632724928397312).access)
print(spapi.get_users([262632724928397312, 264329096920563714]))

View File

@@ -0,0 +1,10 @@
import pyspapi
spapi = pyspapi.SPAPI(card_id='card_id', token='token')
print(spapi.payment(amount=1,
redirect_url='https://www.google.com/',
webhook_url='https://www.google.com/',
data='some-data'
)
)

View File

@@ -0,0 +1,9 @@
import pyspapi
spapi = pyspapi.SPAPI(card_id='CARD_ID', token='TOKEN')
print(spapi.transaction(receiver=12345,
amount=1,
comment="test"
)
)

View File

@@ -0,0 +1,5 @@
import pyspapi
spapi = pyspapi.SPAPI(card_id='your_card_id', token='your_token')
print(spapi.webhook_verify(data='webhook_data', header='webhook_header'))

3
pyspapi/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
from .api import *
__version__ = "2.1.0"

268
pyspapi/api.py Normal file
View File

@@ -0,0 +1,268 @@
import json.decoder
from sys import version_info
import ast
from base64 import b64encode, b64decode
from hmac import new, compare_digest
from hashlib import sha256
from logging import getLogger
from requests import get, post, Response
from typing import Any, Dict, List, Optional
from .models import MojangUserProfile, SPUserProfile
import warnings
log = getLogger('pyspapi')
class _Error(Exception):
"""
"""
def __init__(self, message: Optional[str] = None):
self.message = message if message else self.__class__.__doc__
super().__init__(self.message)
class SPAPI:
"""
class SPAPI
"""
_SPWORLDS_DOMAIN_ = "https://spworlds.ru/api/public"
def __init__(self, card_id: str, token: str):
self.__id = card_id
self.__token = token
self.__header = {
'Authorization': f"Bearer {str(b64encode(str(f'{self.__id}:{self.__token}').encode('utf-8')), 'utf-8')}",
'User-Agent': f'pyspapi (https://github.com/deesiigneer/pyspapi) '
f'Python {version_info.major}.{version_info.minor}.{version_info.micro}'
}
self.balance = self.__check_balance()
def __make_request(self, method: str, path: str, data: Optional[dict]) -> Optional[Response]:
if method == 'GET':
response = get(self._SPWORLDS_DOMAIN_ + path, headers=self.__header)
return response
elif method == 'POST':
response = post(self._SPWORLDS_DOMAIN_ + path, headers=self.__header, json=data)
return response
def get_user(self, user_id: int) -> Optional[SPUserProfile]:
"""
Получение информации об игроке SP \n
:param user_id: ID пользователя в Discord.
:return: Class SPUserProfile.
"""
response = self.__make_request('GET', f'/users/{str(user_id)}', data=None)
if not response.ok:
return None
try:
username = response.json()['username']
return SPUserProfile(access=True if username is not None else False, username=username)
except json.decoder.JSONDecodeError:
return
def get_users(self, user_ids: List[int]) -> List[str]:
"""
Получение никнеймов игроков в майнкрафте. **Не более 10**\n
:param user_ids: List[int] ID пользователей в Discord.
:return: List[str] который содержит майнкрафт никнеймы игроков в том же порядке, который был задан,
None если пользователь не найден или нет проходки.
"""
if len(user_ids) > 10:
user_ids = user_ids[:10]
warnings.warn('user_ids more than 10. Reduced to 10')
nicknames_list = []
for user_id in user_ids:
nicknames_list.append(self.get_user(user_id).username
if self.get_user(user_id) is not None else None)
return nicknames_list
def check_users_access(self, user_ids: List[int]) -> List[bool]:
"""
Проверка наличия проходки у списка пользователей Discord. **Не более 10**\n
:param user_ids: Список(List[int]) содержащий ID пользователей в Discord.
:return: Список(List[bool]) в том же порядке, который был задан.True - проходка имеется, иначе False.
"""
if len(user_ids) > 10:
user_ids = user_ids[:10]
warnings.warn('user_ids more than 10. Reduced to 10')
ids_list = []
for user_id in user_ids:
ids_list.append(self.get_user(user_id).access
if self.get_user(user_id) is not None else None)
return ids_list
def payment(self, amount: int, redirect_url: str, webhook_url: str, data: str) -> Optional[str]:
"""
Создание ссылки для оплаты.\n
:param amount: Стоимость покупки в АРах.
:param redirect_url: URL страницы, на которую попадет пользователь после оплаты.
:param webhook_url: URL, куда наш сервер направит запрос, чтобы оповестить ваш сервер об успешной оплате.
:param data: Строка до 100 символов, сюда можно поместить любые полезные данных.
:return: Ссылку на страницу оплаты, на которую стоит перенаправить пользователя.
"""
if len(data) > 100:
raise _Error('В data больше 100 символов')
body = {
'amount': amount,
'redirectUrl': redirect_url,
'webhookUrl': webhook_url,
'data': data
}
response = self.__make_request('POST', '/payment', data=body)
if not response.ok:
return None
try:
return response.json()['url']
except json.decoder.JSONDecodeError:
return None
def webhook_verify(self, data: str, header) -> bool:
"""
Проверяет достоверность webhook'а. \n
:param data: data из webhook.
:param header: header X-Body-Hash из webhook.
:return: True если header из webhook'а достоверен, иначе False
"""
hmac_data = b64encode(new(self.__token.encode('utf-8'), data, sha256).digest())
return compare_digest(hmac_data, header.encode('utf-8'))
def transaction(self, receiver: int, amount: int, comment: str) -> Optional[str]:
"""
Перевод АР на карту. \n
:param receiver: Номер карты получателя.
:param amount: Количество АР для перевода.
:param comment: Комментарий для перевода.
:return: True если перевод успешен, иначе False.
"""
body = {
'receiver': receiver,
'amount': amount,
'comment': comment
}
response = self.__make_request('POST', 'transactions', data=body)
if not response.ok:
return None
try:
return 'Success' if response.status_code == 200 else 'Fail'
except json.decoder.JSONDecodeError:
return None
def __check_balance(self) -> Optional[int]:
"""
Проверка баланса карты \n
:return: Количество АР на карте.
"""
response = self.__make_request('GET', '/card', None)
if not response.ok:
return None
try:
return response.json()['balance']
except json.decoder.JSONDecodeError:
return None
class MojangAPI:
"""
class MojangAPI
"""
_API_DOMAIN_ = "https://api.mojang.com"
_SESSIONSERVER_DOMAIN_ = "https://sessionserver.mojang.com"
@classmethod
def __make_request(cls, server: str, method: str, path: str, data=Optional[dict]) -> Optional[Response]:
if server == 'API':
if method == 'GET':
return get(cls._API_DOMAIN_ + path)
elif method == 'POST':
return post(cls._API_DOMAIN_ + path, json=data)
elif server == 'SESSION':
if method == 'GET':
return get(cls._SESSIONSERVER_DOMAIN_ + path)
@classmethod
def get_uuid(cls, username: str) -> Optional[str]:
"""
Получить UUID игрока Minecraft.\n
:param username: str никнейм игрока Minecraft.
:return: Optional[str] UUID игрока Minecraft.
"""
response = cls.__make_request('API', 'GET', f'/users/profiles/minecraft/{username}')
if not response.ok:
return None
try:
return response.json()['id']
except json.decoder.JSONDecodeError:
return None
@classmethod
def get_uuids(cls, names: List[str]) -> Dict[str, str]:
"""
Получить UUID's игроков Minecraft.\n
:param names: List[str] Список с никнеймами игроков Minecraft.
:return: Dict[str, str] UUID игрока Minecraft.
"""
if len(names) > 10:
names = names[:10]
response = cls.__make_request('API', 'POST', '/profiles/minecraft', data=names).json()
if not isinstance(response, list):
if response.get('error'):
raise ValueError(response['errorMessage'])
else:
raise _Error(response)
return {uuids['name']: uuids['id'] for uuids in response}
@classmethod
def get_username(cls, uuid: str) -> Optional[str]:
"""
Получить никнейм игрока.\n
:param uuid: UUID игрока Minecraft.
:return: Optional[str] в виде никнейма игрока Minecraft.
"""
response = cls.__make_request('SESSION', 'GET', f'/session/minecraft/profile/{uuid}', None)
if not response.ok:
return None
try:
return response.json()["name"]
except json.decoder.JSONDecodeError:
return None
@classmethod
def get_profile(cls, uuid: str) -> Optional[MojangUserProfile]:
"""
Профиль игрока Minecraft.\n
:param uuid: UUID игрока Minecraft.
:return: Class MojangUserProfile
"""
response = cls.__make_request('SESSION', 'GET', f'/session/minecraft/profile/{uuid}')
if not response.ok:
return None
try:
value = response.json()["properties"][0]["value"]
except (KeyError, json.decoder.JSONDecodeError):
return None
user_profile = ast.literal_eval(b64decode(value).decode())
return MojangUserProfile(user_profile)
@classmethod
def get_name_history(cls, uuid: str) -> List[Dict[str, Any]]:
"""
История никнеймов в Minecraft.\n
:param uuid: UUID игрока Minecraft.
:return: List[Dict[str, Any]] который содержит name и changed_to_at
"""
requests = cls.__make_request('API', 'GET', f"/user/profiles/{uuid}/names")
name_history = requests.json()
name_data = []
for data in name_history:
name_data_dict = {"name": data["name"]}
if data.get("changedToAt"):
name_data_dict["changed_to_at"] = data["changedToAt"]
else:
name_data_dict["changed_to_at"] = 0
name_data.append(name_data_dict)
return name_data

55
pyspapi/models.py Normal file
View File

@@ -0,0 +1,55 @@
class _SPObject:
"""Возвращает словарь всех атрибутов экземпляра"""
def to_dict(self) -> dict:
return self.__dict__.copy()
def __repr__(self):
return "%s(%s)" % (
self.__class__.__name__,
self.__dict__
)
class SPUserProfile(_SPObject):
def __init__(self,
access: bool,
username: str,
):
self.access = access
self.username = username
class _MojangObject:
def to_dict(self) -> dict:
"""Возвращает словарь всех атрибутов экземпляра"""
return self.__dict__.copy()
def __repr__(self):
return "%s(%s)" % (
self.__class__.__name__,
self.__dict__
)
class MojangUserProfile(_MojangObject):
def __init__(self, data: dict):
self.timestamp = data['timestamp']
self.id = data['profileId']
self.name = data['profileName']
self.is_legacy_profile = data.get('legacy')
if self.is_legacy_profile is None:
self.is_legacy_profile = False
self.cape_url = None
self.skin_url = None
self.skin_model = 'classic'
if data['textures'].get('CAPE'):
self.cape_url = data['textures']['CAPE']['url']
if data['textures'].get('SKIN'):
self.skin_url = data['textures']['SKIN']['url']
self.skin = data['textures']['SKIN']
if data['textures']['SKIN'].get('metadata'):
self.skin_model = 'slim'

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
requests==2.28.1

View File

@@ -1,4 +0,0 @@
[egg_info]
tag_build =
tag_date = 0

View File

@@ -1,20 +1,46 @@
import re
from setuptools import setup from setuptools import setup
from os import path requirements = []
this_directory = path.abspath(path.dirname(__file__)) with open("requirements.txt") as f:
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: requirements = f.read().splitlines()
description = f.read()
requires = ['requests==2.25.1'] version = ""
with open("pyspapi/__init__.py") as f:
match = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE)
if match is None or match.group(1) is None:
raise RuntimeError('Version is not set')
version = match.group(1)
if not version:
raise RuntimeError("Version is not set")
readme = ""
with open("README.rst") as f:
readme = f.read()
packages = [
"pyspapi"
]
setup( setup(
name='pyspapi', name='pyspapi',
version='1.0.0a', license='MIT',
description='Framework for SP API',
long_description=description,
long_description_content_type='text/markdown',
author='deesiigneer', author='deesiigneer',
author_email='xdeesiigneerx@gmail.com', version=version,
packages=['spapi'], url='https://github.com/deesiigneer/pyspapi',
install_requires=requires, project_urls={
"Documentation": "https://pyspapi.readthedocs.io/ru/latest/",
"GitHub": "https://github.com/deesiigneer/pyspapi",
"Discord": "https://discord.com/invite/VbyHaKRAaN"
},
description='API wrapper for SP servers written in Python',
long_description=readme,
long_description_content_type='text/x-rst',
packages=packages,
include_package_data=True,
install_requires=requirements,
python_requires='>=3.9.0',
) )

View File

@@ -1,76 +0,0 @@
# pyspapi by deesiigneer
#
import base64
from requests import post, get
class Error(Exception):
pass
class ApiError(Error):
pass
class Api:
def __init__(self, card_id: str, token: str):
self.id = card_id
self.token = token
self.header = {
'Authorization': f"Bearer {str(base64.b64encode(str(f'{self.id}:{self.token}').encode('utf-8')), 'utf-8')}",
}
def _fetch(self, path, data):
if path is None:
result = get(url=f'https://spworlds.ru/api/public/users/{data}',
headers=self.header)
else:
result = post(
url=f'https://spworlds.ru/api/public/{path}',
headers=self.header,
json=data
)
if result.status_code == [200, 400]:
ApiError(f'Ошибка при запросе к API {result.status_code}')
return result.json()
def payment(self, amount, redirecturl, webhookurl, data):
"""
Создание запроса на оплату.
:param amount: Стоимость покупки в АРах
:param redirecturl: URL страницы, на которую попадет пользователь после оплаты
:param webhookurl: URL, куда наш сервер направит запрос, чтобы оповестить ваш сервер об успешной оплате
:param data: Строка до 100 символов, сюда можно поместить любые полезные данных.
:return: url - Ссылка на страницу оплаты, на которую стоит перенаправить пользователя.
"""
return self._fetch('payment', data={'amount': amount,
'redirectUrl': redirecturl,
'webhookUrl': webhookurl,
'data': data})
def transaction(self, receiver, amount, comment):
"""
Перевод АР на карту.
:param receiver : Номер карты получателя
:param amount: Количество АР для перевода
:param comment: Комментарий для перевода
"""
return self._fetch('transactions', data={'receiver': receiver,
'amount': amount,
'comment': comment})
def check_user(self, discord_user_id):
"""
Проверка на наличие проходки
:param discord_user_id: Стоимость покупки в АРах
:return: username - Ник пользователя или null, если у пользователя нет проходки на сервер.
"""
return self._fetch(None, data=discord_user_id)