Ejemplo n.º 1
0
    async def transfer(self, amount: float, address, **kwargs) -> Future:
        """
        Transfer Monero to another wallet.
        If the amount exceeds the available balance, an `InsufficientFunds` exception is raised.

        :param kwargs:
            payment_id: str,
            priority: transaction priority, implies fee.
                The priority can be a number from 1 to 4 (unimportant, normal, elevated, priority).
                Default is 1.
            unlock_time: int, default is 0
        :param amount: the transfer amount
        :param address: the receiver address
        :return: Future of transfer hash, None or InsufficientFundsException
        """
        if self._wallet_connection_alive():
            balance = await self.get_balance()

            if balance['available'] < amount:
                return fail(InsufficientFunds('Insufficient funds found in Monero wallet'))

            self._logger.info('Transfer %f to %s', amount, address)
            transaction = await self.wallet.transfer(address, Decimal(str(amount)), **kwargs, relay=False)
            return succeed(transaction.hash)
        return succeed(None)
Ejemplo n.º 2
0
    async def transfer(self, value: int, address: str):
        """
        Transfer specified value to a specified address and store the bundle and the transactions
        :param value: amount of IOTA tokens to be sent
        :param address: receiving address of the IOTA tokens
        """
        value = int(value)
        if not self.created:
            return RuntimeError('The wallet must be created transfers can be made')

        if value < 0:
            return RuntimeError('Negative value transfers are not allowed.')

        # the pyota library has no support for address validation
        if not re.compile('^[A-Z9]{81}|[A-Z9]{90}$').match(address):
            return RuntimeError('Invalid IOTA address')

        # check wallet balance
        balance = await self.get_balance()
        if balance['available'] < value:
            return InsufficientFunds(f'Balance {balance["available"]} of the wallet is less than {value}.')

        # generate and send a transaction
        self._logger.info(f"Creating {self.network} payment with amount {value} to address {address}")
        transaction = ProposedTransaction(
            address=Address(address),
            value=value
        )
        bundle = await self.provider.submit_transaction(transaction)

        # return bundle hash ID instead of transaction ID
        return bundle.hash.__str__()
Ejemplo n.º 3
0
 def on_balance(balance):
     if balance['available'] >= int(amount):
         self._logger.info(
             "Creating Bitcoin payment with amount %f to address %s",
             amount, address)
         tx = self.wallet.send_to(address, int(amount))
         return str(tx.hash)
     else:
         return fail(InsufficientFunds("Insufficient funds"))
Ejemplo n.º 4
0
    async def transfer(self, amount, address):
        balance = await self.get_balance()

        if balance['available'] >= int(amount):
            self._logger.info("Creating %s payment with amount %d to address %s",
                              self.network, int(amount), address)
            tx = self.wallet.send_to(address, int(amount))
            return str(tx.hash)
        raise InsufficientFunds("Insufficient funds")
Ejemplo n.º 5
0
    async def transfer(self, amount, address) -> str:
        """
        Transfer Ethereum to another wallet.
        If the amount exceeds the available balance, an `InsufficientFunds` exception is raised.

        :param amount: the transfer amount
        :param address: the receiver address
        :return: transfer hash
        """
        balance = await self.get_balance()

        if balance['available'] < int(amount):
            raise InsufficientFunds('Insufficient funds')

        self._logger.info(
            'Creating Ethereum payment with amount %f to address %s', amount,
            address)

        transaction = {
            'from':
            self.get_address().result(),
            'to':
            Web3.toChecksumAddress(
                address),  # addresses should be checksumaddresses to work
            'value':
            int(amount),
            'nonce':
            self.database.get_transaction_count(self.get_address().result()),
            'gasPrice':
            self.provider.get_gas_price(),
            'chainId':
            self.chain_id
        }

        transaction['gas'] = self.provider.estimate_gas()
        # submit to blockchain
        signed = self.account.sign_transaction(transaction)
        self.provider.submit_transaction(signed['rawTransaction'].hex())

        # add transaction to database
        self.database.add(
            Transaction(from_=transaction['from'],
                        to=transaction['to'],
                        value=transaction['value'],
                        gas=transaction['gas'],
                        nonce=transaction['nonce'],
                        gas_price=transaction['gasPrice'],
                        hash=signed['hash'].hex(),
                        is_pending=True,
                        token_identifier=self.get_identifier()))
        return signed['hash'].hex()
Ejemplo n.º 6
0
        def on_balance(balance):
            if balance['available'] < quantity:
                raise InsufficientFunds()

            self.balance -= quantity

            self.transaction_history.append({
                'id': str(quantity),
                'outgoing': True,
                'from': self.address,
                'to': '',
                'amount': quantity,
                'fee_amount': 0.0,
                'currency': self.get_identifier(),
                'timestamp': '',
                'description': ''
            })

            return succeed(str(quantity))
Ejemplo n.º 7
0
    async def transfer(self, quantity, candidate):
        self._logger.info("Transferring %s %s to %s from dummy wallet",
                          quantity, self.get_identifier(), candidate)

        balance = await self.get_balance()
        if balance['available'] < quantity:
            raise InsufficientFunds()
        self.balance -= quantity
        self.transaction_history.append({
            'id': str(quantity),
            'outgoing': True,
            'from': self.address,
            'to': '',
            'amount': quantity,
            'fee_amount': 0.0,
            'currency': self.get_identifier(),
            'timestamp': '',
            'description': ''
        })
        return str(quantity)
