Exemplo n.º 1
0
    def execute(self, bot, update, args):
        username = update.effective_user.username

        if not Bismuth.wallet_exists(username):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        qr_dir = os.path.join(self.get_plg_path(), self.QRCODES_DIR)
        os.makedirs(qr_dir, exist_ok=True)

        qr_name = f"{username}.png"
        qr_code = os.path.join(qr_dir, qr_name)

        address = Bismuth.get_address_for(username)

        if not os.path.isfile(qr_code):
            logo = os.path.join(self.get_plg_path(), con.DIR_RES,
                                self.BIS_LOGO)

            myqr.run(address,
                     version=1,
                     level='H',
                     picture=logo,
                     colorized=True,
                     contrast=1.0,
                     brightness=1.0,
                     save_name=qr_name,
                     save_dir=qr_dir)

        with open(qr_code, "rb") as qr_pic:
            update.message.reply_photo(photo=qr_pic,
                                       caption=f"`{address}`",
                                       parse_mode=ParseMode.MARKDOWN)
Exemplo n.º 2
0
    def _callback(self, bot, update):
        query = update.callback_query
        username = update.effective_user["username"]

        sql = self.get_resource("select_bisurl.sql")
        res = self.execute_sql(sql, query.data)

        user = res["data"][0][1]
        address = res["data"][0][2]
        amount = res["data"][0][3]
        operation = res["data"][0][4]
        message = res["data"][0][5]

        if user == username:
            msg = f"{emo.WAIT} Processing..."
            bot.answer_callback_query(query.id, msg)

            bis = Bismuth(user)
            bis.load_wallet()

            try:
                # Execute sending transaction via BISURL
                trx = bis.send(address, amount, operation, message)
            except Exception as e:
                error = f"Error sending via BISURL {amount} BIS " \
                        f"from @{user} " \
                        f"to {address} " \
                        f"with operation '{operation}' " \
                        f"and message '{message}': {e}"
                logging.error(error)
                trx = None

            if trx:
                logging.debug(f"Sent via BISURL {amount} BIS "
                              f"from @{user} "
                              f"to {address} "
                              f"with operation '{operation}' "
                              f"and message '{message}'")

                url = f"{self.BLCK_EXPL_URL}{utl.encode_url(trx)}"

                # Send success message
                query.edit_message_text(
                    f"{emo.DONE} DONE!\n[View on Block Explorer]({url})\n"
                    f"(Available after ~1 minute)",
                    parse_mode=ParseMode.MARKDOWN)
            else:
                # Send error message
                query.edit_message_text(
                    f"{emo.ERROR} Sending via BISURL not executed. Something went wrong..."
                )
        else:
            msg = f"{emo.ERROR} Wrong user"
            bot.answer_callback_query(query.id, msg)
Exemplo n.º 3
0
    def execute(self, bot, update, args):
        username = update.effective_user.username

        if not Bismuth.wallet_exists(username):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        address = Bismuth.get_address_for(username)

        update.message.reply_text(text=f"Your BIS address is `{address}`",
                                  parse_mode=ParseMode.MARKDOWN)
