polyester-sdk 0.1.0a0__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.
- polyester_sdk-0.1.0a0/.env.example +31 -0
- polyester_sdk-0.1.0a0/.gitignore +27 -0
- polyester_sdk-0.1.0a0/CHANGELOG.md +29 -0
- polyester_sdk-0.1.0a0/LICENSE +7 -0
- polyester_sdk-0.1.0a0/PKG-INFO +236 -0
- polyester_sdk-0.1.0a0/README.md +197 -0
- polyester_sdk-0.1.0a0/SECURITY.md +14 -0
- polyester_sdk-0.1.0a0/examples/basic_bot.py +35 -0
- polyester_sdk-0.1.0a0/pyproject.toml +110 -0
- polyester_sdk-0.1.0a0/src/polyester/__init__.py +32 -0
- polyester_sdk-0.1.0a0/src/polyester/_wire.py +55 -0
- polyester_sdk-0.1.0a0/src/polyester/auth.py +116 -0
- polyester_sdk-0.1.0a0/src/polyester/auth_interceptor.py +43 -0
- polyester_sdk-0.1.0a0/src/polyester/catalogs/__init__.py +157 -0
- polyester_sdk-0.1.0a0/src/polyester/catalogs/zipper.py +71 -0
- polyester_sdk-0.1.0a0/src/polyester/catalogs/zipper_supply.py +84 -0
- polyester_sdk-0.1.0a0/src/polyester/client.py +486 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/__init__.py +30 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/address_book.py +73 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/__init__.py +95 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/address_book.py +458 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/api_keys.py +57 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/auth.py +56 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/balances.py +119 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/common.py +8 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/deposit.py +28 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/guard_signer.py +78 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/heatmap.py +9 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/internal_transfers.py +16 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/ledger_write.py +15 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/lifecycle.py +72 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/market_data.py +88 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/market_overview.py +23 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/orderbook.py +39 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/orders.py +172 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/policies.py +146 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/resolve.py +21 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/sub_accounts.py +166 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/transfers.py +31 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/triggers.py +111 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/withdraw.py +11 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/decode/zipper.py +116 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/enums.py +25 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/guard_signer.py +55 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/heatmap.py +34 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/ledger.py +34 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/ledger_amounts.py +17 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/ledger_write.py +104 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/orderbook.py +20 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/orders.py +361 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/proto_build.py +28 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/proto_helpers.py +80 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/realtime_decode.py +186 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/scalars.py +130 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/triggers.py +135 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/wire_decode.py +652 -0
- polyester_sdk-0.1.0a0/src/polyester/codecs/withdraw.py +66 -0
- polyester_sdk-0.1.0a0/src/polyester/connect_transport.py +85 -0
- polyester_sdk-0.1.0a0/src/polyester/errors.py +59 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/address_book_connect.py +976 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/address_book_pb2.py +412 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/address_book_pb2.pyi +640 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/api_keys_connect.py +391 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/api_keys_pb2.py +114 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/api_keys_pb2.pyi +142 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/auth_connect.py +261 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/auth_pb2.py +81 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/auth_pb2.pyi +158 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/mfa_connect.py +1041 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/mfa_pb2.py +231 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/mfa_pb2.pyi +299 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/policies_connect.py +846 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/policies_pb2.py +218 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/policies_pb2.pyi +436 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/profile_connect.py +261 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/profile_pb2.py +93 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/profile_pb2.pyi +113 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/resolve_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/resolve_pb2.py +55 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/resolve_pb2.pyi +53 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/social_verification_connect.py +261 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/social_verification_pb2.py +80 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/social_verification_pb2.pyi +127 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/subaccounts_connect.py +888 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/subaccounts_pb2.py +221 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/auth/v1/subaccounts_pb2.pyi +369 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/buf/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/buf/validate/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/buf/validate/validate_pb2.py +450 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/buf/validate/validate_pb2.pyi +627 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/analytics/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/analytics/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/analytics/v1/analytics_read_connect.py +261 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/analytics/v1/analytics_read_pb2.py +98 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/analytics/v1/analytics_read_pb2.pyi +132 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/deposit/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/deposit/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/deposit/v1/deposit_connect.py +196 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/deposit/v1/deposit_pb2.py +62 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/deposit/v1/deposit_pb2.pyi +46 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/guard/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/guard/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/guard/v1/guard_signer_connect.py +456 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/guard/v1/guard_signer_pb2.py +124 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/guard/v1/guard_signer_pb2.pyi +170 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/lifecycle_read_connect.py +261 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/lifecycle_read_pb2.py +132 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/lifecycle_read_pb2.pyi +396 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/types_pb2.py +52 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/lifecycle/v1/types_pb2.pyi +118 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/withdraw/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/withdraw/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/withdraw/v1/withdraw_connect.py +196 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/withdraw/v1/withdraw_pb2.py +79 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/withdraw/v1/withdraw_pb2.pyi +72 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/zipper/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/zipper/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/zipper/v1/zipper_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/zipper/v1/zipper_pb2.py +58 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/chain/zipper/v1/zipper_pb2.pyi +130 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/collab/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/collab/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/collab/v1/whiteboard_connect.py +521 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/collab/v1/whiteboard_pb2.py +155 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/collab/v1/whiteboard_pb2.pyi +259 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/v3/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/v3/annotations_pb2.py +37 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/v3/annotations_pb2.pyi +14 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/v3/openapiv3_pb2.py +192 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/gnostic/openapi/v3/openapiv3_pb2.pyi +895 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/annotations_pb2.py +37 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/annotations_pb2.pyi +8 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/field_behavior_pb2.py +40 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/field_behavior_pb2.pyi +29 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/http_pb2.py +41 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/google/api/http_pb2.pyi +47 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/layout/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/layout/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/layout/v1/layout_connect.py +1041 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/layout/v1/layout_pb2.py +194 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/layout/v1/layout_pb2.pyi +384 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/read/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/read/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/read/v1/ledger_read_connect.py +456 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/read/v1/ledger_read_pb2.py +113 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/read/v1/ledger_read_pb2.pyi +318 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/v1/catalog_pb2.py +39 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/v1/catalog_pb2.pyi +43 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/write/v1/ledger_write_connect.py +326 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/write/v1/ledger_write_pb2.py +55 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/ledger/write/v1/ledger_write_pb2.pyi +98 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/heatmap_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/heatmap_pb2.py +92 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/heatmap_pb2.pyi +194 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/marketdata_connect.py +326 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/marketdata_pb2.py +116 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketdata/v1/marketdata_pb2.pyi +289 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketoverview/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketoverview/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketoverview/v1/marketoverview_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketoverview/v1/marketoverview_pb2.py +77 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/marketoverview/v1/marketoverview_pb2.pyi +144 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orderbook/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orderbook/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orderbook/v1/orderbook_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orderbook/v1/orderbook_pb2.py +58 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orderbook/v1/orderbook_pb2.pyi +86 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_connect.py +586 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_pb2.py +257 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_pb2.pyi +634 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_read_connect.py +326 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_read_pb2.py +145 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/orders/v1/orders_read_pb2.pyi +347 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/events/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/events/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/events/v1/polychart_events_pb2.py +50 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/events/v1/polychart_events_pb2.pyi +71 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/v1/polychart_connect.py +1041 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/v1/polychart_pb2.py +171 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polychart/v1/polychart_pb2.pyi +355 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/options_pb2.py +36 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/options_pb2.pyi +9 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/validation/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/validation/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/validation/v1/predefined_string_rules_pb2.py +42 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/api/validation/v1/predefined_string_rules_pb2.pyi +11 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/type/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/type/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/type/v1/u128_pb2.py +37 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/polyester/type/v1/u128_pb2.pyi +13 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/tradews/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/tradews/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/tradews/v1/trade_ws_pb2.py +52 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/tradews/v1/trade_ws_pb2.pyi +91 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/transfer/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/transfer/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/transfer/v1/internal_transfer_connect.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/transfer/v1/internal_transfer_pb2.py +66 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/transfer/v1/internal_transfer_pb2.pyi +71 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/triggers/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/triggers/v1/__init__.py +0 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/triggers/v1/triggers_connect.py +586 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/triggers/v1/triggers_pb2.py +171 -0
- polyester_sdk-0.1.0a0/src/polyester/gen/triggers/v1/triggers_pb2.pyi +430 -0
- polyester_sdk-0.1.0a0/src/polyester/market_overview/__init__.py +3 -0
- polyester_sdk-0.1.0a0/src/polyester/market_overview/subscription.py +49 -0
- polyester_sdk-0.1.0a0/src/polyester/models/__init__.py +255 -0
- polyester_sdk-0.1.0a0/src/polyester/models/address_book.py +212 -0
- polyester_sdk-0.1.0a0/src/polyester/models/auth.py +52 -0
- polyester_sdk-0.1.0a0/src/polyester/models/common.py +66 -0
- polyester_sdk-0.1.0a0/src/polyester/models/guard_signer.py +34 -0
- polyester_sdk-0.1.0a0/src/polyester/models/market.py +46 -0
- polyester_sdk-0.1.0a0/src/polyester/models/policies.py +71 -0
- polyester_sdk-0.1.0a0/src/polyester/models/realtime.py +17 -0
- polyester_sdk-0.1.0a0/src/polyester/models/sub_accounts.py +93 -0
- polyester_sdk-0.1.0a0/src/polyester/models/trading.py +306 -0
- polyester_sdk-0.1.0a0/src/polyester/models/zipper.py +114 -0
- polyester_sdk-0.1.0a0/src/polyester/orderbook/__init__.py +17 -0
- polyester_sdk-0.1.0a0/src/polyester/orderbook/local_book.py +166 -0
- polyester_sdk-0.1.0a0/src/polyester/orderbook/subscription.py +55 -0
- polyester_sdk-0.1.0a0/src/polyester/py.typed +1 -0
- polyester_sdk-0.1.0a0/src/polyester/realtime/__init__.py +16 -0
- polyester_sdk-0.1.0a0/src/polyester/realtime/auth.py +66 -0
- polyester_sdk-0.1.0a0/src/polyester/realtime/client.py +234 -0
- polyester_sdk-0.1.0a0/src/polyester/realtime/snapshot_then_stream.py +144 -0
- polyester_sdk-0.1.0a0/src/polyester/services/__init__.py +59 -0
- polyester_sdk-0.1.0a0/src/polyester/services/_base.py +47 -0
- polyester_sdk-0.1.0a0/src/polyester/services/_generated.py +84 -0
- polyester_sdk-0.1.0a0/src/polyester/services/_realtime_subscribe.py +42 -0
- polyester_sdk-0.1.0a0/src/polyester/services/_scope.py +92 -0
- polyester_sdk-0.1.0a0/src/polyester/services/_symbols.py +24 -0
- polyester_sdk-0.1.0a0/src/polyester/services/address_book.py +424 -0
- polyester_sdk-0.1.0a0/src/polyester/services/api_keys.py +173 -0
- polyester_sdk-0.1.0a0/src/polyester/services/auth.py +25 -0
- polyester_sdk-0.1.0a0/src/polyester/services/balances.py +171 -0
- polyester_sdk-0.1.0a0/src/polyester/services/chain_analytics.py +104 -0
- polyester_sdk-0.1.0a0/src/polyester/services/deposit.py +67 -0
- polyester_sdk-0.1.0a0/src/polyester/services/guard_signer.py +191 -0
- polyester_sdk-0.1.0a0/src/polyester/services/heatmap.py +143 -0
- polyester_sdk-0.1.0a0/src/polyester/services/internal_transfers.py +77 -0
- polyester_sdk-0.1.0a0/src/polyester/services/layout.py +200 -0
- polyester_sdk-0.1.0a0/src/polyester/services/ledger_write.py +128 -0
- polyester_sdk-0.1.0a0/src/polyester/services/lifecycle.py +166 -0
- polyester_sdk-0.1.0a0/src/polyester/services/market_data.py +251 -0
- polyester_sdk-0.1.0a0/src/polyester/services/market_overview.py +131 -0
- polyester_sdk-0.1.0a0/src/polyester/services/orderbook.py +233 -0
- polyester_sdk-0.1.0a0/src/polyester/services/orders.py +429 -0
- polyester_sdk-0.1.0a0/src/polyester/services/policies.py +450 -0
- polyester_sdk-0.1.0a0/src/polyester/services/polychart.py +208 -0
- polyester_sdk-0.1.0a0/src/polyester/services/profile.py +70 -0
- polyester_sdk-0.1.0a0/src/polyester/services/resolve.py +53 -0
- polyester_sdk-0.1.0a0/src/polyester/services/social_verification.py +74 -0
- polyester_sdk-0.1.0a0/src/polyester/services/sub_accounts.py +398 -0
- polyester_sdk-0.1.0a0/src/polyester/services/trades.py +78 -0
- polyester_sdk-0.1.0a0/src/polyester/services/transfers.py +66 -0
- polyester_sdk-0.1.0a0/src/polyester/services/triggers.py +299 -0
- polyester_sdk-0.1.0a0/src/polyester/services/whiteboard.py +139 -0
- polyester_sdk-0.1.0a0/src/polyester/services/withdraw.py +144 -0
- polyester_sdk-0.1.0a0/src/polyester/services/zipper.py +85 -0
- polyester_sdk-0.1.0a0/src/polyester/sync_subscribe.py +86 -0
- polyester_sdk-0.1.0a0/src/polyester/transport.py +94 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
POLYESTER_API_KEY_ID=ak_your_key_id_here
|
|
2
|
+
POLYESTER_API_PRIVATE_KEY=your_64_char_ed25519_private_key_hex
|
|
3
|
+
|
|
4
|
+
# Profile account id (base58) for scoped ledger operations
|
|
5
|
+
POLYESTER_ACCOUNT_ID=your_base58_account_id_here
|
|
6
|
+
|
|
7
|
+
# Live test tiers (local only — not used in CI)
|
|
8
|
+
# POLYESTER_TEST_MUTATION=1
|
|
9
|
+
# POLYESTER_TEST_FUNDED=1
|
|
10
|
+
# POLYESTER_TEST_TREASURY=1
|
|
11
|
+
# POLYESTER_TEST_SMOKE_SYMBOL=ETH-USDT
|
|
12
|
+
# POLYESTER_TEST_MIN_TRADING_QUOTE=10
|
|
13
|
+
# POLYESTER_TEST_INTERNAL_TRANSFER_DEST=
|
|
14
|
+
# POLYESTER_TEST_SKIP_FUNDING_CHECK=1
|
|
15
|
+
# POLYESTER_TEST_TRADE_E2E=1
|
|
16
|
+
# POLYESTER_TEST_TRADE_SYMBOL=BTC-USDT
|
|
17
|
+
# Optional deterministic maker account for fill e2e (otherwise uses visible devnet asks)
|
|
18
|
+
# POLYESTER_TEST_MAKER_API_KEY_ID=
|
|
19
|
+
# POLYESTER_TEST_MAKER_API_PRIVATE_KEY=
|
|
20
|
+
# POLYESTER_TEST_TRADE_PRICE=500000
|
|
21
|
+
# POLYESTER_TEST_TRADE_QTY=
|
|
22
|
+
|
|
23
|
+
# Opt-in ledger_write mutation smoke (route may be unmounted on devnet)
|
|
24
|
+
# POLYESTER_TEST_LEDGER_WRITE_SMOKE=1
|
|
25
|
+
|
|
26
|
+
# Legacy smoke aliases (still supported)
|
|
27
|
+
# POLYESTER_SMOKE_MUTATION=1
|
|
28
|
+
# POLYESTER_SMOKE_SYMBOL=BTC-USDT
|
|
29
|
+
|
|
30
|
+
# Optional overrides (defaults to devnet)
|
|
31
|
+
# POLYESTER_API_URL=https://api-devnet.polyester.ai
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.env
|
|
2
|
+
.env.*
|
|
3
|
+
!.env.example
|
|
4
|
+
|
|
5
|
+
docs/
|
|
6
|
+
|
|
7
|
+
.coverage
|
|
8
|
+
.coverage.*
|
|
9
|
+
htmlcov/
|
|
10
|
+
|
|
11
|
+
*.egg-info/
|
|
12
|
+
*.py[cod]
|
|
13
|
+
__pycache__/
|
|
14
|
+
|
|
15
|
+
.venv/
|
|
16
|
+
.python-version
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
.tox/
|
|
21
|
+
.nox/
|
|
22
|
+
|
|
23
|
+
build/
|
|
24
|
+
dist/
|
|
25
|
+
pip-wheel-metadata/
|
|
26
|
+
|
|
27
|
+
.DS_Store
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### SDK surface
|
|
6
|
+
- Orders: `batch_create`, `batch_cancel`, `cancel_all_after`; `cancel(symbol=…)` resolves `symbol_id`
|
|
7
|
+
- API keys: `create`, `update`, `delete`
|
|
8
|
+
- Withdraw: `create_wallet_trading_withdraw`
|
|
9
|
+
- Address book: full CRUD, views, whitelist, counterparties
|
|
10
|
+
- New services: `policies`, `sub_accounts`, `guard_signer`
|
|
11
|
+
- `market_overview.create_subscription()` — snapshot-then-stream merge (TS parity)
|
|
12
|
+
|
|
13
|
+
### Codecs
|
|
14
|
+
- Proto decode migration for balances history/equity/holds, triggers, transfers, deposit, withdraw, internal transfers, api keys, resolve, and public market services
|
|
15
|
+
- `order_mutation_from_proto` handles `CancelOrderResponse` (no `client_order_id` field)
|
|
16
|
+
|
|
17
|
+
### Testing
|
|
18
|
+
- Restructured `tests/unit`, `tests/integration`, `tests/e2e`, `tests/e2e/funded`
|
|
19
|
+
- Pytest markers: `integration`, `smoke`, `mutation`, `funded`, `treasury`, `optional`, `realtime`
|
|
20
|
+
- `POLYESTER_TEST_TRADE_SYMBOL` for order/trigger mutation (separate from `POLYESTER_TEST_SMOKE_SYMBOL`)
|
|
21
|
+
- Dynamic mutation pricing from `market_overview` (~2% of last trade)
|
|
22
|
+
- `test_orders_get_round_trips_list_open` — proof-style when open orders exist
|
|
23
|
+
- `scripts/test_all.sh` and `scripts/smoke_test.py` (pytest wrapper)
|
|
24
|
+
- CI: `pytest tests/unit` with coverage on non-`gen/` code
|
|
25
|
+
- Full devnet suite documents honest skips for OMS read lag, JWT routes, optional mounts, and account-specific prerequisites
|
|
26
|
+
|
|
27
|
+
## 0.1.0a0
|
|
28
|
+
|
|
29
|
+
- Initial alpha release with core trading and market data services.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) Fabric Blockchain Labs Inc.
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This repository contains generated and handwritten SDK code for the Polyester
|
|
6
|
+
API. No license is granted to copy, modify, distribute, sublicense, or use this
|
|
7
|
+
work except under a separate written agreement with Fabric Blockchain Labs Inc.
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: polyester-sdk
|
|
3
|
+
Version: 0.1.0a0
|
|
4
|
+
Summary: Official Python SDK for Polyester APIs.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Fabric-Labs/polyester-sdk-python
|
|
6
|
+
Project-URL: Documentation, https://polyester.ai/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/Fabric-Labs/polyester-sdk-python
|
|
8
|
+
Project-URL: Issues, https://github.com/Fabric-Labs/polyester-sdk-python/issues
|
|
9
|
+
Author: Fabric Blockchain Labs Inc.
|
|
10
|
+
License: Proprietary
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: connectrpc,polyester,protobuf,sdk,trading
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: base58>=2.1.1
|
|
22
|
+
Requires-Dist: connectrpc>=0.9.0
|
|
23
|
+
Requires-Dist: cryptography>=42
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: msgspec>=0.18
|
|
26
|
+
Requires-Dist: protobuf>=7.35.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy>=1.13; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
33
|
+
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
35
|
+
Requires-Dist: twine>=5; extra == 'dev'
|
|
36
|
+
Provides-Extra: realtime
|
|
37
|
+
Requires-Dist: websockets>=15; extra == 'realtime'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# Polyester Python SDK
|
|
41
|
+
|
|
42
|
+
Official Python SDK for Polyester APIs, built for trading bots, backend jobs,
|
|
43
|
+
research notebooks, and automation.
|
|
44
|
+
|
|
45
|
+
**Status:** Alpha (`0.1.0a0`). The repo is **public** (visible on GitHub) under a
|
|
46
|
+
**proprietary** license — not open source. API-key-only; no browser or JWT flows.
|
|
47
|
+
|
|
48
|
+
Generated protobuf types and ConnectRPC clients live in `src/polyester/gen/` and are
|
|
49
|
+
updated automatically when public API protos change. Hand-written SDK code (client,
|
|
50
|
+
services, models, codecs) lives alongside them under `src/polyester/`.
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
Install the SDK from PyPI:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install "polyester-sdk[realtime]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For local development from a checkout:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cd polyester-sdk-python
|
|
64
|
+
python3.11 -m venv .venv
|
|
65
|
+
source .venv/bin/activate
|
|
66
|
+
pip install -e ".[dev,realtime]"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Authentication
|
|
70
|
+
|
|
71
|
+
Pass credentials to the client from your app's config or secrets manager:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from polyester import AsyncPolyester
|
|
75
|
+
|
|
76
|
+
client = AsyncPolyester(
|
|
77
|
+
api_key_id="ak_...",
|
|
78
|
+
api_private_key="...", # 64-char hex Ed25519 secret or raw 32-byte key
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If your app uses environment variables, read them in your application code and pass
|
|
83
|
+
them explicitly:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import os
|
|
87
|
+
|
|
88
|
+
from polyester import AsyncPolyester
|
|
89
|
+
|
|
90
|
+
client = AsyncPolyester(
|
|
91
|
+
api_key_id=os.environ["POLYESTER_API_KEY_ID"],
|
|
92
|
+
api_private_key=os.environ["POLYESTER_API_PRIVATE_KEY"],
|
|
93
|
+
default_account_id=os.getenv("POLYESTER_ACCOUNT_ID"),
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For scripts and local tests, `AsyncPolyester.from_env()` and `Polyester.from_env()`
|
|
98
|
+
are convenience helpers that read `POLYESTER_*` from `os.environ`. The plain
|
|
99
|
+
constructor does not implicitly read environment variables.
|
|
100
|
+
|
|
101
|
+
## Quickstart
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from polyester import AsyncPolyester
|
|
105
|
+
|
|
106
|
+
async with AsyncPolyester(
|
|
107
|
+
api_key_id="ak_...",
|
|
108
|
+
api_private_key="...",
|
|
109
|
+
) as client:
|
|
110
|
+
overview = await client.market_overview.list(limit=5)
|
|
111
|
+
for market in overview.markets:
|
|
112
|
+
print(market.symbol, market.last_price_ticks)
|
|
113
|
+
|
|
114
|
+
open_orders = await client.orders.list_open()
|
|
115
|
+
print(f"{len(open_orders.orders)} open orders")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Create And Cancel
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from polyester import AsyncPolyester
|
|
122
|
+
|
|
123
|
+
async with AsyncPolyester(
|
|
124
|
+
api_key_id="ak_...",
|
|
125
|
+
api_private_key="...",
|
|
126
|
+
default_sub_account_id="",
|
|
127
|
+
) as client:
|
|
128
|
+
result = await client.orders.create(
|
|
129
|
+
symbol="BNB-USDT",
|
|
130
|
+
side="buy",
|
|
131
|
+
order_type="limit",
|
|
132
|
+
tif="gtc",
|
|
133
|
+
qty="0.01",
|
|
134
|
+
price="100",
|
|
135
|
+
post_only=True,
|
|
136
|
+
client_order_id="my-bot-001",
|
|
137
|
+
)
|
|
138
|
+
print(result.status, result.order_id)
|
|
139
|
+
|
|
140
|
+
await client.orders.cancel(client_order_id="my-bot-001")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use **decimal strings** for `qty` and `price`. Do not pass floats.
|
|
144
|
+
|
|
145
|
+
## Balances: funding vs trading
|
|
146
|
+
|
|
147
|
+
Ledger balances expose separate **funding** and **trading** buckets per asset. Spot
|
|
148
|
+
orders spend **trading** balance. Deposits land in **funding** until you move them
|
|
149
|
+
(Funding → Unified Trading in the UI or on-chain via the funding wallet).
|
|
150
|
+
|
|
151
|
+
- **Funding → trading:** on-chain `TradingGateway.deposit` (not an API-key RPC).
|
|
152
|
+
- **Trading → funding:** `client.trading_withdraws.create_to_funding(...)` with a signed intent payload.
|
|
153
|
+
- **Trading → trading (another account):** `client.internal_transfers.create(...)` or `client.ledger_write.transfer_trading_to_trading(...)`.
|
|
154
|
+
|
|
155
|
+
Format u128 wire amounts with the public helper (18-decimal scale):
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from polyester import format_ledger_u128
|
|
159
|
+
|
|
160
|
+
print(format_ledger_u128(balance.funding), format_ledger_u128(balance.trading))
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Set `POLYESTER_ACCOUNT_ID` to your profile base58 id (not a raw decimal uint64) for
|
|
164
|
+
bucket transfers.
|
|
165
|
+
|
|
166
|
+
## Public Market Data
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
candles = await client.market_data.get_candles(symbol="BTC-USDT", timeframe="1m", limit=50)
|
|
170
|
+
current = await client.market_data.get_current_candle(symbol="BTC-USDT", timeframe="1m")
|
|
171
|
+
trades = await client.market_data.get_trades(symbol="BTC-USDT", limit=20)
|
|
172
|
+
health = await client.balances.get_health()
|
|
173
|
+
|
|
174
|
+
async with client.market_data.subscribe_trades(symbol="BNB-USDT") as sub:
|
|
175
|
+
async for trade in sub:
|
|
176
|
+
print(trade.price_ticks, trade.qty_scaled)
|
|
177
|
+
break
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Realtime requires `pip install polyester-sdk[realtime]` (websockets).
|
|
181
|
+
|
|
182
|
+
Merged market overview stream (snapshot + live updates):
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
sub = await client.market_overview.create_subscription()
|
|
186
|
+
async for markets in sub:
|
|
187
|
+
print(len(markets), "rows")
|
|
188
|
+
break
|
|
189
|
+
await sub.aclose()
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Testing
|
|
193
|
+
|
|
194
|
+
**CI (no network):** `pytest tests/unit -q`, plus ruff and package build.
|
|
195
|
+
|
|
196
|
+
**Full local suite:** devnet integration/e2e tests read `.env` in the test harness and pass credentials to the client as explicit constructor parameters.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
cp .env.example .env
|
|
200
|
+
# POLYESTER_API_KEY_ID, POLYESTER_API_PRIVATE_KEY, POLYESTER_ACCOUNT_ID
|
|
201
|
+
|
|
202
|
+
pip install -e ".[dev,realtime]"
|
|
203
|
+
|
|
204
|
+
./scripts/test_all.sh # unit + tiered live (reads .env flags)
|
|
205
|
+
# or
|
|
206
|
+
pytest tests/unit -q # CI-equivalent
|
|
207
|
+
pytest tests/ -v # full suite
|
|
208
|
+
python scripts/smoke_test.py # backwards-compatible read/mutation wrapper
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Useful markers include `smoke`, `mutation`, `funded`, `treasury`, `optional`, `realtime`, and `jwt_session`.
|
|
212
|
+
|
|
213
|
+
### Known devnet skips (not SDK failures)
|
|
214
|
+
|
|
215
|
+
| Skip reason | Tests affected |
|
|
216
|
+
|-------------|----------------|
|
|
217
|
+
| OMS read never indexes after `orders.create` | `test_order_round_trip`, `test_batch_create_and_cancel` |
|
|
218
|
+
| No open orders on book | `test_orders_get_round_trips_list_open` |
|
|
219
|
+
| `list_holds` unmounted | balance holds tests |
|
|
220
|
+
| JWT/session-only routes | profile, whiteboard, resolve, etc. |
|
|
221
|
+
| Guard signer not on account | `test_guard_signer_get_status` |
|
|
222
|
+
| No BTC-USDT asks / `POLYESTER_TEST_TRADE_E2E` | `test_spot_fill` |
|
|
223
|
+
|
|
224
|
+
Attach a **read/trade policy** to your API key. Spot orders need **USDT in unified trading** (not BTC).
|
|
225
|
+
|
|
226
|
+
Some RPCs return HTTP 404 on devnet. The SDK raises `PolyesterRouteNotFoundError` with a clearer message than `[unimplemented]: Not Found`.
|
|
227
|
+
|
|
228
|
+
## Changelog
|
|
229
|
+
|
|
230
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
231
|
+
|
|
232
|
+
## Transport
|
|
233
|
+
|
|
234
|
+
Connect RPC over HTTP via generated clients in `src/polyester/gen/`. Wire format
|
|
235
|
+
defaults to **binary protobuf**; pass `wire_format="json"` for debugging.
|
|
236
|
+
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Polyester Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for Polyester APIs, built for trading bots, backend jobs,
|
|
4
|
+
research notebooks, and automation.
|
|
5
|
+
|
|
6
|
+
**Status:** Alpha (`0.1.0a0`). The repo is **public** (visible on GitHub) under a
|
|
7
|
+
**proprietary** license — not open source. API-key-only; no browser or JWT flows.
|
|
8
|
+
|
|
9
|
+
Generated protobuf types and ConnectRPC clients live in `src/polyester/gen/` and are
|
|
10
|
+
updated automatically when public API protos change. Hand-written SDK code (client,
|
|
11
|
+
services, models, codecs) lives alongside them under `src/polyester/`.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
Install the SDK from PyPI:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install "polyester-sdk[realtime]"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For local development from a checkout:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd polyester-sdk-python
|
|
25
|
+
python3.11 -m venv .venv
|
|
26
|
+
source .venv/bin/activate
|
|
27
|
+
pip install -e ".[dev,realtime]"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Authentication
|
|
31
|
+
|
|
32
|
+
Pass credentials to the client from your app's config or secrets manager:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from polyester import AsyncPolyester
|
|
36
|
+
|
|
37
|
+
client = AsyncPolyester(
|
|
38
|
+
api_key_id="ak_...",
|
|
39
|
+
api_private_key="...", # 64-char hex Ed25519 secret or raw 32-byte key
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If your app uses environment variables, read them in your application code and pass
|
|
44
|
+
them explicitly:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import os
|
|
48
|
+
|
|
49
|
+
from polyester import AsyncPolyester
|
|
50
|
+
|
|
51
|
+
client = AsyncPolyester(
|
|
52
|
+
api_key_id=os.environ["POLYESTER_API_KEY_ID"],
|
|
53
|
+
api_private_key=os.environ["POLYESTER_API_PRIVATE_KEY"],
|
|
54
|
+
default_account_id=os.getenv("POLYESTER_ACCOUNT_ID"),
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For scripts and local tests, `AsyncPolyester.from_env()` and `Polyester.from_env()`
|
|
59
|
+
are convenience helpers that read `POLYESTER_*` from `os.environ`. The plain
|
|
60
|
+
constructor does not implicitly read environment variables.
|
|
61
|
+
|
|
62
|
+
## Quickstart
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from polyester import AsyncPolyester
|
|
66
|
+
|
|
67
|
+
async with AsyncPolyester(
|
|
68
|
+
api_key_id="ak_...",
|
|
69
|
+
api_private_key="...",
|
|
70
|
+
) as client:
|
|
71
|
+
overview = await client.market_overview.list(limit=5)
|
|
72
|
+
for market in overview.markets:
|
|
73
|
+
print(market.symbol, market.last_price_ticks)
|
|
74
|
+
|
|
75
|
+
open_orders = await client.orders.list_open()
|
|
76
|
+
print(f"{len(open_orders.orders)} open orders")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Create And Cancel
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from polyester import AsyncPolyester
|
|
83
|
+
|
|
84
|
+
async with AsyncPolyester(
|
|
85
|
+
api_key_id="ak_...",
|
|
86
|
+
api_private_key="...",
|
|
87
|
+
default_sub_account_id="",
|
|
88
|
+
) as client:
|
|
89
|
+
result = await client.orders.create(
|
|
90
|
+
symbol="BNB-USDT",
|
|
91
|
+
side="buy",
|
|
92
|
+
order_type="limit",
|
|
93
|
+
tif="gtc",
|
|
94
|
+
qty="0.01",
|
|
95
|
+
price="100",
|
|
96
|
+
post_only=True,
|
|
97
|
+
client_order_id="my-bot-001",
|
|
98
|
+
)
|
|
99
|
+
print(result.status, result.order_id)
|
|
100
|
+
|
|
101
|
+
await client.orders.cancel(client_order_id="my-bot-001")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Use **decimal strings** for `qty` and `price`. Do not pass floats.
|
|
105
|
+
|
|
106
|
+
## Balances: funding vs trading
|
|
107
|
+
|
|
108
|
+
Ledger balances expose separate **funding** and **trading** buckets per asset. Spot
|
|
109
|
+
orders spend **trading** balance. Deposits land in **funding** until you move them
|
|
110
|
+
(Funding → Unified Trading in the UI or on-chain via the funding wallet).
|
|
111
|
+
|
|
112
|
+
- **Funding → trading:** on-chain `TradingGateway.deposit` (not an API-key RPC).
|
|
113
|
+
- **Trading → funding:** `client.trading_withdraws.create_to_funding(...)` with a signed intent payload.
|
|
114
|
+
- **Trading → trading (another account):** `client.internal_transfers.create(...)` or `client.ledger_write.transfer_trading_to_trading(...)`.
|
|
115
|
+
|
|
116
|
+
Format u128 wire amounts with the public helper (18-decimal scale):
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from polyester import format_ledger_u128
|
|
120
|
+
|
|
121
|
+
print(format_ledger_u128(balance.funding), format_ledger_u128(balance.trading))
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Set `POLYESTER_ACCOUNT_ID` to your profile base58 id (not a raw decimal uint64) for
|
|
125
|
+
bucket transfers.
|
|
126
|
+
|
|
127
|
+
## Public Market Data
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
candles = await client.market_data.get_candles(symbol="BTC-USDT", timeframe="1m", limit=50)
|
|
131
|
+
current = await client.market_data.get_current_candle(symbol="BTC-USDT", timeframe="1m")
|
|
132
|
+
trades = await client.market_data.get_trades(symbol="BTC-USDT", limit=20)
|
|
133
|
+
health = await client.balances.get_health()
|
|
134
|
+
|
|
135
|
+
async with client.market_data.subscribe_trades(symbol="BNB-USDT") as sub:
|
|
136
|
+
async for trade in sub:
|
|
137
|
+
print(trade.price_ticks, trade.qty_scaled)
|
|
138
|
+
break
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Realtime requires `pip install polyester-sdk[realtime]` (websockets).
|
|
142
|
+
|
|
143
|
+
Merged market overview stream (snapshot + live updates):
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
sub = await client.market_overview.create_subscription()
|
|
147
|
+
async for markets in sub:
|
|
148
|
+
print(len(markets), "rows")
|
|
149
|
+
break
|
|
150
|
+
await sub.aclose()
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Testing
|
|
154
|
+
|
|
155
|
+
**CI (no network):** `pytest tests/unit -q`, plus ruff and package build.
|
|
156
|
+
|
|
157
|
+
**Full local suite:** devnet integration/e2e tests read `.env` in the test harness and pass credentials to the client as explicit constructor parameters.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cp .env.example .env
|
|
161
|
+
# POLYESTER_API_KEY_ID, POLYESTER_API_PRIVATE_KEY, POLYESTER_ACCOUNT_ID
|
|
162
|
+
|
|
163
|
+
pip install -e ".[dev,realtime]"
|
|
164
|
+
|
|
165
|
+
./scripts/test_all.sh # unit + tiered live (reads .env flags)
|
|
166
|
+
# or
|
|
167
|
+
pytest tests/unit -q # CI-equivalent
|
|
168
|
+
pytest tests/ -v # full suite
|
|
169
|
+
python scripts/smoke_test.py # backwards-compatible read/mutation wrapper
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Useful markers include `smoke`, `mutation`, `funded`, `treasury`, `optional`, `realtime`, and `jwt_session`.
|
|
173
|
+
|
|
174
|
+
### Known devnet skips (not SDK failures)
|
|
175
|
+
|
|
176
|
+
| Skip reason | Tests affected |
|
|
177
|
+
|-------------|----------------|
|
|
178
|
+
| OMS read never indexes after `orders.create` | `test_order_round_trip`, `test_batch_create_and_cancel` |
|
|
179
|
+
| No open orders on book | `test_orders_get_round_trips_list_open` |
|
|
180
|
+
| `list_holds` unmounted | balance holds tests |
|
|
181
|
+
| JWT/session-only routes | profile, whiteboard, resolve, etc. |
|
|
182
|
+
| Guard signer not on account | `test_guard_signer_get_status` |
|
|
183
|
+
| No BTC-USDT asks / `POLYESTER_TEST_TRADE_E2E` | `test_spot_fill` |
|
|
184
|
+
|
|
185
|
+
Attach a **read/trade policy** to your API key. Spot orders need **USDT in unified trading** (not BTC).
|
|
186
|
+
|
|
187
|
+
Some RPCs return HTTP 404 on devnet. The SDK raises `PolyesterRouteNotFoundError` with a clearer message than `[unimplemented]: Not Found`.
|
|
188
|
+
|
|
189
|
+
## Changelog
|
|
190
|
+
|
|
191
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
|
192
|
+
|
|
193
|
+
## Transport
|
|
194
|
+
|
|
195
|
+
Connect RPC over HTTP via generated clients in `src/polyester/gen/`. Wire format
|
|
196
|
+
defaults to **binary protobuf**; pass `wire_format="json"` for debugging.
|
|
197
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
If you believe you have found a security issue in the Polyester Python SDK, do
|
|
4
|
+
not open a public issue.
|
|
5
|
+
|
|
6
|
+
Email security reports to `security@polyester.com` with:
|
|
7
|
+
|
|
8
|
+
- affected package version or commit
|
|
9
|
+
- impacted API, generated type, or helper
|
|
10
|
+
- reproduction steps or proof of concept
|
|
11
|
+
- potential impact
|
|
12
|
+
|
|
13
|
+
We will acknowledge valid reports and coordinate remediation before public
|
|
14
|
+
disclosure.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from polyester import AsyncPolyester
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
async def main() -> None:
|
|
8
|
+
async with AsyncPolyester(
|
|
9
|
+
api_key_id=os.environ["POLYESTER_API_KEY_ID"],
|
|
10
|
+
api_private_key=os.environ["POLYESTER_API_PRIVATE_KEY"],
|
|
11
|
+
default_account_id=os.getenv("POLYESTER_ACCOUNT_ID"),
|
|
12
|
+
default_sub_account_id="",
|
|
13
|
+
) as client:
|
|
14
|
+
overview = await client.market_overview.list(limit=3)
|
|
15
|
+
for row in overview.markets:
|
|
16
|
+
print(row.symbol, row.last_price_ticks)
|
|
17
|
+
|
|
18
|
+
open_orders = await client.orders.list_open()
|
|
19
|
+
print(f"Open orders: {len(open_orders.orders)}")
|
|
20
|
+
|
|
21
|
+
# Uncomment when your API key has trade policy on devnet:
|
|
22
|
+
# created = await client.orders.create(
|
|
23
|
+
# symbol="BNB-USDT",
|
|
24
|
+
# side="buy",
|
|
25
|
+
# order_type="limit",
|
|
26
|
+
# tif="gtc",
|
|
27
|
+
# qty="0.001",
|
|
28
|
+
# price="100",
|
|
29
|
+
# post_only=True,
|
|
30
|
+
# )
|
|
31
|
+
# print("Created", created.status, created.order_id)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.26"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "polyester-sdk"
|
|
7
|
+
version = "0.1.0a0"
|
|
8
|
+
description = "Official Python SDK for Polyester APIs."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "Proprietary" }
|
|
12
|
+
authors = [{ name = "Fabric Blockchain Labs Inc." }]
|
|
13
|
+
keywords = ["polyester", "trading", "sdk", "connectrpc", "protobuf"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: Other/Proprietary License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"base58>=2.1.1",
|
|
25
|
+
"connectrpc>=0.9.0",
|
|
26
|
+
"cryptography>=42",
|
|
27
|
+
"httpx>=0.27",
|
|
28
|
+
"msgspec>=0.18",
|
|
29
|
+
"protobuf>=7.35.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
realtime = [
|
|
34
|
+
"websockets>=15",
|
|
35
|
+
]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=8",
|
|
38
|
+
"pytest-asyncio>=0.23",
|
|
39
|
+
"pytest-cov>=5",
|
|
40
|
+
"python-dotenv>=1.0",
|
|
41
|
+
"ruff>=0.8",
|
|
42
|
+
"mypy>=1.13",
|
|
43
|
+
"build>=1.2",
|
|
44
|
+
"twine>=5",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://github.com/Fabric-Labs/polyester-sdk-python"
|
|
49
|
+
Documentation = "https://polyester.ai/docs"
|
|
50
|
+
Repository = "https://github.com/Fabric-Labs/polyester-sdk-python"
|
|
51
|
+
Issues = "https://github.com/Fabric-Labs/polyester-sdk-python/issues"
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.wheel]
|
|
54
|
+
packages = ["src/polyester"]
|
|
55
|
+
|
|
56
|
+
[tool.hatch.build.targets.sdist]
|
|
57
|
+
include = [
|
|
58
|
+
"/.env.example",
|
|
59
|
+
"/CHANGELOG.md",
|
|
60
|
+
"/LICENSE",
|
|
61
|
+
"/README.md",
|
|
62
|
+
"/SECURITY.md",
|
|
63
|
+
"/examples",
|
|
64
|
+
"/pyproject.toml",
|
|
65
|
+
"/src",
|
|
66
|
+
]
|
|
67
|
+
exclude = [
|
|
68
|
+
"/.coverage",
|
|
69
|
+
"/.coverage.*",
|
|
70
|
+
"/.env",
|
|
71
|
+
"/docs",
|
|
72
|
+
"/scripts",
|
|
73
|
+
"/tests",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
[tool.ruff]
|
|
77
|
+
line-length = 100
|
|
78
|
+
target-version = "py311"
|
|
79
|
+
exclude = ["src/polyester/gen"]
|
|
80
|
+
|
|
81
|
+
[tool.ruff.lint]
|
|
82
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
addopts = ["-ra"]
|
|
86
|
+
asyncio_mode = "auto"
|
|
87
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
88
|
+
pythonpath = ["."]
|
|
89
|
+
testpaths = ["tests"]
|
|
90
|
+
filterwarnings = [
|
|
91
|
+
"ignore:SelectableGroups dict interface is deprecated\\. Use select\\.:DeprecationWarning:opentelemetry\\.util\\._importlib_metadata",
|
|
92
|
+
]
|
|
93
|
+
markers = [
|
|
94
|
+
"integration: live devnet (requires POLYESTER_* env)",
|
|
95
|
+
"mutation: writes state on devnet",
|
|
96
|
+
"funded: balance-changing devnet tests",
|
|
97
|
+
"treasury: withdraw/guard ops",
|
|
98
|
+
"realtime: Centrifugo subscriptions",
|
|
99
|
+
"optional: may skip when route unavailable",
|
|
100
|
+
"jwt_session: JWT/session or app-user route; not part of API-key SDK acceptance",
|
|
101
|
+
"smoke: shallow live RPC check (shape only; empty results OK)",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.coverage.run]
|
|
105
|
+
source = ["src/polyester"]
|
|
106
|
+
omit = ["src/polyester/gen/*"]
|
|
107
|
+
|
|
108
|
+
[tool.coverage.report]
|
|
109
|
+
fail_under = 40
|
|
110
|
+
show_missing = true
|