Пример #1
0
def balance(bot, update):
    """ Fetches and returns the balance (in USD) """
    if not checks.check_username(update):
        return
    create_user(update.message.from_user.username)
    key = Key(get_wif(update.message.from_user.username))
    balance = key.get_balance("usd")
    return update.message.reply_text("You have: $" + str(balance))
 def __init__(self, testing=False, unittest_prkey=''):
     if testing == True:
         self.testing = testing
         self.private_key = read_drive(testing)
         self.key = PrivateKeyTestnet(self.private_key)
     elif unittest_prkey != '':
         self.testing = testing
         self.private_key = unittest_prkey
         self.key = Key(self.private_key)
     else:
         self.testing = testing
         self.private_key = read_drive(testing)
         self.key = Key(self.private_key)
Пример #3
0
def create_user(username):
    """Checks if a Telegram user is present in the database.
    Returns True if a user is created, False otherwise.
    """
    db.connect(reuse_if_open=True)
    key = Key()
    try:
        User.create(username=username, bch_address=key.address, wif=key.to_wif())
        db.close()
        return True
    except IntegrityError:
        db.close()
        return False
Пример #4
0
def index():
    if 'user' not in session:
        session['user'] = secrets.token_hex()
        key = Key()
        wif = key.to_wif()
        # Stores the keys in the cookies
        session['wif'] = wif
        session['address'] = key.address

    return render_template(
        'index.html',
        eb_link=EVENT_BRIBE_LINK,
        address=session['address'],
        wif=session['wif'],
    )
Пример #5
0
 def to_key_pairs(cls, mnemonic):
     w = wallet.create_wallet(network="bch", seed=mnemonic, children=1)
     wif = w['wif']
     key = Key(wif)
     address = key.address
     keypair = {"private_key_WIF": wif, "address": address}
     return keypair
Пример #6
0
def send_bitcash_message(message):
    if len(message.encode('utf-8')) > 213:
        raise ValueError(message + "超长,长度是:" + len(message.encode('utf-8')))
    else:
        config = get_systemconfigs()
        key = Key(config.private_key)
        upspents = key.get_unspents()
        logger.info(upspents)
        logger.info(key.address)
        outputs = [
            (config.outaddress, 10056, 'satoshi'),
        ]
        try:
            txhash, txid = key.send(outputs,
                                    message=message,
                                    fee=config.default_fee)
            logging.info('{m}交易成功,txid:{txid}'.format(m=message, txid=txid))
            return (txhash, txid)
        except Exception as e:
            logging.error('{m}交易失败,异常:{e}'.format(m=message, e=str(e)))
            raise e
Пример #7
0
def withdraw(bot, update, args):
    """ Withdraws BCH to user's wallet """
    if not checks.check_username(update):
        return

    if update.message.chat.type != "private":  # check if in DM
        return bot.send_message(
            chat_id=update.effective_chat.id,
            text="Private message me to withdraw your money",
        )

    if len(args) != 2:
        message = ("Usage: /withdraw [amount] [address]\n\n"
                   "You may also withdraw everything at once using:"
                   " /withdraw all [address]")
        return update.message.reply_text(message)

    address = checks.check_address(update, args[1])
    if not address:  # does not send anything if address is False
        return

    wif = get_wif(update.message.from_user.username)
    key = Key(wif)

    if args[0] == "all":
        sent_amount = 1000
        currency = "satoshi"
    else:
        amount = args[0].replace("$", "")
        if not checks.amount_is_valid(amount):
            return update.message.reply_text(amount + " is not a valid amount")
        currency = "usd"
        sent_amount = float(amount) - 0.01  # after 1 cent fee

    outputs = [
        (address, sent_amount, currency),
    ]
    key.get_unspents()
    try:
        if args[0] == "all":
            tx_id = key.send(outputs, fee=1, leftover=address)
        else:
            tx_id = key.send(outputs, fee=1)
    except Exception:
        return update.message.reply_text("Transaction failed!")

    return update.message.reply_text("Sent! Transaction ID: " + tx_id)
Пример #8
0
def withdraw(bot, update, args):
    """ Withdraws BCH to user's wallet """
    if not checks.check_username(update):
        return

    if update.message.chat.type != 'private':  # check if in DM
        return bot.send_message(
            chat_id=update.effective_chat.id,
            text='Private message me to withdraw your money')

    if len(args) != 2:
        message = 'Usage: /withdraw [amount] [address]\n\n'\
            'You may also withdraw everything at once using:'\
            ' /withdraw all [address]'
        return update.message.reply_text(message)

    address = checks.check_address(update, args[1])
    if not address:  # does not send anything if address is False
        return

    wif = get_wif(update.message.from_user.username)
    key = Key(wif)

    if args[0] == 'all':
        sent_amount = 1000
        currency = 'satoshi'
    else:
        amount = args[0].replace('$', '')
        if not checks.amount_is_valid(amount):
            return update.message.reply_text(amount + ' is not a valid amount')
        currency = 'usd'
        sent_amount = float(amount) - 0.01  # after 1 cent fee

    outputs = [
        (address, sent_amount, currency),
    ]
    key.get_unspents()
    try:
        if args[0] == 'all':
            tx_id = key.send(outputs, fee=1, leftover=address)
        else:
            tx_id = key.send(outputs, fee=1)
    except Exception:
        return update.message.reply_text('Transaction failed!')

    return update.message.reply_text('Sent! Transaction ID: ' + tx_id)
Пример #9
0
 def __init__(self, prkey):
     self.prkey = Key(prkey)
class Wallet:
    def __init__(self, testing=False, unittest_prkey=''):
        if testing == True:
            self.testing = testing
            self.private_key = read_drive(testing)
            self.key = PrivateKeyTestnet(self.private_key)
        elif unittest_prkey != '':
            self.testing = testing
            self.private_key = unittest_prkey
            self.key = Key(self.private_key)
        else:
            self.testing = testing
            self.private_key = read_drive(testing)
            self.key = Key(self.private_key)

    def bch_address(self):
        return self.key.address

    def bch_segwit_address(self):
        return self.key.segwit_address

    def bch_balance(self, currency="bch"):
        spinner.start()
        balance = self.key.get_balance(currency)
        spinner.stop()
        return balance

    def bch_history(self):
        spinner.start()
        transactions = self.key.get_transactions()
        spinner.stop()
        print("")
        print(colorama.Fore.GREEN + str(len(transactions)) + " transactions:")
        print("")
        for transaction in transactions:
            print("[ " + transaction + " ]")

    # perform a transaction
    def transaction(self, recipient_addr, amount, currency):
        cashaddr = re.match(
            '^((bitcoincash|bchreg|bchtest):)?(q|p)[a-z0-9]{41}$',
            recipient_addr)
        legacyaddr = re.match('^([13][a-km-zA-HJ-NP-Z1-9]{25,34})',
                              recipient_addr)
        caplegacyaddr = re.match('^((BITCOINCASH:)?(Q|P)[A-Z0-9]{41})$',
                                 recipient_addr)
        if not any([cashaddr, legacyaddr, caplegacyaddr]):
            print(colorama.Fore.RED +
                  "Transaction aborted: Invalid bitcoin cash address.")
            exit()
        print('You are about to send {} {} to {}'.format(
            str(amount), currency.upper(), recipient_addr))

        amount_left = float(self.bch_balance(currency)) - amount
        if amount_left <= 0:
            print(colorama.Fore.RED +
                  'You don\'t have enough funds to perform the transaction.')
            exit()

        if currency == 'usd':
            print("You will have ${} left on your wallet.".format(
                str(amount_left)))
        elif currency == 'bch':
            print("You will have {} BCH left on your wallet.".format(
                str(amount_left)))
        elif currency == 'eur':
            print("You will have {}€ left on your wallet.".format(
                str(amount_left)))
        elif currency == 'gbp':
            print("You will have £{} left on your wallet.".format(
                str(amount_left)))
        elif currency == 'jpy':
            print("You will have ¥{} left on your wallet.".format(
                str(amount_left)))
        print("")
        decision = input(
            'Are you sure you want to perform this transaction? yes | no\n')
        if decision != 'yes':
            print("")
            print(colorama.Fore.RED + 'Transaction aborted')
            exit()
        else:
            try:
                spinner.start()
                transaction_id = self.key.send([(recipient_addr, amount,
                                                 currency)])
                spinner.stop()
                print(colorama.Fore.GREEN + 'Success: ' + colorama.Fore.WHITE +
                      transaction_id)
            except InsufficientFunds:
                print(
                    colorama.Fore.RED +
                    'You don\'t have enough funds to perform the transaction.')

    def bch_tx_fee(self):
        fee = get_fee()
        return fee