Exemplo n.º 4
0
    def execute(self, bot, update, args):
        if len(args) == 0:
            msg = f"Usage:\n{self.get_usage()}"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            return

        username = update.effective_user.username

        # Check if user has a wallet
        if not Bismuth.wallet_exists(username):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        try:
            decode = BismuthUtil.read_url(args[0])
        except Exception as e:
            msg = f"{emo.ERROR} Does not look like a proper BIS URL"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            logging.error(f"{msg}: {e}")
            return

        amount = float(decode['amount'])
        address = decode['recipient']
        operation = decode['operation']
        message = decode['openfield']
        fees = BismuthUtil.fee_for_tx(message)

        # Check if provided address is valid
        if not BismuthUtil.valid_address(address):
            update.message.reply_text(
                text=f"{emo.ERROR} Provided address is not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        bisurl_id = self.unix_time()

        # Save transaction to database
        insert = self.get_resource("insert_bisurl.sql")
        self.execute_sql(insert, bisurl_id, username, address, amount,
                         operation, message)

        msg = "Execute following transaction?\n\n"
        msg += "▸ Recipient: {}\n".format(address)
        msg += "▸ Amount: {:.2f} BIS\n".format(amount)
        msg += "▸ Operation: {}\n".format(operation)
        msg += "▸ Message: {}\n".format(message)
        msg += "▸ Fees: {} BIS\n".format(fees)

        update.message.reply_text(msg, reply_markup=self._keyboard(bisurl_id))
Exemplo n.º 5
0
    def execute(self, bot, update, args):
        username = update.effective_user.username

        if not Bismuth.wallet_exists(username):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        if len(args) < 2 or len(args) > 4:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        send_to = args[0]
        amount = args[1]

        operation = ""
        if len(args) > 2:
            operation = args[2]

        data = ""
        if len(args) > 3:
            data = args[3]

        if not BismuthUtil.valid_address(send_to):
            update.message.reply_text(
                text=f"{emo.ERROR} Bismuth address is not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        if not utl.is_numeric(amount) or float(amount) < 0:
            update.message.reply_text(
                text=f"{emo.ERROR} Specified amount is not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        message = update.message.reply_text(text=f"{emo.WAIT} Sending...",
                                            parse_mode=ParseMode.MARKDOWN)

        bis = Bismuth(username)
        bis.load_wallet()
        trx = bis.send(send_to, amount, operation, data)

        url = f"{self.BLCK_EXPL_URL}{utl.encode_url(trx)}"

        if trx:
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.DONE} Done!\n[View on Block Explorer]({url})\n"
                f"(Available after ~1 minute)",
                parse_mode=ParseMode.MARKDOWN)
        else:
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.ERROR} Not able to send Transaction")
Exemplo n.º 6
0
    def execute(self, bot, update, args):
        username = update.effective_user.username

        if not Bismuth.wallet_exists(username):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        message = update.message.reply_text(
            text=f"{emo.WAIT} Checking balance...",
            parse_mode=ParseMode.MARKDOWN)

        bis = Bismuth(username)
        bis.load_wallet()

        balance = bis.get_balance()

        if utl.is_numeric(balance):
            balance = f"`{balance}` BIS"

        bot.edit_message_text(chat_id=message.chat_id,
                              message_id=message.message_id,
                              text=f"Balance: {balance}",
                              parse_mode=ParseMode.MARKDOWN)
