232 lines
10 KiB
Python
232 lines
10 KiB
Python
from asyncio import run
|
|
|
|
from tonsdk.boc import Cell, begin_cell
|
|
from tonsdk.utils import Address
|
|
|
|
import pandas as pd
|
|
from datetime import datetime
|
|
from pytonapi import AsyncTonapi
|
|
|
|
from _auth import get_or_create_wallet_settings
|
|
from _core import unpack_wallet, serialize_command, perform_action, print_actions
|
|
|
|
|
|
async def main():
|
|
print('\n' * 30)
|
|
wallet_settings = get_or_create_wallet_settings()
|
|
wallet = unpack_wallet(wallet_settings)
|
|
wallet_address = wallet.address.to_string(1, 1, 1)
|
|
print(f"=== Successfully loaded wallet {wallet.address.to_string(1, 1, 0)}")
|
|
# print(wallet_settings)
|
|
actions = []
|
|
while len(actions) < 4:
|
|
print_actions(actions)
|
|
print("Available actions:")
|
|
print("1) Send TON")
|
|
print("2) Send Jetton")
|
|
print("3) Send NFT")
|
|
print("4) Update wallet contract")
|
|
print("5) Export mnemonic phrase")
|
|
print("7) New decentralized note")
|
|
print("8) Read decentralized note")
|
|
print("9) View transactions history")
|
|
print("10) Export transactions history")
|
|
print("0) View actions and exit | send transactions")
|
|
|
|
choice = input("Select an action (1/2/3/4/0): ")
|
|
|
|
if choice == "0":
|
|
break
|
|
elif choice in {"5"}:
|
|
print("=== Mnemonic phrase:")
|
|
print(wallet_settings['mnemonic'])
|
|
continue
|
|
elif choice in {"9", "10"}:
|
|
print("=== Transactions history:")
|
|
tonapi = AsyncTonapi('AEA5YM3PU2YFXJIAAAAH3JWVNWRM57SFIBJGVJHCOK2GGPJ2L2MNKXBYPO7VTTY26ZRLX6I')
|
|
|
|
transactions = []
|
|
start_ts = None
|
|
while not start_ts or events.events:
|
|
try:
|
|
events = await tonapi.accounts.get_events(wallet_address, end_date=start_ts or None)
|
|
except BaseException as e:
|
|
if "rate limit" in str(e):
|
|
print("Rate limit exceeded. Please try again later.")
|
|
time.sleep(1)
|
|
continue
|
|
else:
|
|
print(f"TonAPI error: {e}")
|
|
|
|
print(f"Fetched {len(events.events)} events from {start_ts}")
|
|
for event in events.events:
|
|
if event.in_progress is True:
|
|
continue
|
|
|
|
event_dt = datetime.fromtimestamp(event.timestamp)
|
|
event_dtf = event_dt.strftime("%Y-%m-%d %H:%M:%S")
|
|
for event_action in event.actions:
|
|
transactions.append(
|
|
(event.event_id, event.lt, event_dtf, event_action.type, event_action)
|
|
)
|
|
|
|
if not start_ts or start_ts > event.timestamp:
|
|
start_ts = event.timestamp
|
|
|
|
if choice == "9":
|
|
for event_action in reversed(transactions):
|
|
e_id, e_lt, e_dtf, e_type, e_action = event_action
|
|
action_formatted = f"TXID: {e_id}, logic time: {e_lt}. {e_dtf} {e_type}:" + '\n' + " " * 6
|
|
if e_type == "TonTransfer":
|
|
e_action = e_action.TonTransfer
|
|
action_formatted += f"{Address(e_action.sender.address.to_raw()).to_string(1, 1, 1)}" \
|
|
+ f" sent {round(int(e_action.amount) / 10 ** 9, 3)} TON => {Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1)}"
|
|
if e_action.comment:
|
|
action_formatted += f". Comment: {e_action.comment}"
|
|
elif e_type == "JettonTransfer":
|
|
e_action = e_action.JettonTransfer
|
|
action_formatted += f"{Address(e_action.sender.address.to_raw()).to_string(1, 1, 1)}" \
|
|
+ f" sent {round(int(e_action.amount) / 10 ** e_action.jetton.decimals, 3)} {e_action.jetton.symbol} => {Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1)}"
|
|
if e_action.comment:
|
|
action_formatted += f". Comment: {e_action.comment}"
|
|
elif e_type == "NftItemTransfer":
|
|
e_action = e_action.NftItemTransfer
|
|
action_formatted += f"{Address(e_action.sender.address.to_raw()).to_string(1, 1, 1)}" \
|
|
+ f" sent NFT ({e_action.nft}) => {Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1)}"
|
|
else:
|
|
e_action = getattr(e_action, e_type)
|
|
action_formatted += "unknown action: " + str(e_action)
|
|
|
|
print(action_formatted + '\n')
|
|
elif choice == "10":
|
|
dfr = []
|
|
for event_action in reversed(transactions):
|
|
e_id, e_lt, e_dtf, e_type, e_action = event_action
|
|
if e_type == "TonTransfer":
|
|
e_action = e_action.TonTransfer
|
|
dfr.append([
|
|
e_id, e_lt, e_dtf, e_type,
|
|
Address(e_action.sender.address.to_raw()).to_string(1, 1, 1),
|
|
Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1),
|
|
str(round(int(e_action.amount) / 10 ** 9, 3)),
|
|
e_action.comment or ''
|
|
])
|
|
elif e_type == "JettonTransfer":
|
|
e_action = e_action.JettonTransfer
|
|
dfr.append([
|
|
e_id, e_lt, e_dtf, e_type,
|
|
Address(e_action.sender.address.to_raw()).to_string(1, 1, 1),
|
|
Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1),
|
|
str(round(int(e_action.amount) / 10 ** e_action.jetton.decimals, 3)),
|
|
e_action.comment or ''
|
|
])
|
|
elif e_type == "NftItemTransfer":
|
|
e_action = e_action.NftItemTransfer
|
|
dfr.append([
|
|
e_id, e_lt, e_dtf, e_type,
|
|
Address(e_action.sender.address.to_raw()).to_string(1, 1, 1),
|
|
Address(e_action.recipient.address.to_raw()).to_string(1, 1, 1),
|
|
e_action.nft,
|
|
''
|
|
])
|
|
|
|
df = pd.DataFrame(dfr, columns=[
|
|
'TXID', 'Logic Time', 'Time', 'Type', 'Sender', 'Recipient', 'Amount', 'Comment'
|
|
])
|
|
df.to_csv('transactions_history.csv', sep=",")
|
|
print("Transactions history saved to transactions_history.csv")
|
|
|
|
continue
|
|
elif choice in {"1", "2", "3", "4", "7"}:
|
|
action_type = int(choice)
|
|
action = {"type": action_type, "args": []}
|
|
|
|
if action_type == 1:
|
|
destination = input("Enter the destination address: ")
|
|
Address(destination).to_string(1, 1, 1)
|
|
amount = float(input("Enter the amount in TON: "))
|
|
comment = input("Enter a comment (or leave it empty): ")
|
|
if comment:
|
|
raw_payload = (
|
|
begin_cell()
|
|
.store_uint(0, 32)
|
|
.store_bytes(comment.encode())
|
|
.end_cell()
|
|
)
|
|
else:
|
|
raw_payload = input("Enter raw_payload in HEX (or leave it empty): ")
|
|
try:
|
|
raw_payload = Cell.one_from_boc(raw_payload)
|
|
except:
|
|
raw_payload = None
|
|
|
|
action["args"] = {
|
|
"destination": destination,
|
|
"amount": int(amount * 10 ** 9),
|
|
"payload_cell": raw_payload
|
|
}
|
|
elif action_type == 2:
|
|
token_contract = input("Enter the token contract address: ")
|
|
recipient = input("Enter the recipient address: ")
|
|
Address(token_contract).to_string(1, 1, 1)
|
|
Address(recipient).to_string(1, 1, 1)
|
|
amount = float(input("Enter the amount in tokens: "))
|
|
decimals = int(input("Enter token decimals: "))
|
|
amount = int(amount * 10 ** decimals)
|
|
comment = input("Enter a comment: ")
|
|
action["args"] = {
|
|
"token_contract": token_contract,
|
|
"recipient": recipient,
|
|
"amount": amount,
|
|
"comment": comment
|
|
}
|
|
elif action_type == 3:
|
|
nft_address = input("Enter the NFT address: ")
|
|
recipient = input("Enter the recipient address: ")
|
|
Address(nft_address).to_string(1, 1, 1)
|
|
Address(recipient).to_string(1, 1, 1)
|
|
action["args"] = {
|
|
"nft_address": nft_address,
|
|
"recipient": recipient
|
|
}
|
|
elif action_type == 4:
|
|
hex_code = input("Enter the smart contract code in HEX: ")
|
|
hex_data = input("Enter smart contract data in HEX: ")
|
|
action["args"] = {
|
|
'new_code': Cell.one_from_boc(hex_code),
|
|
'new_data': Cell.one_from_boc(hex_data)
|
|
}
|
|
elif action_type == 7:
|
|
note_key = input("Enter the note key: ")
|
|
print(f"""[?] Please, enter plain text & input 0 for write the note:""")
|
|
plain_text = ""
|
|
while True:
|
|
new_input = input()
|
|
if new_input == '0':
|
|
break
|
|
|
|
plain_text += new_input + '\n'
|
|
|
|
action['args'] = {
|
|
'note_key': note_key.strip(),
|
|
'plain_text': plain_text.strip(),
|
|
'private_key': bytes.fromhex(wallet_settings['secret_key'])
|
|
}
|
|
|
|
actions.append(action)
|
|
|
|
if not actions:
|
|
print("No actions selected")
|
|
return
|
|
|
|
_commands = begin_cell()
|
|
for action in actions:
|
|
_commands = _commands.store_ref(
|
|
serialize_command(action, response_address=wallet.address)
|
|
)
|
|
|
|
await perform_action(wallet_settings, _commands.end_cell())
|
|
|
|
if __name__ == "__main__":
|
|
run(main())
|