Esempio n. 1
0
async def make_transaction_to_address(source_user, amount, withdraw_address, uid, target_id=None, giveaway_id=0, verify_address=False):
	# Do not validate address for giveaway tx because we do not know it yet
	if verify_address:
		# Check to see if the withdraw address is valid
		#pulowi falta servicio de validacion
		#wallet_command = {'action': 'validate_account_number',
		#		  'account': withdraw_address}
		#address_validation = await communicate_wallet_async(wallet_command)

		#if ((withdraw_address[:4] == 'ban_' and len(withdraw_address) != 64)
		#		or address_validation['valid'] != '1'):
		#	raise util.TipBotException('invalid_address')

		if ((withdraw_address[:4] == 'tgm_' and len(withdraw_address) != 106)):
			raise util.TipBotException('invalid_address')


	amount = int(amount)
	if amount >= 1:
		# See if destination address belongs to a user
		if target_id is None:
			user = db.get_user_by_wallet_address(withdraw_address)
			if user is not None:
				target_id=user.user_id
		# Update pending send for user
		db.create_transaction(source_user, uid, withdraw_address,amount, target_id, giveaway_id)
		logger.info('TX queued, uid %s', uid)
	else:
		raise util.TipBotException('balance_error')

	return amount
Esempio n. 2
0
def find_address(input_text):
	address = input_text.split(' ')
	if len(address) == 1:
		raise util.TipBotException("address_not_found")
	elif address[1] is None:
		raise util.TipBotException("address_not_found")
	return address[1]
Esempio n. 3
0
async def givearai(message):
    if message.channel.is_private:
        return
    try:
        # One giveaway at a time
        if db.is_active_giveaway():
            await post_dm(message.author, GIVEAWAY_EXISTS)
            return
        split_content = message.content.split(' ')
        if len(split_content) > 2:
            amount = find_amount(split_content[1])
            fee = find_amount(split_content[2])
        else:
            raise util.TipBotException("usage_error")
        if amount < GIVEAWAY_MINIMUM:
            raise util.TipBotException("usage_error")
        max_fee = int(0.05 * amount)
        if fee > max_fee:
            await post_response(message, GIVEAWAY_MAX_FEE)
            return
        if 0 > fee:
            raise util.TipBotException("usage_error")
        user = db.get_user_by_id(message.author.id)
        if user is None:
            return
        balance = await wallet.get_balance(user)
        user_balance = balance['available']
        if user_balance < amount:
            await add_x_reaction(message)
            await post_dm(message.author, INSUFFICIENT_FUNDS_TEXT)
            return
        end_time = datetime.datetime.now() + datetime.timedelta(
            minutes=GIVEAWAY_DURATION)
        nano_amt = amount / 1000000
        giveaway = db.start_giveaway(message.author.id,
                                     message.author.name,
                                     nano_amt,
                                     end_time,
                                     message.channel.id,
                                     entry_fee=fee)
        uid = str(uuid.uuid4())
        await wallet.make_transaction_to_address(user,
                                                 amount,
                                                 None,
                                                 uid,
                                                 giveaway_id=giveaway.id)
        if fee > 0:
            await post_response(message, GIVEAWAY_STARTED_FEE,
                                message.author.name, nano_amt, fee, fee)
        else:
            await post_response(message, GIVEAWAY_STARTED, message.author.name,
                                nano_amt)
        asyncio.get_event_loop().create_task(start_giveaway_timer())
        db.update_tip_stats(user, amount)
        db.add_contestant(message.author.id, override_ban=True)
    except util.TipBotException as e:
        if e.error_type == "amount_not_found" or e.error_type == "usage_error":
            await post_dm(message.author, GIVEAWAY_USAGE)
