Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Shibarium 1.3.0 contracts #744

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ff8a3e8
Add Shibarium 1.3.0 contracts (#1)
melnour Jan 17, 2024
d30a08c
Merge branch 'master' into master
melnour Jan 20, 2024
3cfb5de
Bump faker from 21.0.0 to 22.4.0
dependabot[bot] Jan 22, 2024
6f99438
Bump actions/cache from 3 to 4
dependabot[bot] Jan 22, 2024
8fe5f42
Bump web3 from 6.12.0 to 6.14.0
dependabot[bot] Jan 15, 2024
4672097
Add BASE Sepolia Safe addresses
Uxio0 Jan 22, 2024
0a1358a
Add Haqq networks (#730)
Hirama Jan 24, 2024
3329903
Add Mode Mainnet 1.3.0 contracts (#741)
ElvisKrop Jan 24, 2024
f4f4eb5
Remove goerli from tests (#749)
Uxio0 Jan 25, 2024
2032e20
Bump safe_deployments to v1.32.0
moisses89 Jan 26, 2024
6936c94
Set version v6.0.0b15
moisses89 Jan 31, 2024
db5d49f
Bump faker from 22.4.0 to 22.6.0
dependabot[bot] Feb 5, 2024
46ba488
Fix readthedocs configuration
Uxio0 Feb 7, 2024
5cb29bd
Bump django from 4.2.7 to 4.2.10
dependabot[bot] Feb 7, 2024
b2856d2
Add Felipe to CLA
Uxio0 Feb 9, 2024
cd078f9
Bump pytest-sugar from 0.9.7 to 1.0.0
dependabot[bot] Feb 12, 2024
2e6c419
Bump pytest from 7.4.4 to 8.0.0
dependabot[bot] Feb 5, 2024
4263d02
Bump coverage from 7.4.0 to 7.4.1
dependabot[bot] Feb 5, 2024
4da4477
Add Zora Sepolia 1.3.0 safe contracts (#758)
ElvisKrop Feb 15, 2024
f4e82ff
Refactor Safe Transaction API client (#753)
moisses89 Feb 16, 2024
36d29ad
Rename Gnosis Protocol libraries to Cowswap (#778)
falvaradorodriguez Feb 16, 2024
6471a07
Set version to 6.0.0b16
moisses89 Feb 16, 2024
03dbbda
Bump pytest-django from 4.7.0 to 4.8.0
dependabot[bot] Feb 19, 2024
f0f1293
Bump pytest from 8.0.0 to 8.0.1
dependabot[bot] Feb 19, 2024
4b3b798
Support Python 3.12 (#656)
Uxio0 Feb 19, 2024
311e757
Bump py-evm from 0.8.0b1 to 0.9.0b1
dependabot[bot] Feb 19, 2024
2848d8c
Add Mode Testnet 1.3.0 safe contracts (#759)
ElvisKrop Feb 19, 2024
a6ebe6d
Add 4337 bundler API client (#776)
Uxio0 Feb 20, 2024
519370b
Add Mantle Sepolia support (#742)
ElvisKrop Feb 20, 2024
60a71a7
Add OP Sepolia 1.3.0 and 1.4.1 safe contracts (#765)
ElvisKrop Feb 21, 2024
88d2bc9
Add Linea Mainnet and Testnet 1.3.0 safe contracts deployed via safe …
ElvisKrop Feb 21, 2024
c2be195
Add Scroll Mainnet and Testnet 1.3.0 safe contracts deployed via safe…
ElvisKrop Feb 21, 2024
5d76a61
Add Zora Mainnet 1.3.0 safe contracts deployed via safe singleton fac…
ElvisKrop Feb 21, 2024
754f6da
Add unreal Testnet support (#787)
ElvisKrop Feb 21, 2024
50a2599
Add Taiko Katla L2 1.3.0 contracts (#790)
ElvisKrop Feb 21, 2024
e305b7b
Add Aurora, Scroll and Linea safe Singleton (#760)
Majorfi Feb 22, 2024
faef4ad
Update Aurora default singleton address blocks
falvaradorodriguez Feb 22, 2024
07bd2d9
Update CODEOWNERS to core-api team
moisses89 Feb 21, 2024
a16c708
resolved conflicts
melnour Feb 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence.
* @safe-global/safe-services
* @safe-global/core-api
2 changes: 1 addition & 1 deletion .github/workflows/cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
path-to-document: 'https://safe.global/cla'
# branch should not be protected
branch: 'cla-signatures'
allowlist: hectorgomezv,moisses89,fmrsabino,luarx,rmeissner,Uxio0,*bot # may need to update this expression if we add new bots
allowlist: falvaradorodriguez,hectorgomezv,moisses89,fmrsabino,luarx,rmeissner,Uxio0,*bot # may need to update this expression if we add new bots

#below are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11]
python-version: [3.12]

steps:
- uses: actions/checkout@v4
Expand All @@ -24,7 +24,7 @@ jobs:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: '.pre-commit-config.yaml'
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
Expand All @@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", 3.11]
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
services:
postgres:
image: postgres:13
Expand All @@ -62,7 +62,7 @@ jobs:
cache-dependency-path: 'requirements*.txt'
- name: Install dependencies
run: |
pip install wheel
pip install wheel setuptools
pip install -r requirements-test.txt coveralls
env:
PIP_USE_MIRRORS: true
Expand Down
35 changes: 25 additions & 10 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
# .readthedocs.yaml
# Read the Docs configuration file
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Build documentation in the docs/ directory with Sphinx
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
# golang: "1.20"

# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/source/conf.py
configuration: docs/source/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
# fail_on_warning: true

# Optionally build your docs in additional formats such as PDF
# Optionally build your docs in additional formats such as PDF and ePub
formats:
- pdf
- pdf
- epub

# Optionally set the version of Python and requirements required to build your docs
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
version: 3.8
install:
- requirements: requirements-dev.txt
install:
- requirements: requirements-dev.txt
18 changes: 9 additions & 9 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,21 @@ To work with Multisig Transactions:
safe_tx.call() # Check it works
safe_tx.execute(tx_sender_private_key)

Protocol
CowSwap
~~~~~~~~
On ``gnosis.protocol`` there're classes to work with `Gnosis Protocol v2 <https://docs.cowswap.app>`_
On ``gnosis.cowswap`` there're classes to work with `CowSwap <https://docs.cowswap.app>`_

.. code-block:: python

import time
from gnosis.eth import EthereumNetwork
from gnosis.protocol import Order, OrderKind, GnosisProtocolAPI
from gnosis.cowswap import Order, OrderKind, CowSwapAPI

account_address = '' # Fill with checksummed version of a Gnosis Protocol user address
account_address = '' # Fill with checksummed version of a CowSwap user address
account_private_key = '' # Fill with private key of a user address
gnosis_protocol_api = GnosisProtocolAPI(EthereumNetwork.RINKEBY)
print(gnosis_protocol_api.get_trades(owner=account_address))
buy_amount = gnosis_protocol_api.get_estimated_amount(base_token, quote_token, OrderKind.SELL, sell_amount)
cow_swap_api = CowSwapAPI(EthereumNetwork.SEPOLIA)
print(cow_swap_api.get_trades(owner=account_address))
buy_amount = cow_swap_api.get_estimated_amount(base_token, quote_token, OrderKind.SELL, sell_amount)
valid_to = int(time.time() + (24 * 60 * 60)) # Order valid for 1 day
order = Order(
sellToken=base_token,
Expand All @@ -207,11 +207,11 @@ On ``gnosis.protocol`` there're classes to work with `Gnosis Protocol v2 <https:
sellAmount=sell_amount,
buyAmount=buy_amount,
validTo=valid_to, # timestamp
appData=ipfs_hash, # IPFS hash for metadata
appData={}, # Dict with CowSwap AppData schema definition (https://github.com/cowprotocol/app-data)
fee_amount=0, # If set to `0` it will be autodetected
kind='sell', # `sell` or `buy`
partiallyFillable=True, # `True` or `False`
sellTokenBalance='erc20', # `erc20`, `external` or `internal`
buyTokenBalance='erc20', # `erc20` or `internal`
)
gnosis_protocol_api.place_order(order, account_private_key)
cow_swap_api.place_order(order, account_private_key)
4 changes: 2 additions & 2 deletions gnosis/protocol/__init__.py → gnosis/cowsap/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# flake8: noqa F401
from .gnosis_protocol_api import GnosisProtocolAPI
from .cow_swap_api import CowSwapAPI
from .order import Order, OrderKind

__all__ = [
"GnosisProtocolAPI",
"CowSwapAPI",
"Order",
"OrderKind",
]
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import json
from functools import cached_property
from typing import Any, Dict, List, Optional, TypedDict, Union, cast

import requests
from eth_account import Account
from eth_account.messages import encode_defunct
from eth_typing import AnyAddress, ChecksumAddress, HexStr
from hexbytes import HexBytes

from gnosis.eth import EthereumNetwork, EthereumNetworkNotSupported
from gnosis.eth.eip712 import eip712_encode_hash

from ..eth.constants import NULL_ADDRESS
from ..util.http import prepare_http_session
from .order import Order, OrderKind


Expand All @@ -37,78 +37,57 @@ class ErrorResponse(TypedDict):
description: str


class GnosisProtocolAPI:
class CowSwapAPI:
"""
Client for GnosisProtocol API. More info: https://docs.cowswap.exchange/
Client for CowSwap API. More info: https://docs.cowswap.exchange/
"""

SETTLEMENT_CONTRACT_ADDRESSES = {
EthereumNetwork.MAINNET: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
EthereumNetwork.GOERLI: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
EthereumNetwork.GNOSIS: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
EthereumNetwork.SEPOLIA: "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
}

API_BASE_URLS = {
EthereumNetwork.MAINNET: "https://api.cow.fi/mainnet/api/v1/",
EthereumNetwork.GOERLI: "https://api.cow.fi/goerli/api/v1/",
EthereumNetwork.GNOSIS: "https://api.cow.fi/xdai/api/v1/",
EthereumNetwork.MAINNET: "https://api.cow.fi/mainnet",
EthereumNetwork.GNOSIS: "https://api.cow.fi/xdai",
EthereumNetwork.SEPOLIA: "https://api.cow.fi/sepolia",
}

def __init__(self, ethereum_network: EthereumNetwork, request_timeout: int = 10):
self.network = ethereum_network
if self.network not in self.API_BASE_URLS:
raise EthereumNetworkNotSupported(
f"{self.network.name} network not supported by Gnosis Protocol"
f"{self.network.name} network not supported by CowSwap"
)
self.settlement_contract_address = self.SETTLEMENT_CONTRACT_ADDRESSES[
self.network
]
self.base_url = self.API_BASE_URLS[self.network]
self.http_session = self._prepare_http_session()
self.http_session = prepare_http_session(10, 100)
self.request_timeout = request_timeout

def _prepare_http_session(self) -> requests.Session:
"""
Prepare http session with custom pooling. See:
https://urllib3.readthedocs.io/en/stable/advanced-usage.html
https://docs.python-requests.org/en/v1.2.3/api/#requests.adapters.HTTPAdapter
https://web3py.readthedocs.io/en/stable/providers.html#httpprovider
"""
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(
pool_connections=10,
pool_maxsize=100,
pool_block=False,
)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session

@cached_property
def weth_address(self) -> ChecksumAddress:
"""
:return: Wrapped ether checksummed address
"""
if self.network == EthereumNetwork.GNOSIS: # WXDAI
return ChecksumAddress("0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d")
if self.network == EthereumNetwork.GOERLI: # Goerli WETH9
return ChecksumAddress("0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6")

# Mainnet WETH9
return ChecksumAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")

def get_quote(
self, order: Order, from_address: ChecksumAddress
) -> Union[Dict[str, Any], ErrorResponse]:
url = self.base_url + "quote"
url = self.base_url + "/api/v1/quote"
data_json = {
"sellToken": order.sellToken.lower(),
"buyToken": order.buyToken.lower(),
"sellAmountAfterFee": str(order.sellAmount),
# "validTo": order.validTo,
"appData": HexBytes(order.appData).hex()
if isinstance(order.appData, bytes)
else order.appData,
"appData": json.dumps(order.appData),
"feeAmount": str(order.feeAmount),
"kind": order.kind,
"partiallyFillable": order.partiallyFillable,
Expand Down Expand Up @@ -144,7 +123,7 @@ def place_order(
order.buyAmount and order.sellAmount
), "Order buyAmount and sellAmount cannot be empty"

url = self.base_url + "orders/"
url = self.base_url + "/api/v1/orders"
from_address = Account.from_key(private_key).address
if not order.feeAmount:
fee_amount = self.get_fee(order, from_address)
Expand All @@ -167,9 +146,7 @@ def place_order(
"sellAmount": str(order.sellAmount),
"buyAmount": str(order.buyAmount),
"validTo": order.validTo,
"appData": HexBytes(order.appData).hex()
if isinstance(order.appData, bytes)
else order.appData,
"appData": json.dumps(order.appData),
"feeAmount": str(order.feeAmount),
"kind": order.kind,
"partiallyFillable": order.partiallyFillable,
Expand All @@ -196,7 +173,7 @@ def get_orders(
total number of returned results. When a response contains less than the limit
the last page has been reached.
"""
url = self.base_url + f"account/{owner}/orders"
url = self.base_url + f"/api/v1/account/{owner}/orders"
r = self.http_session.get(url, timeout=self.request_timeout)
if r.ok:
return cast(List[Dict[str, Any]], r.json())
Expand All @@ -209,7 +186,7 @@ def get_trades(
assert bool(order_ui) ^ bool(
owner
), "order_ui or owner must be provided, but not both"
url = self.base_url + "trades/?"
url = self.base_url + "/api/v1/trades/?"
if order_ui:
url += f"orderUid={order_ui}"
elif owner:
Expand Down Expand Up @@ -243,7 +220,7 @@ def get_estimated_amount(
sellAmount=amount_wei * 10 if kind == OrderKind.SELL else 0,
buyAmount=amount_wei * 10 if kind == OrderKind.BUY else 0,
validTo=0, # Valid for 1 hour
appData="0x0000000000000000000000000000000000000000000000000000000000000000",
appData={},
feeAmount=0,
kind=kind.name.lower(), # `sell` or `buy`
partiallyFillable=False,
Expand Down
11 changes: 6 additions & 5 deletions gnosis/protocol/order.py → gnosis/cowsap/order.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import json
from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, Literal

from eth_typing import ChecksumAddress, Hash32
from eth_typing import ChecksumAddress


@dataclass
Expand All @@ -13,7 +14,7 @@ class Order:
sellAmount: int
buyAmount: int
validTo: int
appData: Hash32
appData: Dict
feeAmount: int
kind: Literal["sell", "buy"]
partiallyFillable: bool
Expand All @@ -40,7 +41,7 @@ def get_eip712_structured_data(
{"name": "sellAmount", "type": "uint256"},
{"name": "buyAmount", "type": "uint256"},
{"name": "validTo", "type": "uint32"},
{"name": "appData", "type": "bytes32"},
{"name": "appData", "type": "string"},
{"name": "feeAmount", "type": "uint256"},
{"name": "kind", "type": "string"},
{"name": "partiallyFillable", "type": "bool"},
Expand All @@ -55,7 +56,7 @@ def get_eip712_structured_data(
"sellAmount": self.sellAmount,
"buyAmount": self.buyAmount,
"validTo": self.validTo,
"appData": self.appData,
"appData": json.dumps(self.appData),
"feeAmount": self.feeAmount,
"kind": self.kind,
"partiallyFillable": self.partiallyFillable,
Expand All @@ -67,7 +68,7 @@ def get_eip712_structured_data(
"types": types,
"primaryType": "Order",
"domain": {
"name": "Gnosis Protocol",
"name": "CowSwap",
"version": "v2",
"chainId": chain_id,
"verifyingContract": verifying_contract,
Expand Down
File renamed without changes.
Loading
Loading