afp-sdk 0.2.2__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/CHANGELOG.md +11 -0
  2. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/PKG-INFO +20 -4
  3. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/README.md +19 -3
  4. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/final_settlement_facet.py +54 -0
  5. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/config.py +8 -7
  6. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/exchange.py +11 -2
  7. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/pyproject.toml +1 -1
  8. afp_sdk-0.3.0/tests/test_exchange_client.py +24 -0
  9. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/uv.lock +1 -1
  10. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/.env.template +0 -0
  11. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/.envrc +0 -0
  12. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/LICENSE +0 -0
  13. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/__init__.py +0 -0
  14. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/__init__.py +0 -0
  15. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/admin.py +0 -0
  16. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/base.py +0 -0
  17. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/builder.py +0 -0
  18. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/clearing.py +0 -0
  19. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/liquidation.py +0 -0
  20. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/api/trading.py +0 -0
  21. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/__init__.py +0 -0
  22. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/auctioneer_facet.py +0 -0
  23. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/bankruptcy_facet.py +0 -0
  24. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/clearing_facet.py +0 -0
  25. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/erc20.py +0 -0
  26. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/facade.py +0 -0
  27. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/margin_account.py +0 -0
  28. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/margin_account_registry.py +0 -0
  29. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/mark_price_tracker_facet.py +0 -0
  30. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/oracle_provider.py +0 -0
  31. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/product_registry.py +0 -0
  32. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/system_viewer.py +0 -0
  33. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/bindings/trading_protocol.py +0 -0
  34. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/decorators.py +0 -0
  35. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/enums.py +0 -0
  36. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/exceptions.py +0 -0
  37. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/py.typed +0 -0
  38. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/schemas.py +0 -0
  39. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/signing.py +0 -0
  40. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/afp/validators.py +0 -0
  41. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/devenv.lock +0 -0
  42. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/devenv.nix +0 -0
  43. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/devenv.yaml +0 -0
  44. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/examples/cancel_order.py +0 -0
  45. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/examples/create_product.py +0 -0
  46. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/examples/execute_trade.py +0 -0
  47. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/__init__.py +0 -0
  48. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/test_decorators.py +0 -0
  49. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/test_hashing.py +0 -0
  50. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/test_login.py +0 -0
  51. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/test_schemas.py +0 -0
  52. {afp_sdk-0.2.2 → afp_sdk-0.3.0}/tests/test_validators.py +0 -0