Esempio n. 4
0
async def tipsplit(message):
    if message.channel.is_private:
        return
    try:
        amount = find_amount(message.content)
        # Make sure amount is valid and at least 1 user is mentioned
        if amount < 1 or len(message.mentions) < 1:
            raise util.TipBotException("usage_error")
        if int(amount / len(message.mentions)) < 1:
            raise util.TipBotException("invalid_tipsplit")
        # Create tip list
        users_to_tip = []
        for member in message.mentions:
            # Disregard mentions of self and exempt users
            if member.id not in settings.exempt_users and member.id != message.author.id and not db.is_banned(
                    member.id) and not member.bot:
                users_to_tip.append(member)
        if len(users_to_tip) < 1:
            raise util.TipBotException("no_valid_recipient")
        # Remove duplicates
        users_to_tip = list(set(users_to_tip))
        # Make sure user has enough in their balance
        user = db.get_user_by_id(message.author.id)
        if user is None:
            return
        balance = await wallet.get_balance(user)
        user_balance = balance['available']
        if user_balance < amount:
            await add_x_reaction(ctx.message)
            await post_dm(message.author, INSUFFICIENT_FUNDS_TEXT)
            return
        # Distribute tips
        tip_amount = int(amount / len(users_to_tip))
        # Recalculate amount as it may be different since truncating decimal
        real_amount = tip_amount * len(users_to_tip)
        for member in users_to_tip:
            uid = str(uuid.uuid4())
            actual_amt = await wallet.make_transaction_to_user(
                user, tip_amount, member.id, member.name, uid)
            # Tip didn't go through
            if actual_amt == 0:
                amount -= tip_amount
            else:
                await post_dm(member, TIP_RECEIVED_TEXT, tip_amount,
                              message.author.name)
        await react_to_message(message, amount)
        db.update_tip_stats(user, real_amount)
    except util.TipBotException as e:
        if e.error_type == "amount_not_found" or e.error_type == "usage_error":
            await post_dm(message.author, TIPSPLIT_USAGE)
        elif e.error_type == "invalid_tipsplit":
            await post_dm(message.author, TIPSPLIT_SMALL)
        elif e.error_type == "no_valid_recipient":
            await post_dm(message.author, TIP_SELF)
        else:
            await post_response(message, TIP_ERROR_TEXT)
Esempio n. 5
0
def make_transaction_to_user(user_id, amount, target_user_id,
                             target_user_name):
    if check_balance(user_id, amount):
        target_user = create_or_fetch_user(target_user_id, target_user_name)
        user = db.get_user_by_id(user_id)
        if db.move_funds(user, amount, target_user):
            logger.info('tip successful. (from: %s, to: %s, amount: %.3f)',
                        user_id, target_user.user_id, amount)
            return
        else:
            raise util.TipBotException("error")
    else:
        raise util.TipBotException("insufficient_funds")
Esempio n. 6
0
async def tip(message):
    if message.channel.is_private:
        return

    try:
        amount = find_amount(message.content)
        # Make sure amount is valid and at least 1 user is mentioned
        if amount < 1 or len(message.mentions) < 1:
            raise util.TipBotException("usage_error")
        # Create tip list
        users_to_tip = []
        for member in message.mentions:
            # Disregard mentions of exempt users and self
            if member.id not in settings.exempt_users and member.id != message.author.id and not db.is_banned(
                    member.id) and not member.bot:
                users_to_tip.append(member)
        if len(users_to_tip) < 1:
            raise util.TipBotException("no_valid_recipient")
        # Cut out duplicate mentions
        users_to_tip = list(set(users_to_tip))
        # Make sure this user has enough in their balance to complete this tip
        required_amt = amount * len(users_to_tip)
        user = db.get_user_by_id(message.author.id)
        balance = await wallet.get_balance(user)
        user_balance = balance['available']
        if user_balance < required_amt:
            await add_x_reaction(message)
            await post_dm(message.author, INSUFFICIENT_FUNDS_TEXT)
            return
        # Distribute tips
        for member in users_to_tip:
            uid = str(uuid.uuid4())
            actual_amt = await wallet.make_transaction_to_user(
                user, amount, member.id, member.name, uid)
            # Something went wrong, tip didn't go through
            if actual_amt == 0:
                required_amt -= amount
            else:
                await post_dm(member, TIP_RECEIVED_TEXT, actual_amt,
                              message.author.name)
        # Post message reactions
        await react_to_message(message, required_amt)
        # Update tip stats
        db.update_tip_stats(user, required_amt)
    except util.TipBotException as e:
        if e.error_type == "amount_not_found" or e.error_type == "usage_error":
            await post_dm(message.author, TIP_USAGE)
        elif e.error_type == "no_valid_recipient":
            await post_dm(message.author, TIP_SELF)
        else:
            await post_response(message, TIP_ERROR_TEXT)
