Ejemplo n.º 1
0
async def withdraw_bulk(*args, **kwargs):
    try:
        WithdrawValidator.validate_withdraw(kwargs)
    except Exception as e:
        return WithdrawValidator.error_400(str(e))

    try:
        request = await withdraw_handler.withdraw_bulk(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))
    return request
Ejemplo n.º 2
0
async def is_valid_address(*args, **kwargs):
    try:
        WithdrawValidator.validate_is_valid_address(kwargs)
    except Exception as e:
        return WithdrawValidator.error_400(str(e))

    try:
        request = await withdraw_handler.is_valid_address(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))

    return request
Ejemplo n.º 3
0
async def create_token(*args, **kwargs):

    try:
        WithdrawValidator.validate_create_token(kwargs)
    except Exception as e:
        return WithdrawValidator.error_400(str(e))

    try:
        request = await withdraw_handler.create_token(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))
    return request
Ejemplo n.º 4
0
async def hot_wallet_history(*args, **kwargs):
    try:
        request = await withdraw_handler.hot_wallet_history(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))

    return request
Ejemplo n.º 5
0
async def available_tokens(*args, **kwargs):
    try:
        request = await withdraw_handler.available_tokens(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))

    return request
Ejemplo n.º 6
0
    async def available_tokens(self, *args, **kwargs):
        try:
            token_names = []
            async for token in self.db.available_tokens.find():
                token_names.append(token)
            return token_names

        except Exception as e:
            return WithdrawValidator.error_500(str(e))
Ejemplo n.º 7
0
    async def func_wrapper(*args, **kwargs):

        if check_sig:
            try:
                signature_validator.verify(kwargs)
            except:
                return WithdrawValidator.error_403('Invalid signature')

            kwargs = signature_validator.hex_to_json(kwargs['message'])
            return signature_validator.sign(await func(*args, **kwargs))
        else:
            return await func(*args, **kwargs)
Ejemplo n.º 8
0
    async def register_token(self, *args, **kwargs):
        try:
            await self.db.available_tokens.insert_one({
                "_id":
                kwargs.get("token_name"),
                "contract_address":
                kwargs.get("contract_address"),
                "blockchain":
                kwargs.get("blockchain")
            })

        except Exception as e:
            return WithdrawValidator.error_500(str(e))
        return {'success': True}
Ejemplo n.º 9
0
    async def hot_wallet_history(self, *args, **kwargs):
        try:
            executed_requests = []
            async for executed in self.db.executed_withdraws.find(
                {}, {
                    '_id': 0,
                    'timestamp': 0
                }):
                executed['execution_time'] = executed[
                    'execution_time'].isoformat()
                executed_requests.append(executed)
            return executed_requests

        except Exception as e:
            return WithdrawValidator.error_500(str(e))
Ejemplo n.º 10
0
async def send_to_cold_wallet(*args, **kwargs):
    try:
        WithdrawValidator.validate_withdraw(kwargs)
        WithdrawValidator.validate_cold_wallet_address(kwargs)
    except Exception as e:
        return WithdrawValidator.error_400(str(e))

    try:
        request = await withdraw_handler.withdraw(*args, **kwargs)
    except Exception as e:
        return WithdrawValidator.error_500(str(e))
    return request
Ejemplo n.º 11
0
    async def execute_withdraws(self):
        print('reload')
        try:
            self.reload_connections()
        except Exception as e:
            return WithdrawValidator.error_500(str(e))
        print('reloaded')

        query = {
            'timestamp': {'$lte': datetime.datetime.utcnow() - datetime.timedelta(milliseconds=WITHDRAW_DELAY)}
        }

        print('start loop')

        document_count = await self.db.withdraw_requests.count_documents(query)
        print('document_count: ', document_count)

        while document_count != 0:
            withdrawal_requests = {}

            for coinid in bitcoinlike_coinids:
                withdrawal_requests[coinid] = []
            for coinid in ethereumlike_coinids:
                withdrawal_requests[coinid] = []

            cursor = self.db.withdraw_requests.find(query)
            cursor.limit(OUTPUTS_PER_TX)

            to_delete = []
            pprint(await self.db.withdraw_requests.count_documents(query))
            async for withdrawal in cursor:
                if await self.db.executed_withdraws.find_one({'_id': withdrawal['_id']}):
                    to_delete.append(withdrawal)
                    print('deleted', withdrawal)
                else:
                    withdrawal_requests[withdrawal['coinid']].append(withdrawal)
                    print('appended', withdrawal)

            for expired in to_delete:
                await self.db.withdraw_requests.delete_one({'_id': expired['_id']})
                print('deleted')

            for coinid, withdrawals in withdrawal_requests.items():
                if coinid in ('BTCTEST', 'LTCTEST', 'QTUMTEST') and withdrawals:
                    connection = self.connections[coinid]
                    addresses_with_amount = {
                        withdrawal['address']: withdrawal['amount'] / decimals_k for withdrawal in withdrawals
                    }
                    try:
                        txid = connection.sendmany('', addresses_with_amount)

                        for withdrawal in withdrawals:
                            withdrawal['txid'] = txid
                            withdrawal['execution_time'] = datetime.datetime.utcnow()
                            await self.db.executed_withdraws.insert_one(withdrawal)
                            await self.db.withdraw_requests.delete_one({'_id': withdrawal['_id']})
                            print('executed')
                    except Exception as e:
                        pprint(WithdrawValidator.error_500(str(e)))
                        pprint(addresses_with_amount)

                else:
                    for withdrawal in withdrawals:
                        if coinid in ('ETH', 'ETHRINKEBY', 'ETHROPSTEN'):
                            connection = self.connections[coinid]
                            address = Web3.toChecksumAddress(withdrawal['address'])

                            try:
                                txid = connection.eth.sendTransaction({
                                    'to': address,
                                    'from': hot_wallets[coinid],
                                    'value': Web3.toWei(withdrawal['amount'] / decimals_k, 'ether')
                                })
                                txid = encode_hex(txid)[0].decode()
                                withdrawal['txid'] = txid
                                withdrawal['execution_time'] = datetime.datetime.utcnow()
                                await self.db.executed_withdraws.insert_one(withdrawal)
                                await self.db.withdraw_requests.delete_one({'_id': withdrawal['_id']})
                                print('executed')

                            except Exception as e:
                                pprint(WithdrawValidator.error_500(str(e)))
                                pprint(withdrawal)

                        else:
                            token = await self.db.available_tokens.find_one({'_id': coinid})
                            if token is None:
                                pprint(WithdrawValidator.error_500('Unsupported coinid'))

                            elif token['blockchain'] in ('QTUM', 'QTUMTEST'):
                                connection = self.connections[coinid]
                                address = Bip32Addresses.address_to_hex(withdrawal['address'])
                                handler = Qrc20.from_connection(
                                    connection,
                                    token['contract_address'],
                                    erc20_abi
                                )
                                handler.set_send_params({
                                    'gasLimit': transfer_settings[token['blockchain']]['gasLimit'],
                                    'gasPrice': transfer_settings[token['blockchain']]['gasPrice'],
                                    'sender': hot_wallets[coinid]
                                })
                                try:
                                    txid = handler.transfer(address, withdrawal['amount'])['txid']
                                    withdrawal['txid'] = txid
                                    withdrawal['execution_time'] = datetime.datetime.utcnow()
                                    await self.db.executed_withdraws.insert_one(withdrawal)
                                    await self.db.withdraw_requests.delete_one({'_id': withdrawal['_id']})
                                    print('executed')

                                except Exception as e:
                                    pprint(WithdrawValidator.error_500(str(e)))
                                    pprint(withdrawal)

                            elif token['blockchain'] in ('ETHRINKEBY', 'ETH'):
                                connection = self.connections[coinid]
                                address = Web3.toChecksumAddress(withdrawal['address'])
                                handler = Erc20.from_connection(
                                    connection,
                                    token['contract_address'],
                                    erc20_abi
                                )
                                handler.set_send_params({
                                    'gasLimit': transfer_settings[token['blockchain']]['gasLimit'],
                                    'gasPrice': transfer_settings[token['blockchain']]['gasPrice'],
                                    'sender': hot_wallets[coinid]})
                                try:
                                    txid = handler.transfer(address, withdrawal['amount'])['txid']
                                    withdrawal['txid'] = txid
                                    withdrawal['execution_time'] = datetime.datetime.utcnow()
                                    await self.db.executed_withdraws.insert_one(withdrawal)
                                    await self.db.withdraw_requests.delete_one({'_id': withdrawal['_id']})
                                    print('executed')

                                except Exception as e:
                                    pprint(WithdrawValidator.error_500(str(e)))
                                    pprint(withdrawal)

            document_count = await self.db.withdraw_requests.count_documents(query)
            print('document_count: ', document_count)
