-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathorderbookapi.py
More file actions
127 lines (117 loc) · 4.77 KB
/
orderbookapi.py
File metadata and controls
127 lines (117 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
OrderbookAPI for fetching relevant data using the CoW Swap Orderbook API.
"""
# pylint: disable=logging-fstring-interpolation
from typing import Any, Optional
import json
import requests
from src.helper_functions import get_logger
from src.models import Trade, OrderData, OrderExecution
from src.constants import (
header,
REQUEST_TIMEOUT,
SUCCESS_CODE,
FAIL_CODE,
)
class OrderbookAPI:
"""
Class for fetching data from a Web3 API.
"""
def __init__(self, chain_name: str) -> None:
self.logger = get_logger()
self.prod_url_prefix = f"https://api.cow.fi/{chain_name}/api/v1/"
self.barn_url_prefix = f"https://barn.api.cow.fi/{chain_name}/api/v1/"
def get_solver_competition_data(self, tx_hash: str) -> Optional[dict[str, Any]]:
"""
Get solver competition data from a transaction hash.
The returned dict follows the schema outlined here:
https://api.cow.fi/docs/#/default/get_api_v1_solver_competition_by_tx_hash__tx_hash_
"""
prod_endpoint_url = (
f"{self.prod_url_prefix}solver_competition/by_tx_hash/{tx_hash}"
)
barn_endpoint_url = (
f"{self.barn_url_prefix}solver_competition/by_tx_hash/{tx_hash}"
)
solver_competition_data: Optional[dict[str, Any]] = None
try:
json_competition_data = requests.get(
prod_endpoint_url,
headers=header,
timeout=REQUEST_TIMEOUT,
)
if json_competition_data.status_code == SUCCESS_CODE:
solver_competition_data = json.loads(json_competition_data.text)
elif json_competition_data.status_code == FAIL_CODE:
barn_competition_data = requests.get(
barn_endpoint_url, headers=header, timeout=REQUEST_TIMEOUT
)
if barn_competition_data.status_code == SUCCESS_CODE:
solver_competition_data = json.loads(barn_competition_data.text)
else:
return None
except requests.RequestException as err:
self.logger.warning(
f"Connection error while fetching competition data. Hash: {tx_hash}, error: {err}"
)
return None
return solver_competition_data
def get_order_data(self, uid: str) -> dict[str, Any] | None:
"""Get order data from uid.
The returned dict follows the schema outlined here:
https://api.cow.fi/docs/#/default/get_api_v1_orders__UID_
"""
prod_endpoint_url = f"{self.prod_url_prefix}orders/{uid}"
barn_endpoint_url = f"{self.barn_url_prefix}orders/{uid}"
order_data: Optional[dict[str, Any]] = None
try:
json_order_data = requests.get(
prod_endpoint_url,
headers=header,
timeout=REQUEST_TIMEOUT,
)
if json_order_data.status_code == SUCCESS_CODE:
order_data = json_order_data.json()
elif json_order_data.status_code == FAIL_CODE:
barn_order_data = requests.get(
barn_endpoint_url, headers=header, timeout=REQUEST_TIMEOUT
)
if barn_order_data.status_code == SUCCESS_CODE:
order_data = barn_order_data.json()
else:
return None
except requests.RequestException as err:
self.logger.warning(
f"Connection error while fetching order data. UID: {uid}, error: {err}"
)
return None
return order_data
def get_trade(
self, order_response: dict[str, Any], execution_response: dict[str, Any]
) -> Trade:
"""Create Trade from order and execution data."""
data = OrderData(
int(order_response["buyAmount"]),
int(order_response["sellAmount"]),
int(order_response["feeAmount"]),
order_response["buyToken"],
order_response["sellToken"],
order_response["kind"] == "sell",
order_response["partiallyFillable"],
)
execution = OrderExecution(
int(execution_response["buyAmount"]),
int(execution_response["sellAmount"]),
0,
)
return Trade(data, execution)
def get_uid_trades(self, solution: dict[str, Any]) -> dict[str, Trade] | None:
"""Get a dictionary mapping UIDs to trades in a solution."""
trades_dict: dict[str, Trade] = {}
for execution in solution["orders"]:
uid = execution["id"]
order_data = self.get_order_data(uid)
if order_data is None:
return None
trades_dict[uid] = self.get_trade(order_data, execution)
return trades_dict