Пример #11
0
def tip(bot, update, args):
    """ Sends Bitcoin Cash on-chain """
    if not checks.check_username(update):
        return

    if len(args) != 2 and not update.message.reply_to_message:
        return update.message.reply_text("Usage: /tip [amount] [username]")

    if "@" in args[0]:
        # this swaps args[0] and args[1] in case user input username before
        # amount (e.g. /tip @merc1er $1) - the latter will still work
        tmp = args[1]
        args[1] = args[0]
        args[0] = tmp

    amount = args[0].replace("$", "")
    if not checks.amount_is_valid(amount):
        return update.message.reply_text(amount + " is not a valid amount.")

    if update.message.reply_to_message:
        recipient_username = update.message.reply_to_message.from_user.username
        if not recipient_username:
            return update.message.reply_text(
                "You cannot tip someone who has not set a username.")
    else:
        recipient_username = args[1]
        if not checks.username_is_valid(recipient_username):
            return update.message.reply_text(recipient_username +
                                             " is not a valid username.")

    recipient_username = recipient_username.replace("@", "")
    sender_username = update.message.from_user.username

    if recipient_username == sender_username:
        return update.message.reply_text("You cannot send money to yourself.")

    create_user(recipient_username)  # IMPROVE
    recipient_address = get_address(recipient_username)
    sender_wif = get_wif(sender_username)

    key = Key(sender_wif)
    balance = key.get_balance("usd")
    # checks the balance
    if float(amount) > float(balance):
        return update.message.reply_text("You don't have enough funds! " +
                                         "Type /deposit to add funds!!")

    fee = float(amount) * FEE_PERCENTAGE
    sent_amount = float(amount) - 0.01

    if fee < 0.01:
        outputs = [
            (recipient_address, sent_amount, "usd"),
        ]
    else:
        sent_amount -= fee  # deducts fee
        outputs = [
            (recipient_address, sent_amount, "usd"),
            (FEE_ADDRESS, fee, "usd"),
        ]

    try:
        key.send(outputs, fee=1)
    except Exception:
        return bot.send_message(
            chat_id=update.effective_chat.id,
            text="Transaction failed!",
            parse_mode=ParseMode.MARKDOWN,
        )

    return bot.send_message(
        chat_id=update.effective_chat.id,
        text="You sent $" + amount + " to " + recipient_username,
    )
Пример #12
0
def bch_network(net=CRYPTO_NETWORK, prkey=None):
    if net == 'mainnet':
        key = Key(prkey)
    elif net == 'testnet':
        key = PrivateKeyTestnet(prkey)
    return key
Пример #13
0
    return satoshi_to_currency_cached(satoshi, 'bch')


def is_address_valid(address):
    return convert.is_valid(address)


def send(address, amount):
    outputs = [
        (address, amount, 'bch'),
    ]
    try:
        return key.send(outputs)
    except:
        return false


if key_exists():
    print('Debug: key exists')
    priv_key = open(PRIVATE_KEY, 'r')
    key = Key(priv_key.read())
else:
    print('Debug: key does not exists')
    key = Key()
    create_path(PRIVATE_KEY)
    priv_key = open(PRIVATE_KEY, 'w')
    priv_key.write(key.to_wif())
    priv_key.close()
    img = pyqrcode.create(key.address)
    img.svg(QR)
