Example #1
0
    def configurarBilleteraPrimeraVez(self, listaUsuarios, umbralLista):
        server = Server(horizon_url=self.Horizon_url)
        root_keypair = Keypair.from_secret(self.sLlave)
        root_account = server.load_account(account_id=root_keypair.public_key)
        base_fee = server.fetch_base_fee()

        transaction = TransactionBuilder(
            base_fee=base_fee,
            network_passphrase=self.networkTrabajar,
            source_account=root_account)\
            .append_set_options_op(master_weight=1,
                                low_threshold=int(umbralLista[1])-1,
                                med_threshold=int(umbralLista[1]),
                                high_threshold=int(umbralLista[0]))\
            .set_timeout(30)
        for i in listaUsuarios:
            transaction.append_ed25519_public_key_signer(account_id=i[3],
                                                         weight=1)

        transaction = transaction.build()
        transaction.sign(root_keypair)
        try:
            response = server.submit_transaction(transaction)
            return [True, response]
        except exceptions.BadRequestError as d:
            return [False, d]
        except exceptions.NotFoundError as n:
            return [False, n]
    def _merge_account(self, address):
        server = self._get_horizon_server()
        account = server.load_account(address)
        # Increment the sequence number in case the unlock transaction was not processed before the load_account call
        # account.increment_sequence_number()
        balances = self._get_free_balances(address)
        base_fee = server.fetch_base_fee()
        transaction_builder = TransactionBuilder(
            source_account=account,
            network_passphrase=_NETWORK_PASSPHRASES[str(self.network)],
            base_fee=base_fee)
        for balance in balances.balances:
            if balance.is_native():
                continue
            # Step 1: Transfer custom assets
            transaction_builder.append_payment_op(
                destination=self.address,
                amount=balance.balance,
                asset_code=balance.asset_code,
                asset_issuer=balance.asset_issuer,
            )
            # Step 2: Delete trustlines
            transaction_builder.append_change_trust_op(
                asset_issuer=balance.asset_issuer,
                asset_code=balance.asset_code,
                limit="0")
        # Step 3: Merge account
        transaction_builder.append_account_merge_op(self.address)

        transaction_builder.set_timeout(30)
        transaction = transaction_builder.build()
        signer_kp = Keypair.from_secret(self.secret)
        transaction.sign(signer_kp)
        server.submit_transaction(transaction)
Example #3
0
 def create_transaction(self, sourceAccountPublicKey, operationList):
     sourceAccount = self.load_account(sourceAccountPublicKey)
     transactionBuilder = TransactionBuilder(
         source_account=sourceAccount,
         network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE)
     #for operation in operationList:
     #    transactionBuilder.append_operation(operation)
     txnEnv = transactionBuilder.build()
     return txnEnv.to_xdr()
    def modify_signing_requirements(self,
                                    public_keys_signers,
                                    signature_count,
                                    low_treshold=0,
                                    high_treshold=2,
                                    master_weight=2):
        """modify_signing_requirements sets the signing requirements for a multisig account. It also adds
        the public keys of the signer to this account.
        :param public_keys_signers: list of public keys of signers.
        :type public_keys_signers: list
        :param signature_count: amount of signatures required to transfer funds.
        :type signature_count: int
        :param low_treshold: weight required for low security operations (transaction processing, allow trust, bump sequence)
        :type low_treshold: int
        :param high_treshold: weight required for high security operations (set options, account merge)
        :type high_treshold: int
        :param master_weight: A number from 0-255 (inclusive) representing the weight of the master key. If the weight of the master key is updated to 0, it is effectively disabled.
        :type master_weight: int 
        """
        account = self.load_account()
        source_keypair = Keypair.from_secret(self.secret)

        horizon_server = self._get_horizon_server()
        base_fee = horizon_server.fetch_base_fee()
        transaction_builder = TransactionBuilder(
            account,
            network_passphrase=_NETWORK_PASSPHRASES[str(self.network)],
            base_fee=base_fee)
        # set the signing options
        transaction_builder.append_set_options_op(
            low_threshold=low_treshold,
            med_threshold=signature_count,
            high_threshold=high_treshold,
            master_weight=master_weight)

        # For every public key given, add it as a signer to this account
        for public_key_signer in public_keys_signers:
            transaction_builder.append_ed25519_public_key_signer(
                public_key_signer, 1)

        transaction_builder.set_timeout(30)
        tx = transaction_builder.build()
        tx.sign(source_keypair)

        try:
            response = horizon_server.submit_transaction(tx)
            self._log_info(response)
            self._log_info(
                "Set the signers of {address} to require {signature_count} signers"
                .format(address=self.address, signature_count=signature_count))
        except BadRequestError:
            self._log_info(
                "Transaction need additional signatures in order to send")
            return tx.to_xdr()