Exemplo n.º 7
0
    def execute(self, bot, update, args):
        if not args:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        # command <total amount> <number of users>
        if len(args) == 2:
            amount = args[0]
            users = args[1]

        # command <total amount>/<number of users>
        elif len(args) == 1 and "/" in args[0]:
            lst = args[0].split("/")
            if len(lst) == 2:
                amount = lst[0]
                users = lst[1]
            else:
                update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                          parse_mode=ParseMode.MARKDOWN)
                return
        else:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        # Make sure that 'amount' and 'users' are valid values
        try:
            amount = float(amount)
            users = int(users)
        except ValueError as e:
            msg = f"{emo.ERROR} Arguments not valid"
            update.message.reply_text(msg)
            logging.error(e)
            return

        if users < 1:
            msg = f"{emo.ERROR} You have to rain on at least one user"
            update.message.reply_text(msg)
            return

        multiplier = 10**2
        user_amount = math.floor(amount / users * multiplier) / multiplier

        if user_amount < 0.01:
            msg = f"{emo.ERROR} Amount per user to small. Has to be at least `0.01`"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            return

        from_user = update.effective_user.username
        from_user_id = update.effective_user.id

        # Check if sender has a wallet
        if not Bismuth.wallet_exists(from_user):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        sql = self.get_resource("read_users.sql")
        res = self.execute_sql(sql, plugin="wallet")

        if not res["success"]:
            msg = f"{emo.ERROR} Not possible to retrieve users"
            update.message.reply_text(msg)

            error = res["data"]
            logging.error(error)
            self.notify(error)
            return

        # Remove own user from list of users to rain on
        user_list = [x for x in res["data"] if x[1] != from_user]

        # Check if enough users available to be rained on
        if len(user_list) < users:
            msg = f"{emo.ERROR} Not enough users. {len(user_list)} available"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            return

        # Randomly choose users from all users
        chosen = random.sample(user_list, users)

        msg = f"{emo.WAIT} Processing..."
        message = update.message.reply_text(msg)

        # Init sender wallet
        bis = Bismuth(from_user)
        bis.load_wallet()

        # Check for sufficient funds
        fees = amount + (users * self.FEE)
        if float(bis.get_balance()) < fees:
            msg = f"{emo.ERROR} Not enough funds"
            update.message.reply_text(msg)
            return

        result = f"{emo.DONE} @{utl.esc_md(from_user)} sent `{user_amount}` BIS each to: "

        for to_data in chosen:
            to_user_id = to_data[0]
            to_user = to_data[1]

            try:
                # Execute tipping
                trx = bis.tip(to_user, user_amount)
            except Exception as e:
                error = "Error while executing rain tip"
                logging.error(f"{error}: {e}")
                self.notify(e)
                trx = None

            if trx:
                # Save tipping in database
                # TODO: Do i have to lock the DB while writing?
                insert = self.get_resource("insert_rain.sql")
                self.execute_sql(insert, from_user, to_user, amount)

                # Add username of tipped user to confirmation message
                result += f"@{utl.esc_md(to_user)} "

                try:
                    # Send success message to tipped user
                    msg = f"You've been tipped with `{user_amount}` BIS by @{utl.esc_md(from_user)}"
                    bot.send_message(to_user_id,
                                     msg,
                                     parse_mode=ParseMode.MARKDOWN)
                except Exception as e:
                    error = f"Not possible to notify user '{to_user}' about rain tip"
                    logging.debug(f"{error}: {e}")
            else:
                try:
                    # Send error message to tipping user
                    msg = f"{emo.ERROR} Not possible to send `{user_amount}` BIS to @{utl.esc_md(to_user)}"
                    bot.send_message(from_user_id,
                                     msg,
                                     parse_mode=ParseMode.MARKDOWN)

                    logging.error(msg)
                    self.notify(msg)
                except Exception as e:
                    error = f"Not possible to notify tipping user '{from_user}' about failed rain tip"
                    logging.debug(f"{error}: {e}")

        # Check if at least one user got tipped
        if result.count("@") > 1:
            # TODO: Use 'split_msg' from utils here
            # Send success message
            bot.edit_message_text(chat_id=message.chat_id,
                                  message_id=message.message_id,
                                  text=result,
                                  parse_mode=ParseMode.MARKDOWN)
        else:
            # Send error message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.ERROR} Rain not executed. Something went wrong...",
                parse_mode=ParseMode.MARKDOWN)
Exemplo n.º 8
0
    def execute(self, bot, update, args):
        user = update.effective_user.username

        if len(args) < 2 or len(args) > 4:
            update.message.reply_text(text=f"Usage:\n{self.get_usage()}",
                                      parse_mode=ParseMode.MARKDOWN)
            return

        address = args[0]
        amount = args[1]

        operation = ""
        if len(args) > 2:
            operation = args[2]

        data = ""
        if len(args) > 3:
            data = args[3]

        # Check if provided amount is valid
        if not utl.is_numeric(amount) or float(amount) < 0:
            update.message.reply_text(
                text=f"{emo.ERROR} Specified amount is not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        # Check if provided address is valid
        if not BismuthUtil.valid_address(address):
            update.message.reply_text(
                text=f"{emo.ERROR} Provided address is not valid",
                parse_mode=ParseMode.MARKDOWN)
            return

        # Check if user has a wallet
        if not Bismuth.wallet_exists(user):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        message = update.message.reply_text(text=f"{emo.WAIT} Processing...",
                                            parse_mode=ParseMode.MARKDOWN)

        bis = Bismuth(user)
        bis.load_wallet()

        balance = bis.get_balance()
        total = float(amount) + BismuthUtil.fee_for_tx(data)

        # Check for sufficient funds
        if not utl.is_numeric(balance) or float(balance) < total:
            bot.edit_message_text(chat_id=message.chat_id,
                                  message_id=message.message_id,
                                  text=f"{emo.ERROR} Not enough funds")
            return

        try:
            # Execute withdrawing
            trx = bis.send(address, amount, operation, data)
        except Exception as e:
            error = f"Error withdrawing {amount} BIS " \
                    f"from @{user} " \
                    f"to {address} " \
                    f"with '{operation}' " \
                    f"and '{data}': {e}"
            logging.error(error)
            self.notify(error)
            trx = None

        if trx:
            logging.debug(f"Withdraw {amount} BIS "
                          f"from @{user} "
                          f"to {address} "
                          f"with '{operation}' "
                          f"and '{data}'")

            # Save withdrawing to database
            insert = self.get_resource("insert_withdraw.sql")
            self.execute_sql(insert, user, address, amount)

            url = f"{self.BLCK_EXPL_URL}{utl.encode_url(trx)}"

            # Send success message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.DONE} DONE!\n[View on Block Explorer]({url})\n"
                f"(Available after ~1 minute)",
                parse_mode=ParseMode.MARKDOWN)
        else:
            # Send error message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=
                f"{emo.ERROR} Withdrawing not executed. Something went wrong..."
            )
Exemplo n.º 9
0
    def execute(self, bot, update, args):
        reply = update.message.reply_to_message

        # Tip the user that you reply to
        if reply:
            # Determine amount to tip
            if len(args) == 0:
                # Tip default BIS amount
                amount = self.DEFAULT_TIP
            elif len(args) == 1:
                # Tip specified BIS amount
                try:
                    amount = float(args[0])
                except:
                    msg = f"{emo.ERROR} Specified amount is not valid"
                    update.message.reply_text(msg)
                    return
            else:
                msg = "You are tipping the user you reply to. " \
                      "Only allowed argument is the amount."
                update.message.reply_text(msg)
                return

            to_user = reply.from_user.username

        # Provide username to be tipped
        else:
            if not args:
                msg = f"Usage:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            # Determine amount to tip
            if len(args) == 1:
                # Tip default BIS amount
                amount = self.DEFAULT_TIP
            elif len(args) == 2:
                # Tip specified BIS amount
                try:
                    amount = float(args[1])
                except:
                    msg = f"{emo.ERROR} Specified amount is not valid"
                    update.message.reply_text(msg)
                    return
            else:
                # Wrong syntax
                msg = f"{emo.ERROR} Wrong number of arguments:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            to_user = args[0]

            # Check if username starts with @
            if not to_user.startswith("@"):
                msg = f"{emo.ERROR} Username not valid:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            to_user = to_user[1:]

        from_user = update.effective_user.username

        # Check if sender has a wallet
        if not Bismuth.wallet_exists(from_user):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        # Check if recipient has a wallet
        if not Bismuth.wallet_exists(to_user):
            msg = f"{emo.ERROR} User @{utl.esc_md(to_user)} doesn't have a wallet yet"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            return

        msg = f"{emo.WAIT} Processing..."
        message = update.message.reply_text(msg)

        # Init sender wallet
        bis = Bismuth(from_user)
        bis.load_wallet()

        # Check for sufficient funds
        if float(bis.get_balance()) <= amount:
            msg = f"{emo.ERROR} Not enough funds"
            update.message.reply_text(msg)
            return

        # Process actual tipping
        if bis.tip(to_user, amount):
            # Save tipping in database
            insert = self.get_resource("insert_tip.sql")
            self.execute_sql(insert, from_user, to_user, amount)

            # Send success message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.DONE} @{utl.esc_md(to_user)} received `{amount}` BIS",
                parse_mode=ParseMode.MARKDOWN)

            try:
                # Get user ID from tipped user
                sql = self.get_resource("get_user_id.sql")
                res = self.execute_sql(sql, to_user, plugin="wallet")
                user_id = res["data"][0][0] if res["success"] else None

                if user_id:
                    # Send message to tipped user
                    msg = f"You've been tipped with `{amount}` BIS by @{utl.esc_md(from_user)}"
                    bot.send_message(user_id, msg, parse_mode=ParseMode.MARKDOWN)
            except Exception as e:
                logging.warning(e)
        else:
            # Send error message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.ERROR} Something went wrong")