@@ -1,3 +1,13 @@
1
+ ## [v0.3.0] - 2025-09-05
2
+
3
+ _First public release for Forecastathon._
4
+
5
+ ### Changed
6
+
7
+ - Update the interface with the AutEx exchange ([#17](https://github.com/autonity/afp-sdk/pull/17))
8
+ - Update the contract bindings ([#18](https://github.com/autonity/afp-sdk/pull/18))
9
+ - Update Clearing System parameters for Autonity Mainnet ([#19](https://github.com/autonity/afp-sdk/pull/19))
10
+
1
11
  ## [v0.2.2] - 2025-09-03
2
12
 
3
13
  ### Added
@@ -45,6 +55,7 @@
45
55
 
46
56
  _First release._
47
57
 
58
+ [v0.3.0]: https://github.com/autonity/afp-sdk/releases/tag/v0.3.0
48
59
  [v0.2.2]: https://github.com/autonity/afp-sdk/releases/tag/v0.2.2
49
60
  [v0.2.1]: https://github.com/autonity/afp-sdk/releases/tag/v0.2.1
50
61
  [v0.2.0]: https://github.com/autonity/afp-sdk/releases/tag/v0.2.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afp-sdk
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Autonomous Futures Protocol Python SDK
5
5
  Keywords: autonity,web3,trading,crypto,prediction,forecast,markets
6
6
  License-Expression: MIT
@@ -38,7 +38,7 @@ pip install afp-sdk
38
38
 
39
39
  The `afp` package consists of the following:
40
40
 
41
- - `afp` top-level module: High-level API for interacting with the Clearing
41
+ - `afp` top-level module: High-level API for interacting with the AFP Clearing
42
42
  System and the AutEx exchange.
43
43
  - `afp.bindings` submodule: Low-level API that provides typed Python bindings
44
44
  for the Clearing System smart contracts.
@@ -47,7 +47,7 @@ The `afp` package consists of the following:
47
47
 
48
48
  ### Preparation
49
49
 
50
- In order to use the AFP system, traders need to prepare the following:
50
+ In order to trade in the AFP system, traders need to prepare the following:
51
51
 
52
52
  - The ID of a product to be traded.
53
53
  - The address of the product's collateral token.
@@ -55,7 +55,7 @@ In order to use the AFP system, traders need to prepare the following:
55
55
  balance in ATN (for paying gas fee) and in the product's collateral token.
56
56
  - An Autonity account for signing intents. The two accounts can be the same.
57
57
  - The address of an Autonity RPC provider. They can be found on
58
- [Chainlist](https://chainlist.org/?search=autonity&testnets=true).
58
+ [Chainlist](https://chainlist.org/?search=autonity).
59
59
 
60
60
  We can store those in the following constants (using random example IDs):
61
61
 
@@ -169,6 +169,22 @@ print(fills)
169
169
 
170
170
  See further code examples in the [examples](./examples/) directory.
171
171
 
172
+ ## Configuration
173
+
174
+ By default the SDK communicates with the AFP Clearing System contracts on
175
+ Autonity Mainnet, and the AutEx Exchange. Connection parameters can be
176
+ overridden with the following environment variables:
177
+
178
+ ```sh
179
+ AFP_EXCHANGE_URL=
180
+ AFP_CHAIN_ID=
181
+ AFP_CLEARING_DIAMOND_ADDRESS=
182
+ AFP_MARGIN_ACCOUNT_REGISTRY_ADDRESS=
183
+ AFP_ORACLE_PROVIDER_ADDRESS=
184
+ AFP_PRODUCT_REGISTRY_ADDRESS=
185
+ AFP_SYSTEM_VIEWER_ADDRESS=
186
+ ```
187
+
172
188
  ## Development
173
189
 
174
190
  The package uses [`uv`](https://docs.astral.sh/uv/) as project manager.
@@ -13,7 +13,7 @@ pip install afp-sdk
13
13
 
14
14
  The `afp` package consists of the following:
15
15
 
16
- - `afp` top-level module: High-level API for interacting with the Clearing
16
+ - `afp` top-level module: High-level API for interacting with the AFP Clearing
17
17
  System and the AutEx exchange.
18
18
  - `afp.bindings` submodule: Low-level API that provides typed Python bindings
19
19
  for the Clearing System smart contracts.
@@ -22,7 +22,7 @@ The `afp` package consists of the following:
22
22
 
23
23
  ### Preparation
24
24
 
25
- In order to use the AFP system, traders need to prepare the following:
25
+ In order to trade in the AFP system, traders need to prepare the following:
26
26
 
27
27
  - The ID of a product to be traded.
28
28
  - The address of the product's collateral token.
@@ -30,7 +30,7 @@ In order to use the AFP system, traders need to prepare the following:
30
30
  balance in ATN (for paying gas fee) and in the product's collateral token.
31
31
  - An Autonity account for signing intents. The two accounts can be the same.
32
32
  - The address of an Autonity RPC provider. They can be found on
33
- [Chainlist](https://chainlist.org/?search=autonity&testnets=true).
33
+ [Chainlist](https://chainlist.org/?search=autonity).
34
34
 
35
35
  We can store those in the following constants (using random example IDs):
36
36
 
@@ -144,6 +144,22 @@ print(fills)
144
144
 
145
145
  See further code examples in the [examples](./examples/) directory.
146
146
 
147
+ ## Configuration
148
+
149
+ By default the SDK communicates with the AFP Clearing System contracts on
150
+ Autonity Mainnet, and the AutEx Exchange. Connection parameters can be
151
+ overridden with the following environment variables:
152
+
153
+ ```sh
154
+ AFP_EXCHANGE_URL=
155
+ AFP_CHAIN_ID=
156
+ AFP_CLEARING_DIAMOND_ADDRESS=
157
+ AFP_MARGIN_ACCOUNT_REGISTRY_ADDRESS=
158
+ AFP_ORACLE_PROVIDER_ADDRESS=
159
+ AFP_PRODUCT_REGISTRY_ADDRESS=
160
+ AFP_SYSTEM_VIEWER_ADDRESS=
161
+ ```
162
+
147
163
  ## Development
148
164
 
149
165
  The package uses [`uv`](https://docs.astral.sh/uv/) as project manager.
@@ -32,6 +32,16 @@ class FinalSettlementFacet:
32
32
  abi=ABI,
33
33
  )
34
34
 
35
+ @property
36
+ def FSPFinalized(self) -> contract.ContractEvent:
37
+ """Binding for `event FSPFinalized` on the FinalSettlementFacet contract."""
38
+ return self._contract.events.FSPFinalized
39
+
40
+ @property
41
+ def FinalSettlementCloseout(self) -> contract.ContractEvent:
42
+ """Binding for `event FinalSettlementCloseout` on the FinalSettlementFacet contract."""
43
+ return self._contract.events.FinalSettlementCloseout
44
+
35
45
  def closeout_fee_rate(
36
46
  self,
37
47
  ) -> int:
@@ -210,6 +220,50 @@ ABI = typing.cast(
210
220
  "name": "ProductNotInFinalSettlement",
211
221
  "type": "error",
212
222
  },
223
+ {
224
+ "anonymous": False,
225
+ "inputs": [
226
+ {
227
+ "indexed": True,
228
+ "internalType": "bytes32",
229
+ "name": "productID",
230
+ "type": "bytes32",
231
+ },
232
+ {
233
+ "indexed": False,
234
+ "internalType": "uint256",
235
+ "name": "fsp",
236
+ "type": "uint256",
237
+ },
238
+ ],
239
+ "name": "FSPFinalized",
240
+ "type": "event",
241
+ },
242
+ {
243
+ "anonymous": False,
244
+ "inputs": [
245
+ {
246
+ "indexed": True,
247
+ "internalType": "bytes32",
248
+ "name": "productID",
249
+ "type": "bytes32",
250
+ },
251
+ {
252
+ "indexed": False,
253
+ "internalType": "uint256",
254
+ "name": "accountLength",
255
+ "type": "uint256",
256
+ },
257
+ {
258
+ "indexed": False,
259
+ "internalType": "address",
260
+ "name": "closedBy",
261
+ "type": "address",
262
+ },
263
+ ],
264
+ "name": "FinalSettlementCloseout",
265
+ "type": "event",
266
+ },
213
267
  {
214
268
  "inputs": [],
215
269
  "name": "CLOSEOUT_FEE_RATE",
@@ -9,33 +9,34 @@ FEE_RATE_MULTIPLIER = 10**6
9
9
  FULL_PRECISION_MULTIPLIER = 10**18
10
10
 
11
11
  USER_AGENT = "afp-sdk"
12
+ DEFAULT_EXCHANGE_API_VERSION = 1
12
13
  EXCHANGE_URL = os.getenv(
13
- "AFP_EXCHANGE_URL", "https://afp-exchange-staging.up.railway.app"
14
+ "AFP_EXCHANGE_URL", "https://afp-exchange-stable.up.railway.app"
14
15
  )
15
16
 
16
- CHAIN_ID = int(os.getenv("AFP_CHAIN_ID", 65010004))
17
+ CHAIN_ID = int(os.getenv("AFP_CHAIN_ID", 65000000))
17
18
 
18
19
  CLEARING_DIAMOND_ADDRESS = Web3.to_checksum_address(
19
20
  os.getenv(
20
- "AFP_CLEARING_DIAMOND_ADDRESS", "0xB894bFf368Bf1EA89c18612670B7E072866a5264"
21
+ "AFP_CLEARING_DIAMOND_ADDRESS", "0x5B5411F1548254d25360d71FE40cFc1cC983B2A2"
21
22
  )
22
23
  )
23
24
  MARGIN_ACCOUNT_REGISTRY_ADDRESS = Web3.to_checksum_address(
24
25
  os.getenv(
25
26
  "AFP_MARGIN_ACCOUNT_REGISTRY_ADDRESS",
26
- "0xDA71FdE0E7cfFf445e848EAdB3B2255B68Ed6ef6",
27
+ "0x99f4FA9Cdce7AD227eB84907936a8FeF2095D846",
27
28
  )
28
29
  )
29
30
  ORACLE_PROVIDER_ADDRESS = Web3.to_checksum_address(
30
31
  os.getenv(
31
- "AFP_ORACLE_PROVIDER_ADDRESS", "0x626da921088a5A00C75C208Decbb60E816488481"
32
+ "AFP_ORACLE_PROVIDER_ADDRESS", "0xF2A2A27da33D30B4BF38D7e186E7B0b1e964e55c"
32
33
  )
33
34
  )
34
35
  PRODUCT_REGISTRY_ADDRESS = Web3.to_checksum_address(
35
36
  os.getenv(
36
- "AFP_PRODUCT_REGISTRY_ADDRESS", "0x9b92EAC112c996a513e515Cf8c3BDd83619F730D"
37
+ "AFP_PRODUCT_REGISTRY_ADDRESS", "0x86B3829471929B115367DA0958f56A6AB844b08e"
37
38
  )
38
39
  )
39
40
  SYSTEM_VIEWER_ADDRESS = Web3.to_checksum_address(
40
- os.getenv("AFP_SYSTEM_VIEWER_ADDRESS", "0xcB3F71Db710544283a1FfB38FE1bEC554d0634A5")
41
+ os.getenv("AFP_SYSTEM_VIEWER_ADDRESS", "0xfF2DFcC44a95cce96E03EfC33C65c8Be671Bae5B")
41
42
  )
@@ -116,7 +116,13 @@ class ExchangeClient:
116
116
  yield MarketDepthData.model_validate_json(line)
117
117
 
118
118
  def _send_request(
119
- self, method: str, endpoint: str, stream: bool = False, **kwargs: Any
119
+ self,
120
+ method: str,
121
+ endpoint: str,
122
+ *,
123
+ stream: bool = False,
124
+ api_version: int = config.DEFAULT_EXCHANGE_API_VERSION,
125
+ **kwargs: Any,
120
126
  ) -> Response:
121
127
  kwargs["headers"] = {
122
128
  "Content-Type": "application/json",
@@ -126,7 +132,10 @@ class ExchangeClient:
126
132
 
127
133
  try:
128
134
  response = self._session.request(
129
- method, f"{config.EXCHANGE_URL}{endpoint}", stream=stream, **kwargs
135
+ method,
136
+ f"{config.EXCHANGE_URL}/v{api_version}{endpoint}",
137
+ stream=stream,
138
+ **kwargs,
130
139
  )
131
140
  except requests.exceptions.RequestException as request_exception:
132
141
  raise ExchangeError(
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "afp-sdk"
7
- version = "0.2.2"
7
+ version = "0.3.0"
8
8
  description = "Autonomous Futures Protocol Python SDK"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -0,0 +1,24 @@
1
+ from unittest.mock import Mock
2
+
3
+ from requests import Response
4
+ from requests.adapters import HTTPAdapter
5
+
6
+ from afp import config
7
+ from afp.exchange import ExchangeClient
8
+
9
+
10
+ def test_send_request(monkeypatch):
11
+ fake_response = Response()
12
+ fake_response.status_code = 200
13
+ mock_send = Mock(return_value=fake_response)
14
+ monkeypatch.setattr(HTTPAdapter, "send", mock_send)
15
+ monkeypatch.setattr(config, "EXCHANGE_URL", "https://foobar.com")
16
+
17
+ client = ExchangeClient()
18
+ client._send_request("POST", "/orders", api_version=2, data="hello")
19
+
20
+ mock_send.assert_called_once()
21
+ request = mock_send.call_args_list[0].args[0]
22
+ assert request.method == "POST"
23
+ assert request.url == "https://foobar.com/v2/orders"
24
+ assert request.body == "hello"
@@ -13,7 +13,7 @@ wheels = [
13
13
 
14
14
  [[package]]
15
15
  name = "afp-sdk"
16
- version = "0.2.2"
16
+ version = "0.3.0"
17
17
  source = { editable = "." }
18
18
  dependencies = [
19
19
  { name = "decorator" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes