Skip to content
Snippets Groups Projects
Commit c078ae8e authored by Janssen, D.D. (Dylan, Student M-CS)'s avatar Janssen, D.D. (Dylan, Student M-CS)
Browse files

Created a better file structure for the commands plus started creating stub...

Created a better file structure for the commands plus started creating stub implementations, so that they can be implemented by others
parent 21b050f4
No related branches found
No related tags found
1 merge request!2Draft: initial user flow for creating a wallet
This commit is part of merge request !2. Comments created here will be created in the context of that merge request.
import ast
import os
from bitcoinlib.encoding import EncodingError
from bitcoinlib.keys import Address
from bitcoinlib.wallets import Wallet
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram import Update
from telegram.ext import CallbackContext
import database
from database import AppUser, AppState, AppWallet, AppWalletRequest, AppUserWallet
from util import generate_wallets, get_wallet_name, has_enough_funds, do_transaction
def generate_message(state_id, extra_menu=None):
if extra_menu is None:
extra_menu = []
state = AppState.get(AppState.id == state_id)
reply_msg = state.message
menu_string = ast.literal_eval(state.menu)
menu = extra_menu + [[InlineKeyboardButton(y[0], callback_data=y[1]) for y in x] for x in menu_string]
reply_markup = InlineKeyboardMarkup(menu)
return reply_msg, reply_markup
def start(update: Update, context: CallbackContext):
msg = update.effective_message.text
params = msg.split(" ")
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
if len(params) == 2:
token = params[1]
request = AppWalletRequest.get(AppWalletRequest.token == token)
user_wallet, created = AppUserWallet.get_or_create(user_id=user.id, wallet_id=request.wallet_id)
# TODO remove or True
if created or True:
request.delete_instance()
update.effective_message.reply_text("Succesfully joined the wallet")
count = AppWalletRequest.select().where(AppWalletRequest.wallet_id == request.wallet_id).count()
if count == 0:
user_wallets = AppUserWallet.select().where(AppUserWallet.wallet_id == request.wallet_id)
wallets, mnemonics = generate_wallets(user_wallets)
for i in range(user_wallets.count()):
user = user_wallets[i].user_id
wallet = user_wallets[i].wallet_id
context.bot.send_message(chat_id=user.telegram_id, text="A wallet has been created for you: {}\n"
"A mnemonic has been created for you, save this carefully:\n\n"
"{}".format(wallet.name, mnemonics[i]))
pass
else:
update.effective_message.reply_text("You cannot join a wallet twice")
user.set_state(1)
user.set_variables({})
reply_msg, reply_markup = generate_message(1)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def back(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
state = AppState.get(AppState.id == user.state_id)
user.set_state(state.prev_state)
reply_msg, reply_markup = generate_message(state.prev_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def send_a_transaction(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
if user.state_id.id != 6:
update.effective_message.reply_text("You cannot do this operation right now")
else:
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
pass
def create_wallet(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
user.set_state(2)
reply_msg, reply_markup = generate_message(2)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def choose_wallet(update: Update, context: CallbackContext):
# TODO: some information about the wallet when choosing the wallet
# TODO: check if wallet is already created (choose wallet)
telegram_user = update.effective_user
user = AppUser.get(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
user_wallets = AppUserWallet.select().where(AppUserWallet.user_id == user)
user.set_state(5)
menu = [[InlineKeyboardButton(uw.wallet_id.name, callback_data=uw.wallet_id.id)] for uw in user_wallets]
reply_msg, reply_markup = generate_message(5, menu)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
pass
def wallet_options(update: Update, context: CallbackContext, user: AppUser):
wallet_id = update.callback_query.data
user.set_variable("wallet_id", wallet_id)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def transaction_address(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
address = Address(msg, network=os.getenv("BTC_NETWORK"))
user.set_variable("address", msg)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except EncodingError:
update.effective_message.reply_text("This is not a valid address")
def transaction_amount(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
amount = float(msg)
user.set_variable("amount", amount)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
pass
# update.effective_message.reply_text("This is not a number, try again")
def transaction_fee(update: Update, context: CallbackContext, user: AppUser):
cq = update.callback_query
cm = update.effective_message
success = False
if cq:
query = cq.data
if query == "low" or query == "normal" or query == "high":
user.set_variable("fee", query)
success = True
elif cm:
msg = cm.text
try:
amount = float(msg)
user.set_variable("fee", amount)
success = True
except ValueError:
pass
if success:
variables = user.variables()
t, has_funds, error = do_transaction(variables["wallet_id"], user.id, variables["address"], variables["amount"], variables["fee"])
if not has_funds:
update.effective_message.reply_text("The wallet does not have enough funds to do this transaction, please change the amount or fee")
elif error:
update.effective_message.reply_text("Something went wrong during the creating of the transaction please try again later")
else:
# TODO: send notification to the other co signers
pass
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
else:
update.effective_message.reply_text("Please send a number or use the buttons to identify the fee amount")
def enter_co_signers(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
co_signers = int(msg)
user.set_variable('max_co_signers', co_signers)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
update.effective_message.reply_text("This is not a number, try again")
def minimum_co_signers(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
min_signers = int(msg)
if user.all_variables['max_co_signers'] < min_signers:
update.effective_message.reply_text("Minimum signers cannot be smaller than the maximum signers, please try again")
return
user.set_variable('min_co_signers', min_signers)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
update.effective_message.reply_text("This is not a number, try again")
def name_wallet(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
if len(msg) > 100:
update.effective_message.reply_text("The chosen name is too long, please try again")
else:
user.set_variable('wallet_name', msg)
variables = user.all_variables
app_wallet = AppWallet.create(max_co_signers=variables['max_co_signers'],
min_co_signers=variables['min_co_signers'],
initiator_user_id=user.id,
name=variables['wallet_name'])
AppUserWallet.create(user_id=user.id, wallet_id=app_wallet.id)
wallet_requests = AppWalletRequest.generate_requests(variables['max_co_signers'] - 1, app_wallet.id)
update.effective_message.reply_text("Wallet is created, forward each of these messages to one co-signer")
for request in wallet_requests:
update.effective_message.reply_text("Hi, please join this wallet as co-signer.\n"
"Wallet name= {}\n"
"https://t.me/BitcoinLibTestbot?start={}".format(variables['wallet_name'], request["token"]))
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
from commands.general import start, back
from commands.transaction import transaction_address, transaction_amount, transaction_fee, send_a_transaction, show_sign_transaction
from commands.wallet import enter_co_signers, minimum_co_signers, name_wallet, wallet_options, create_wallet, choose_wallet
from database import AppUser
def callback_handler(update: Update, context: CallbackContext):
......@@ -265,4 +46,5 @@ COMMANDS = {
"send_a_transaction": send_a_transaction,
"back": back,
"choose_wallet": choose_wallet,
"sign_transaction": show_sign_transaction
}
import transaction
import util
import wallet
import general
__all__ = ["transaction", "util", "wallet", "general"]
\ No newline at end of file
from telegram import Update
from telegram.ext import CallbackContext
from commands.util import generate_message
from database import AppUser, AppWalletRequest, AppUserWallet, AppState
from util import generate_wallets
def start(update: Update, context: CallbackContext):
msg = update.effective_message.text
params = msg.split(" ")
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
if len(params) == 2:
token = params[1]
request = AppWalletRequest.get(AppWalletRequest.token == token)
user_wallet, created = AppUserWallet.get_or_create(user_id=user.id, wallet_id=request.wallet_id)
# TODO remove or True
if created or True:
request.delete_instance()
update.effective_message.reply_text("Succesfully joined the wallet")
count = AppWalletRequest.select().where(AppWalletRequest.wallet_id == request.wallet_id).count()
if count == 0:
user_wallets = AppUserWallet.select().where(AppUserWallet.wallet_id == request.wallet_id)
wallets, mnemonics = generate_wallets(user_wallets)
for i in range(user_wallets.count()):
user = user_wallets[i].user_id
wallet = user_wallets[i].wallet_id
context.bot.send_message(chat_id=user.telegram_id, text="A wallet has been created for you: {}\n"
"A mnemonic has been created for you, save this carefully:\n\n"
"{}".format(wallet.name, mnemonics[i]))
pass
else:
update.effective_message.reply_text("You cannot join a wallet twice")
user.set_state(1)
user.set_variables({})
reply_msg, reply_markup = generate_message(1)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def back(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
state = AppState.get(AppState.id == user.state_id)
user.set_state(state.prev_state)
reply_msg, reply_markup = generate_message(state.prev_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
import os
from bitcoinlib.encoding import EncodingError
from bitcoinlib.keys import Address
from telegram import Update
from telegram.ext import CallbackContext
from commands.util import generate_message
from database import AppUser
from util import do_transaction
def send_a_transaction(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
if user.state_id.id != 6:
update.effective_message.reply_text("You cannot do this operation right now")
else:
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
pass
def transaction_address(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
address = Address(msg, network=os.getenv("BTC_NETWORK"))
user.set_variable("address", msg)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except EncodingError:
update.effective_message.reply_text("This is not a valid address")
def transaction_amount(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
amount = float(msg)
user.set_variable("amount", amount)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
update.effective_message.reply_text("This is not a number, try again")
def transaction_fee(update: Update, context: CallbackContext, user: AppUser):
cq = update.callback_query
cm = update.effective_message
success = False
if cq:
query = cq.data
if query == "low" or query == "normal" or query == "high":
user.set_variable("fee", query)
success = True
elif cm:
msg = cm.text
try:
amount = float(msg)
user.set_variable("fee", amount)
success = True
except ValueError:
pass
if success:
variables = user.variables()
# TODO: create pending_tx's
t, has_funds, error = do_transaction(variables["wallet_id"], user.id, variables["address"], variables["amount"], variables["fee"])
if not has_funds:
update.effective_message.reply_text("The wallet does not have enough funds to do this transaction, please change the amount or fee")
elif error:
update.effective_message.reply_text("Something went wrong during the creating of the transaction please try again later")
else:
# TODO: send notification to the other co signers
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
else:
update.effective_message.reply_text("Please send a number or use the buttons to identify the fee amount")
def show_sign_transaction(update: Update, context: CallbackContext):
# TODO: When the user wants to sign a transaction
# TODO: show a list of transactions
pass
def choose_sign_transaction(update: Update, context: CallbackContext, user: AppUser):
# TODO: store the retrieve transaction_id or hash in the variables of the user and proceed to the next state
query = update.callback_query.data
# TODO show menu of are you sure you want to sgn the transaction
def sign_transaction(update: Update, context: CallbackContext, user: AppUser):
# TODO: sign the transaction if the answer is yes otherwise go back to state 0
query = update.callback_query.data
import ast
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from database import AppState
def generate_message(state_id, extra_menu=None):
if extra_menu is None:
extra_menu = []
state = AppState.get(AppState.id == state_id)
reply_msg = state.message
menu_string = ast.literal_eval(state.menu)
menu = extra_menu + [[InlineKeyboardButton(y[0], callback_data=y[1]) for y in x] for x in menu_string]
reply_markup = InlineKeyboardMarkup(menu)
return reply_msg, reply_markup
from telegram import Update, InlineKeyboardButton
from telegram.ext import CallbackContext
from commands.util import generate_message
from database import AppUser, AppWallet, AppUserWallet, AppWalletRequest
def create_wallet(update: Update, context: CallbackContext):
telegram_user = update.effective_user
user, created = AppUser.get_or_create(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
user.set_state(2)
reply_msg, reply_markup = generate_message(2)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def enter_co_signers(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
co_signers = int(msg)
user.set_variable('max_co_signers', co_signers)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
update.effective_message.reply_text("This is not a number, try again")
def minimum_co_signers(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
try:
min_signers = int(msg)
if user.all_variables['max_co_signers'] < min_signers:
update.effective_message.reply_text("Minimum signers cannot be smaller than the maximum signers, please try again")
return
user.set_variable('min_co_signers', min_signers)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
except ValueError:
update.effective_message.reply_text("This is not a number, try again")
def name_wallet(update: Update, context: CallbackContext, user: AppUser):
msg = update.effective_message.text
if len(msg) > 100:
update.effective_message.reply_text("The chosen name is too long, please try again")
else:
user.set_variable('wallet_name', msg)
variables = user.all_variables
app_wallet = AppWallet.create(max_co_signers=variables['max_co_signers'],
min_co_signers=variables['min_co_signers'],
initiator_user_id=user.id,
name=variables['wallet_name'])
AppUserWallet.create(user_id=user.id, wallet_id=app_wallet.id)
wallet_requests = AppWalletRequest.generate_requests(variables['max_co_signers'] - 1, app_wallet.id)
update.effective_message.reply_text("Wallet is created, forward each of these messages to one co-signer")
for request in wallet_requests:
update.effective_message.reply_text("Hi, please join this wallet as co-signer.\n"
"Wallet name= {}\n"
"https://t.me/BitcoinLibTestbot?start={}".format(variables['wallet_name'], request["token"]))
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def wallet_options(update: Update, context: CallbackContext, user: AppUser):
wallet_id = update.callback_query.data
user.set_variable("wallet_id", wallet_id)
next_state = user.next_state()
reply_msg, reply_markup = generate_message(next_state)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
def choose_wallet(update: Update, context: CallbackContext):
# TODO: some information about the wallet when choosing the wallet
# TODO: check if wallet is already created (choose wallet)
telegram_user = update.effective_user
user = AppUser.get(telegram_id=telegram_user.id, nickname=telegram_user.full_name)
user_wallets = AppUserWallet.select().where(AppUserWallet.user_id == user)
user.set_state(5)
menu = [[InlineKeyboardButton(uw.wallet_id.name, callback_data=uw.wallet_id.id)] for uw in user_wallets]
reply_msg, reply_markup = generate_message(5, menu)
update.effective_message.reply_text(reply_msg, reply_markup=reply_markup)
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment