Files
to_session/tg接口/interface_tools.py
Administrator a0720d80dc fefdwef
2025-11-12 12:54:37 +08:00

329 lines
11 KiB
Python

import time
import json
import base64
import urllib
import hashlib
import requests
from urllib.parse import unquote
from typing import Optional, List
from nacl.signing import SigningKey
from tonsdk.utils import bytes_to_b64str
from tonsdk.contract.wallet import Wallets, WalletVersionEnum
def get_user_data1(
phone,
bot_name,
url,
invite_code="",
platform="",
start_params="",
channel_name='',
device_model=""
):
# data = {
# "phone": phone, # 区号加号码
# "bot_name": bot_name, # 机器人名称
# "url": url,
# "platform": platform, # 平台 web_3 tdesktop
# "start_params": start_params,
# 'channel_name': channel_name, # 频道名称
# }
data = {
"phone": phone, # 区号加号码
"bot_name": bot_name, # 机器人名称
"url": url,
"invite_code": invite_code, # 邀请码
"platform": platform, # 平台 web_3 tdesktop
"start_params": start_params,
"channel_name": channel_name, # 频道名称
# 'device_model': device_model,
}
resp = requests.post("http://192.168.11.30:9000/api/get_token", json=data)
# print(resp.json())
if resp.status_code == 200:
return resp.json().get("data")
return False
def send_click1(phone, bot_name, datas):
json_data = {
"phone": phone,
"bot_name": bot_name,
"datas": datas
}
try:
res = requests.post("http://192.168.11.30:9000/api/send_click", json=json_data)
print(res.json())
return True
except:
pass
return False
def join(phone, bot_name):
json_data = {
"phone": phone,
"bot_name": bot_name,
}
try:
res = requests.post("http://192.168.11.30:9000/api/join_channe", json=json_data)
print(res.json())
if res.json()["code"] == 200:
return True
except:
pass
return False
def get_bot_message(phone, bot_name):
json_data = {
"phone": phone,
"bot_name": bot_name,
}
try:
res = requests.post("http://192.168.11.30:9000/api/get_bot_message", json=json_data)
print(res.json())
if res.json()["code"] == 200:
return True
except:
pass
return False
# 解析url
def url_to_json(data):
# 解码URL编码的数据为字典
decoded_data = urllib.parse.parse_qs(data)
# 提取单一值并解析嵌套的JSON数据
parsed_data = {k: json.loads(v[0]) if v[0].startswith('{') else v[0] for k, v in decoded_data.items()}
return parsed_data
async def wallet(mnemonic: Optional[List[str]] = None):
"""
This function creates or loads a wallet depending on whether a mnemonic is provided.
- If a mnemonic is provided, it loads the wallet using the mnemonic phrase.
- If no mnemonic is provided, it creates a new wallet.
The function returns the following details:
- Wallet address
- Secret key (first 32 bytes of private key)
- Mnemonic phrase as a string
- Ton address in user-friendly format
- Public key in hexadecimal format
- Private key in hexadecimal format
- State initialization data in base64 format
Args:
- mnemonic (Optional[List[str]]): A list of words representing the mnemonic phrase to load an existing wallet. Defaults to None.
Returns:
- Tuple: Contains wallet address, secret key, mnemonic, user-friendly Ton address, public key, private key, and state_init.
"""
if mnemonic is None:
mnemonic, pub_k, priv_k, wallet = Wallets.create(WalletVersionEnum.v4r2, workchain=0)
else:
mnemonic, pub_k, priv_k, wallet = Wallets.from_mnemonics(mnemonic, WalletVersionEnum.v4r2, workchain=0)
state = wallet.create_state_init()
init = state["state_init"]
address = wallet.address.to_string(is_user_friendly=False)
secret_key = priv_k[:32]
mnemonics = " ".join(mnemonic)
address_ton = wallet.address.to_string(True, True, False)
public_key = pub_k.hex()
private_key = priv_k.hex()
state_init = bytes_to_b64str(init.to_boc(has_idx=False))
return address, secret_key, mnemonics, address_ton, public_key, private_key, state_init
async def proof(manifest_url: str, payload: str, mnemonic: Optional[str] = None):
"""
This function creates a proof by signing a message and returning the proof details in a structured format.
- The proof is generated by hashing the address, domain (manifest URL), timestamp, and payload.
- It then signs the resulting hash using the wallet's private key.
- The final proof contains the signature and other details such as the wallet information, timestamp, and state initialization.
Args:
- manifest_url (str): The URL from the manifest (domain) to include in the proof.
- payload (str): The payload (data) to be included in the proof.
- mnemonic (Optional[str]): A string representing the mnemonic phrase for the wallet. Defaults to None.
Returns:
- str: A JSON string containing the wallet information (mnemonics, Ton address, public/private keys)
and the proof details (signature, timestamp, domain, state init, etc.).
"""
if mnemonic is not None:
phrase = mnemonic.split()
else:
phrase = None
address, secret_key, mnemonics, address_ton, public_key, private_key, state_init = await wallet(phrase)
try:
timestamp = int(time.time())
timestamp_bytes = timestamp.to_bytes(8, 'little')
domain = manifest_url
domain_bytes = domain.encode('utf-8')
domain_len_bytes = len(domain_bytes).to_bytes(4, 'little')
workchain, addr_hash = address.split(':')
workchain_bytes = int(workchain).to_bytes(4, 'big')
address_bytes = workchain_bytes + bytes.fromhex(addr_hash)
msg_bytes = b''.join([
b'ton-proof-item-v2/',
address_bytes,
domain_len_bytes,
domain_bytes,
timestamp_bytes,
payload.encode('utf-8') if payload else b'',
])
msg_hash = hashlib.sha256(msg_bytes).digest()
buffer_bytes = b''.join([
bytes.fromhex('ffff'),
b'ton-connect',
msg_hash
])
key = SigningKey(secret_key)
data = key.sign(hashlib.sha256(buffer_bytes).digest())
signature = base64.b64encode(data.signature).decode('utf-8')
proof = {
"wallet": {
"mnemonics": mnemonics,
"ton_address": address_ton
},
"address": address,
"network": "-239",
"public_key": public_key,
"private_key": private_key,
"proof": {
"name": "ton_proof",
"timestamp": timestamp,
"domain": {
"lengthBytes": len(domain_bytes),
"value": domain
},
"signature": signature,
"payload": payload,
"state_init": state_init
}
}
return proof
except Exception as e:
print(f"CreateTonProof: {e} | {str(e)}")
return None
# def url_decode_in_query_string(query_string):
# """
# 将包含 URL 编码数据的 URL 查询字符串解码
#
# :param query_string: 包含 URL 编码数据的 URL 查询字符串
# :return: 解码后的字典
# """
#
# def decode_url_in_value(value):
# if isinstance(value, str):
# try:
# # 尝试将字符串解析为 JSON 对象
# json_value = json.loads(value)
# # 递归处理 JSON 对象中的每个值
# return decode_url_in_value(json_value)
# except json.JSONDecodeError:
# # 如果不是 JSON 格式,则直接解码 URL 编码字符串
# return urllib.parse.unquote(value)
# elif isinstance(value, dict):
# return {k: decode_url_in_value(v) for k, v in value.items()}
# elif isinstance(value, list):
# return [decode_url_in_value(v) for v in value]
# else:
# return value
#
# try:
# # 将 URL 查询字符串解析为字典
# query_params = urllib.parse.parse_qs(query_string)
# # 将字典的值转换为单个元素
# query_params = {k: v[0] for k, v in query_params.items()}
# # 对字典中的每个 URL 编码字符串进行解码
# decoded_params = decode_url_in_value(query_params)
# return decoded_params
# except Exception as e:
# return f"解码失败: {e}"
# 解析url
# if __name__ == '__main__':
# print(get_user_data1(
# phone="15798297810",
# bot_name="collection_hunt_bot",
# url="https://clicker.liveart.io"
# ))
# a = 'query_id=AAGCcmcdAwAAAIJyZx0_LSS7&user={"id":6935769730,"first_name":"🐦 SUI Alexander","last_name":"Pratt","username":"dJQQPM996","language_code":"zh-hans","allows_write_to_pm":true,"photo_url":"https:\/\/t.me\/i\/userpic\/320\/SFt9SCZ5oRgBLi1Wg8yMBGegf6qQK7_7N8_dcT3j1BH1fryjg0sFfEw0NzKeXBX8.svg"}&auth_date=1751355393&signature=Bcdr-HzJZEwpY_Tq0nRIoffh4ZiK0YeZBTi2SB1IrzUb3mZKP0KjlbM8r6kPP2xMfitXUgK0HS6XXCSZPS8oAw&hash=94f06b976fbf295a29f999a490a7c7974f6a809143c3527f5e7866d8a29b6d68'
# print(url_to_json(data=a))
# join_the_group(phone="15798298193", channel_name="timefarmcommunitychat",device_model="")
#
# # url = "query_id=AAG0N3o0AwAAALQ3ejRk9rhk&user=%7B%22id%22%3A7322875828%2C%22first_name%22%3A%22%F0%9F%90%A6%20SUI%20Rodney%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22rcXbpC4996%22%2C%22language_code%22%3A%22en%22%2C%22allows_write_to_pm%22%3Atrue%2C%22photo_url%22%3A%22https%3A%5C%2F%5C%2Ft.me%5C%2Fi%5C%2Fuserpic%5C%2F320%5C%2FZz_aXp8Ip-umZPJhOWom2KTGBs3Xe8dwwgEqc-A5KG7J3Aq3CRmiv097xryPafqp.svg%22%7D&auth_date=1735561646&signature=cL2Y2F58ZhwSf47V4OhUAnaKQJlan_IFcYAec8EOUjK-f-jNtRVlgB6cIHu3IV62xCXsW6w3zoemmLSpRao3DA&hash=765a84035331eb5b2d379bb23e62ee72f8a12813e4156e2d3831a0a6996656da"
# # print(url_to_json(data=url)["user"]["username"])
#
# # tg_interactive_bot(
# # phone="972525788299",
# # device_model="P8Z68-V LX",
# # bot_name="BlumCryptoTradingBot",
# # message="/start",
# # btn=""
# # )
#
# json_data = {
# "phone": "8619260226414",
# "device_model": "USOPPBH",
# "bot_name": "BlumCryptoTradingBot",
# "data": [
# # {"message": "/start", "btn_lst": ["Settings", "Language", "English"]},
# # {"message": "/start", "btn_lst": ["BUY", "Token", "Blum hot", "FPIBANK", "slippage"]},
# # {"message": "3", "btn_lst": ["amount", ]},
# # {"message": "4", "btn_lst": ["BUY", ]},
# {"message": "/start", "btn_lst": ["Positions", "FPIBANK", "SELL"]},
# ],
# }
# url = "http://192.168.50.180:9696/bot/click"
# resp = requests.post(url, json=json_data)
# print(resp.text)
# json_data = {
# "phone": "8613641930695",
# "bot_name": "pengu_clash_bot",
# "datas": [
# {"send_message": ["/start"], "click_button": ["now"], },
# ]
# }
#
# res = requests.post("http://192.168.50.175:9000/api/send_click", json=json_data)
# print(res.json())