wallet-v3cr3/scripts/_auth.py

102 lines
4.1 KiB
Python

import json
import os
from getpass import getpass
from tonsdk.contract.wallet import Wallets
from tonsdk.crypto import mnemonic_to_wallet_key
from tonsdk.utils import Address
from _core import unpack_wallet, encrypt_data, decrypt_data
def mnemonic_new(subwallet_id: int=0):
while True:
mnemonic, public_key, private_key, _ = Wallets.create('v3r2', 0)
wallet = unpack_wallet({
'mnemonic': mnemonic,
'public_key': public_key.hex(),
'secret_key': private_key.hex(),
'subwallet_id': subwallet_id,
'custom_address': None,
'is_testnet': False,
})
ugly = False
for wallet_address in [
wallet.address.to_string(1, 1, 0),
wallet.address.to_string(1, 1, 1)
]:
if ('_' in wallet_address or '-' in wallet_address):
ugly = True
if not ugly:
return mnemonic
def get_or_create_wallet_settings():
wallet_settings_file = os.environ.get('ENCRYPTED_WALLET_FILE', '.saved_wallet')
# Check if the .saved_wallet file exists
if os.path.exists(wallet_settings_file):
# If the file exists, read and decrypt its contents
with open(wallet_settings_file, 'rb') as file:
_content = file.read()
hashpart = _content[:32].hex()
_content = _content[32:]
print(f"=== Saved wallet: {Address('0:' + hashpart).to_string(1, 1, 0)}")
password = getpass("Enter the password to decrypt the wallet: ")
try:
wallet_settings = decrypt_data(_content, password.encode("UTF-8"))
wallet_settings = json.loads(wallet_settings.decode())
except (ValueError, KeyError):
print("Incorrect password or corrupted data. Please try again.")
return get_or_create_wallet_settings()
print(f"=== Mainnet: {not wallet_settings.get('is_testnet', True)}")
return wallet_settings
else:
# If the file doesn't exist, prompt the user for input
try:
subwallet_id = int(input("Enter the subwallet_id (default is 0): ") or 0)
assert subwallet_id >= 0, "Subwallet ID must be a positive integer"
mnemonic = input("Enter the wallet mnemonic (24 words, separated by spaces): ")
if mnemonic == 'new':
mnemonic = ' '.join(mnemonic_new(subwallet_id=subwallet_id))
assert len(mnemonic.split()) == 24, "Mnemonic must be 24 words long"
public_key, secret_key = mnemonic_to_wallet_key(mnemonic.split())
custom_address = input("Enter a custom address (if available): ")
custom_address = Address(custom_address) if custom_address else None
password = getpass("Enter a password to protect the wallet: ")
assert len(password) > 3, "Password must be at least 4 characters long"
is_testnet = input("Is this a testnet wallet? (yes/NO): ").lower() == 'yes'
except KeyboardInterrupt:
os._exit(1)
except BaseException as e:
print(f"Error: {e}")
print("Please try again")
return get_or_create_wallet_settings()
# Create a dictionary with the user input
wallet_settings = {
'mnemonic': mnemonic,
'public_key': public_key.hex(),
'secret_key': secret_key.hex(),
'subwallet_id': subwallet_id,
'custom_address': custom_address.to_string(1, 1, 1) if custom_address else None,
'is_testnet': is_testnet,
}
print(f"=== Mainnet: {not is_testnet}")
wallet_address = unpack_wallet(wallet_settings).address.to_string(0, 0, 0)
# Encrypt and save the data to the file
encrypted_wallet = encrypt_data(json.dumps(wallet_settings).encode("UTF-8"), password.encode("UTF-8"))
with open(wallet_settings_file, 'wb') as file:
file.write(bytes.fromhex(wallet_address.split(':')[1]) + encrypted_wallet)
# Recursively call the function to read data from the file
return get_or_create_wallet_settings()