def do_transfer(ctx: Context, identifier: str, address: Address, amount: int, tx_fee: int) -> Optional[str]: """ Perform wealth transfer to another account. :param ctx: click context :param identifier: str, ledger id to perform transfer operation :param address: address of the recepient :param amount: int, amount of wealth to transfer :param tx_fee: int, fee for transaction :return: str, transaction digest or None if failed. """ click.echo("Starting transfer ...") wallet = get_wallet_from_context(ctx) source_address = wallet.addresses[identifier] _override_ledger_configurations(ctx.agent_config) balance = int(try_get_balance(ctx.agent_config, wallet, identifier)) total_payable = amount + tx_fee if total_payable > balance: raise click.ClickException( f"Balance is not enough! Available={balance}, required={total_payable}!" ) tx_nonce = LedgerApis.generate_tx_nonce(identifier, source_address, address) transaction = LedgerApis.get_transfer_transaction(identifier, source_address, address, amount, tx_fee, tx_nonce) tx_signed = wallet.sign_transaction(identifier, transaction) return LedgerApis.send_signed_transaction(identifier, tx_signed)
def test_generate_tx_nonce_negative(self, *mocks): """Test generate_tx_nonce init negative result.""" ledger_apis = LedgerApis( {ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI, ) result = ledger_apis.generate_tx_nonce(FETCHAI, "seller", "client") assert result == ""
def test_validate_ethereum_transaction(self): seller = EthereumCrypto() client = EthereumCrypto() ledger_apis = LedgerApis( {ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI, ) tx_nonce = ledger_apis.generate_tx_nonce( ETHEREUM, seller.address, client.address ) tx_digest = "0xbefa7768c313ff49bf274eefed001042a0ff9e3cfbe75ff1a9c2baf18001cec4" result = AttributeDict( { "blockHash": HexBytes( "0x0bfc237d2a17f719a3300a4822779391ec6e3a74832fe1b05b8c477902b0b59e" ), "blockNumber": 7161932, "from": client.address, "gas": 200000, "gasPrice": 50000000000, "hash": HexBytes( "0xbefa7768c313ff49bf274eefed001042a0ff9e3cfbe75ff1a9c2baf18001cec4" ), "input": tx_nonce, "nonce": 4, "r": HexBytes( "0xb54ce8b9fa1d1be7be316c068af59a125d511e8dd51202b1a7e3002dee432b52" ), "s": HexBytes( "0x4f44702b3812d3b4e4b76da0fd5b554b3ae76d1717db5b6b5faebd7b85ae0303" ), "to": seller.address, "transactionIndex": 0, "v": 42, "value": 2, } ) with mock.patch.object( ledger_apis.apis.get(ETHEREUM).api.eth, "getTransaction", return_value=result, ): assert ledger_apis.is_tx_valid( identifier=ETHEREUM, tx_digest=tx_digest, seller=seller.address, client=client.address, tx_nonce=tx_nonce, amount=2, )
def test_generate_tx_nonce_fetchai(self): """Test the generated tx_nonce.""" seller_crypto = FetchAICrypto() client_crypto = FetchAICrypto() ledger_apis = LedgerApis( {ETHEREUM: DEFAULT_ETHEREUM_CONFIG, FETCHAI: DEFAULT_FETCHAI_CONFIG}, FETCHAI, ) seller_address = seller_crypto.address client_address = client_crypto.address tx_nonce = ledger_apis.generate_tx_nonce( FETCHAI, seller_address, client_address ) logger.info(tx_nonce) assert tx_nonce != ""
def run(): # Create a private keys create_private_key(FetchAICrypto.identifier, private_key_file=FETCHAI_PRIVATE_KEY_FILE_1) create_private_key(FetchAICrypto.identifier, private_key_file=FETCHAI_PRIVATE_KEY_FILE_2) # Set up the wallets wallet_1 = Wallet({FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE_1}) wallet_2 = Wallet({FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE_2}) # Set up the LedgerApis ledger_apis = LedgerApis( {FetchAICrypto.identifier: { "network": "testnet" }}, FetchAICrypto.identifier) # Generate some wealth try_generate_testnet_wealth(FetchAICrypto.identifier, wallet_1.addresses[FetchAICrypto.identifier]) logger.info("Sending amount to {}".format( wallet_2.addresses.get(FetchAICrypto.identifier))) # Create the transaction and send it to the ledger. tx_nonce = ledger_apis.generate_tx_nonce( FetchAICrypto.identifier, wallet_2.addresses.get(FetchAICrypto.identifier), wallet_1.addresses.get(FetchAICrypto.identifier), ) transaction = ledger_apis.get_transfer_transaction( identifier=FetchAICrypto.identifier, sender_address=wallet_1.addresses.get(FetchAICrypto.identifier), destination_address=wallet_2.addresses.get(FetchAICrypto.identifier), amount=1, tx_fee=1, tx_nonce=tx_nonce, ) signed_transaction = wallet_1.sign_transaction(FetchAICrypto.identifier, transaction) transaction_digest = ledger_apis.send_signed_transaction( FetchAICrypto.identifier, signed_transaction) logger.info("Transaction complete.") logger.info("The transaction digest is {}".format(transaction_digest))
def run(): # Create a private keys create_private_key( CosmosCrypto.identifier, private_key_file=COSMOS_PRIVATE_KEY_FILE_1 ) create_private_key( CosmosCrypto.identifier, private_key_file=COSMOS_PRIVATE_KEY_FILE_2 ) # Set up the wallets wallet_1 = Wallet({CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE_1}) wallet_2 = Wallet({CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE_2}) # Generate some wealth try_generate_testnet_wealth( CosmosCrypto.identifier, wallet_1.addresses[CosmosCrypto.identifier] ) logger.info( "Sending amount to {}".format(wallet_2.addresses.get(CosmosCrypto.identifier)) ) # Create the transaction and send it to the ledger. tx_nonce = LedgerApis.generate_tx_nonce( CosmosCrypto.identifier, wallet_2.addresses.get(CosmosCrypto.identifier), wallet_1.addresses.get(CosmosCrypto.identifier), ) transaction = LedgerApis.get_transfer_transaction( identifier=CosmosCrypto.identifier, sender_address=wallet_1.addresses.get(CosmosCrypto.identifier), destination_address=wallet_2.addresses.get(CosmosCrypto.identifier), amount=1, tx_fee=1, tx_nonce=tx_nonce, ) signed_transaction = wallet_1.sign_transaction(CosmosCrypto.identifier, transaction) transaction_digest = LedgerApis.send_signed_transaction( CosmosCrypto.identifier, signed_transaction ) logger.info("Transaction complete.") logger.info("The transaction digest is {}".format(transaction_digest))
def test_generate_proposal_terms_and_data(self): """Test the generate_proposal_terms_and_data method of the GenericStrategy class.""" # setup seller = self.skill.skill_context.agent_address total_price = len(self.data_for_sale) * self.unit_price sale_quantity = len(self.data_for_sale) tx_nonce = LedgerApis.generate_tx_nonce( identifier=self.ledger_id, seller=seller, client=COUNTERPARTY_ADDRESS, ) query = Query([ Constraint("seller_service", ConstraintType("==", "some_service")) ]) # expected returned values expected_proposal = Description({ "ledger_id": self.ledger_id, "price": total_price, "currency_id": self.currency_id, "service_id": self.service_id, "quantity": sale_quantity, "tx_nonce": tx_nonce, }) expected_terms = Terms( ledger_id=self.ledger_id, sender_address=seller, counterparty_address=COUNTERPARTY_ADDRESS, amount_by_currency_id={self.currency_id: total_price}, quantities_by_good_id={self.service_id: -sale_quantity}, is_sender_payable_tx_fee=False, nonce=tx_nonce, fee_by_currency_id={self.currency_id: 0}, ) # operation proposal, terms, data = self.strategy.generate_proposal_terms_and_data( query, COUNTERPARTY_ADDRESS) # after assert proposal == expected_proposal assert terms == expected_terms assert data == self.data_for_sale
def generate_proposal_terms_and_data( # pylint: disable=unused-argument self, query: Query, counterparty_address: Address ) -> Tuple[Description, Terms, Dict[str, str]]: """ Generate a proposal matching the query. :param query: the query :param counterparty_address: the counterparty of the proposal. :return: a tuple of proposal, terms and the weather data """ data_for_sale = self.data_for_sale sale_quantity = len(data_for_sale) seller_address = self.context.agent_addresses[self.ledger_id] total_price = sale_quantity * self._unit_price if self.is_ledger_tx: tx_nonce = LedgerApis.generate_tx_nonce( identifier=self.ledger_id, seller=seller_address, client=counterparty_address, ) else: tx_nonce = uuid.uuid4().hex # pragma: nocover proposal = Description({ "ledger_id": self.ledger_id, "price": total_price, "currency_id": self._currency_id, "service_id": self._service_id, "quantity": sale_quantity, "tx_nonce": tx_nonce, }) terms = Terms( ledger_id=self.ledger_id, sender_address=seller_address, counterparty_address=counterparty_address, amount_by_currency_id={self._currency_id: total_price}, quantities_by_good_id={self._service_id: -sale_quantity}, is_sender_payable_tx_fee=False, nonce=tx_nonce, fee_by_currency_id={self._currency_id: 0}, ) return proposal, terms, data_for_sale
def test_generate_tx_nonce_positive(self): """Test generate_tx_nonce positive result.""" result = LedgerApis.generate_tx_nonce(CosmosApi.identifier, "seller", "client") assert int(result, 16)