diff --git a/requirements.txt b/requirements.txt index 5c779c374..5e5c0f05e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -32,5 +32,5 @@ psycogreen==1.0.2 psycopg2==2.9.6 redis==4.5.5 requests==2.31.0 -safe-eth-py[django]==5.5.0 +safe-eth-py[django]==5.6.0 web3==6.5.0 diff --git a/safe_transaction_service/__init__.py b/safe_transaction_service/__init__.py index 4b55ef95d..cfb96d473 100644 --- a/safe_transaction_service/__init__.py +++ b/safe_transaction_service/__init__.py @@ -1,4 +1,4 @@ -__version__ = "4.21.3" +__version__ = "4.22.0" __version_info__ = tuple( int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".") diff --git a/safe_transaction_service/history/helpers.py b/safe_transaction_service/history/helpers.py index 770f8b1ae..a17097227 100644 --- a/safe_transaction_service/history/helpers.py +++ b/safe_transaction_service/history/helpers.py @@ -62,7 +62,7 @@ def is_valid_unique_transfer_id(unique_transfer_id: str) -> bool: :return: ``True`` for a valid ``unique_transfer_id``, ``False`` otherwise """ token_transfer_id_pattern = r"^(e)([a-fA-F0-9]{64})(\d+)" - internal_transfer_id_pattern = r"^(i)([a-fA-F0-9]{64})(\d+)(,\d+)*" + internal_transfer_id_pattern = r"^(i)([a-fA-F0-9]{64})(\d*)(,\d+)*" return bool( re.fullmatch(token_transfer_id_pattern, unique_transfer_id) diff --git a/safe_transaction_service/history/tests/test_views.py b/safe_transaction_service/history/tests/test_views.py index 45c4c8f2f..b245ac7d2 100644 --- a/safe_transaction_service/history/tests/test_views.py +++ b/safe_transaction_service/history/tests/test_views.py @@ -2559,16 +2559,6 @@ def test_get_transfer_view(self): ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - # test internal_tx transfer_id empty trace_address - transfer_id = ( - "ief060441f0101ab83d62066b962f97e3a582686e0720157407c965c5946c2f7a" - ) - response = self.client.get( - reverse("v1:history:transfer", args=(transfer_id,)), - format="json", - ) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - # test invalid erc20 transfer_id empty log_index transfer_id = ( "e27e15ba8dea473d98c80a6b45d372c0f3c6f8c184177044c935c37eb419d7216" @@ -2633,6 +2623,39 @@ def test_get_transfer_view(self): } self.assertEqual(response.json(), expected_result) + # test internal_tx transfer_id empty trace_address + ethereum_tx_hash = ( + "0x12bafc5ee165d825201a24418e00bef6039bb06f6d09420ab1c5f7b4098c0809" + ) + ethereum_tx = EthereumTxFactory(tx_hash=ethereum_tx_hash) + internal_tx_empty_trace_address = InternalTxFactory( + ethereum_tx=ethereum_tx, to=safe_address, trace_address="" + ) + transfer_id_empty_trace_address = ( + "i12bafc5ee165d825201a24418e00bef6039bb06f6d09420ab1c5f7b4098c0809" + ) + response = self.client.get( + reverse("v1:history:transfer", args=(transfer_id_empty_trace_address,)), + format="json", + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + expected_result = { + "type": TransferType.ETHER_TRANSFER.name, + "executionDate": internal_tx_empty_trace_address.ethereum_tx.block.timestamp.isoformat().replace( + "+00:00", "Z" + ), + "blockNumber": internal_tx_empty_trace_address.ethereum_tx.block_id, + "transferId": transfer_id_empty_trace_address, + "transactionHash": internal_tx_empty_trace_address.ethereum_tx_id, + "to": safe_address, + "value": str(internal_tx_empty_trace_address.value), + "tokenId": None, + "tokenAddress": None, + "from": internal_tx_empty_trace_address._from, + "tokenInfo": None, + } + self.assertEqual(response.json(), expected_result) + # Test filtering ERC20 transfer by transfer_id erc20_tx_hash = ( "0x406754000f0432d3b5e6d8341597ec3c5338239f8d311de9061fbc959f443d59"