afp-sdk 0.5.4__tar.gz → 0.6.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.
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/CHANGELOG.md +25 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/PKG-INFO +73 -10
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/README.md +66 -7
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/__init__.py +4 -1
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/afp.py +11 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/api/admin.py +1 -1
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/api/base.py +11 -2
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/api/margin_account.py +12 -148
- afp_sdk-0.6.0/afp/api/product.py +445 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/api/trading.py +10 -19
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/auth.py +14 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/__init__.py +30 -16
- afp_sdk-0.6.0/afp/bindings/admin_facet.py +890 -0
- afp_sdk-0.6.0/afp/bindings/clearing_facet.py +625 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/facade.py +9 -6
- afp_sdk-0.6.0/afp/bindings/final_settlement_facet.py +481 -0
- afp_sdk-0.6.0/afp/bindings/margin_account.py +1148 -0
- afp_sdk-0.6.0/afp/bindings/margin_account_facet.py +722 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/margin_account_registry.py +184 -310
- afp_sdk-0.6.0/afp/bindings/mark_price_tracker_facet.py +169 -0
- afp_sdk-0.6.0/afp/bindings/product_registry.py +2291 -0
- afp_sdk-0.6.0/afp/bindings/product_registry_facet.py +1467 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/system_viewer.py +592 -369
- afp_sdk-0.6.0/afp/bindings/types.py +223 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/config.py +4 -0
- afp_sdk-0.6.0/afp/constants.py +98 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/decorators.py +25 -3
- afp_sdk-0.6.0/afp/dtos.py +142 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/exceptions.py +10 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/exchange.py +10 -8
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/hashing.py +7 -5
- afp_sdk-0.6.0/afp/ipfs.py +245 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreiaw34o6l3rmatabzbds2i2myazdw2yolevcpsoyd2i2g3ms7wa2eq.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreibnfg6nq74dvpkre5rakkccij7iadp5rxpim7omsatjnrpmj3y7v4.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreicgr6dfo5yduixjkcifghiulskfegwojvuwodtouvivl362zndhxe.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreicheoypx6synljushh7mq2572iyhlolf4nake2p5dwobgnj3r5eua.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreid35a67db4sqh4fs6boddyt2xvscbqy6nqvsp5jjur56qhkw4ixre.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreidzs7okcpqiss6ztftltyptqwnw5e5opsy5yntospekjha4kpykaa.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreifcec2km7hxwq6oqzjlspni2mgipetjb7pqtaewh2efislzoctboi.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreihn3oiaxffe4e2w7pwtreadpw3obfd7gqlogbcxm56jc2hzfvco74.json +1 -0
- afp_sdk-0.6.0/afp/json-schemas/bafyreihur3dzwhja6uxsbcw6eeoj3xmmc4e3zkmyzpot5v5dleevxe5zam.json +1 -0
- afp_sdk-0.6.0/afp/schemas.py +337 -0
- afp_sdk-0.6.0/afp/types.py +169 -0
- afp_sdk-0.6.0/afp/validators.py +267 -0
- afp_sdk-0.6.0/examples/create_product.py +56 -0
- afp_sdk-0.6.0/examples/prediction-product-example.json +64 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/pyproject.toml +8 -4
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_base_api.py +1 -1
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_hashing.py +5 -4
- afp_sdk-0.6.0/tests/test_product_api.py +72 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_schemas.py +15 -2
- afp_sdk-0.6.0/tests/test_validators.py +185 -0
- afp_sdk-0.6.0/uv.lock +2134 -0
- afp_sdk-0.5.4/afp/api/product.py +0 -291
- afp_sdk-0.5.4/afp/bindings/auctioneer_facet.py +0 -752
- afp_sdk-0.5.4/afp/bindings/bankruptcy_facet.py +0 -391
- afp_sdk-0.5.4/afp/bindings/clearing_facet.py +0 -1042
- afp_sdk-0.5.4/afp/bindings/final_settlement_facet.py +0 -322
- afp_sdk-0.5.4/afp/bindings/margin_account.py +0 -1463
- afp_sdk-0.5.4/afp/bindings/mark_price_tracker_facet.py +0 -111
- afp_sdk-0.5.4/afp/bindings/product_registry.py +0 -1255
- afp_sdk-0.5.4/afp/bindings/trading_protocol.py +0 -1158
- afp_sdk-0.5.4/afp/constants.py +0 -55
- afp_sdk-0.5.4/afp/schemas.py +0 -287
- afp_sdk-0.5.4/afp/validators.py +0 -57
- afp_sdk-0.5.4/examples/create_product.py +0 -45
- afp_sdk-0.5.4/tests/test_validators.py +0 -67
- afp_sdk-0.5.4/uv.lock +0 -1757
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/.env.template +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/.envrc +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/LICENSE +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/api/__init__.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/erc20.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/bindings/oracle_provider.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/enums.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/afp/py.typed +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/devenv.lock +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/devenv.nix +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/devenv.yaml +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/examples/cancel_order.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/examples/execute_trade.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/__init__.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/assets/test.key +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_afp.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_decorators.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_exchange_client.py +0 -0
- {afp_sdk-0.5.4 → afp_sdk-0.6.0}/tests/test_signing.py +0 -0
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## [v0.6.0] - 2026-01-22
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- Add Python 3.14 support ([#45](https://github.com/autonity/afp-sdk/pull/45))
|
|
6
|
+
- Add Prediction Product schemas to `afp.schemas` module for product creation ([#45](https://github.com/autonity/afp-sdk/pull/45))
|
|
7
|
+
- Add `Product.pin()` method for extended metadata IPFS upload an pinning ([#46](https://github.com/autonity/afp-sdk/pull/46))
|
|
8
|
+
- Add `Product.validate()` and `Product.validate_json()` methods for importing and validating product specifications ([#46](https://github.com/autonity/afp-sdk/pull/46))
|
|
9
|
+
- Add `Product.dump()` and `Product.dump_json()` methods for exporting product specifications ([#46](https://github.com/autonity/afp-sdk/pull/46))
|
|
10
|
+
- Add `Product.get()` method for downloading product specifications from Autonity & IPFS ([#46](https://github.com/autonity/afp-sdk/pull/46))
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Update `Product.register()` method signature with the `initial_builder_stake` attribute ([#45](https://github.com/autonity/afp-sdk/pull/45))
|
|
15
|
+
- Update the AutEx exchange interface ([#42](https://github.com/autonity/afp-sdk/pull/42))
|
|
16
|
+
- Update contract bindings for the updated Clearing System interface ([#42](https://github.com/autonity/afp-sdk/pull/42))
|
|
17
|
+
- Update default contract addresses ([5948faa](https://github.com/autonity/afp-sdk/commit/5948faa1882a1ee1237936525df6534043b30f03))
|
|
18
|
+
|
|
19
|
+
### Removed
|
|
20
|
+
|
|
21
|
+
- Remove Python 3.11 support ([#45](https://github.com/autonity/afp-sdk/pull/45))
|
|
22
|
+
- Remove the `Product.create()` method ([#45](https://github.com/autonity/afp-sdk/pull/45))
|
|
23
|
+
- Remove deprecated methods `Trading.open_orders()`, `Product.create_product()`, `Product.register_product()` and `Product.product_state()` ([#41](https://github.com/autonity/afp-sdk/pull/41))
|
|
24
|
+
|
|
1
25
|
## [v0.5.4] - 2025-11-05
|
|
2
26
|
|
|
3
27
|
### Added
|
|
@@ -78,6 +102,7 @@
|
|
|
78
102
|
|
|
79
103
|
_First public release for Forecastathon._
|
|
80
104
|
|
|
105
|
+
[v0.6.0]: https://github.com/autonity/afp-sdk/releases/tag/v0.6.0
|
|
81
106
|
[v0.5.4]: https://github.com/autonity/afp-sdk/releases/tag/v0.5.4
|
|
82
107
|
[v0.5.3]: https://github.com/autonity/afp-sdk/releases/tag/v0.5.3
|
|
83
108
|
[v0.5.2]: https://github.com/autonity/afp-sdk/releases/tag/v0.5.2
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: afp-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Autonomous Futures Protocol Python SDK
|
|
5
5
|
Keywords: autonity,web3,trading,crypto,prediction,forecast,markets
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Classifier: Development Status :: 4 - Beta
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: dag-cbor>=0.3.3
|
|
13
14
|
Requires-Dist: decorator>=5.2.1
|
|
14
15
|
Requires-Dist: inflection>=0.5.1
|
|
16
|
+
Requires-Dist: ipld-car>=0.0.1
|
|
17
|
+
Requires-Dist: multiformats>=0.3.1.post4
|
|
15
18
|
Requires-Dist: pydantic>=2.10.6
|
|
16
19
|
Requires-Dist: requests>=2.32.0
|
|
20
|
+
Requires-Dist: rfc8785>=0.1.4
|
|
17
21
|
Requires-Dist: siwe>=4.4.0
|
|
18
22
|
Requires-Dist: web3>=7.6.0
|
|
19
|
-
Requires-Python: >=3.
|
|
23
|
+
Requires-Python: >=3.12
|
|
20
24
|
Project-URL: Changes, https://github.com/autonity/afp-sdk/blob/master/CHANGELOG.md
|
|
21
25
|
Project-URL: Homepage, https://github.com/autonity/afp-sdk
|
|
22
26
|
Project-URL: Issues, https://github.com/autonity/afp-sdk/issues
|
|
@@ -187,14 +191,73 @@ fills = trading.order_fills(product_id=PRODUCT_ID)
|
|
|
187
191
|
print(fills)
|
|
188
192
|
```
|
|
189
193
|
|
|
194
|
+
### Product API
|
|
195
|
+
|
|
196
|
+
Use the `Product` session object to validate a product schema, pin the
|
|
197
|
+
specification to IPFS, and register it on-chain.
|
|
198
|
+
|
|
199
|
+
In order to use the product API for product building, connection parameters of
|
|
200
|
+
an IPFS pinning service like [Filebase](https://filebase.com/) should be
|
|
201
|
+
included in the `AFP` constructor parameters.
|
|
202
|
+
|
|
203
|
+
```py
|
|
204
|
+
IPFS_API_URL = "https://rpc.filebase.io"
|
|
205
|
+
IPFS_API_KEY = os.environ["IPFS_API_KEY"]
|
|
206
|
+
|
|
207
|
+
app = afp.AFP(
|
|
208
|
+
rpc_url=AUTONITY_RPC_URL,
|
|
209
|
+
authenticator=afp.PrivateKeyAuthenticator(PRIVATE_KEY),
|
|
210
|
+
ipfs_api_url=IPFS_API_URL,
|
|
211
|
+
ipfs_api_key=IPFS_API_KEY,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
product = app.Product()
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
A JSON product specification can be parsed and validated with
|
|
218
|
+
`product.validate_json()`.
|
|
219
|
+
|
|
220
|
+
```py
|
|
221
|
+
with open("product-spec.json") as spec_file:
|
|
222
|
+
specification = product.validate_json(spec_file.read())
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Alternatively, it can also be validated from a Python dictionary.
|
|
226
|
+
|
|
227
|
+
```py
|
|
228
|
+
spec_dict = {
|
|
229
|
+
"product": {...},
|
|
230
|
+
"outcome_space": {...},
|
|
231
|
+
"outcome_point": {...},
|
|
232
|
+
"oracle_config": {...},
|
|
233
|
+
"oracle_fallback": {...},
|
|
234
|
+
}
|
|
235
|
+
specification = product.validate(spec_dict)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Product specifications are stored at two different places, the `PredictionProductV1`
|
|
239
|
+
object is stored on-chain in the Product Registry contract, while the rest of the
|
|
240
|
+
product specification is referred to as _extended metadata_ and it is uploaded to IPFS.
|
|
241
|
+
|
|
242
|
+
The first step therefore is to upload the extended metadata of the product to
|
|
243
|
+
IPFS and to pin the root node of the DAG. `product.pin()` returns a modified
|
|
244
|
+
copy of the specification that incudes the extended metadata CID.
|
|
245
|
+
|
|
246
|
+
```py
|
|
247
|
+
pinned_specification = product.pin(specification)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The product can then be registered with the Product Registry contract via a
|
|
251
|
+
blockchain transaction.
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
tx = product.register(
|
|
255
|
+
pinned_specification, initial_builder_stake=Decimal("10")
|
|
256
|
+
)
|
|
257
|
+
```
|
|
258
|
+
|
|
190
259
|
See further code examples in the [examples](./examples/) directory.
|
|
191
260
|
|
|
192
261
|
## Development
|
|
193
262
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- Install dependencies with the `uv sync` command.
|
|
197
|
-
- Execute linters with the `uv run poe lint` command.
|
|
198
|
-
- Run tests with the `uv run poe test` command.
|
|
199
|
-
- Check distributions before release with the `uv run poe check-dist` command.
|
|
200
|
-
- Generate markdown API documentation with the `uv run poe doc-gen` command.
|
|
263
|
+
See [DEVELOPMENT.md](./DEVELOPMENT.md) for developer documentation.
|
|
@@ -162,14 +162,73 @@ fills = trading.order_fills(product_id=PRODUCT_ID)
|
|
|
162
162
|
print(fills)
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
+
### Product API
|
|
166
|
+
|
|
167
|
+
Use the `Product` session object to validate a product schema, pin the
|
|
168
|
+
specification to IPFS, and register it on-chain.
|
|
169
|
+
|
|
170
|
+
In order to use the product API for product building, connection parameters of
|
|
171
|
+
an IPFS pinning service like [Filebase](https://filebase.com/) should be
|
|
172
|
+
included in the `AFP` constructor parameters.
|
|
173
|
+
|
|
174
|
+
```py
|
|
175
|
+
IPFS_API_URL = "https://rpc.filebase.io"
|
|
176
|
+
IPFS_API_KEY = os.environ["IPFS_API_KEY"]
|
|
177
|
+
|
|
178
|
+
app = afp.AFP(
|
|
179
|
+
rpc_url=AUTONITY_RPC_URL,
|
|
180
|
+
authenticator=afp.PrivateKeyAuthenticator(PRIVATE_KEY),
|
|
181
|
+
ipfs_api_url=IPFS_API_URL,
|
|
182
|
+
ipfs_api_key=IPFS_API_KEY,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
product = app.Product()
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
A JSON product specification can be parsed and validated with
|
|
189
|
+
`product.validate_json()`.
|
|
190
|
+
|
|
191
|
+
```py
|
|
192
|
+
with open("product-spec.json") as spec_file:
|
|
193
|
+
specification = product.validate_json(spec_file.read())
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Alternatively, it can also be validated from a Python dictionary.
|
|
197
|
+
|
|
198
|
+
```py
|
|
199
|
+
spec_dict = {
|
|
200
|
+
"product": {...},
|
|
201
|
+
"outcome_space": {...},
|
|
202
|
+
"outcome_point": {...},
|
|
203
|
+
"oracle_config": {...},
|
|
204
|
+
"oracle_fallback": {...},
|
|
205
|
+
}
|
|
206
|
+
specification = product.validate(spec_dict)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Product specifications are stored at two different places, the `PredictionProductV1`
|
|
210
|
+
object is stored on-chain in the Product Registry contract, while the rest of the
|
|
211
|
+
product specification is referred to as _extended metadata_ and it is uploaded to IPFS.
|
|
212
|
+
|
|
213
|
+
The first step therefore is to upload the extended metadata of the product to
|
|
214
|
+
IPFS and to pin the root node of the DAG. `product.pin()` returns a modified
|
|
215
|
+
copy of the specification that incudes the extended metadata CID.
|
|
216
|
+
|
|
217
|
+
```py
|
|
218
|
+
pinned_specification = product.pin(specification)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The product can then be registered with the Product Registry contract via a
|
|
222
|
+
blockchain transaction.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
tx = product.register(
|
|
226
|
+
pinned_specification, initial_builder_stake=Decimal("10")
|
|
227
|
+
)
|
|
228
|
+
```
|
|
229
|
+
|
|
165
230
|
See further code examples in the [examples](./examples/) directory.
|
|
166
231
|
|
|
167
232
|
## Development
|
|
168
233
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- Install dependencies with the `uv sync` command.
|
|
172
|
-
- Execute linters with the `uv run poe lint` command.
|
|
173
|
-
- Run tests with the `uv run poe test` command.
|
|
174
|
-
- Check distributions before release with the `uv run poe check-dist` command.
|
|
175
|
-
- Generate markdown API documentation with the `uv run poe doc-gen` command.
|
|
234
|
+
See [DEVELOPMENT.md](./DEVELOPMENT.md) for developer documentation.
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Autonomous Futures Protocol Python SDK."""
|
|
2
2
|
|
|
3
|
-
from . import bindings
|
|
3
|
+
from . import bindings, enums, exceptions, schemas
|
|
4
4
|
from .afp import AFP
|
|
5
5
|
from .auth import Authenticator, KeyfileAuthenticator, PrivateKeyAuthenticator
|
|
6
6
|
from .exceptions import AFPException
|
|
7
7
|
|
|
8
8
|
__all__ = (
|
|
9
9
|
"bindings",
|
|
10
|
+
"enums",
|
|
11
|
+
"exceptions",
|
|
12
|
+
"schemas",
|
|
10
13
|
"AFP",
|
|
11
14
|
"AFPException",
|
|
12
15
|
"Authenticator",
|
|
@@ -27,6 +27,13 @@ class AFP:
|
|
|
27
27
|
The REST API base URL of the exchange. Defaults to the URL of the AutEx
|
|
28
28
|
exchange. Its default value can be overridden with the `AFP_EXCHANGE_URL`
|
|
29
29
|
environment variable.
|
|
30
|
+
ipfs_api_url : str, optional
|
|
31
|
+
The RPC API root URL of an IPFS node that supports Kubo RPC API v0, required
|
|
32
|
+
for product registration. Defaults to the URL of a local IPFS node. Its default
|
|
33
|
+
value can be overridden with the `AFP_IPFS_API_URL` environment variable.
|
|
34
|
+
ipfs_api_key : str, optional
|
|
35
|
+
The access token to include in API requests to the IPFS client. Its default
|
|
36
|
+
value can be overridden with the `AFP_IPFS_API_KEY` environment variable.
|
|
30
37
|
chain_id : str, optional
|
|
31
38
|
The chain ID of the Autonity network. Defauls to the chain ID of Autonity
|
|
32
39
|
Mainnet. Its default value can be overridden with the `AFP_CHAIN_ID` environment
|
|
@@ -79,6 +86,8 @@ class AFP:
|
|
|
79
86
|
authenticator: Authenticator | None = None,
|
|
80
87
|
rpc_url: str | None = defaults.RPC_URL,
|
|
81
88
|
exchange_url: str = defaults.EXCHANGE_URL,
|
|
89
|
+
ipfs_api_url: str = defaults.IPFS_API_URL,
|
|
90
|
+
ipfs_api_key: str | None = defaults.IPFS_API_KEY,
|
|
82
91
|
chain_id: int = defaults.CHAIN_ID,
|
|
83
92
|
gas_limit: int | None = defaults.GAS_LIMIT,
|
|
84
93
|
max_fee_per_gas: int | None = defaults.MAX_FEE_PER_GAS,
|
|
@@ -97,6 +106,8 @@ class AFP:
|
|
|
97
106
|
authenticator=authenticator,
|
|
98
107
|
exchange_url=exchange_url,
|
|
99
108
|
rpc_url=rpc_url,
|
|
109
|
+
ipfs_api_url=ipfs_api_url,
|
|
110
|
+
ipfs_api_key=ipfs_api_key,
|
|
100
111
|
chain_id=chain_id,
|
|
101
112
|
gas_limit=gas_limit,
|
|
102
113
|
max_fee_per_gas=max_fee_per_gas,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .. import validators
|
|
2
2
|
from ..decorators import refresh_token_on_expiry
|
|
3
3
|
from ..enums import ListingState
|
|
4
|
-
from ..
|
|
4
|
+
from ..dtos import ExchangeProductListingSubmission, ExchangeProductUpdateSubmission
|
|
5
5
|
from .base import ExchangeAPI
|
|
6
6
|
|
|
7
7
|
|
|
@@ -11,11 +11,13 @@ from web3.contract.contract import ContractFunction
|
|
|
11
11
|
from web3.types import TxParams
|
|
12
12
|
|
|
13
13
|
from ..auth import Authenticator
|
|
14
|
-
from ..config import Config
|
|
15
14
|
from ..bindings.erc20 import ERC20
|
|
15
|
+
from ..config import Config
|
|
16
|
+
from ..dtos import LoginSubmission
|
|
16
17
|
from ..exceptions import ConfigurationError
|
|
17
18
|
from ..exchange import ExchangeClient
|
|
18
|
-
from ..
|
|
19
|
+
from ..ipfs import IPFSClient
|
|
20
|
+
from ..schemas import Transaction
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class BaseAPI(ABC):
|
|
@@ -127,3 +129,10 @@ class ExchangeAPI(BaseAPI, ABC):
|
|
|
127
129
|
statement=None,
|
|
128
130
|
)
|
|
129
131
|
return message.prepare_message()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class IPFSManager(ABC):
|
|
135
|
+
_ipfs_client: IPFSClient
|
|
136
|
+
|
|
137
|
+
def __init__(self, config: Config):
|
|
138
|
+
self._ipfs_client = IPFSClient(config.ipfs_api_url, config.ipfs_api_key)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
2
|
from functools import cache
|
|
3
|
-
from typing import Iterable
|
|
4
3
|
|
|
5
4
|
from eth_typing.evm import ChecksumAddress
|
|
6
5
|
from hexbytes import HexBytes
|
|
@@ -9,54 +8,26 @@ from web3.exceptions import ContractCustomError
|
|
|
9
8
|
|
|
10
9
|
from .. import validators
|
|
11
10
|
from ..bindings import (
|
|
12
|
-
BidData,
|
|
13
|
-
ClearingDiamond,
|
|
14
11
|
MarginAccount as MarginContract,
|
|
15
12
|
MarginAccountRegistry,
|
|
16
13
|
ProductRegistry,
|
|
17
|
-
Side as OnChainOrderSide,
|
|
18
14
|
)
|
|
19
15
|
from ..bindings.erc20 import ERC20
|
|
20
16
|
from ..bindings.facade import CLEARING_DIAMOND_ABI
|
|
21
17
|
from ..bindings.margin_account import ABI as MARGIN_CONTRACT_ABI
|
|
22
18
|
from ..bindings.margin_account_registry import ABI as MARGIN_ACCOUNT_REGISTRY_ABI
|
|
23
|
-
from ..bindings.product_registry import ABI as PRODUCT_REGISTRY_ABI
|
|
24
19
|
from ..decorators import convert_web3_error
|
|
25
20
|
from ..exceptions import NotFoundError
|
|
26
|
-
from ..schemas import
|
|
21
|
+
from ..schemas import Position, Transaction
|
|
27
22
|
from .base import ClearingSystemAPI
|
|
28
23
|
|
|
29
24
|
|
|
30
25
|
class MarginAccount(ClearingSystemAPI):
|
|
31
26
|
"""API for managing margin accounts."""
|
|
32
27
|
|
|
33
|
-
### Factories ###
|
|
34
|
-
|
|
35
|
-
@staticmethod
|
|
36
|
-
def create_bid(product_id: str, price: Decimal, quantity: int, side: str) -> Bid:
|
|
37
|
-
"""Create a bid to be submitted to a liquidation auction.
|
|
38
|
-
|
|
39
|
-
Parameters
|
|
40
|
-
----------
|
|
41
|
-
product_id : str
|
|
42
|
-
price: Decimal
|
|
43
|
-
quantity: int
|
|
44
|
-
side: str
|
|
45
|
-
|
|
46
|
-
Returns
|
|
47
|
-
-------
|
|
48
|
-
afp.schemas.Bid
|
|
49
|
-
"""
|
|
50
|
-
return Bid(
|
|
51
|
-
product_id=product_id,
|
|
52
|
-
price=price,
|
|
53
|
-
quantity=quantity,
|
|
54
|
-
side=getattr(OrderSide, side.upper()),
|
|
55
|
-
)
|
|
56
|
-
|
|
57
28
|
### Transactions ###
|
|
58
29
|
|
|
59
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
30
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
60
31
|
def authorize(self, collateral_asset: str, intent_account_id: str) -> Transaction:
|
|
61
32
|
"""Authorizes a blockchain account to submit intents to the clearing system
|
|
62
33
|
using the margin account associated with the collateral asset.
|
|
@@ -79,7 +50,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
79
50
|
self._margin_contract(collateral_asset).authorize(intent_account_id)
|
|
80
51
|
)
|
|
81
52
|
|
|
82
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
53
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
83
54
|
def deposit(
|
|
84
55
|
self, collateral_asset: str, amount: Decimal
|
|
85
56
|
) -> tuple[Transaction, Transaction]:
|
|
@@ -118,7 +89,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
118
89
|
)
|
|
119
90
|
return (tx1, tx2)
|
|
120
91
|
|
|
121
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
92
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
122
93
|
def withdraw(self, collateral_asset: str, amount: Decimal) -> Transaction:
|
|
123
94
|
"""Withdraws the specified amount of collateral tokens from the margin account
|
|
124
95
|
associated with the collateral asset.
|
|
@@ -141,78 +112,9 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
141
112
|
self._margin_contract(collateral_asset).withdraw(token_amount)
|
|
142
113
|
)
|
|
143
114
|
|
|
144
|
-
@convert_web3_error(CLEARING_DIAMOND_ABI)
|
|
145
|
-
def request_liquidation(
|
|
146
|
-
self, margin_account_id: str, collateral_asset: str
|
|
147
|
-
) -> Transaction:
|
|
148
|
-
"""Request a liquidation auction to be started.
|
|
149
|
-
|
|
150
|
-
Parameters
|
|
151
|
-
----------
|
|
152
|
-
margin_account_id : str
|
|
153
|
-
The ID of the margin account to be liquidated.
|
|
154
|
-
collateral_asset : str
|
|
155
|
-
The address of the collateral token that the margin account is trading with.
|
|
156
|
-
|
|
157
|
-
Returns
|
|
158
|
-
-------
|
|
159
|
-
afp.schemas.Transaction
|
|
160
|
-
Transaction parameters.
|
|
161
|
-
"""
|
|
162
|
-
margin_account_id = validators.validate_address(margin_account_id)
|
|
163
|
-
collateral_asset = validators.validate_address(collateral_asset)
|
|
164
|
-
|
|
165
|
-
clearing_contract = ClearingDiamond(
|
|
166
|
-
self._w3, self._config.clearing_diamond_address
|
|
167
|
-
)
|
|
168
|
-
return self._transact(
|
|
169
|
-
clearing_contract.request_liquidation(margin_account_id, collateral_asset)
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
@convert_web3_error(CLEARING_DIAMOND_ABI, PRODUCT_REGISTRY_ABI)
|
|
173
|
-
def submit_bids(
|
|
174
|
-
self, margin_account_id: str, collateral_asset: str, bids: Iterable[Bid]
|
|
175
|
-
) -> Transaction:
|
|
176
|
-
"""Submit bids to a liquidation auction.
|
|
177
|
-
|
|
178
|
-
Parameters
|
|
179
|
-
----------
|
|
180
|
-
margin_account_id : str
|
|
181
|
-
The ID of the margin account that is being liquidated.
|
|
182
|
-
collateral_asset : str
|
|
183
|
-
The address of the collateral token that the margin account is trading with.
|
|
184
|
-
bids: list of afp.schemas.Bid
|
|
185
|
-
|
|
186
|
-
Returns
|
|
187
|
-
-------
|
|
188
|
-
afp.schemas.Transaction
|
|
189
|
-
Transaction parameters.
|
|
190
|
-
"""
|
|
191
|
-
margin_account_id = validators.validate_address(margin_account_id)
|
|
192
|
-
collateral_asset = validators.validate_address(collateral_asset)
|
|
193
|
-
|
|
194
|
-
converted_bids = [
|
|
195
|
-
BidData(
|
|
196
|
-
product_id=HexBytes(bid.product_id),
|
|
197
|
-
price=int(bid.price * 10 ** self._tick_size(bid.product_id)),
|
|
198
|
-
quantity=bid.quantity,
|
|
199
|
-
side=getattr(OnChainOrderSide, bid.side.name),
|
|
200
|
-
)
|
|
201
|
-
for bid in bids
|
|
202
|
-
]
|
|
203
|
-
|
|
204
|
-
clearing_contract = ClearingDiamond(
|
|
205
|
-
self._w3, self._config.clearing_diamond_address
|
|
206
|
-
)
|
|
207
|
-
return self._transact(
|
|
208
|
-
clearing_contract.bid_auction(
|
|
209
|
-
margin_account_id, collateral_asset, converted_bids
|
|
210
|
-
)
|
|
211
|
-
)
|
|
212
|
-
|
|
213
115
|
### Views ###
|
|
214
116
|
|
|
215
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
117
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
216
118
|
def capital(self, collateral_asset: str) -> Decimal:
|
|
217
119
|
"""Returns the amount of collateral tokens in the margin account associated
|
|
218
120
|
with the collateral asset.
|
|
@@ -232,7 +134,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
232
134
|
)
|
|
233
135
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
234
136
|
|
|
235
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
137
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
236
138
|
def position(self, collateral_asset: str, position_id: str) -> Position:
|
|
237
139
|
"""Returns the parameters of a position in the margin account associated with
|
|
238
140
|
the collateral asset.
|
|
@@ -261,7 +163,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
261
163
|
pnl=Decimal(data.pnl) / 10**decimals,
|
|
262
164
|
)
|
|
263
165
|
|
|
264
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
166
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
265
167
|
def positions(self, collateral_asset: str) -> list[Position]:
|
|
266
168
|
"""Returns all positions in the margin account associated with the collateral
|
|
267
169
|
asset.
|
|
@@ -281,7 +183,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
281
183
|
)
|
|
282
184
|
return [self.position(collateral_asset, Web3.to_hex(id)) for id in position_ids]
|
|
283
185
|
|
|
284
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
186
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
285
187
|
def equity(self, collateral_asset: str) -> Decimal:
|
|
286
188
|
"""Returns the margin account equity in the margin account associated with the
|
|
287
189
|
collateral asset.
|
|
@@ -301,7 +203,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
301
203
|
)
|
|
302
204
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
303
205
|
|
|
304
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
206
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
305
207
|
def maintenance_margin_available(self, collateral_asset: str) -> Decimal:
|
|
306
208
|
"""Returns the maintenance margin available in the margin account associated
|
|
307
209
|
with the collateral asset.
|
|
@@ -321,7 +223,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
321
223
|
)
|
|
322
224
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
323
225
|
|
|
324
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
226
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
325
227
|
def maintenance_margin_used(self, collateral_asset: str) -> Decimal:
|
|
326
228
|
"""Returns the maintenance margin used in the margin account associated with
|
|
327
229
|
the collateral asset.
|
|
@@ -341,7 +243,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
341
243
|
)
|
|
342
244
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
343
245
|
|
|
344
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
246
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
345
247
|
def profit_and_loss(self, collateral_asset: str) -> Decimal:
|
|
346
248
|
"""Returns the profit and loss in the margin account associated with the
|
|
347
249
|
collateral asset.
|
|
@@ -361,7 +263,7 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
361
263
|
)
|
|
362
264
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
363
265
|
|
|
364
|
-
@convert_web3_error(MARGIN_CONTRACT_ABI)
|
|
266
|
+
@convert_web3_error(MARGIN_CONTRACT_ABI, CLEARING_DIAMOND_ABI)
|
|
365
267
|
def withdrawable_amount(self, collateral_asset: str) -> Decimal:
|
|
366
268
|
"""Returns the amount of collateral tokens withdrawable from the margin account
|
|
367
269
|
associated with the collateral asset.
|
|
@@ -381,44 +283,6 @@ class MarginAccount(ClearingSystemAPI):
|
|
|
381
283
|
)
|
|
382
284
|
return Decimal(amount) / 10 ** self._decimals(collateral_asset)
|
|
383
285
|
|
|
384
|
-
@convert_web3_error(CLEARING_DIAMOND_ABI)
|
|
385
|
-
def auction_data(
|
|
386
|
-
self, margin_account_id: str, collateral_asset: str
|
|
387
|
-
) -> AuctionData:
|
|
388
|
-
"""Returns information on a liquidation auction.
|
|
389
|
-
|
|
390
|
-
Parameters
|
|
391
|
-
----------
|
|
392
|
-
margin_account_id : str
|
|
393
|
-
The ID of the margin account to be liquidated.
|
|
394
|
-
collateral_asset : str
|
|
395
|
-
The address of the collateral token that the margin account is trading with.
|
|
396
|
-
|
|
397
|
-
Returns
|
|
398
|
-
-------
|
|
399
|
-
str
|
|
400
|
-
The hash of the transaction.
|
|
401
|
-
"""
|
|
402
|
-
margin_account_id = validators.validate_address(margin_account_id)
|
|
403
|
-
collateral_asset = validators.validate_address(collateral_asset)
|
|
404
|
-
|
|
405
|
-
clearing_contract = ClearingDiamond(
|
|
406
|
-
self._w3, self._config.clearing_diamond_address
|
|
407
|
-
)
|
|
408
|
-
data = clearing_contract.auction_data(margin_account_id, collateral_asset)
|
|
409
|
-
divisor = 10 ** self._decimals(collateral_asset)
|
|
410
|
-
return AuctionData(
|
|
411
|
-
start_block=data.start_block,
|
|
412
|
-
margin_account_equity_at_initiation=(
|
|
413
|
-
Decimal(data.mae_at_initiation) / divisor
|
|
414
|
-
),
|
|
415
|
-
maintenance_margin_used_at_initiation=(
|
|
416
|
-
Decimal(data.mmu_at_initiation) / divisor
|
|
417
|
-
),
|
|
418
|
-
margin_account_equity_now=(Decimal(data.mae_now) / divisor),
|
|
419
|
-
maintenance_margin_used_now=(Decimal(data.mmu_now) / divisor),
|
|
420
|
-
)
|
|
421
|
-
|
|
422
286
|
### Internal getters ###
|
|
423
287
|
|
|
424
288
|
@cache
|