Ejemplo n.º 12
0
    async def create_token(self, *args, **kwargs):

        try:
            super().reload_connections()
        except Exception as e:
            return WithdrawValidator.error_500(str(e))

        token_name = kwargs.get('token_name')
        token_symbol = kwargs.get('token_symbol')
        total_supply = kwargs.get('total_supply')
        token_decimals = kwargs.get('decimals')
        blockchain = kwargs.get('blockchain')
        is_burnable = kwargs.get('is_burnable')
        is_mintable = kwargs.get('is_mintable')
        token_class_name = token_name.replace(' ', '_')

        await self.db.create_token_requests.insert_one({
            'token_name':
            token_name,
            'token_symbol':
            token_symbol,
            'total_supply':
            total_supply,
            'token_decimals':
            token_decimals,
            'blockchain':
            blockchain,
            'is_burnable':
            is_burnable,
            'is_mintable':
            is_mintable,
            'timestamp':
            datetime.datetime.utcnow()
        })

        formatted_code = erc20_code.format(token_name=token_name,
                                           token_class_name=token_class_name,
                                           token_symbol=token_symbol,
                                           token_decimals=token_decimals,
                                           total_supply=total_supply)

        try:
            contract_code = compile_source(formatted_code)['<stdin>:%s' %
                                                           token_name]['bin']
        except Exception as e:
            return WithdrawValidator.error_500(str(e))

        if blockchain in ['QTUM', 'QTUMTEST']:
            qtum_connection = self.connections[blockchain]
            contract_handler = QtumContractHandler.from_connection(
                qtum_connection, None, '{}')
            contract_handler.set_send_params({
                'gasLimit':
                deploy_settings[blockchain]['gasLimit'],
                'gasPrice':
                deploy_settings[blockchain]['gasPrice'],
                'sender':
                hot_wallets[blockchain]
            })
            try:
                result = contract_handler.deploy_contract(contract_code)
            except Exception as e:
                return WithdrawValidator.error_500(
                    "Couldn't deploy smart contract. %s" % str(e))

            return result

        elif blockchain in ['ETH', 'ETHRINKEBY', 'ETHROPSTEN']:
            connection = self.connections[blockchain]
            contract_address = make_contract_address(
                hot_wallets[blockchain],
                connection.eth.getTransactionCount(hot_wallets[blockchain]))
            custom_token_contract = connection.eth.contract(
                abi=erc20_abi, bytecode=contract_code)
            try:
                contract_data = custom_token_contract.constructor(
                ).buildTransaction(
                    transaction={
                        'from': hot_wallets[blockchain],
                        'gas': deploy_settings[blockchain]['gasLimit'],
                        'gasPrice': deploy_settings[blockchain]['gasPrice'],
                    })
            except Exception as e:
                return WithdrawValidator.error_500(
                    'Error building transaction. %s' % str(e))
            try:
                tx_hash = connection.eth.sendTransaction(contract_data)
            except Exception as e:
                return WithdrawValidator.error_500(
                    "Error sending transaction. %s" % str(e))
            if tx_hash is None:
                return WithdrawValidator.error_500(
                    "Error sending transaction. Hash is None")
            tx_hex = encode_hex(tx_hash)[0].decode()

            return {'txid': tx_hex, 'contract_address': contract_address}
        else:
            return WithdrawValidator.error_403('Unsupported blockchain')
Ejemplo n.º 13
0
    async def withdraw_custom_token(self, *args, **kwargs):
        """
        Withdraw custom token to user wallet

        Accepts:
            - address [hex string] (withdrawal address in hex form)
            - amount [int] withdrawal amount multiplied by decimals_k (10**8)
            - blockchain [string]  token's blockchain (QTUMTEST, ETH)
            - contract_address [hex string] token contract address
        Returns dictionary with following fields:
            - txid [string]
        """
        try:
            super().reload_connections()
        except Exception as e:
            return WithdrawValidator.error_500(str(e))

        address = kwargs.get("address")
        amount = kwargs.get("amount")
        blockchain = kwargs.get("blockchain")
        contract_address = kwargs.get("contract_address")

        await self.db.withdraw_custom_token_requests.insert_one({
            'address':
            address,
            'amount':
            amount,
            'blockchain':
            blockchain,
            'contract_address':
            contract_address,
            'timestamp':
            datetime.datetime.utcnow()
        })

        connection = self.connections[blockchain]

        if blockchain in ['QTUMTEST', 'QTUM']:
            address = Bip32Addresses.address_to_hex(address)
            handler = Qrc20.from_connection(connection, contract_address,
                                            erc20_abi)
            handler.set_send_params({
                'gasLimit':
                transfer_settings[blockchain]['gasLimit'],
                'gasPrice':
                transfer_settings[blockchain]['gasPrice'],
                'sender':
                hot_wallets[blockchain]
            })
            try:
                txid = handler.transfer(address, amount)['txid']
            except Exception as e:
                return WithdrawValidator.error_500(str(e))

        elif blockchain in ['ETH', 'ETHRINKEBY', 'ETHROPSTEN']:
            address = Web3.toChecksumAddress(address)
            contract_address = Web3.toChecksumAddress(contract_address)
            handler = Erc20.from_connection(connection, contract_address,
                                            erc20_abi)
            handler.set_send_params({
                'gasLimit':
                transfer_settings[blockchain]['gasLimit'],
                'gasPrice':
                transfer_settings[blockchain]['gasPrice'],
                'sender':
                hot_wallets[blockchain]
            })
            try:
                txid = handler.transfer(address, amount)['txid']
            except Exception as e:
                return WithdrawValidator.error_500(str(e))
        else:
            return WithdrawValidator.error_403('Unsupported blockchain')

        return {'txid': txid}