Пример #14
0
def broadcast(op, token_address=None):
    orbit = API()
    '''
    messages = orbit.prepare(op, limit=MESSAGE_LIMIT)

    for message in messages:
        if len(message) > MESSAGE_LIMIT:
            raise AssertionError("The data is too large")

    # sanity check
    if orbit.parse(b''.join(messages), combined=True) != op:
        raise AssertionError('Re-parsing the prepared bytes of this operation does not return the same values')
    '''

    interactive = True

    if not stdin.isatty():
        key = stdin.readline().rstrip()
        interactive = False

    else:
        print()
        value = False

        while not value:
            value = input(
                "    Enter wallet name (leave blank to list), '@' for private key: "
            )  # TODO: "or '!' to self-sign"

            if not value:
                print()
                list_wallets()
                print()

            elif value == '@':
                value = getpass("    Enter private key (hex): ")

                if value:
                    key = value

            #elif value == '!':
            #    self = True
            #    confirm = False

            else:
                print()
                try:
                    key = get_key(value, display=False)

                except ValueError as e:
                    print()
                    print("Sorry: {}".format(e))
                    value = False

                print()

    print("Loading wallet...")
    wallet = Key.from_hex(key[0])
    print("    Your Address: {}".format(wallet.address))
    print("    Balance: {} satoshi".format(wallet.get_balance()))

    print("    Unspents:")
    for unspent in wallet.unspents:
        print("        {}".format(unspent))
    print("        {} unspent transaction{}".format(
        len(wallet.unspents), "" if len(wallet.unspents) == 1 else "s"))

    print()
    print("Preparing transaction...")
    if not token_address:
        token_address = wallet.address
    print("    Token Address: {}".format(token_address))

    try:
        message = orbit.prepare(token_address, op)
    except InvalidAddress as e:
        raise ValueError("An invalid bitcoincash address was entered")

    #print(message)

    if len(message) > MESSAGE_LIMIT:
        raise ValueError(
            "The data is too large; try reducing some text or removing optional data"
        )

    # sanity check
    parsed = orbit.parse(message)
    if parsed != (token_address, op):
        #print(parsed)
        raise AssertionError(
            'Re-parsing the prepared bytes of this operation does not return the same values'
        )
    '''
    sig = Address.sign(wallet, token_address)
    token = Address(token_address, wallet.public_key, sig)
    token_messages = orbit.prepare(token, limit=MESSAGE_LIMIT)

    for token_message in token_messages:
        if len(token_message) > MESSAGE_LIMIT:
            raise AssertionError("The token address data is too large")

    # sanity check
    if orbit.parse(b''.join(token_messages), combined=True) != token:
        raise AssertionError('Re-parsing the prepared bytes of the token address operation does not return the same values')
    '''

    fee = get_fee()
    #fee = 1

    if interactive:
        print()
        print(
            "    Enter fee per byte in satoshi ({} is currently recommended),".
            format(fee))
        userfee = input("        leave blank to use the recommended fee: ")

        if userfee:
            fee = int(userfee)
            if fee < 1:
                raise ValueError('Fee must be at least 1 satoshi')

        print()
        print("------------------------------------------")
        print("CAREFULLY REVIEW THE FOLLOWING TRANSACTION")
        print("------------------------------------------")
        print()

    print("    Signer's Address:")
    print("        {}".format(wallet.address))

    print()
    print("    Token Address:")
    print("        {}".format(token_address))

    print()
    #print("    {}".format(token.__str__('        ')))
    print("    {}".format(op.__str__('        ')))

    print()
    print("    Fee/byte: {} satoshi".format(fee))

    if interactive:
        print()

        confirm = input(
            "    Type 'confirm' if you are sure you want to broadcast this transaction: "
        )

        if confirm != "confirm":
            raise ValueError("User abort")

    # TODO: attempt broadcast through ORBIT node first, use bitcash wallet as fallback

    print()
    #print("Waiting 60 seconds to broadcast (rate limit?)...")
    #sleep(60)

    #token_messages.extend(messages)
    #print(token_messages)

    try:
        print("Broadcasting...")
        #tx = wallet.send([], fee=fee, message=token_messages)
        tx = wallet.send([], fee=fee, message=message)
        print('Transaction: {}'.format(tx))
        return tx

    except ConnectionError as e:
        raise ValueError(
            "Unable to broadcast, try again later or try increasing the fee: {}"
            .format(e))

    except InsufficientFunds as e:
        raise ValueError(e)