Esempio n. 7
0
def find_amount(input_text):
    regex = r'(?:^|\s)(\d*\.?\d+)(?=$|\s)'
    matches = re.findall(regex, input_text, re.IGNORECASE)

    if len(matches) == 1:
        try:
            assert Decimal(matches[0]).as_tuple().exponent >= -6
            return float(matches[0].strip())

        except AssertionError:
            raise util.TipBotException("too_many_decimals")

    else:
        raise util.TipBotException("amount_not_found")
Esempio n. 8
0
def find_user_id(input_text):
    regex = r'(?:^|\s)<@!?(\w*)>(?=$|\s)'
    matches = re.findall(regex, input_text, re.IGNORECASE)
    if len(matches) == 1:
        return matches[0].strip()
    else:
        raise util.TipBotException("user_not_found")
Esempio n. 9
0
def find_amount(input_text):
    regex = r'(?:^|\s)(\d*\.?\d+)(?=$|\s)'
    matches = re.findall(regex, input_text, re.IGNORECASE)
    if len(matches) == 1:
        return float(matches[0].strip())
    else:
        raise util.TipBotException("amount_not_found")
Esempio n. 10
0
def find_address(input_text):
    regex = r'\w{25,34}'
    matches = re.findall(regex, input_text, re.IGNORECASE)
    if len(matches) == 1:
        return matches[0].strip()
    else:
        raise util.TipBotException("address_not_found")
Esempio n. 11
0
def find_address(input_text: str) -> str:

    # regex catching all kinds of Peercoin addreses
    regex = r'(?:(?:tpc|pc)(?:0(?:[ac-hj-np-z02-9]{39}|[ac-hj-np-z02-9]{59})|1[ac-hj-np-z02-9]{8,87})|(?:[Pp]|[mn2])[a-km-zA-HJ-NP-Z1-9]{25,39})'
    matches = re.findall(regex, input_text, re.IGNORECASE)
    if len(matches) == 1:
        return matches[0].strip()
    else:
        raise util.TipBotException("address_not_found")
Esempio n. 12
0
async def make_transaction_to_address(source_user,
                                      amount,
                                      withdraw_address,
                                      uid,
                                      target_id=None,
                                      giveaway_id=0,
                                      verify_address=False):
    # Do not validate address for giveaway tx because we do not know it yet
    if verify_address:
        # Check to see if the withdraw address is valid
        wallet_command = {
            'action': 'validate_account_number',
            'account': withdraw_address
        }
        address_validation = await asyncio.get_event_loop().run_in_executor(
            None, communicate_wallet, wallet_command)

        # If the address was the incorrect length, did not start with xrb_ or nano_ or was deemed invalid by the node, return an error.
        address_prefix_valid = withdraw_address[:4] == 'ban_' \
         or withdraw_address[:5] == 'ban_'
        if len(withdraw_address) != 64 or not address_prefix_valid \
         or address_validation['valid'] != '1':
            raise util.TipBotException('invalid_address')

    amount = int(amount)
    if amount >= 1:
        # See if destination address belongs to a user
        if target_id is None:
            user = db.get_user_by_wallet_address(withdraw_address)
            if user is not None:
                target_id = user.user_id
        # Update pending send for user
        db.create_transaction(source_user, uid, withdraw_address, amount,
                              target_id, giveaway_id)
        logger.info('TX queued, uid %s', uid)
    else:
        raise util.TipBotException('balance_error')

    return amount