Example #5
0
def claim_claimable_balance_operation(claimant_private_key, balance_ids):

    claimant_keypair = Keypair.from_secret(claimant_private_key)
    claimant_account = server.load_account(claimant_keypair.public_key)

    claim_claimable_balance_txn = TransactionBuilder(
        claimant_account, Network.TESTNET_NETWORK_PASSPHRASE)

    for balance_id in balance_ids:
        claim_claimable_balance_txn = (
            claim_claimable_balance_txn.append_claim_claimable_balance_op(
                balance_id, claimant_keypair.public_key))

    claim_claimable_balance_te = claim_claimable_balance_txn.build()
    claim_claimable_balance_te.sign(claimant_keypair)

    return claim_claimable_balance_te
    def modify_signing_requirements(self, public_keys_signers, signature_count, low_treshold=1, high_treshold=2):
        """modify_signing_requirements sets to amount of signatures required for the creation of multisig account. It also adds
        the public keys of the signer to this account
        :param public_keys_signers: list of public keys of signers.
        :type public_keys_signers: list
        :param signature_count: amount of signatures requires to transfer funds.
        :type signature_count: str
        :param low_treshold: amount of signatures required for low security operations (transaction processing, allow trust, bump sequence)
        :type low_treshold: str
        :param high_treshold: amount of signatures required for high security operations (set options, account merge)
        :type: str
        """
        if len(public_keys_signers) != signature_count - 1:
            raise Exception(
                "Number of public_keys must be 1 less than the signature count in order to set the signature count"
            )

        account = self.load_account()
        source_keypair = Keypair.from_secret(self.secret)

        transaction_builder = TransactionBuilder(account)
        # set the signing options
        transaction_builder.append_set_options_op(
            low_threshold=low_treshold, med_threshold=signature_count, high_threshold=high_treshold
        )

        # For every public key given, add it as a signer to this account
        for public_key_signer in public_keys_signers:
            transaction_builder.append_ed25519_public_key_signer(public_key_signer, 1)

        transaction_builder.set_timeout(30)
        tx = transaction_builder.build()
        tx.sign(source_keypair)

        horizon_server = self._get_horizon_server()
        try:
            response = horizon_server.submit_transaction(tx)
            self._log_info(response)
            self._log_info(
                "Set the signers of {address} to require {signature_count} signers".format(
                    address=self.address, signature_count=signature_count
                )
            )
        except BadRequestError:
            self._log_info("Transaction need additional signatures in order to send")
            return tx.to_xdr()
    def transfer(
        self,
        destination_address,
        amount,
        asset="XLM",
        locked_until=None,
        memo_text=None,
        memo_hash=None,
        fund_transaction=True,
        from_address=None,
    ):
        """Transfer assets to another address
        :param destination_address: address of the destination.
        :type destination_address: str
        :param amount: amount, can be a floating point number with 7 numbers after the decimal point expressed as a Decimal or a string.
        :type amount: Union[str, Decimal]
        :param asset: asset to transfer (if none is specified the default 'XLM' is used),
        if you wish to specify an asset it should be in format 'assetcode:issuer'. Where issuer is the address of the
        issuer of the asset.
        :type asset: str
        :param locked_until: optional epoch timestamp indicating until when the tokens  should be locked.
        :type locked_until: float
        :param text_memo: optional memo text to add to the transaction, a string encoded using either ASCII or UTF-8, up to 28-bytes long
        :type: Union[str, bytes]
        :param memo_hash: optional memo hash to add to the transaction, A 32 byte hash
        :type: Union[str, bytes]
        :param fund_transaction: use the threefoldfoundation transaction funding service
        :type: fund_transaction: bool
        :param from_address: Use a different address to send the tokens from, useful in multisig use cases.
        :type from_address: str
        """
        issuer = None
        self._log_info(f"Sending {amount} {asset} to {destination_address}")
        if asset != "XLM":
            assetStr = asset.split(":")
            if len(assetStr) != 2:
                raise Exception("Wrong asset format")
            asset = assetStr[0]
            issuer = assetStr[1]

        if locked_until is not None:
            return self._transfer_locked_tokens(
                destination_address,
                amount,
                asset,
                issuer,
                locked_until,
                memo_text=memo_text,
                memo_hash=memo_hash,
                fund_transaction=fund_transaction,
                from_address=from_address)

        horizon_server = self._get_horizon_server()

        base_fee = horizon_server.fetch_base_fee()
        if from_address:
            source_account = horizon_server.load_account(from_address)
        else:
            source_account = self.load_account()

        transaction_builder = TransactionBuilder(
            source_account=source_account,
            network_passphrase=_NETWORK_PASSPHRASES[str(self.network)],
            base_fee=base_fee)
        transaction_builder.append_payment_op(
            destination=destination_address,
            amount=amount,
            asset_code=asset,
            asset_issuer=issuer,
            source=source_account.account_id,
        )
        transaction_builder.set_timeout(30)
        if memo_text is not None:
            transaction_builder.add_text_memo(memo_text)
        if memo_hash is not None:
            transaction_builder.add_hash_memo(memo_hash)

        transaction = transaction_builder.build()
        transaction = transaction.to_xdr()

        if asset in _NETWORK_KNOWN_TRUSTS[str(self.network)]:
            if fund_transaction:
                transaction = self._fund_transaction(transaction=transaction)
                transaction = transaction["transaction_xdr"]

        transaction = TransactionEnvelope.from_xdr(
            transaction, _NETWORK_PASSPHRASES[str(self.network)])

        my_keypair = Keypair.from_secret(self.secret)
        transaction.sign(my_keypair)

        try:
            response = horizon_server.submit_transaction(transaction)
            tx_hash = response["hash"]
            self._log_info("Transaction hash: {}".format(tx_hash))
            return tx_hash
        except BadRequestError as e:
            result_codes = e.extras.get("result_codes")
            operations = result_codes.get("operations")
            if operations is not None:
                for op in operations:
                    if op == "op_underfunded":
                        raise e
                    # if op_bad_auth is returned then we assume the transaction needs more signatures
                    # so we return the transaction as xdr
                    elif op == "op_bad_auth":
                        self._log_info(
                            "Transaction might need additional signatures in order to send"
                        )
                        return transaction.to_xdr()
            raise e
Example #8
0
    def transfer(self,
                 destination_address,
                 amount,
                 asset="XLM",
                 locked_until=None,
                 memo_text=None,
                 memo_hash=None):
        """Transfer assets to another address
        :param destination_address: address of the destination.
        :type destination_address: str
        :param amount: amount, can be a floating point number with 7 numbers after the decimal point expressed as a string.
        :type amount: str
        :param asset: asset to transfer (if none is specified the default 'XLM' is used),
        if you wish to specify an asset it should be in format 'assetcode:issuer'. Where issuer is the address of the
        issuer of the asset.
        :type asset: str
        :param locked_until: optional epoch timestamp indicating until when the tokens  should be locked.
        :type locked_until: float
        :param text_memo: optional memo text to add to the transaction, a string encoded using either ASCII or UTF-8, up to 28-bytes long
        :type: Union[str, bytes]
        :param memo_hash: optional memo hash to add to the transaction, A 32 byte hash
        :type: Union[str, bytes]
        """
        issuer = None
        self._log_info("Sending {} {} to {}".format(amount, asset,
                                                    destination_address))
        if asset != "XLM":
            assetStr = asset.split(":")
            if len(assetStr) != 2:
                raise Exception("Wrong asset format")
            asset = assetStr[0]
            issuer = assetStr[1]

        if locked_until is not None:
            return self._transfer_locked_tokens(destination_address, amount,
                                                asset, issuer, locked_until)

        server = self._get_horizon_server()
        source_keypair = Keypair.from_secret(self.secret)
        source_public_key = source_keypair.public_key
        source_account = server.load_account(source_public_key)

        base_fee = server.fetch_base_fee()

        transaction_builder = TransactionBuilder(
            source_account=source_account,
            network_passphrase=_NETWORK_PASSPHRASES[str(self.network)],
            base_fee=base_fee)
        transaction_builder.append_payment_op(destination=destination_address,
                                              amount=str(amount),
                                              asset_code=asset,
                                              asset_issuer=issuer)
        transaction_builder.set_timeout(30)
        if memo_text is not None:
            transaction_builder.add_text_memo(memo_text)
        if memo_hash is not None:
            transaction_builder.add_hash_memo(memo_hash)

        transaction = transaction_builder.build()

        transaction.sign(source_keypair)

        try:
            response = server.submit_transaction(transaction)
            tx_hash = response["hash"]
            self._log_info("Transaction hash: {}".format(tx_hash))
            return tx_hash
        except BadRequestError as e:
            self._log_debug(e)
            raise e
Example #9
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