Exemplo n.º 10
0
    def execute(self, bot, update, args):
        reply = update.message.reply_to_message

        # Tip the user that you reply to
        if reply:
            # Determine amount to tip
            if len(args) == 0:
                # Tip default BIS amount
                amount = self.DEFAULT_TIP
            elif len(args) == 1:
                # Tip specified BIS amount
                try:
                    amount = float(args[0])
                except:
                    msg = f"{emo.ERROR} Specified amount is not valid"
                    update.message.reply_text(msg)
                    return
            else:
                msg = "You are tipping the user you reply to. " \
                      "Only allowed argument is the amount."
                update.message.reply_text(msg)
                return

            to_user = reply.from_user.username

        # Provide username to be tipped
        else:
            if not args:
                msg = f"Usage:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            # Determine amount to tip
            if len(args) == 1:
                # Tip default BIS amount
                amount = self.DEFAULT_TIP
            elif len(args) == 2:
                # Tip specified BIS amount
                try:
                    amount = float(args[1])
                except:
                    msg = f"{emo.ERROR} Specified amount is not valid"
                    update.message.reply_text(msg)
                    return
            else:
                # Wrong syntax
                msg = f"{emo.ERROR} Wrong number of arguments:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            to_user = args[0]

            # Check if username starts with @
            if not to_user.startswith("@"):
                msg = f"{emo.ERROR} Username not valid:\n{self.get_usage()}"
                update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
                return

            to_user = to_user[1:]

        from_user = update.effective_user.username

        # Check if sender has a wallet
        if not Bismuth.wallet_exists(from_user):
            msg = "Accept terms and create a wallet first with:\n/accept"
            update.message.reply_text(msg)
            return

        # Check if recipient has a wallet
        if not Bismuth.wallet_exists(to_user):
            msg = f"{emo.ERROR} User @{utl.esc_md(to_user)} doesn't have a wallet yet"
            update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
            return

        msg = f"{emo.WAIT} Processing..."
        message = update.message.reply_text(msg)

        # Init sender wallet
        bis = Bismuth(from_user)
        bis.load_wallet()

        balance = bis.get_balance()
        total = amount + con.TRX_FEE

        # Check for sufficient funds
        if not utl.is_numeric(balance) or float(balance) < total:
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.ERROR} Not enough funds")
            return

        try:
            # Execute tipping
            trx = bis.tip(to_user, amount)
        except Exception as e:
            error = f"Error executing tip from @{from_user} to @{to_user} with {amount}: {e}"
            logging.error(error)
            self.notify(error)
            trx = None

        if trx:
            logging.debug(f"Tip from '{from_user}' to '{to_user}' with {amount} BIS - TRX: {trx}")

            # Save tipping to database
            insert = self.get_resource("insert_tip.sql")
            self.execute_sql(insert, from_user, to_user, amount)

            # Send success message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.DONE} @{utl.esc_md(to_user)} received `{amount}` BIS",
                parse_mode=ParseMode.MARKDOWN)

            # Get user ID from tipped user
            sql = self.get_resource("get_user_id.sql")
            res = self.execute_sql(sql, to_user, plugin="wallet")
            to_user_id = res["data"][0][0] if res["success"] else None

            if to_user_id:
                try:
                    # Send success message to tipped user
                    msg = f"You've been tipped with `{amount}` BIS by @{utl.esc_md(from_user)}"
                    bot.send_message(to_user_id, msg, parse_mode=ParseMode.MARKDOWN)
                except Exception as e:
                    error = f"Can't notify user '{to_user}' about tip"
                    logging.debug(f"{error}: {e}")
            else:
                error = f"Can't notify user '{to_user}' about tip. User ID not found in DB"
                logging.error(error)
                self.notify(error)
        else:
            # Send error message
            bot.edit_message_text(
                chat_id=message.chat_id,
                message_id=message.message_id,
                text=f"{emo.ERROR} Tipping not executed. Something went wrong...")