Esempio n. 13
0
def make_transaction_to_address(user, amount, address):

    rpc_connection = connect()

    txid = rpc_connection.sendtoaddress(address, round(amount, 6),
                                        "tippbot withdraw")

    logger.info(
        'creating withdraw transaction (user: %s, amount: %.3f, address: %s, txid: %s)',
        user.user_id, amount, address, txid)
    if db.create_withdraw_transaction(txid, amount, user):
        logger.info('withdraw successful.')
        return txid
    else:
        raise util.TipBotException("error")
Esempio n. 14
0
def make_transaction_to_address(user, amount, address):
    txfee = 0.01
    commands = [["settxfee", txfee]]
    rpc_connection = connect()
    result = rpc_connection.batch_(commands)
    if result[0]:
        commands = [[
            "sendtoaddress", address, amount - txfee, "ztipbot withdraw"
        ]]
        result = rpc_connection.batch_(commands)
        txid = result[0]
        logger.info(
            'creating withdraw transaction (user: %s, amount: %.3f, address: %s)',
            user.user_id, amount, address)
        if db.create_withdraw_transaction(txid, amount, user):
            logger.info('withdraw successful.')
            return
        else:
            raise util.TipBotException("error")
Esempio n. 15
0
async def rain(message):
    if message.channel.is_private:
        return
    try:
        amount = find_amount(message.content)
        if amount < RAIN_MINIMUM:
            raise util.TipBotException("usage_error")
        # Create tip list
        users_to_tip = []
        active_user_ids = db.get_active_users(RAIN_DELTA)
        if len(active_user_ids) < 1:
            raise util.TipBotException("no_valid_recipient")
        for auid in active_user_ids:
            dmember = message.server.get_member(auid)
            if dmember is not None and (dmember.status == discord.Status.online
                                        or dmember.status
                                        == discord.Status.idle):
                if dmember.id not in settings.exempt_users and dmember.id != message.author.id and not db.is_banned(
                        dmember.id) and not dmember.bot:
                    users_to_tip.append(dmember)
        users_to_tip = list(set(users_to_tip))
        if len(users_to_tip) < 1:
            raise util.TipBotException("no_valid_recipient")
        if int(amount / len(users_to_tip)) < 1:
            raise util.TipBotException("invalid_tipsplit")
        user = db.get_user_by_id(message.author.id)
        if user is None:
            return
        balance = await wallet.get_balance(user)
        user_balance = balance['available']
        if user_balance < amount:
            await add_x_reaction(message)
            await post_dm(message.author, INSUFFICIENT_FUNDS_TEXT)
            return
        # Distribute Tips
        tip_amount = int(amount / len(users_to_tip))
        # Recalculate actual tip amount as it may be smaller now
        real_amount = tip_amount * len(users_to_tip)
        for member in users_to_tip:
            uid = str(uuid.uuid4())
            actual_amt = await wallet.make_transaction_to_user(
                user, tip_amount, member.id, member.name, uid)
            # Tip didn't go through for some reason
            if actual_amt == 0:
                amount -= tip_amount
            else:
                await post_dm(member, TIP_RECEIVED_TEXT, actual_amt,
                              message.author.name)

        # Message React
        await react_to_message(message, amount)
        await client.add_reaction(message, '\U0001F4A6')  # Sweat Drops
        db.update_tip_stats(user, real_amount)
    except util.TipBotException as e:
        if e.error_type == "amount_not_found" or e.error_type == "usage_error":
            await post_dm(message.author, RAIN_USAGE)
        elif e.error_type == "no_valid_recipient":
            await post_dm(message.author, RAIN_NOBODY)
        elif e.error_type == "invalid_tipsplit":
            await post_dm(message.author, TIPSPLIT_SMALL)
        else:
            await post_response(message, TIP_ERROR_TEXT)