Skip to content

Commit

Permalink
Merge branch 'main' into insert_ordered_signatures_safe_tx
Browse files Browse the repository at this point in the history
  • Loading branch information
falvaradorodriguez committed Jun 6, 2024
2 parents 314d30b + 522c74d commit a3099e6
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 14 deletions.
2 changes: 2 additions & 0 deletions gnosis/eth/clients/etherscan_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class EtherscanClient:
EthereumNetwork.BASE: "https://api.basescan.org/",
EthereumNetwork.BLAST: "https://blastscan.io",
EthereumNetwork.TAIKO_MAINNET: "https://taikoscan.io",
EthereumNetwork.BASE_SEPOLIA_TESTNET: "https://sepolia.basescan.org",
}

NETWORK_WITH_API_URL = {
Expand Down Expand Up @@ -109,6 +110,7 @@ class EtherscanClient:
EthereumNetwork.BASE: "https://api.basescan.org",
EthereumNetwork.BLAST: "https://api.blastscan.io",
EthereumNetwork.TAIKO_MAINNET: "https://api.taikoscan.io",
EthereumNetwork.BASE_SEPOLIA_TESTNET: "https://api-sepolia.basescan.org/api",
}
HTTP_HEADERS = {
"User-Agent": "curl/7.77.0",
Expand Down
36 changes: 36 additions & 0 deletions gnosis/safe/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@
"1.3.0+L2",
), # default singleton address
("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", 79000, "1.3.0"),
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 6702420, "1.4.1"), # v1.4.1
(
"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
8792328,
"1.4.1+L2",
), # v1.4.1+L2
],
EthereumNetwork.MUMBAI: [
("0x3E5c63644E683549055b9Be8653de26E0B4CD36E", 13736914, "1.3.0+L2"),
Expand All @@ -167,6 +173,12 @@
"1.3.0+L2",
), # default singleton address
("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", 1140, "1.3.0"),
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 144832221, "1.4.1"), # v1.4.1
(
"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
163904906,
"1.4.1+L2",
), # v1.4.1+L2
],
EthereumNetwork.ARBITRUM_NOVA: [
("0x3E5c63644E683549055b9Be8653de26E0B4CD36E", 426, "1.3.0+L2"),
Expand Down Expand Up @@ -211,6 +223,12 @@
EthereumNetwork.CELO_MAINNET: [
("0xfb1bffC9d739B8D520DaF37dF666da4C687191EA", 8944350, "1.3.0+L2"),
("0x69f4D1788e39c87893C980c06EdF4b7f686e2938", 8944351, "1.3.0"),
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 23116909, "1.4.1"), # v1.4.1
(
"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
23116907,
"1.4.1+L2",
), # v1.4.1+L2
],
EthereumNetwork.AVALANCHE_C_CHAIN: [
(
Expand All @@ -233,6 +251,12 @@
4_949_512,
"1.3.0",
), # safe singleton address
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 37031334, "1.4.1"), # v1.4.1
(
"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
43431152,
"1.4.1+L2",
), # v1.4.1+L2
],
EthereumNetwork.MOONBEAM: [
("0x3E5c63644E683549055b9Be8653de26E0B4CD36E", 172_092, "1.3.0+L2"),
Expand Down Expand Up @@ -434,6 +458,7 @@
8405927,
"1.4.1+L2",
), # v1.4.1+L2
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 5854670, "1.4.1"), # v1.4.1
],
EthereumNetwork.BASE_GOERLI_TESTNET: [
("0x29fcB43b46531BcA003ddC8FCB67FFE91900C762", 7330635, "1.4.1+L2"),
Expand All @@ -446,6 +471,12 @@
("0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552", 3282056, "1.3.0"),
("0xfb1bffC9d739B8D520DaF37dF666da4C687191EA", 5125249, "1.3.0+L2"),
("0x69f4D1788e39c87893C980c06EdF4b7f686e2938", 5125256, "1.3.0"),
("0x41675C099F32341bf84BFc5382aF534df5C7461a", 5172602, "1.4.1"), # v1.4.1
(
"0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
5172599,
"1.4.1+L2",
), # v1.4.1+L2
],
EthereumNetwork.KAVA: [
("0x3E5c63644E683549055b9Be8653de26E0B4CD36E", 2116303, "1.3.0+L2"),
Expand Down Expand Up @@ -1293,6 +1324,7 @@
"0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
79000,
), # v1.3.0 default singleton address
("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", 6702792), # v1.4.1
],
EthereumNetwork.ARBITRUM_ONE: [
(
Expand All @@ -1303,6 +1335,7 @@
"0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
1140,
), # v1.3.0 default singleton address
("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", 99258141), # v1.4.1
],
EthereumNetwork.ARBITRUM_NOVA: [
("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", 419), # v1.3.0
Expand All @@ -1329,6 +1362,7 @@
],
EthereumNetwork.CELO_MAINNET: [
("0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC", 8944342), # v1.3.0
("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", 23116898), # v1.4.1
],
EthereumNetwork.AVALANCHE_C_CHAIN: [
(
Expand All @@ -1339,6 +1373,7 @@
"0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC",
4_949_487,
), # v1.3.0 safe singleton address
("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", 37031436), # v1.4.1
],
EthereumNetwork.MOONBEAM: [
("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", 172078), # v1.3.0
Expand Down Expand Up @@ -1490,6 +1525,7 @@
EthereumNetwork.BASE_SEPOLIA_TESTNET: [
("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", 3282032), # v1.3.0
("0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC", 5125191), # v1.3.0
("0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67", 5172579), # v1.4.1
],
EthereumNetwork.KAVA: [
("0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2", 2116356), # v1.3.0
Expand Down
36 changes: 22 additions & 14 deletions gnosis/safe/api/transaction_service_api/transaction_service_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from typing import Any, Dict, List, Optional, Tuple, Union
from urllib.parse import urlencode

from eth_account.signers.local import LocalAccount
from eth_typing import ChecksumAddress, Hash32, HexStr
from hexbytes import HexBytes

Expand Down Expand Up @@ -265,39 +264,48 @@ def post_signatures(self, safe_tx_hash: bytes, signatures: bytes) -> bool:

def add_delegate(
self,
safe_address: ChecksumAddress,
delegate_address: ChecksumAddress,
delegator_address: ChecksumAddress,
label: str,
signer_account: LocalAccount,
signature: bytes,
safe_address: Optional[ChecksumAddress] = None,
) -> bool:
hash_to_sign = self.create_delegate_message_hash(delegate_address)
signature = signer_account.signHash(hash_to_sign)
add_payload = {
"safe": safe_address,
"delegate": delegate_address,
"delegator": delegator_address,
"signature": signature.signature.hex(),
"signature": HexBytes(signature).hex(),
"label": label,
}
if safe_address:
add_payload["safe"] = safe_address
response = self._post_request("/api/v2/delegates/", add_payload)
if not response.ok:
raise SafeAPIException(f"Cannot add delegate: {response.content}")
return True

def remove_delegate(
self,
safe_address: ChecksumAddress,
delegate_address: ChecksumAddress,
signer_account: LocalAccount,
delegator_address: ChecksumAddress,
signature: bytes,
safe_address: Optional[ChecksumAddress] = None,
) -> bool:
hash_to_sign = self.create_delegate_message_hash(delegate_address)
signature = signer_account.signHash(hash_to_sign)
"""
Deletes a delegated user
:param delegator_address:
:param delegate_address:
:param signature: Signature of a hash of an eip712 message.
:param safe_address: If specified, a delegate is removed for a delegator for the specific safe.
Otherwise, the delegate is deleted in a global form.
:return:
"""
remove_payload = {
"safe": safe_address,
"delegator": signer_account.address,
"signature": signature.signature.hex(),
"delegator": delegator_address,
"signature": HexBytes(signature).hex(),
}
if safe_address:
remove_payload["safe"] = safe_address
response = self._delete_request(
f"/api/v2/delegates/{delegate_address}/",
remove_payload,
Expand Down
75 changes: 75 additions & 0 deletions gnosis/safe/tests/api/test_transaction_service_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from django.test import TestCase

from eth_account import Account
from eth_typing import HexStr
from hexbytes import HexBytes

Expand Down Expand Up @@ -189,6 +190,80 @@ def test_get_safe_transaction(self):
str(context.exception),
)

def test_remove_delegate(self):
with patch.object(
TransactionServiceApi, "_delete_request"
) as mock_delete_request:
delegate_address = Account().create().address
delegator_account = Account().create()
message_hash = self.transaction_service_api.create_delegate_message_hash(
delegate_address
)
signature = delegator_account.signHash(message_hash).signature.hex()
self.transaction_service_api.remove_delegate(
delegate_address, delegator_account.address, signature
)

expected_url = f"/api/v2/delegates/{delegate_address}/"
expected_payload = {
"delegator": delegator_account.address,
"signature": signature,
}
mock_delete_request.assert_called_once_with(expected_url, expected_payload)

self.transaction_service_api.remove_delegate(
delegate_address,
delegator_account.address,
signature,
self.safe_address,
)

expected_payload = {
"safe": self.safe_address,
"delegator": delegator_account.address,
"signature": signature,
}
mock_delete_request.assert_called_with(expected_url, expected_payload)

def test_add_delegate(self):
with patch.object(TransactionServiceApi, "_post_request") as mock_post_request:
delegate_address = Account().create().address
delegator_account = Account().create()
message_hash = self.transaction_service_api.create_delegate_message_hash(
delegate_address
)
signature = delegator_account.signHash(message_hash).signature.hex()
label = "test label"
self.transaction_service_api.add_delegate(
delegate_address, delegator_account.address, label, signature
)

expected_url = "/api/v2/delegates/"
expected_payload = {
"delegate": delegate_address,
"delegator": delegator_account.address,
"signature": signature,
"label": label,
}
mock_post_request.assert_called_once_with(expected_url, expected_payload)

self.transaction_service_api.add_delegate(
delegate_address,
delegator_account.address,
label,
signature,
self.safe_address,
)

expected_payload = {
"safe": self.safe_address,
"delegate": delegate_address,
"delegator": delegator_account.address,
"signature": signature,
"label": label,
}
mock_post_request.assert_called_with(expected_url, expected_payload)

def test_decode_data(self):
with patch.object(TransactionServiceApi, "_post_request") as mock_post_request:
mock_post_request.return_value.ok = True
Expand Down

0 comments on commit a3099e6

Please sign in to comment.