Ejemplo n.º 14
0
    async def withdraw(self, *args, **kwargs):
        """
        Withdraw funds to user wallet

        Accepts:
            - coinid [string] (blockchain id (example: BTCTEST, LTCTEST))
            - address [string] withdrawal address (in hex for tokens)
            - amount [int]     withdrawal amount multiplied by decimals_k (10**8)
        Returns dictionary with following fields:
            - txid [string]
        """
        try:
            super().reload_connections()
        except Exception as e:
            return WithdrawValidator.error_500(str(e))

        coinid = kwargs.get("coinid")
        address = kwargs.get("address")
        amount = int(kwargs.get("amount"))
        txid = None
        connection = self.connections[coinid]

        if coinid in ['BTCTEST', 'LTCTEST', 'QTUMTEST', 'BTC', 'LTC', 'QTUM']:
            try:
                txid = connection.sendtoaddress(address,
                                                str(amount / decimals_k))
            except Exception as e:
                return WithdrawValidator.error_400(str(e))
        elif coinid in ['ETH', 'ETHRINKEBY', 'ETHROPSTEN']:
            address = Web3.toChecksumAddress(address)
            try:
                txid = connection.eth.sendTransaction({
                    'to':
                    address,
                    'from':
                    hot_wallets[coinid],
                    'value':
                    Web3.toWei(amount / decimals_k, 'ether')
                })
                txid = encode_hex(txid)[0].decode()
            except Exception as e:
                return WithdrawValidator.error_500(str(e))
        else:
            token = await self.db.available_tokens.find_one({'_id': coinid})
            if token is None:
                return WithdrawValidator.error_500('Unsupported coinid')

            elif token['blockchain'] in ('QTUM', 'QTUMTEST'):
                connection = self.connections[coinid]
                address = Bip32Addresses.address_to_hex(address)
                handler = Qrc20.from_connection(connection,
                                                token['contract_address'],
                                                erc20_abi)
                handler.set_send_params({
                    'gasLimit':
                    transfer_settings[token['blockchain']]['gasLimit'],
                    'gasPrice':
                    transfer_settings[token['blockchain']]['gasPrice'],
                    'sender':
                    hot_wallets[coinid]
                })
                print(hot_wallets[coinid])
                try:
                    txid = handler.transfer(address, amount)['txid']
                except Exception as e:
                    return WithdrawValidator.error_500(str(e))

            elif token['blockchain'] in ('ETHRINKEBY', 'ETH'):
                connection = self.connections[coinid]
                address = Web3.toChecksumAddress(address)
                handler = Erc20.from_connection(connection,
                                                token['contract_address'],
                                                erc20_abi)
                handler.set_send_params({
                    'gasLimit':
                    transfer_settings[token['blockchain']]['gasLimit'],
                    'gasPrice':
                    transfer_settings[token['blockchain']]['gasPrice'],
                    'sender':
                    hot_wallets[coinid]
                })
                try:
                    txid = handler.transfer(address, amount)['txid']
                except Exception as e:
                    return WithdrawValidator.error_500(str(e))

        await self.db.executed_withdraws.insert_one({
            'coinid':
            coinid,
            'address':
            address,
            'amount':
            amount,
            'txid':
            txid,
            'timestamp':
            datetime.datetime.utcnow(),
            'execution_time':
            datetime.datetime.utcnow()
        })
        return {'txid': txid}