Ejemplo n.º 8
0
    async def transfer_multiple(self, transfers: list, **kwargs) -> list:
        """
        Submit multiple transfers simultaneously to the Monero blockchain.
        May reduce fee.

        :param transfers: list of tuples of format (address, Decimal(amount))
        :param kwargs: payment_id, priority, unlock_time (see `transfer` method above)
        :return: list of resulting hashes or return InsufficientFundsException
        """
        balance = await self.get_balance()

        total_amount = float(sum([transfer[1] for transfer in transfers]))

        if balance['available'] < total_amount:
            return fail(InsufficientFunds('Insufficient funds found in Monero wallet for all transfers'))

        if self._wallet_connection_alive():
            results = await self.wallet.transfer_multiple(transfers, **kwargs)
            hashes = [result[0].hash for result in results]
            return succeed(hashes)
        return fail(WalletConnectionError('No connection to wallet for making transfers'))
Ejemplo n.º 9
0
    async def transfer(self, amount, address):
        balance = await self.get_balance()
        if balance['available'] < int(amount):
            raise InsufficientFunds('Insufficient funds')

        self._logger.info(
            'Creating Ethereum Token (%s) payment with amount %f to address %s',
            self.get_name(), amount, address)
        tx = self.contract.functions.transfer(
            Web3.toChecksumAddress(address), amount).buildTransaction({
                'gas':
                self.provider.estimate_gas(),
                'gasPrice':
                self.provider.get_gas_price(),
                'chainId':
                self.chain_id
            })
        tx.update({
            'nonce':
            self.database.get_transaction_count(self.get_address().result())
        })
        s_tx = self.account.sign_transaction(tx)

        # add transaction to database
        self.database.add(
            Transaction(from_=self.get_address().result(),
                        to=address,
                        value=amount,
                        gas=tx['gas'],
                        nonce=tx['nonce'],
                        gas_price=tx['gasPrice'],
                        hash=s_tx['hash'].hex(),
                        is_pending=True,
                        token_identifier=self.get_identifier()))

        return self.provider.submit_transaction(s_tx['rawTransaction'].hex())
Ejemplo n.º 10
0
 async def transfer(self, quantity, peer):
     balance = await self.get_balance()
     if self.check_negative_balance and balance['available'] < quantity:
         raise InsufficientFunds()
     return await self.create_transfer_block(peer, quantity)
Ejemplo n.º 11
0
        def on_balance(balance):
            if self.check_negative_balance and balance['available'] < quantity:
                return fail(InsufficientFunds())

            return self.create_transfer_block(peer, quantity)
Ejemplo n.º 12
0
    async def transfer(self,
                       amount,
                       address,
                       memo_id: int = None,
                       asset='XLM'):
        """
        Transfer stellar lumens to the specified address.
        In the future sending other assets might also be possible.

        Normally a payment operation is used, but if the account is not created
        then an account create operation will be done.

        if you wish to send all of your balance then a merge account operation is used.

        :param amount: amount of lumens to send, in stroop (0.0000001 XLM)
        :param address: address to sent lumens to. Should be a normal encoded public key.
        :param memo_id: memo id for sending lumens to exchanges.
        :param asset: asset type. only XLM is currently supported.
        :return: Transaction hash
        """
        balance = await self.get_balance()
        fee = self.provider.get_base_fee()  # fee for one operation
        if balance['available'] - 1 < int(
                amount
        ) + fee:  # stellar accounts need to hold a minimum of 1 XLM
            raise InsufficientFunds('Insufficient funds')

        self._logger.info(
            'Creating Stellar Lumens payment with amount %s to address %s',
            amount, address)
        network = Network.PUBLIC_NETWORK_PASSPHRASE if not self.testnet else Network.TESTNET_NETWORK_PASSPHRASE
        tx_builder = TransactionBuilder(
            source_account=self.account,
            base_fee=self.provider.get_base_fee(),
            network_passphrase=network,
        )
        amount_in_xlm = Decimal(
            amount / self.STROOP_IN_LUMEN
        )  # amount in xlm instead of stroop (0.0000001 xlm)
        if self.provider.check_account_created(address):
            tx_builder.append_payment_op(address, amount_in_xlm, asset)
        else:
            tx_builder.append_create_account_op(address, amount_in_xlm)
        if memo_id:
            tx_builder.add_id_memo(memo_id)
        tx = tx_builder.build()
        tx.sign(self.keypair)
        xdr_tx_envelope = tx.to_xdr()

        tx_hash = self.provider.submit_transaction(xdr_tx_envelope)
        tx_db = Transaction(
            hash=tx_hash,
            source_account=self.get_address(),
            operation_count=len(tx.transaction.operations),
            sequence_number=tx.transaction.sequence,
            succeeded=False,
            transaction_envelope=xdr_tx_envelope,
            is_pending=True,
            fee=tx.transaction.fee,
        )
        self.database.insert_transaction(tx_db)
        return tx_hash