developing
This commit is contained in:
parent
f2d37cb5ca
commit
5c8f1acace
|
|
@ -1,5 +1,7 @@
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from custom_decorators import singleton
|
||||||
|
|
||||||
trc20token_info = {
|
trc20token_info = {
|
||||||
"usdt": {"tokenId": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
"usdt": {"tokenId": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
||||||
"tokenAbbr": "USDT",
|
"tokenAbbr": "USDT",
|
||||||
|
|
@ -9,7 +11,7 @@ trc20token_info = {
|
||||||
"vip": True}
|
"vip": True}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@singleton
|
||||||
class Tronscan:
|
class Tronscan:
|
||||||
def __init__(self, api_key):
|
def __init__(self, api_key):
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
|
|
@ -25,19 +27,19 @@ class Tronscan:
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
def transactions(self, start=0, limit=10, start_timestamp=None, end_timestamp=None,
|
def transactions(self, start=0, limit=10, start_timestamp=None, end_timestamp=None,
|
||||||
fromAddress=None, toAddress=None, tokens=None, block=None,
|
from_address=None, to_address=None, tokens=None, block=None,
|
||||||
type=None, method=None):
|
type_=None, method=None):
|
||||||
"""
|
"""
|
||||||
Get a list of transactions.
|
Get a list of transactions.
|
||||||
:param start: Start number. Default 0
|
:param start: Start number. Default 0
|
||||||
:param limit: Number of items per page. Default 10
|
:param limit: Number of items per page. Default 10
|
||||||
:param start_timestamp: Start time
|
:param start_timestamp: Start time
|
||||||
:param end_timestamp: End time
|
:param end_timestamp: End time
|
||||||
:param fromAddress: Sender's address.
|
:param from_address: Sender's address.
|
||||||
:param toAddress: Recipient's address.
|
:param to_address: Recipient's address.
|
||||||
:param tokens: Tokens involved
|
:param tokens: Tokens involved
|
||||||
:param block: Block
|
:param block: Block
|
||||||
:param type: Transaction type
|
:param type_: Transaction type
|
||||||
:param method: Method called in a smart contract signature. Only one value can be specified each time.
|
:param method: Method called in a smart contract signature. Only one value can be specified each time.
|
||||||
:return: Getx a list of transactions.
|
:return: Getx a list of transactions.
|
||||||
"""
|
"""
|
||||||
|
|
@ -52,16 +54,16 @@ class Tronscan:
|
||||||
params["start_timestamp"] = start_timestamp
|
params["start_timestamp"] = start_timestamp
|
||||||
if end_timestamp is not None:
|
if end_timestamp is not None:
|
||||||
params["end_timestamp"] = end_timestamp
|
params["end_timestamp"] = end_timestamp
|
||||||
if fromAddress is not None:
|
if from_address is not None:
|
||||||
params["fromAddress"] = fromAddress
|
params["fromAddress"] = from_address
|
||||||
if toAddress is not None:
|
if to_address is not None:
|
||||||
params["toAddress"] = toAddress
|
params["toAddress"] = to_address
|
||||||
if tokens is not None:
|
if tokens is not None:
|
||||||
params["tokens"] = tokens
|
params["tokens"] = tokens
|
||||||
if block is not None:
|
if block is not None:
|
||||||
params["block"] = block
|
params["block"] = block
|
||||||
if type is not None:
|
if type_ is not None:
|
||||||
params["type"] = type
|
params["type"] = type_
|
||||||
if method is not None:
|
if method is not None:
|
||||||
params["method"] = method
|
params["method"] = method
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
config = {
|
||||||
|
'user': 'your_mysql_username',
|
||||||
|
'password': 'your_mysql_password',
|
||||||
|
'host': 'localhost',
|
||||||
|
'database': 'your_database_name',
|
||||||
|
'autocommit': False,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
def singleton(cls):
|
||||||
|
"""
|
||||||
|
Decorator for making a class a singleton.
|
||||||
|
This ensures that only one instance of the class exists.
|
||||||
|
"""
|
||||||
|
instances = {} # Dictionary to store the instance of the singleton class
|
||||||
|
|
||||||
|
def get_instance(*args, **kwargs):
|
||||||
|
"""
|
||||||
|
If an instance of the class does not exist, create one and store it.
|
||||||
|
If it exists, return the existing instance.
|
||||||
|
"""
|
||||||
|
if cls not in instances:
|
||||||
|
instances[cls] = cls(*args, **kwargs)
|
||||||
|
return instances[cls]
|
||||||
|
|
||||||
|
return get_instance
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
from custom_decorators import singleton
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class OrderRepository:
|
||||||
|
def __init__(self):
|
||||||
|
self.db = None
|
||||||
|
|
||||||
|
def create(self, order_id, from_address, to_address):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_status(self, order_id, status):
|
||||||
|
# 更新状态和时间
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_creation_time(self, order_id):
|
||||||
|
pass
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
loguru==0.7.2
|
||||||
|
mysql-connector-python==9.1.0
|
||||||
|
Requests==2.32.3
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from custom_decorators import singleton
|
||||||
|
from repositories.order import OrderRepository
|
||||||
|
from utils.datetime import current, current_timestamp, is_time_difference_greater_than
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class OrderService:
|
||||||
|
def __init__(self):
|
||||||
|
self.order_repo = OrderRepository()
|
||||||
|
|
||||||
|
def create_order(self, from_address, to_address, *args, **kwargs):
|
||||||
|
date_str = current().strftime('%Y%m%d%H%M%S')
|
||||||
|
unique_id = str(uuid.uuid4()).split('-')[0]
|
||||||
|
order_id = f"{date_str}-{unique_id}"
|
||||||
|
self.order_repo.create(order_id, from_address, to_address)
|
||||||
|
return order_id
|
||||||
|
|
||||||
|
def finish_order(self, order_id):
|
||||||
|
# 判断支付时间是否超过订单存活时间
|
||||||
|
order_creation_time = self.order_repo.get_creation_time(order_id)
|
||||||
|
if is_time_difference_greater_than(current_timestamp(), order_creation_time, minutes=15):
|
||||||
|
status = 2
|
||||||
|
else:
|
||||||
|
status = 1
|
||||||
|
self.order_repo.update_status(order_id, status)
|
||||||
|
return status
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
from api import Tronscan
|
||||||
|
from custom_decorators import singleton
|
||||||
|
from utils.datetime import current_timestamp
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class Payment:
|
||||||
|
def __init__(self, api_key):
|
||||||
|
self.tronscan = Tronscan(api_key)
|
||||||
|
|
||||||
|
def check_payment(self, quant, from_address, to_address, order_create_timestamp):
|
||||||
|
result = self.tronscan.token_trc20_transfers(from_address=from_address,
|
||||||
|
to_address=to_address,
|
||||||
|
start_timestamp=order_create_timestamp,
|
||||||
|
end_timestamp=int(current_timestamp() * 1000))
|
||||||
|
token_transfers = result['token_transfers']
|
||||||
|
token_transfer = token_transfers[-1]
|
||||||
|
confirmed = token_transfer['confirmed']
|
||||||
|
correct_quant = quant == (token_transfer['quant'] / 6)
|
||||||
|
confirmed = confirmed and correct_quant
|
||||||
|
return confirmed
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def current():
|
||||||
|
return datetime.datetime.now()
|
||||||
|
|
||||||
|
def current_timestamp():
|
||||||
|
datetime.datetime.now().timestamp()
|
||||||
|
|
||||||
|
def is_time_difference_greater_than(timestamp1, timestamp2, hours=0, minutes=0, seconds=0):
|
||||||
|
"""
|
||||||
|
判断两个时间戳的时间差是否大于指定的小时、分钟和秒数
|
||||||
|
|
||||||
|
参数:
|
||||||
|
timestamp1 (int): 第一个时间戳
|
||||||
|
timestamp2 (int): 第二个时间戳
|
||||||
|
hours (int): 要比较的小时数,默认是0小时
|
||||||
|
minutes (int): 要比较的分钟数,默认是0分钟
|
||||||
|
seconds (int): 要比较的秒数,默认是0秒
|
||||||
|
|
||||||
|
返回:
|
||||||
|
bool: 如果时间差大于指定的小时、分钟和秒数返回True,否则返回False
|
||||||
|
"""
|
||||||
|
# 将时间戳转换为 datetime 对象
|
||||||
|
time1 = datetime.fromtimestamp(timestamp1)
|
||||||
|
time2 = datetime.fromtimestamp(timestamp2)
|
||||||
|
|
||||||
|
# 计算时间差
|
||||||
|
time_difference = abs(time2 - time1)
|
||||||
|
|
||||||
|
# 计算指定的时间差值
|
||||||
|
threshold = datetime.timedelta(hours=hours, minutes=minutes, seconds=seconds)
|
||||||
|
|
||||||
|
# 判断时间差是否大于指定的时间
|
||||||
|
return time_difference > threshold
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
from loguru import logger
|
||||||
|
from mysql.connector import connect, Error, OperationalError
|
||||||
|
from mysql.connector import errors as db_errors
|
||||||
|
|
||||||
|
from custom_decorators import singleton
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class Database:
|
||||||
|
def __init__(self, config):
|
||||||
|
self.connection = None
|
||||||
|
self.config = config
|
||||||
|
self.connect()
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
"""Establish a new database connection."""
|
||||||
|
try:
|
||||||
|
self.connection = connect(**self.config)
|
||||||
|
if self.connection.is_connected():
|
||||||
|
logger.info("Connected to MySQL database")
|
||||||
|
except Error as e:
|
||||||
|
logger.info(f"Error while connecting to MySQL: {e}")
|
||||||
|
self.connection = None
|
||||||
|
|
||||||
|
def get_connection(self):
|
||||||
|
"""Get the database connection, with reconnection logic."""
|
||||||
|
if self.connection is None or not self.connection.is_connected():
|
||||||
|
logger.info("Reconnecting to the database...")
|
||||||
|
self.connect()
|
||||||
|
return self.connection
|
||||||
|
|
||||||
|
def close_connection(self):
|
||||||
|
if self.connection and self.connection.is_connected():
|
||||||
|
self.connection.close()
|
||||||
|
logger.info("MySQL connection is closed")
|
||||||
|
|
||||||
|
def execute_query(self, query, params=None):
|
||||||
|
"""Execute a query with optional parameters, supports transactions."""
|
||||||
|
cursor = None
|
||||||
|
try:
|
||||||
|
connection = self.get_connection()
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute(query, params)
|
||||||
|
return cursor
|
||||||
|
except OperationalError as e:
|
||||||
|
logger.info(f"Operational error: {e}. Attempting to reconnect...")
|
||||||
|
self.connect()
|
||||||
|
cursor = self.get_connection().cursor()
|
||||||
|
cursor.execute(query, params)
|
||||||
|
return cursor
|
||||||
|
except db_errors.Error as e:
|
||||||
|
logger.info(f"Database error: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if cursor:
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
"""Commit the current transaction."""
|
||||||
|
if self.connection:
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def rollback(self):
|
||||||
|
"""Rollback the current transaction."""
|
||||||
|
if self.connection:
|
||||||
|
self.connection.rollback()
|
||||||
Loading…
Reference in New Issue