mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 16:28:06 +00:00
refactor: restructure Lighter SDK by removing deprecated Go files and enhancing Python documentation with new examples and models
This commit is contained in:
@@ -68,4 +68,9 @@ openapi-generator-cli.jar
|
||||
|
||||
.idea
|
||||
|
||||
examples/secrets.py
|
||||
examples/secrets.py
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.*
|
||||
api_key_config.json
|
||||
@@ -1,6 +1,7 @@
|
||||
docs/Account.md
|
||||
docs/AccountApi.md
|
||||
docs/AccountApiKeys.md
|
||||
docs/AccountAsset.md
|
||||
docs/AccountLimits.md
|
||||
docs/AccountMarginStats.md
|
||||
docs/AccountMarketStats.md
|
||||
@@ -14,9 +15,12 @@ docs/Announcement.md
|
||||
docs/AnnouncementApi.md
|
||||
docs/Announcements.md
|
||||
docs/ApiKey.md
|
||||
docs/Asset.md
|
||||
docs/AssetDetails.md
|
||||
docs/Block.md
|
||||
docs/BlockApi.md
|
||||
docs/Blocks.md
|
||||
docs/Bridge.md
|
||||
docs/BridgeApi.md
|
||||
docs/BridgeSupportedNetwork.md
|
||||
docs/Candlestick.md
|
||||
@@ -46,28 +50,27 @@ docs/LiqTrade.md
|
||||
docs/Liquidation.md
|
||||
docs/LiquidationInfo.md
|
||||
docs/LiquidationInfos.md
|
||||
docs/MarketInfo.md
|
||||
docs/MarketConfig.md
|
||||
docs/NextNonce.md
|
||||
docs/NotificationApi.md
|
||||
docs/Order.md
|
||||
docs/OrderApi.md
|
||||
docs/OrderBook.md
|
||||
docs/OrderBookDepth.md
|
||||
docs/OrderBookDetail.md
|
||||
docs/OrderBookDetails.md
|
||||
docs/OrderBookOrders.md
|
||||
docs/OrderBookStats.md
|
||||
docs/OrderBooks.md
|
||||
docs/Orders.md
|
||||
docs/PerpsMarketStats.md
|
||||
docs/PerpsOrderBookDetail.md
|
||||
docs/PnLEntry.md
|
||||
docs/PositionFunding.md
|
||||
docs/PositionFundings.md
|
||||
docs/PriceLevel.md
|
||||
docs/PublicPool.md
|
||||
docs/PublicPoolInfo.md
|
||||
docs/PublicPoolMetadata.md
|
||||
docs/PublicPoolShare.md
|
||||
docs/PublicPools.md
|
||||
docs/ReferralApi.md
|
||||
docs/ReferralPointEntry.md
|
||||
docs/ReferralPoints.md
|
||||
@@ -81,8 +84,10 @@ docs/ReqGetAccountLimits.md
|
||||
docs/ReqGetAccountMetadata.md
|
||||
docs/ReqGetAccountPnL.md
|
||||
docs/ReqGetAccountTxs.md
|
||||
docs/ReqGetAssetDetails.md
|
||||
docs/ReqGetBlock.md
|
||||
docs/ReqGetBlockTxs.md
|
||||
docs/ReqGetBridgesByL1Addr.md
|
||||
docs/ReqGetByAccount.md
|
||||
docs/ReqGetCandlesticks.md
|
||||
docs/ReqGetDepositHistory.md
|
||||
@@ -97,7 +102,6 @@ docs/ReqGetOrderBookDetails.md
|
||||
docs/ReqGetOrderBookOrders.md
|
||||
docs/ReqGetOrderBooks.md
|
||||
docs/ReqGetPositionFunding.md
|
||||
docs/ReqGetPublicPools.md
|
||||
docs/ReqGetPublicPoolsMetadata.md
|
||||
docs/ReqGetRangeWithCursor.md
|
||||
docs/ReqGetRangeWithIndex.md
|
||||
@@ -110,10 +114,14 @@ docs/ReqGetTransferHistory.md
|
||||
docs/ReqGetTx.md
|
||||
docs/ReqGetWithdrawHistory.md
|
||||
docs/RespChangeAccountTier.md
|
||||
docs/RespGetBridgesByL1Addr.md
|
||||
docs/RespGetFastBridgeInfo.md
|
||||
docs/RespGetIsNextBridgeFast.md
|
||||
docs/RespPublicPoolsMetadata.md
|
||||
docs/RespSendTx.md
|
||||
docs/RespSendTxBatch.md
|
||||
docs/RespUpdateKickback.md
|
||||
docs/RespUpdateReferralCode.md
|
||||
docs/RespWithdrawalDelay.md
|
||||
docs/ResultCode.md
|
||||
docs/RiskInfo.md
|
||||
@@ -121,6 +129,8 @@ docs/RiskParameters.md
|
||||
docs/RootApi.md
|
||||
docs/SharePrice.md
|
||||
docs/SimpleOrder.md
|
||||
docs/SpotMarketStats.md
|
||||
docs/SpotOrderBookDetail.md
|
||||
docs/Status.md
|
||||
docs/SubAccounts.md
|
||||
docs/Ticker.md
|
||||
@@ -160,6 +170,7 @@ lighter/exceptions.py
|
||||
lighter/models/__init__.py
|
||||
lighter/models/account.py
|
||||
lighter/models/account_api_keys.py
|
||||
lighter/models/account_asset.py
|
||||
lighter/models/account_limits.py
|
||||
lighter/models/account_margin_stats.py
|
||||
lighter/models/account_market_stats.py
|
||||
@@ -172,8 +183,11 @@ lighter/models/account_trade_stats.py
|
||||
lighter/models/announcement.py
|
||||
lighter/models/announcements.py
|
||||
lighter/models/api_key.py
|
||||
lighter/models/asset.py
|
||||
lighter/models/asset_details.py
|
||||
lighter/models/block.py
|
||||
lighter/models/blocks.py
|
||||
lighter/models/bridge.py
|
||||
lighter/models/bridge_supported_network.py
|
||||
lighter/models/candlestick.py
|
||||
lighter/models/candlesticks.py
|
||||
@@ -199,26 +213,25 @@ lighter/models/liq_trade.py
|
||||
lighter/models/liquidation.py
|
||||
lighter/models/liquidation_info.py
|
||||
lighter/models/liquidation_infos.py
|
||||
lighter/models/market_info.py
|
||||
lighter/models/market_config.py
|
||||
lighter/models/next_nonce.py
|
||||
lighter/models/order.py
|
||||
lighter/models/order_book.py
|
||||
lighter/models/order_book_depth.py
|
||||
lighter/models/order_book_detail.py
|
||||
lighter/models/order_book_details.py
|
||||
lighter/models/order_book_orders.py
|
||||
lighter/models/order_book_stats.py
|
||||
lighter/models/order_books.py
|
||||
lighter/models/orders.py
|
||||
lighter/models/perps_market_stats.py
|
||||
lighter/models/perps_order_book_detail.py
|
||||
lighter/models/pn_l_entry.py
|
||||
lighter/models/position_funding.py
|
||||
lighter/models/position_fundings.py
|
||||
lighter/models/price_level.py
|
||||
lighter/models/public_pool.py
|
||||
lighter/models/public_pool_info.py
|
||||
lighter/models/public_pool_metadata.py
|
||||
lighter/models/public_pool_share.py
|
||||
lighter/models/public_pools.py
|
||||
lighter/models/referral_point_entry.py
|
||||
lighter/models/referral_points.py
|
||||
lighter/models/req_export_data.py
|
||||
@@ -231,8 +244,10 @@ lighter/models/req_get_account_limits.py
|
||||
lighter/models/req_get_account_metadata.py
|
||||
lighter/models/req_get_account_pn_l.py
|
||||
lighter/models/req_get_account_txs.py
|
||||
lighter/models/req_get_asset_details.py
|
||||
lighter/models/req_get_block.py
|
||||
lighter/models/req_get_block_txs.py
|
||||
lighter/models/req_get_bridges_by_l1_addr.py
|
||||
lighter/models/req_get_by_account.py
|
||||
lighter/models/req_get_candlesticks.py
|
||||
lighter/models/req_get_deposit_history.py
|
||||
@@ -247,7 +262,6 @@ lighter/models/req_get_order_book_details.py
|
||||
lighter/models/req_get_order_book_orders.py
|
||||
lighter/models/req_get_order_books.py
|
||||
lighter/models/req_get_position_funding.py
|
||||
lighter/models/req_get_public_pools.py
|
||||
lighter/models/req_get_public_pools_metadata.py
|
||||
lighter/models/req_get_range_with_cursor.py
|
||||
lighter/models/req_get_range_with_index.py
|
||||
@@ -260,16 +274,22 @@ lighter/models/req_get_transfer_history.py
|
||||
lighter/models/req_get_tx.py
|
||||
lighter/models/req_get_withdraw_history.py
|
||||
lighter/models/resp_change_account_tier.py
|
||||
lighter/models/resp_get_bridges_by_l1_addr.py
|
||||
lighter/models/resp_get_fast_bridge_info.py
|
||||
lighter/models/resp_get_is_next_bridge_fast.py
|
||||
lighter/models/resp_public_pools_metadata.py
|
||||
lighter/models/resp_send_tx.py
|
||||
lighter/models/resp_send_tx_batch.py
|
||||
lighter/models/resp_update_kickback.py
|
||||
lighter/models/resp_update_referral_code.py
|
||||
lighter/models/resp_withdrawal_delay.py
|
||||
lighter/models/result_code.py
|
||||
lighter/models/risk_info.py
|
||||
lighter/models/risk_parameters.py
|
||||
lighter/models/share_price.py
|
||||
lighter/models/simple_order.py
|
||||
lighter/models/spot_market_stats.py
|
||||
lighter/models/spot_order_book_detail.py
|
||||
lighter/models/status.py
|
||||
lighter/models/sub_accounts.py
|
||||
lighter/models/ticker.py
|
||||
@@ -291,4 +311,19 @@ lighter/rest.py
|
||||
setup.cfg
|
||||
test-requirements.txt
|
||||
test/__init__.py
|
||||
test/test_account_asset.py
|
||||
test/test_asset.py
|
||||
test/test_asset_details.py
|
||||
test/test_bridge.py
|
||||
test/test_market_config.py
|
||||
test/test_perps_market_stats.py
|
||||
test/test_perps_order_book_detail.py
|
||||
test/test_req_get_asset_details.py
|
||||
test/test_req_get_bridges_by_l1_addr.py
|
||||
test/test_resp_get_bridges_by_l1_addr.py
|
||||
test/test_resp_get_is_next_bridge_fast.py
|
||||
test/test_resp_update_kickback.py
|
||||
test/test_resp_update_referral_code.py
|
||||
test/test_spot_market_stats.py
|
||||
test/test_spot_order_book_detail.py
|
||||
tox.ini
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -36,9 +36,12 @@ import asyncio
|
||||
|
||||
async def main():
|
||||
client = lighter.ApiClient()
|
||||
account_api = lighter.AccountApi(client)
|
||||
account = await account_api.get_account(by="index", value="1")
|
||||
print(account)
|
||||
try:
|
||||
account_api = lighter.AccountApi(client)
|
||||
account = await account_api.account(by="index", value="1")
|
||||
print(account)
|
||||
finally:
|
||||
await client.close() # Make sure connection is cleanly closed
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
disallowAdditionalPropertiesIfNotPresent: false
|
||||
library: asyncio
|
||||
packageName: lighter-sdk
|
||||
projectName: lighter-sdk
|
||||
@@ -12,7 +12,6 @@ Name | Type | Description | Notes
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
|
||||
@@ -14,7 +14,6 @@ Method | HTTP request | Description
|
||||
[**liquidations**](AccountApi.md#liquidations) | **GET** /api/v1/liquidations | liquidations
|
||||
[**pnl**](AccountApi.md#pnl) | **GET** /api/v1/pnl | pnl
|
||||
[**position_funding**](AccountApi.md#position_funding) | **GET** /api/v1/positionFunding | positionFunding
|
||||
[**public_pools**](AccountApi.md#public_pools) | **GET** /api/v1/publicPools | publicPools
|
||||
[**public_pools_metadata**](AccountApi.md#public_pools_metadata) | **GET** /api/v1/publicPoolsMetadata | publicPoolsMetadata
|
||||
|
||||
|
||||
@@ -770,85 +769,6 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **public_pools**
|
||||
> PublicPools public_pools(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
|
||||
publicPools
|
||||
|
||||
Get public pools
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.public_pools import PublicPools
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.AccountApi(api_client)
|
||||
index = 56 # int |
|
||||
limit = 56 # int |
|
||||
authorization = 'authorization_example' # str | (optional)
|
||||
auth = 'auth_example' # str | (optional)
|
||||
filter = 'filter_example' # str | (optional)
|
||||
account_index = 56 # int | (optional)
|
||||
|
||||
try:
|
||||
# publicPools
|
||||
api_response = await api_instance.public_pools(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
print("The response of AccountApi->public_pools:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling AccountApi->public_pools: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**index** | **int**| |
|
||||
**limit** | **int**| |
|
||||
**authorization** | **str**| | [optional]
|
||||
**auth** | **str**| | [optional]
|
||||
**filter** | **str**| | [optional]
|
||||
**account_index** | **int**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**PublicPools**](PublicPools.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **public_pools_metadata**
|
||||
> RespPublicPoolsMetadata public_pools_metadata(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# AccountAsset
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**balance** | **str** | |
|
||||
**locked_balance** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.account_asset import AccountAsset
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of AccountAsset from a JSON string
|
||||
account_asset_instance = AccountAsset.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(AccountAsset.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
account_asset_dict = account_asset_instance.to_dict()
|
||||
# create an instance of AccountAsset from a dict
|
||||
account_asset_from_dict = AccountAsset.from_dict(account_asset_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ Name | Type | Description | Notes
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**max_llp_percentage** | **int** | |
|
||||
**max_llp_amount** | **str** | |
|
||||
**user_tier** | **str** | |
|
||||
**can_create_public_pool** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ Name | Type | Description | Notes
|
||||
**title** | **str** | |
|
||||
**content** | **str** | |
|
||||
**created_at** | **int** | |
|
||||
**expired_at** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Asset
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**asset_id** | **int** | |
|
||||
**symbol** | **str** | |
|
||||
**l1_decimals** | **int** | |
|
||||
**decimals** | **int** | |
|
||||
**min_transfer_amount** | **str** | |
|
||||
**min_withdrawal_amount** | **str** | |
|
||||
**margin_mode** | **str** | |
|
||||
**index_price** | **str** | |
|
||||
**l1_address** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.asset import Asset
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Asset from a JSON string
|
||||
asset_instance = Asset.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Asset.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
asset_dict = asset_instance.to_dict()
|
||||
# create an instance of Asset from a dict
|
||||
asset_from_dict = Asset.from_dict(asset_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
+9
-10
@@ -1,4 +1,4 @@
|
||||
# PublicPools
|
||||
# AssetDetails
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -7,25 +7,24 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**total** | **int** | |
|
||||
**public_pools** | [**List[PublicPool]**](PublicPool.md) | |
|
||||
**asset_details** | [**List[Asset]**](Asset.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.public_pools import PublicPools
|
||||
from lighter.models.asset_details import AssetDetails
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of PublicPools from a JSON string
|
||||
public_pools_instance = PublicPools.from_json(json)
|
||||
# create an instance of AssetDetails from a JSON string
|
||||
asset_details_instance = AssetDetails.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(PublicPools.to_json())
|
||||
print(AssetDetails.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
public_pools_dict = public_pools_instance.to_dict()
|
||||
# create an instance of PublicPools from a dict
|
||||
public_pools_from_dict = PublicPools.from_dict(public_pools_dict)
|
||||
asset_details_dict = asset_details_instance.to_dict()
|
||||
# create an instance of AssetDetails from a dict
|
||||
asset_details_from_dict = AssetDetails.from_dict(asset_details_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Bridge
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **int** | |
|
||||
**version** | **int** | |
|
||||
**source** | **str** | |
|
||||
**source_chain_id** | **str** | |
|
||||
**fast_bridge_tx_hash** | **str** | |
|
||||
**batch_claim_tx_hash** | **str** | |
|
||||
**cctp_burn_tx_hash** | **str** | |
|
||||
**amount** | **str** | |
|
||||
**intent_address** | **str** | |
|
||||
**status** | **str** | |
|
||||
**step** | **str** | |
|
||||
**description** | **str** | |
|
||||
**created_at** | **int** | |
|
||||
**updated_at** | **int** | |
|
||||
**is_external_deposit** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.bridge import Bridge
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Bridge from a JSON string
|
||||
bridge_instance = Bridge.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Bridge.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
bridge_dict = bridge_instance.to_dict()
|
||||
# create an instance of Bridge from a dict
|
||||
bridge_from_dict = Bridge.from_dict(bridge_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,9 +4,149 @@ All URIs are relative to *https://mainnet.zklighter.elliot.ai*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**bridges**](BridgeApi.md#bridges) | **GET** /api/v1/bridges | bridges
|
||||
[**bridges_is_next_bridge_fast**](BridgeApi.md#bridges_is_next_bridge_fast) | **GET** /api/v1/bridges/isNextBridgeFast | bridges_isNextBridgeFast
|
||||
[**fastbridge_info**](BridgeApi.md#fastbridge_info) | **GET** /api/v1/fastbridge/info | fastbridge_info
|
||||
|
||||
|
||||
# **bridges**
|
||||
> RespGetBridgesByL1Addr bridges(l1_address)
|
||||
|
||||
bridges
|
||||
|
||||
Get bridges for given l1 address
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_get_bridges_by_l1_addr import RespGetBridgesByL1Addr
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.BridgeApi(api_client)
|
||||
l1_address = 'l1_address_example' # str |
|
||||
|
||||
try:
|
||||
# bridges
|
||||
api_response = await api_instance.bridges(l1_address)
|
||||
print("The response of BridgeApi->bridges:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling BridgeApi->bridges: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**l1_address** | **str**| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespGetBridgesByL1Addr**](RespGetBridgesByL1Addr.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **bridges_is_next_bridge_fast**
|
||||
> RespGetIsNextBridgeFast bridges_is_next_bridge_fast(l1_address)
|
||||
|
||||
bridges_isNextBridgeFast
|
||||
|
||||
Get if next bridge is fast
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_get_is_next_bridge_fast import RespGetIsNextBridgeFast
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.BridgeApi(api_client)
|
||||
l1_address = 'l1_address_example' # str |
|
||||
|
||||
try:
|
||||
# bridges_isNextBridgeFast
|
||||
api_response = await api_instance.bridges_is_next_bridge_fast(l1_address)
|
||||
print("The response of BridgeApi->bridges_is_next_bridge_fast:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling BridgeApi->bridges_is_next_bridge_fast: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**l1_address** | **str**| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespGetIsNextBridgeFast**](RespGetIsNextBridgeFast.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **fastbridge_info**
|
||||
> RespGetFastBridgeInfo fastbridge_info()
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
||||
**high** | **float** | |
|
||||
**low** | **float** | |
|
||||
**close** | **float** | |
|
||||
**open_raw** | **float** | |
|
||||
**high_raw** | **float** | |
|
||||
**low_raw** | **float** | |
|
||||
**close_raw** | **float** | |
|
||||
**volume0** | **float** | |
|
||||
**volume1** | **float** | |
|
||||
**last_trade_id** | **int** | |
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**status** | **str** | |
|
||||
|
||||
@@ -12,7 +12,6 @@ Name | Type | Description | Notes
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
@@ -23,6 +22,7 @@ Name | Type | Description | Notes
|
||||
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
||||
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
||||
**positions** | [**List[AccountPosition]**](AccountPosition.md) | |
|
||||
**assets** | [**List[AccountAsset]**](AccountAsset.md) | |
|
||||
**total_asset_value** | **str** | |
|
||||
**cross_asset_value** | **str** | |
|
||||
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
||||
|
||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
||||
**high** | **float** | |
|
||||
**low** | **float** | |
|
||||
**close** | **float** | |
|
||||
**open_raw** | **float** | |
|
||||
**high_raw** | **float** | |
|
||||
**low_raw** | **float** | |
|
||||
**close_raw** | **float** | |
|
||||
**volume0** | **float** | |
|
||||
**volume1** | **float** | |
|
||||
**last_trade_id** | **int** | |
|
||||
|
||||
@@ -22,6 +22,7 @@ Name | Type | Description | Notes
|
||||
**executed_at** | **int** | |
|
||||
**sequence_index** | **int** | |
|
||||
**parent_hash** | **str** | |
|
||||
**api_key_index** | **int** | |
|
||||
**committed_at** | **int** | |
|
||||
**verified_at** | **int** | |
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# MarketConfig
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_margin_mode** | **int** | |
|
||||
**insurance_fund_account_index** | **int** | |
|
||||
**liquidation_mode** | **int** | |
|
||||
**force_reduce_only** | **bool** | |
|
||||
**trading_hours** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.market_config import MarketConfig
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of MarketConfig from a JSON string
|
||||
market_config_instance = MarketConfig.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(MarketConfig.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
market_config_dict = market_config_instance.to_dict()
|
||||
# create an instance of MarketConfig from a dict
|
||||
market_config_from_dict = MarketConfig.from_dict(market_config_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ Name | Type | Description | Notes
|
||||
**to_cancel_order_id_0** | **str** | |
|
||||
**block_height** | **int** | |
|
||||
**timestamp** | **int** | |
|
||||
**created_at** | **int** | |
|
||||
**updated_at** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**account_active_orders**](OrderApi.md#account_active_orders) | **GET** /api/v1/accountActiveOrders | accountActiveOrders
|
||||
[**account_inactive_orders**](OrderApi.md#account_inactive_orders) | **GET** /api/v1/accountInactiveOrders | accountInactiveOrders
|
||||
[**asset_details**](OrderApi.md#asset_details) | **GET** /api/v1/assetDetails | assetDetails
|
||||
[**exchange_stats**](OrderApi.md#exchange_stats) | **GET** /api/v1/exchangeStats | exchangeStats
|
||||
[**export**](OrderApi.md#export) | **GET** /api/v1/export | export
|
||||
[**order_book_details**](OrderApi.md#order_book_details) | **GET** /api/v1/orderBookDetails | orderBookDetails
|
||||
@@ -173,6 +174,75 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **asset_details**
|
||||
> AssetDetails asset_details(asset_id=asset_id)
|
||||
|
||||
assetDetails
|
||||
|
||||
Get asset details
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.asset_details import AssetDetails
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
asset_id = 0 # int | (optional) (default to 0)
|
||||
|
||||
try:
|
||||
# assetDetails
|
||||
api_response = await api_instance.asset_details(asset_id=asset_id)
|
||||
print("The response of OrderApi->asset_details:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling OrderApi->asset_details: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**asset_id** | **int**| | [optional] [default to 0]
|
||||
|
||||
### Return type
|
||||
|
||||
[**AssetDetails**](AssetDetails.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **exchange_stats**
|
||||
> ExchangeStats exchange_stats()
|
||||
|
||||
@@ -316,7 +386,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **order_book_details**
|
||||
> OrderBookDetails order_book_details(market_id=market_id)
|
||||
> OrderBookDetails order_book_details(market_id=market_id, filter=filter)
|
||||
|
||||
orderBookDetails
|
||||
|
||||
@@ -343,10 +413,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
market_id = 255 # int | (optional) (default to 255)
|
||||
filter = all # str | (optional) (default to all)
|
||||
|
||||
try:
|
||||
# orderBookDetails
|
||||
api_response = await api_instance.order_book_details(market_id=market_id)
|
||||
api_response = await api_instance.order_book_details(market_id=market_id, filter=filter)
|
||||
print("The response of OrderApi->order_book_details:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -361,6 +432,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**market_id** | **int**| | [optional] [default to 255]
|
||||
**filter** | **str**| | [optional] [default to all]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -456,7 +528,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **order_books**
|
||||
> OrderBooks order_books(market_id=market_id)
|
||||
> OrderBooks order_books(market_id=market_id, filter=filter)
|
||||
|
||||
orderBooks
|
||||
|
||||
@@ -483,10 +555,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
market_id = 255 # int | (optional) (default to 255)
|
||||
filter = all # str | (optional) (default to all)
|
||||
|
||||
try:
|
||||
# orderBooks
|
||||
api_response = await api_instance.order_books(market_id=market_id)
|
||||
api_response = await api_instance.order_books(market_id=market_id, filter=filter)
|
||||
print("The response of OrderApi->order_books:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -501,6 +574,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**market_id** | **int**| | [optional] [default to 255]
|
||||
**filter** | **str**| | [optional] [default to all]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -596,7 +670,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **trades**
|
||||
> Trades trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter)
|
||||
> Trades trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter, role=role, type=type, aggregate=aggregate)
|
||||
|
||||
trades
|
||||
|
||||
@@ -633,10 +707,13 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
cursor = 'cursor_example' # str | (optional)
|
||||
var_from = -1 # int | (optional) (default to -1)
|
||||
ask_filter = -1 # int | (optional) (default to -1)
|
||||
role = all # str | (optional) (default to all)
|
||||
type = all # str | (optional) (default to all)
|
||||
aggregate = False # bool | (optional) (default to False)
|
||||
|
||||
try:
|
||||
# trades
|
||||
api_response = await api_instance.trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter)
|
||||
api_response = await api_instance.trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter, role=role, type=type, aggregate=aggregate)
|
||||
print("The response of OrderApi->trades:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -661,6 +738,9 @@ Name | Type | Description | Notes
|
||||
**cursor** | **str**| | [optional]
|
||||
**var_from** | **int**| | [optional] [default to -1]
|
||||
**ask_filter** | **int**| | [optional] [default to -1]
|
||||
**role** | **str**| | [optional] [default to all]
|
||||
**type** | **str**| | [optional] [default to all]
|
||||
**aggregate** | **bool**| | [optional] [default to False]
|
||||
|
||||
### Return type
|
||||
|
||||
|
||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
|
||||
@@ -10,6 +10,7 @@ Name | Type | Description | Notes
|
||||
**asks** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||
**bids** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||
**offset** | **int** | |
|
||||
**nonce** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**order_book_details** | [**List[OrderBookDetail]**](OrderBookDetail.md) | |
|
||||
**order_book_details** | [**List[PerpsOrderBookDetail]**](PerpsOrderBookDetail.md) | |
|
||||
**spot_order_book_details** | [**List[SpotOrderBookDetail]**](SpotOrderBookDetail.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
+12
-8
@@ -1,14 +1,18 @@
|
||||
# MarketInfo
|
||||
# PerpsMarketStats
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**index_price** | **str** | |
|
||||
**mark_price** | **str** | |
|
||||
**open_interest** | **str** | |
|
||||
**open_interest_limit** | **str** | |
|
||||
**funding_clamp_small** | **str** | |
|
||||
**funding_clamp_big** | **str** | |
|
||||
**last_trade_price** | **str** | |
|
||||
**current_funding_rate** | **str** | |
|
||||
**funding_rate** | **str** | |
|
||||
@@ -22,19 +26,19 @@ Name | Type | Description | Notes
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.market_info import MarketInfo
|
||||
from lighter.models.perps_market_stats import PerpsMarketStats
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of MarketInfo from a JSON string
|
||||
market_info_instance = MarketInfo.from_json(json)
|
||||
# create an instance of PerpsMarketStats from a JSON string
|
||||
perps_market_stats_instance = PerpsMarketStats.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(MarketInfo.to_json())
|
||||
print(PerpsMarketStats.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
market_info_dict = market_info_instance.to_dict()
|
||||
# create an instance of MarketInfo from a dict
|
||||
market_info_from_dict = MarketInfo.from_dict(market_info_dict)
|
||||
perps_market_stats_dict = perps_market_stats_instance.to_dict()
|
||||
# create an instance of PerpsMarketStats from a dict
|
||||
perps_market_stats_from_dict = PerpsMarketStats.from_dict(perps_market_stats_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
+13
-8
@@ -1,4 +1,4 @@
|
||||
# OrderBookDetail
|
||||
# PerpsOrderBookDetail
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
@@ -32,23 +36,24 @@ Name | Type | Description | Notes
|
||||
**daily_price_change** | **float** | |
|
||||
**open_interest** | **float** | |
|
||||
**daily_chart** | **Dict[str, float]** | |
|
||||
**market_config** | [**MarketConfig**](MarketConfig.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.order_book_detail import OrderBookDetail
|
||||
from lighter.models.perps_order_book_detail import PerpsOrderBookDetail
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of OrderBookDetail from a JSON string
|
||||
order_book_detail_instance = OrderBookDetail.from_json(json)
|
||||
# create an instance of PerpsOrderBookDetail from a JSON string
|
||||
perps_order_book_detail_instance = PerpsOrderBookDetail.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(OrderBookDetail.to_json())
|
||||
print(PerpsOrderBookDetail.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
order_book_detail_dict = order_book_detail_instance.to_dict()
|
||||
# create an instance of OrderBookDetail from a dict
|
||||
order_book_detail_from_dict = OrderBookDetail.from_dict(order_book_detail_dict)
|
||||
perps_order_book_detail_dict = perps_order_book_detail_instance.to_dict()
|
||||
# create an instance of PerpsOrderBookDetail from a dict
|
||||
perps_order_book_detail_from_dict = PerpsOrderBookDetail.from_dict(perps_order_book_detail_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
@@ -7,8 +7,11 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**timestamp** | **int** | |
|
||||
**trade_pnl** | **float** | |
|
||||
**trade_spot_pnl** | **float** | |
|
||||
**inflow** | **float** | |
|
||||
**outflow** | **float** | |
|
||||
**spot_outflow** | **float** | |
|
||||
**spot_inflow** | **float** | |
|
||||
**pool_pnl** | **float** | |
|
||||
**pool_inflow** | **float** | |
|
||||
**pool_outflow** | **float** | |
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# PublicPool
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**account_type** | **int** | |
|
||||
**index** | **int** | |
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
**collateral** | **str** | |
|
||||
**account_index** | **int** | |
|
||||
**name** | **str** | |
|
||||
**description** | **str** | |
|
||||
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
||||
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
||||
**total_asset_value** | **str** | |
|
||||
**cross_asset_value** | **str** | |
|
||||
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
||||
**account_share** | [**PublicPoolShare**](PublicPoolShare.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.public_pool import PublicPool
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of PublicPool from a JSON string
|
||||
public_pool_instance = PublicPool.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(PublicPool.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
public_pool_dict = public_pool_instance.to_dict()
|
||||
# create an instance of PublicPool from a dict
|
||||
public_pool_from_dict = PublicPool.from_dict(public_pool_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ Name | Type | Description | Notes
|
||||
**total_shares** | **int** | |
|
||||
**operator_shares** | **int** | |
|
||||
**annual_percentage_yield** | **float** | |
|
||||
**sharpe_ratio** | **float** | |
|
||||
**daily_returns** | [**List[DailyReturn]**](DailyReturn.md) | |
|
||||
**share_prices** | [**List[SharePrice]**](SharePrice.md) | |
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@ Name | Type | Description | Notes
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**account_index** | **int** | |
|
||||
**created_at** | **int** | |
|
||||
**master_account_index** | **int** | |
|
||||
**account_type** | **int** | |
|
||||
**name** | **str** | |
|
||||
**l1_address** | **str** | |
|
||||
**annual_percentage_yield** | **float** | |
|
||||
**sharpe_ratio** | **float** | |
|
||||
**status** | **int** | |
|
||||
**operator_fee** | **str** | |
|
||||
**total_asset_value** | **str** | |
|
||||
|
||||
@@ -4,9 +4,86 @@ All URIs are relative to *https://mainnet.zklighter.elliot.ai*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**referral_kickback_update**](ReferralApi.md#referral_kickback_update) | **POST** /api/v1/referral/kickback/update | referral_kickback_update
|
||||
[**referral_points**](ReferralApi.md#referral_points) | **GET** /api/v1/referral/points | referral_points
|
||||
[**referral_update**](ReferralApi.md#referral_update) | **POST** /api/v1/referral/update | referral_update
|
||||
|
||||
|
||||
# **referral_kickback_update**
|
||||
> RespUpdateKickback referral_kickback_update(account_index, kickback_percentage, authorization=authorization, auth=auth)
|
||||
|
||||
referral_kickback_update
|
||||
|
||||
Update kickback percentage for referral rewards
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_update_kickback import RespUpdateKickback
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.ReferralApi(api_client)
|
||||
account_index = 56 # int |
|
||||
kickback_percentage = 3.4 # float |
|
||||
authorization = 'authorization_example' # str | make required after integ is done (optional)
|
||||
auth = 'auth_example' # str | made optional to support header auth clients (optional)
|
||||
|
||||
try:
|
||||
# referral_kickback_update
|
||||
api_response = await api_instance.referral_kickback_update(account_index, kickback_percentage, authorization=authorization, auth=auth)
|
||||
print("The response of ReferralApi->referral_kickback_update:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ReferralApi->referral_kickback_update: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**account_index** | **int**| |
|
||||
**kickback_percentage** | **float**| |
|
||||
**authorization** | **str**| make required after integ is done | [optional]
|
||||
**auth** | **str**| made optional to support header auth clients | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespUpdateKickback**](RespUpdateKickback.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: multipart/form-data
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **referral_points**
|
||||
> ReferralPoints referral_points(account_index, authorization=authorization, auth=auth)
|
||||
|
||||
@@ -80,3 +157,78 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **referral_update**
|
||||
> RespUpdateReferralCode referral_update(account_index, new_referral_code, authorization=authorization, auth=auth)
|
||||
|
||||
referral_update
|
||||
|
||||
Update referral code (allowed once per account)
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_update_referral_code import RespUpdateReferralCode
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.ReferralApi(api_client)
|
||||
account_index = 56 # int |
|
||||
new_referral_code = 'new_referral_code_example' # str |
|
||||
authorization = 'authorization_example' # str | make required after integ is done (optional)
|
||||
auth = 'auth_example' # str | made optional to support header auth clients (optional)
|
||||
|
||||
try:
|
||||
# referral_update
|
||||
api_response = await api_instance.referral_update(account_index, new_referral_code, authorization=authorization, auth=auth)
|
||||
print("The response of ReferralApi->referral_update:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ReferralApi->referral_update: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**account_index** | **int**| |
|
||||
**new_referral_code** | **str**| |
|
||||
**authorization** | **str**| make required after integ is done | [optional]
|
||||
**auth** | **str**| made optional to support header auth clients | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespUpdateReferralCode**](RespUpdateReferralCode.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: multipart/form-data
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**l1_address** | **str** | |
|
||||
**total_points** | **int** | |
|
||||
**week_points** | **int** | |
|
||||
**total_reward_points** | **int** | |
|
||||
**week_reward_points** | **int** | |
|
||||
**total_points** | **float** | |
|
||||
**week_points** | **float** | |
|
||||
**total_reward_points** | **float** | |
|
||||
**week_reward_points** | **float** | |
|
||||
**reward_point_multiplier** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**referrals** | [**List[ReferralPointEntry]**](ReferralPointEntry.md) | |
|
||||
**user_total_points** | **int** | |
|
||||
**user_last_week_points** | **int** | |
|
||||
**user_total_referral_reward_points** | **int** | |
|
||||
**user_last_week_referral_reward_points** | **int** | |
|
||||
**user_total_points** | **float** | |
|
||||
**user_last_week_points** | **float** | |
|
||||
**user_total_referral_reward_points** | **float** | |
|
||||
**user_last_week_referral_reward_points** | **float** | |
|
||||
**reward_point_multiplier** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# ReqGetAssetDetails
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**asset_id** | **int** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_asset_details import ReqGetAssetDetails
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetAssetDetails from a JSON string
|
||||
req_get_asset_details_instance = ReqGetAssetDetails.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetAssetDetails.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_asset_details_dict = req_get_asset_details_instance.to_dict()
|
||||
# create an instance of ReqGetAssetDetails from a dict
|
||||
req_get_asset_details_from_dict = ReqGetAssetDetails.from_dict(req_get_asset_details_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# ReqGetBridgesByL1Addr
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**l1_address** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_bridges_by_l1_addr import ReqGetBridgesByL1Addr
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetBridgesByL1Addr from a JSON string
|
||||
req_get_bridges_by_l1_addr_instance = ReqGetBridgesByL1Addr.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetBridgesByL1Addr.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_bridges_by_l1_addr_dict = req_get_bridges_by_l1_addr_instance.to_dict()
|
||||
# create an instance of ReqGetBridgesByL1Addr from a dict
|
||||
req_get_bridges_by_l1_addr_from_dict = ReqGetBridgesByL1Addr.from_dict(req_get_bridges_by_l1_addr_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_id** | **int** | | [optional]
|
||||
**filter** | **str** | | [optional] [default to 'all']
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_id** | **int** | | [optional]
|
||||
**filter** | **str** | | [optional] [default to 'all']
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# ReqGetPublicPools
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**auth** | **str** | | [optional]
|
||||
**filter** | **str** | | [optional]
|
||||
**index** | **int** | |
|
||||
**limit** | **int** | |
|
||||
**account_index** | **int** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_public_pools import ReqGetPublicPools
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetPublicPools from a JSON string
|
||||
req_get_public_pools_instance = ReqGetPublicPools.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetPublicPools.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_public_pools_dict = req_get_public_pools_instance.to_dict()
|
||||
# create an instance of ReqGetPublicPools from a dict
|
||||
req_get_public_pools_from_dict = ReqGetPublicPools.from_dict(req_get_public_pools_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@ Name | Type | Description | Notes
|
||||
**cursor** | **str** | | [optional]
|
||||
**var_from** | **int** | | [optional] [default to -1]
|
||||
**ask_filter** | **int** | | [optional]
|
||||
**role** | **str** | | [optional] [default to 'all']
|
||||
**type** | **str** | | [optional] [default to 'all']
|
||||
**limit** | **int** | |
|
||||
**aggregate** | **bool** | | [optional] [default to False]
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespGetBridgesByL1Addr
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**bridges** | [**List[Bridge]**](Bridge.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_get_bridges_by_l1_addr import RespGetBridgesByL1Addr
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespGetBridgesByL1Addr from a JSON string
|
||||
resp_get_bridges_by_l1_addr_instance = RespGetBridgesByL1Addr.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespGetBridgesByL1Addr.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_get_bridges_by_l1_addr_dict = resp_get_bridges_by_l1_addr_instance.to_dict()
|
||||
# create an instance of RespGetBridgesByL1Addr from a dict
|
||||
resp_get_bridges_by_l1_addr_from_dict = RespGetBridgesByL1Addr.from_dict(resp_get_bridges_by_l1_addr_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespGetIsNextBridgeFast
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**is_next_bridge_fast** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_get_is_next_bridge_fast import RespGetIsNextBridgeFast
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespGetIsNextBridgeFast from a JSON string
|
||||
resp_get_is_next_bridge_fast_instance = RespGetIsNextBridgeFast.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespGetIsNextBridgeFast.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_get_is_next_bridge_fast_dict = resp_get_is_next_bridge_fast_instance.to_dict()
|
||||
# create an instance of RespGetIsNextBridgeFast from a dict
|
||||
resp_get_is_next_bridge_fast_from_dict = RespGetIsNextBridgeFast.from_dict(resp_get_is_next_bridge_fast_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
|
||||
**message** | **str** | | [optional]
|
||||
**tx_hash** | **str** | |
|
||||
**predicted_execution_time_ms** | **int** | |
|
||||
**volume_quota_remaining** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
|
||||
**message** | **str** | | [optional]
|
||||
**tx_hash** | **List[str]** | |
|
||||
**predicted_execution_time_ms** | **int** | |
|
||||
**volume_quota_remaining** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespUpdateKickback
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**success** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_update_kickback import RespUpdateKickback
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespUpdateKickback from a JSON string
|
||||
resp_update_kickback_instance = RespUpdateKickback.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespUpdateKickback.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_update_kickback_dict = resp_update_kickback_instance.to_dict()
|
||||
# create an instance of RespUpdateKickback from a dict
|
||||
resp_update_kickback_from_dict = RespUpdateKickback.from_dict(resp_update_kickback_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespUpdateReferralCode
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**success** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_update_referral_code import RespUpdateReferralCode
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespUpdateReferralCode from a JSON string
|
||||
resp_update_referral_code_instance = RespUpdateReferralCode.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespUpdateReferralCode.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_update_referral_code_dict = resp_update_referral_code_instance.to_dict()
|
||||
# create an instance of RespUpdateReferralCode from a dict
|
||||
resp_update_referral_code_from_dict = RespUpdateReferralCode.from_dict(resp_update_referral_code_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# SpotMarketStats
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**index_price** | **str** | |
|
||||
**mid_price** | **str** | |
|
||||
**last_trade_price** | **str** | |
|
||||
**daily_base_token_volume** | **float** | |
|
||||
**daily_quote_token_volume** | **float** | |
|
||||
**daily_price_low** | **float** | |
|
||||
**daily_price_high** | **float** | |
|
||||
**daily_price_change** | **float** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.spot_market_stats import SpotMarketStats
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of SpotMarketStats from a JSON string
|
||||
spot_market_stats_instance = SpotMarketStats.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(SpotMarketStats.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
spot_market_stats_dict = spot_market_stats_instance.to_dict()
|
||||
# create an instance of SpotMarketStats from a dict
|
||||
spot_market_stats_from_dict = SpotMarketStats.from_dict(spot_market_stats_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# SpotOrderBookDetail
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
**size_decimals** | **int** | |
|
||||
**price_decimals** | **int** | |
|
||||
**last_trade_price** | **float** | |
|
||||
**daily_trades_count** | **int** | |
|
||||
**daily_base_token_volume** | **float** | |
|
||||
**daily_quote_token_volume** | **float** | |
|
||||
**daily_price_low** | **float** | |
|
||||
**daily_price_high** | **float** | |
|
||||
**daily_price_change** | **float** | |
|
||||
**daily_chart** | **Dict[str, float]** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.spot_order_book_detail import SpotOrderBookDetail
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of SpotOrderBookDetail from a JSON string
|
||||
spot_order_book_detail_instance = SpotOrderBookDetail.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(SpotOrderBookDetail.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
spot_order_book_detail_dict = spot_order_book_detail_instance.to_dict()
|
||||
# create an instance of SpotOrderBookDetail from a dict
|
||||
spot_order_book_detail_from_dict = SpotOrderBookDetail.from_dict(spot_order_book_detail_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ Name | Type | Description | Notes
|
||||
**usd_amount** | **str** | |
|
||||
**ask_id** | **int** | |
|
||||
**bid_id** | **int** | |
|
||||
**ask_client_id** | **int** | |
|
||||
**bid_client_id** | **int** | |
|
||||
**ask_account_id** | **int** | |
|
||||
**bid_account_id** | **int** | |
|
||||
**is_maker_ask** | **bool** | |
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**type** | **str** | |
|
||||
@@ -13,6 +14,8 @@ Name | Type | Description | Notes
|
||||
**to_l1_address** | **str** | |
|
||||
**from_account_index** | **int** | |
|
||||
**to_account_index** | **int** | |
|
||||
**from_route** | **str** | |
|
||||
**to_route** | **str** | |
|
||||
**tx_hash** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -20,6 +20,7 @@ Name | Type | Description | Notes
|
||||
**executed_at** | **int** | |
|
||||
**sequence_index** | **int** | |
|
||||
**parent_hash** | **str** | |
|
||||
**api_key_index** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**status** | **str** | |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
api_key_config.json
|
||||
@@ -5,18 +5,152 @@
|
||||
- this will require you to enter your Ethereum private key
|
||||
- the eth private key will only be used in the Py SDK to sign a message
|
||||
- the eth private key is not required in order to trade on the platform
|
||||
- the eth private key is not passed to the binary
|
||||
- copy the output of the script and post it into `create_cancel_order.py`
|
||||
- the output should look like
|
||||
```
|
||||
BASE_URL = 'https://testnet.zklighter.elliot.ai'
|
||||
API_KEY_PRIVATE_KEY = '0xea5d2eca5be67eca056752eaf27b173518b8a5550117c09d2b58c7ea7d306cc4426f913ccf27ab19'
|
||||
ACCOUNT_INDEX = 595
|
||||
API_KEY_INDEX = 1
|
||||
```
|
||||
- start trading using
|
||||
- `create_cancel_order.py` has an example which created an order on testnet & cancels it
|
||||
- you'll need to set up both your account index, api key index & API Key private key
|
||||
- the eth private key is not passed to the binary
|
||||
- the API key config is saved in a local file `./api_key_config.json`
|
||||
|
||||
## Start trading on testnet
|
||||
- `create_modify_cancel_order_http.py`
|
||||
- creates an ask (sell) order for 0.1 ETH @ $4050
|
||||
- modified the order and increases the size to 0.11 ETH and increases the price to $4100
|
||||
- cancels the order
|
||||
- Note: all of these operations use the client order index of the order. You can use the order from the exchange as well
|
||||
|
||||
- `create_modify_cancel_order_ws.py`
|
||||
- same flow as `create_modify_cancel_order_http.py`
|
||||
- sends TXs over WS instead of HTTP
|
||||
|
||||
- `create_market_order_eth_buy.py`
|
||||
- creates a market buy order for 0.1 ETH @ market price
|
||||
- `create_market_order_eth_sell.py`
|
||||
- creates a market sell order for 0.1 ETH @ market price
|
||||
|
||||
- `create_grouped_ioc_with_attached_sl_tp.py`
|
||||
- creates an ask (sell) IoC order for 0.1 ETH
|
||||
- along w/ the order, it sets up a Stop Loss (SL) and a Take Profit (TP) order for the whole size of the order
|
||||
- the size of the SL/TP will be equal to the executed size of the order
|
||||
- the SL/TP orders are canceled when the sign of your position changes
|
||||
|
||||
- `create_position_tied_sl_tp.py`
|
||||
- creates a bid (buy) Stop Loss (SL) and a Take Profit (TP) to close your short position
|
||||
- the size of the orders will be for your whole position (because BaseAmount=0)
|
||||
- the orders will grow / shrink as you accumulate more position
|
||||
- the SL/TP orders are canceled when the sign of your position changes
|
||||
|
||||
## On SL/TP orders
|
||||
SL/TP orders need to be configured beyond just setting the trigger price. When the trigger price is set,
|
||||
the order will just be executed, like a normal order. This means that a market order, for example, might not have enough slippage! \
|
||||
Let's say that you have a 1 BTC long position, and the current price is $110'000. \
|
||||
You want to set up a take profit at $120'000
|
||||
- order should be an ask (sell) order, to close your position
|
||||
- the trigger price should be $120'000
|
||||
|
||||
What about the order types? Just as normal orders, SL/TP orders trigger an order, which can be:
|
||||
- market order
|
||||
- limit IOC / GTC
|
||||
|
||||
## Modify leverage / Margin Mode (Cross, Isolated) / Add Collateral to isolated-only positions
|
||||
- `margin_eth_20x_cross_http`
|
||||
- sets ETH market to 20x leverage and cross-margin mode, using HTTP
|
||||
- `margin_eth_50x_isolate_ws`
|
||||
- sets ETH market to 50x leverage and isolated margin mode, using HTTP
|
||||
- `margin_eth_add_collateral_http.py`
|
||||
- adds $10.5 USDC to the ETH position (must be opened and in isolated mode)
|
||||
- `margin_eth_remove_collateral_ws.py`
|
||||
- removes $5 USDC from the ETH position (must be opened and in isolated mode)
|
||||
|
||||
## Batch orders
|
||||
- `send_batch_tx_http.py`
|
||||
- sends multiple orders in a single HTTP request
|
||||
- `send_batch_tx_ws.py`
|
||||
- sends multiple orders in a single WS request`
|
||||
|
||||
Batch TXs will be executed back to back, without the possibility of other TXs interfering.
|
||||
|
||||
## Spot Trading
|
||||
To trade spot markets, you need to have spot USDC. USDC used in your perpetual account will be used as collateral for your cross-positions.
|
||||
USDC deposited in the spot account can only be used to buy spot assets.
|
||||
To transfer USDC between spot <> perp balance, or vice verse, check out
|
||||
- `spot_self_transfer_perp_spot.py`
|
||||
- `spot_self_transfer_spot_perp.py`
|
||||
|
||||
Order placement / trades work in the same way as for perpetual markets.
|
||||
The fee will be paid in the received asset for premium spot trades.
|
||||
This means that if you sell ETH, you'll receive less USDC, and if you BUY 1 ETH, you'll receive slightly less than 1 ETH.
|
||||
You can check out the following examples, which should work on spot ETH by changing the market index to 2048 instead of 0.
|
||||
- `create_modify_cancel_order_http.py`
|
||||
- `create_modify_cancel_order_ws.py`
|
||||
- `create_market_order_eth_buy.py`
|
||||
- `create_market_order_eth_sell.py`
|
||||
- `send_batch_tx_http.py`
|
||||
- `send_batch_tx_ws.py`
|
||||
|
||||
Trading setup is very similar to perpetual markets.
|
||||
The only difference is that you'll need to hold USDC / ETH before placing an order.
|
||||
For example, on perp markets you can place an order to short (sell) ETH without having to worry that much.
|
||||
The limitation there would be to have enough available collateral to cover the order.
|
||||
On spot orders, you need to have enough assets in your spot account to cover all open orders.
|
||||
If you want to place two orders, to buy 1000 USDC worth of ETH and 1000 USDC worth of ZK, you'll need to have at least 2000 available USDC.
|
||||
|
||||
You can get the order book details (including symbol and market index) as well as quote asset id (ETH) and base asset id (USDC)
|
||||
by following the example below:
|
||||
- `spot_get_order_books.py`
|
||||
|
||||
Note: you'll need the quote asset id and base asset id to check available balance.
|
||||
Available balance is not locked in open orders.
|
||||
|
||||
To keep track of your spot balance, you can use HTTP calls or a websocket subscription.
|
||||
Examples on how to do this can be found here:
|
||||
- `spot_get_account_assets_http.py`
|
||||
- `spot_get_account_assets_ws.py`
|
||||
|
||||
Moving money to / from subaccounts is possible for spot assets.
|
||||
For USDC, you can move directly from main perp balance to subaccount spot balance, for example.
|
||||
More details can be found in the following example:
|
||||
- `sub_account_create.py`
|
||||
- `sub_account_transfer_eth.py`
|
||||
- `sub_account_transfer_usdc.py`
|
||||
|
||||
## Public Pools
|
||||
Public pools behave just like subaccounts, except that anyone can join them.
|
||||
You can create / modify a public pool using the SDK. Check out the following example:
|
||||
- `public_pool_create_modify.py`
|
||||
|
||||
To create API keys for a public pool, you need to run the setup script but specify the `ACCOUNT_INDEX` to be the one of the public pool.
|
||||
After that, you can trade from the public as from any other account.
|
||||
|
||||
If you want to deposit / withdraw from a public pool, check the following example:
|
||||
- `public_pool_deposit.py`
|
||||
- `public_pool_withdraw.py`
|
||||
|
||||
To get information about pools, check:
|
||||
- `public_pool_info.py`
|
||||
|
||||
## Moving funds around
|
||||
- `withdraw_fast.py`
|
||||
- send USDC directly from Lighter to Arbitrum
|
||||
- `withdraw_normal.py`
|
||||
- send USDC/ETH from Lighter to Ethereum
|
||||
- `transfer.py`
|
||||
- generic example of how to transfer funds between accounts.
|
||||
- same functionality as `sub_account_transfer_eth` and `sub_account_transfer_usdc`
|
||||
|
||||
## Transfer Notes
|
||||
The `memo` field is a user message, and it has to be exactly 32 bytes long. In case of fast withdrawals, you need to specify the recipient in the memo.
|
||||
This is the case since the memo is part of the signature. This way, the recipient is verified.
|
||||
|
||||
When calling `client.transfer`, you pass the amount without needing to worry about the decimals.
|
||||
When calling `client.sign_transfer` on the other hand, you need to specify the decimals and pass an integer.
|
||||
|
||||
The `fee` field can be obtained by calling `info_api.transfer_fee_info(...)`. The field can be passed as it is.
|
||||
Transfers between subaccounts are free for all assets.
|
||||
|
||||
When sending assets, you can specify the source and destination routes.
|
||||
A route is either `perp` or `spot`. You can send USDC directly from your perp balance to another person's spot balance.
|
||||
If you receive USDC in your perp account, it will be instantly used as collateral for open positions.
|
||||
This also allows you to move USDC from your spot balance to your perp balance.
|
||||
Spot assets (like ETH) need to have both the from and to route set to `spot`.
|
||||
You can get all `asset_id`s by following the example below:
|
||||
- `spot_get_order_books.py`
|
||||
|
||||
## Setup steps for mainnet
|
||||
- deposit money on Lighter to create an account first
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
# Alternatively, you can go to https://app.lighter.xyz/apikeys for mainnet api keys
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 1
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
api_client = lighter.ApiClient(configuration=lighter.Configuration(host=BASE_URL))
|
||||
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {trim_exception(err)}")
|
||||
return
|
||||
|
||||
# create order
|
||||
tx, tx_hash, err = await client.create_order(
|
||||
market_index=0,
|
||||
client_order_index=123,
|
||||
base_amount=100000,
|
||||
price=405000,
|
||||
is_ask=True,
|
||||
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
|
||||
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=0,
|
||||
trigger_price=0,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
auth, err = client.create_auth_token_with_expiry(lighter.SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY)
|
||||
print(f"{auth=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
# cancel order
|
||||
tx, tx_hash, err = await client.cancel_order(
|
||||
market_index=0,
|
||||
order_index=123,
|
||||
)
|
||||
print(f"Cancel Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,69 @@
|
||||
import asyncio
|
||||
from lighter.signer_client import CreateOrderTxReq
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Sell some ETH at $2500
|
||||
# The size of the SL/TP orders will be equal to the size of the executed order
|
||||
|
||||
# set SL trigger price at 5000 and limit price at 5050
|
||||
# set TP trigger price at 1500 and limit price at 1550
|
||||
# Note: set the limit price to be higher than the SL/TP trigger price to ensure the order will be filled
|
||||
# If the mark price of ETH reaches 1500, there might be no one willing to sell you ETH at 1500, so trying to buy at 1550 would increase the fill rate
|
||||
|
||||
ioc_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=1000, # 0.1 ETH
|
||||
Price=2500_00, # $2500
|
||||
IsAsk=1, # sell
|
||||
Type=client.ORDER_TYPE_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_IMMEDIATE_OR_CANCEL,
|
||||
ReduceOnly=0,
|
||||
TriggerPrice=0,
|
||||
OrderExpiry=0,
|
||||
)
|
||||
|
||||
# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
|
||||
take_profit_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=1550_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=1500_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
stop_loss_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=5050_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_STOP_LOSS_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=5000_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
transaction = await client.create_grouped_orders(
|
||||
grouping_type=client.GROUPING_TYPE_ONE_TRIGGERS_A_ONE_CANCELS_THE_OTHER,
|
||||
orders=[ioc_order, take_profit_order, stop_loss_order],
|
||||
)
|
||||
|
||||
print("Create Grouped Order Tx:", transaction)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,39 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and serves as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
tx = await client.create_market_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=170000, # $1700 -- worst acceptable price for the order
|
||||
is_ask=True,
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,28 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
tx, tx_hash, err = await client.create_market_order(
|
||||
market_index=market_index,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=4000_00, # $4000 -- worst acceptable price for the order
|
||||
is_ask=False,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,28 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
tx, tx_hash, err = await client.create_market_order(
|
||||
market_index=market_index,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=1700_00, # $1700 -- worst acceptable price for the order
|
||||
is_ask=True,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,33 +1,21 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and serves as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xe0fa55e11d6b5575d54c0500bd2f3b240221ae90241e3b573f2307e27de20c04ea628de3f1936e56"
|
||||
ACCOUNT_INDEX = 22
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# tx = await client.create_market_order_limited_slippage(market_index=0, client_order_index=0, base_amount=30000000,
|
||||
# max_slippage=0.001, is_ask=True)
|
||||
tx = await client.create_market_order_if_slippage(market_index=0, client_order_index=0, base_amount=30000000,
|
||||
max_slippage=0.01, is_ask=True, ideal_price=300000)
|
||||
tx = await client.create_market_order_if_slippage(
|
||||
market_index=0, # ETH
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
max_slippage=0.01, # 1%
|
||||
is_ask=True,
|
||||
ideal_price=300000 # $3000
|
||||
)
|
||||
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
# create order
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
tx, tx_hash, err = await client.create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=123,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=4050_00, # $4050
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
## modify order
|
||||
# use the same API key so the TX goes after the create order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx, tx_hash, err = await client.modify_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
base_amount=1100, # 0.11 ETH
|
||||
price=4100_00, # $4100
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Modify Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
## cancel order
|
||||
# use the same API key so the TX goes after the modify order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx, tx_hash, err = await client.cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Cancel Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,72 @@
|
||||
import websockets
|
||||
import asyncio
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
# this example does the same thing as the create_modify_cancel_order.py example, but sends the TX over WS instead of HTTP
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
# create order
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
tx_type, tx_info, tx_hash, err = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=123,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=4050_00, # $4050
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
## modify order
|
||||
# use the same API key so the TX goes after the create order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx_type, tx_info, tx_hash, err = client.sign_modify_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
base_amount=1100, # 0.11 ETH
|
||||
price=4100_00, # $4100
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
## cancel order
|
||||
# use the same API key so the TX goes after the modify order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx_type, tx_info, tx_hash, err = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,56 @@
|
||||
import asyncio
|
||||
from lighter.signer_client import CreateOrderTxReq
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Creates a position tied SL/TP pair
|
||||
# The SL/TP orders will close your whole position, even if you add/remove from it later on
|
||||
# if the positions reach 0 or switches from short -> long, the orders are canceled
|
||||
|
||||
# this particular example, sets the SL/TP for a short position
|
||||
# set SL trigger price at 5000 and limit price at 5050
|
||||
# set TP trigger price at 1500 and limit price at 1550
|
||||
# Note: set the limit price to be higher than the SL/TP trigger price to ensure the order will be filled
|
||||
# If the mark price of ETH reaches 1500, there might be no one willing to sell you ETH at 1500, so trying to buy at 1550 would increase the fill rate
|
||||
|
||||
# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
|
||||
take_profit_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=1550_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=1500_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
stop_loss_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=4050_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_STOP_LOSS_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=4000_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
transaction = await client.create_grouped_orders(
|
||||
grouping_type=client.GROUPING_TYPE_ONE_CANCELS_THE_OTHER,
|
||||
orders=[take_profit_order, stop_loss_order],
|
||||
)
|
||||
|
||||
print("Create Grouped Order Tx:", transaction)
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,70 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xe0fa55e11d6b5575d54c0500bd2f3b240221ae90241e3b573f2307e27de20c04ea628de3f1936e56"
|
||||
ACCOUNT_INDEX = 22
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
tx = await client.create_tp_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
|
||||
|
||||
tx = await client.create_sl_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
|
||||
tx = await client.create_tp_limit_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
|
||||
tx = await client.create_sl_limit_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,47 +1,30 @@
|
||||
import time
|
||||
import asyncio
|
||||
import lighter
|
||||
|
||||
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
# use examples/system_setup.py or the apikeys page (for mainnet) to generate new api keys
|
||||
KEYS = {
|
||||
5: "API_PRIVATE_KEY_5",
|
||||
6: "API_PRIVATE_KEY_6",
|
||||
7: "API_PRIVATE_KEY_7",
|
||||
}
|
||||
ACCOUNT_INDEX = 100 # replace with your account_index
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=KEYS[5],
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=5,
|
||||
max_api_key_index=7,
|
||||
private_keys=KEYS,
|
||||
)
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
# create 20 orders. The client will use as many API keys as it was configured.
|
||||
|
||||
for i in range(20):
|
||||
res_tuple = await client.create_order(
|
||||
market_index=0,
|
||||
client_order_index=123 + i,
|
||||
base_amount=100000 + i,
|
||||
price=385000 + i,
|
||||
base_amount=1000 + i, # 0.1 ETH + dust
|
||||
price=3850_00 + i,
|
||||
is_ask=True,
|
||||
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
|
||||
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=0,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
)
|
||||
print(res_tuple)
|
||||
|
||||
await client.cancel_all_orders(time_in_force=client.CANCEL_ALL_TIF_IMMEDIATE, time=0)
|
||||
# wait for orders to be created
|
||||
time.sleep(1)
|
||||
await client.cancel_all_orders(time_in_force=client.CANCEL_ALL_TIF_IMMEDIATE, timestamp_ms=0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -75,7 +75,11 @@ async def transaction_apis(client: lighter.ApiClient):
|
||||
# use with a valid sequence index
|
||||
# await print_api(transaction_instance.tx, by="sequence_index", value="5")
|
||||
await print_api(transaction_instance.txs, index=0, limit=2)
|
||||
|
||||
|
||||
async def funding_apis(client: lighter.ApiClient):
|
||||
logging.info("FUNDING APIS")
|
||||
account_instance = lighter.FundingApi(client)
|
||||
await print_api(account_instance.funding_rates)
|
||||
|
||||
async def main():
|
||||
client = lighter.ApiClient(configuration=lighter.Configuration(host="https://testnet.zklighter.elliot.ai"))
|
||||
@@ -84,6 +88,7 @@ async def main():
|
||||
await candlestick_apis(client)
|
||||
await order_apis(client)
|
||||
await transaction_apis(client)
|
||||
await funding_apis(client)
|
||||
await client.close()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: the HTTP method `update_leverage` receives `leverage` as the argument,
|
||||
# while the WS one that calls `sign_update_leverage` to get the TX to send it directly over WS
|
||||
# receives `fraction` as the argument, which is 10_000 / leverage
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx, tx_hash, err = await client.update_leverage(
|
||||
market_index=0,
|
||||
leverage=20,
|
||||
margin_mode=client.CROSS_MARGIN_MODE
|
||||
)
|
||||
|
||||
print(f"Update Leverage {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import websockets
|
||||
import asyncio
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: the HTTP method `update_leverage` receives `leverage` as the argument,
|
||||
# while the WS one that calls `sign_update_leverage` to get the TX to send it directly over WS
|
||||
# receives `fraction` as the argument, which is 10_000 / leverage
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx_type, tx_info, tx_hash, err = client.sign_update_leverage(
|
||||
market_index=0,
|
||||
fraction=10_000 // 50,
|
||||
margin_mode=client.ISOLATED_MARGIN_MODE
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,29 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: the HTTP method `update_margin` receives `usdc_amount` (float) as the argument,
|
||||
# while the WS one that calls `sign_update_margin` to get the TX to send it directly over WS
|
||||
# receives `usdc_amount` (int) as the argument, which is the float one * 1_000_000
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx, tx_hash, err = await client.update_margin(
|
||||
market_index=0,
|
||||
usdc_amount=10.5,
|
||||
direction=client.ISOLATED_MARGIN_ADD_COLLATERAL
|
||||
)
|
||||
|
||||
print(f"Update Margin {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: the HTTP method `update_margin` receives `usdc_amount` (float) as the argument,
|
||||
# while the WS one that calls `sign_update_margin` to get the TX to send it directly over WS
|
||||
# receives `usdc_amount` (int) as the argument, which is the float one * 1_000_000
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx_type, tx_info, tx_hash, err = client.sign_update_margin(
|
||||
market_index=0,
|
||||
usdc_amount=5_000_000, # 5 USDC
|
||||
direction=client.ISOLATED_MARGIN_REMOVE_COLLATERAL
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,59 @@
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
tx_api = lighter.TransactionApi(api_client)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
auth, _ = client.create_auth_token_with_expiry()
|
||||
|
||||
# create a public pool
|
||||
tx_info, response, err = await client.create_public_pool(
|
||||
operator_fee=100000, # 10%
|
||||
initial_total_shares=1_000_000, # 1000 USDC
|
||||
min_operator_share_rate=100, # 1%
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to create public pool {err}')
|
||||
tx_hash = response.tx_hash
|
||||
print(f"✅ send create public pool tx. hash: {tx_hash}")
|
||||
|
||||
# fetch pool account index from tx hash
|
||||
pool_account_index = -1
|
||||
for i in range(10):
|
||||
time.sleep(1)
|
||||
try:
|
||||
response = await tx_api.tx(by="hash", value=tx_hash)
|
||||
event_info_j = json.loads(response.event_info)
|
||||
pool_account_index = event_info_j['a']
|
||||
except Exception as e:
|
||||
pass
|
||||
if pool_account_index != -1:
|
||||
break
|
||||
if pool_account_index == -1:
|
||||
raise Exception(f"failed to find pool account index for tx {tx_hash}")
|
||||
print(f"✅ pool account index: {pool_account_index}")
|
||||
|
||||
# Note: ❗️operator_fee can only decrease
|
||||
# modify pool metadata
|
||||
tx_info, response, err = await client.update_public_pool(
|
||||
public_pool_index=pool_account_index,
|
||||
status=0, # 0 is active | 1 is frozen
|
||||
operator_fee=50000, # 5%
|
||||
min_operator_share_rate=1000, # 10%
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to create update pool {err}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
|
||||
from utils import default_example_setup
|
||||
|
||||
POOL_ACCOUNT_INDEX = 281474976710651
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
tx_info, response, err = await client.mint_shares(public_pool_index=POOL_ACCOUNT_INDEX, share_amount=10_000)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to mint shares {err}')
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,33 @@
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
POOL_ACCOUNT_INDEX = 281474976710651
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
account_api = lighter.AccountApi(api_client)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
account = await account_api.account(by="index", value=str(client.account_index))
|
||||
|
||||
# Note: ❗️shares field does not return the shared you have in pools that you're the operator
|
||||
for pool in account.accounts[0].shares:
|
||||
pool_resp = await account_api.account(by="index", value=str(pool.public_pool_index))
|
||||
pool_account = pool_resp.accounts[0]
|
||||
|
||||
share_price = float(pool_account.total_asset_value) / float(pool_account.pool_info.total_shares)
|
||||
print(
|
||||
f"poolAccountId: {pool.public_pool_index} numShared: {pool.shares_amount} sharePrice: {share_price:.6f} value: {share_price * pool.shares_amount:.2f} pnl: {share_price * pool.shares_amount - float(pool.entry_usdc):.2f}")
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,26 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
POOL_ACCOUNT_INDEX = 281474976710651
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
auth, _ = client.create_auth_token_with_expiry()
|
||||
|
||||
tx_info, response, err = await client.burn_shares(public_pool_index=POOL_ACCOUNT_INDEX, share_amount=10_000)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to mint shares {err}')
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1 @@
|
||||
*.json
|
||||
@@ -0,0 +1,168 @@
|
||||
# Read-Only Auth Token Pre-Generation
|
||||
|
||||
This example demonstrates how to pre-generate authentication tokens for read-only operations on the Lighter platform. By generating tokens ahead of time, you can avoid needing access to your API private keys during runtime for read-only queries.
|
||||
|
||||
## Overview
|
||||
|
||||
Authentication tokens on Lighter have a maximum expiry of 8 hours. This example allows you to:
|
||||
|
||||
1. Configure a dedicated API key (index 253) for all your accounts
|
||||
2. Pre-generate authentication tokens for future time periods
|
||||
3. Use these tokens for read-only operations without exposing your private keys
|
||||
|
||||
The tokens are generated at 6-hour intervals (aligned to Unix timestamp // 6 hours), with each token valid for 8 hours. This provides an overlap period ensuring continuous coverage.
|
||||
|
||||
## Setup
|
||||
|
||||
The setup script configures API key 253 for all accounts associated with your Ethereum private key.
|
||||
|
||||
### Running Setup
|
||||
|
||||
```bash
|
||||
cd examples/read-only-auth
|
||||
python3 setup.py config.json
|
||||
```
|
||||
|
||||
This will:
|
||||
- Query all accounts for your L1 address
|
||||
- Generate new API key pairs for each account
|
||||
- Change API key 253 to use the new keys
|
||||
- Output configuration in JSON format
|
||||
|
||||
### Configuration Variables
|
||||
|
||||
Edit the constants in `setup.py`:
|
||||
|
||||
```python
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
ETH_PRIVATE_KEY = "your_ethereum_private_key_here"
|
||||
API_KEY_INDEX = 253 # Using 253 as it's typically unused
|
||||
```
|
||||
|
||||
### Config Format
|
||||
|
||||
```json
|
||||
{
|
||||
"BASE_URL": "https://testnet.zklighter.elliot.ai",
|
||||
"ACCOUNTS": [
|
||||
{
|
||||
"api_key_private_key": "...",
|
||||
"account_index": 0,
|
||||
"api_key_index": 253
|
||||
},
|
||||
{
|
||||
"api_key_private_key": "...",
|
||||
"account_index": 1,
|
||||
"api_key_index": 253
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Generating Tokens
|
||||
|
||||
The generation script creates authentication tokens for future time periods.
|
||||
|
||||
### Running Generation
|
||||
|
||||
```bash
|
||||
NUM_DAYS=10 python3 generate.py config.json
|
||||
```
|
||||
|
||||
If no config file is specified, it defaults to `config.json`.
|
||||
|
||||
### Duration Configuration
|
||||
|
||||
You can specify the duration in days using the `NUM_DAYS` environment variable, as in the command above.
|
||||
If the value is not specified, it defaults to 28 days.
|
||||
|
||||
### Output Format
|
||||
|
||||
The script generates `auth-tokens.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"0": {
|
||||
"1697184000": "auth_token_string_1",
|
||||
"1697205600": "auth_token_string_2",
|
||||
"1697227200": "auth_token_string_3"
|
||||
},
|
||||
"1": {
|
||||
"1697184000": "auth_token_string_1",
|
||||
"1697205600": "auth_token_string_2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Where:
|
||||
- First level key: account index
|
||||
- Second level key: Unix timestamp (aligned to 6-hour boundaries)
|
||||
- Value: authentication token
|
||||
|
||||
## Usage
|
||||
|
||||
### Looking Up Tokens
|
||||
|
||||
Check the `get_auth_token.py` script which prints the Auth Token that should be used **at this moment**, as this will be invalidated in at most 8 hours.
|
||||
|
||||
### Time Alignment
|
||||
|
||||
All timestamps are aligned to 6-hour boundaries:
|
||||
- Timestamps are divisible by 21600 seconds (6 hours)
|
||||
- Calculation: `unix_timestamp // (6 * 3600) * (6 * 3600)`
|
||||
- This ensures consistent token lookup across different systems
|
||||
|
||||
### Token Expiry
|
||||
|
||||
Each token is valid for 8 hours from its timestamp:
|
||||
- Token timestamp: aligned to 6-hour boundary
|
||||
- Valid until: timestamp + 8 hours
|
||||
- This provides 2 hours of overlap between consecutive tokens
|
||||
|
||||
## Security
|
||||
|
||||
### API Key 253
|
||||
|
||||
We use API key index 253 because:
|
||||
- It's the last available index [0-253]
|
||||
- It's not typically used by trading
|
||||
- Easy to remember for this specific use case
|
||||
- Easy to change and invalidate all tokens.
|
||||
|
||||
### Invalidating Tokens
|
||||
|
||||
To invalidate all existing tokens:
|
||||
|
||||
```bash
|
||||
python3 setup.py config.json
|
||||
```
|
||||
|
||||
Re-running the setup script generates new API keys for index 253, which invalidates all previously generated authentication tokens. This is useful if:
|
||||
- You suspect your tokens have been compromised
|
||||
- You want to rotate your tokens periodically
|
||||
- You need to revoke access immediately
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Store tokens securely**: The `auth-tokens.json` file contains sensitive data (read only, but still)
|
||||
2. **Dedicated API key**: Use API key 253 for read-only token generation, as it can be invalidated easely.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Account not found" error
|
||||
|
||||
Make sure your Ethereum private key corresponds to an account registered on the Lighter platform.
|
||||
|
||||
### "Failed to change API key" error
|
||||
|
||||
This could happen if:
|
||||
- The API key change transaction failed
|
||||
- Network connectivity issues
|
||||
- The account is not active
|
||||
|
||||
## Additional Notes
|
||||
|
||||
- Tokens are specific to each account index
|
||||
- Each account has its own set of time-aligned tokens
|
||||
- The system uses the SignerClient's native `create_auth_token_with_expiry` method
|
||||
@@ -0,0 +1,103 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.INFO, force=True)
|
||||
|
||||
|
||||
def create_auth_token_for_timestamp(signer_client, timestamp, expiry_hours):
|
||||
auth_token, error = signer_client.create_auth_token_with_expiry(expiry_hours * 3600, timestamp=timestamp)
|
||||
if error is not None:
|
||||
raise Exception(f"Failed to create auth token: {error}")
|
||||
return auth_token
|
||||
|
||||
|
||||
async def generate_tokens_for_account(account_info, base_url, duration_days):
|
||||
account_index = account_info["account_index"]
|
||||
api_key_private_key = account_info["api_key_private_key"]
|
||||
api_key_index = account_info["api_key_index"]
|
||||
|
||||
logging.info(f"Generating tokens for account {account_index}")
|
||||
|
||||
signer_client = lighter.SignerClient(
|
||||
url=base_url,
|
||||
private_key=api_key_private_key,
|
||||
account_index=account_index,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
current_time = int(time.time())
|
||||
interval_seconds = 6 * 3600
|
||||
start_timestamp = (current_time // interval_seconds) * interval_seconds
|
||||
|
||||
num_tokens = 4 * duration_days
|
||||
expiry_hours = 8
|
||||
|
||||
tokens = {}
|
||||
for i in range(num_tokens):
|
||||
timestamp = start_timestamp + (i * interval_seconds)
|
||||
try:
|
||||
auth_token = create_auth_token_for_timestamp(signer_client, timestamp, expiry_hours)
|
||||
tokens[str(timestamp)] = auth_token
|
||||
logging.debug(f"Generated token for timestamp {timestamp}")
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to generate token for timestamp {timestamp}: {e}")
|
||||
|
||||
await signer_client.close()
|
||||
|
||||
return account_index, tokens
|
||||
|
||||
|
||||
async def main():
|
||||
config_file = "config.json"
|
||||
if len(sys.argv) > 1:
|
||||
config_file = sys.argv[1]
|
||||
|
||||
try:
|
||||
with open(config_file, "r") as f:
|
||||
config = json.load(f)
|
||||
except FileNotFoundError:
|
||||
logging.error(f"Config file '{config_file}' not found")
|
||||
logging.error("Run setup.py first: python3 setup.py > config.json")
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(f"Invalid JSON in config file: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
num_days = int(os.getenv("NUM_DAYS") or 28)
|
||||
base_url = config.get("BASE_URL")
|
||||
accounts = config.get("ACCOUNTS", [])
|
||||
duration_days = config.get("DURATION_IN_DAYS", num_days)
|
||||
|
||||
if not base_url:
|
||||
logging.error("BASE_URL not found in config")
|
||||
sys.exit(1)
|
||||
|
||||
if not accounts:
|
||||
logging.error("No accounts found in config")
|
||||
sys.exit(1)
|
||||
|
||||
logging.info(f"Generating tokens for {len(accounts)} account(s)")
|
||||
logging.info(f"Duration: {duration_days} days ({4 * duration_days} tokens per account)")
|
||||
|
||||
auth_tokens = {}
|
||||
for account_info in accounts:
|
||||
account_index, tokens = await generate_tokens_for_account(account_info, base_url, duration_days)
|
||||
auth_tokens[str(account_index)] = tokens
|
||||
|
||||
output_file = "auth-tokens.json"
|
||||
with open(output_file, "w") as f:
|
||||
json.dump(auth_tokens, f, indent=2)
|
||||
|
||||
logging.info(f"Successfully generated tokens and saved to {output_file}")
|
||||
logging.info(f"Total accounts: {len(auth_tokens)}")
|
||||
for account_index, tokens in auth_tokens.items():
|
||||
logging.info(f" Account {account_index}: {len(tokens)} tokens")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,30 @@
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
|
||||
logging.basicConfig(level=logging.INFO, force=True)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) == 1:
|
||||
logging.error("No account index specified")
|
||||
return
|
||||
|
||||
account_index = sys.argv[1]
|
||||
|
||||
# Load pre-generated tokens
|
||||
with open('auth-tokens.json') as f:
|
||||
auth_tokens = json.load(f)
|
||||
|
||||
# Get current aligned timestamp (6-hour boundary)
|
||||
current_timestamp = (int(time.time()) // (6 * 3600)) * (6 * 3600)
|
||||
|
||||
# Look up token for specific account
|
||||
auth_token = auth_tokens[account_index][str(current_timestamp)]
|
||||
|
||||
print(f"{auth_token=}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,113 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
import eth_account
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.INFO, force=True)
|
||||
|
||||
# use https://mainnet.zklighter.elliot.ai for mainnet
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
API_KEY_INDEX = 253
|
||||
|
||||
|
||||
async def setup_account(eth_private_key, account_index, base_url, api_key_index):
|
||||
private_key, public_key, err = lighter.create_api_key()
|
||||
if err is not None:
|
||||
return None, f"Failed to create API key for account {account_index}: {err}"
|
||||
|
||||
tx_client = lighter.SignerClient(
|
||||
url=base_url,
|
||||
private_key=private_key,
|
||||
account_index=account_index,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
response, err = await tx_client.change_api_key(
|
||||
eth_private_key=eth_private_key,
|
||||
new_pubkey=public_key,
|
||||
)
|
||||
if err is not None:
|
||||
await tx_client.close()
|
||||
return None, f"Failed to change API key for account {account_index}: {err}"
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
err = tx_client.check_client()
|
||||
if err is not None:
|
||||
await tx_client.close()
|
||||
return None, f"Failed to verify API key for account {account_index}: {err}"
|
||||
|
||||
await tx_client.close()
|
||||
|
||||
return {
|
||||
"api_key_private_key": private_key,
|
||||
"account_index": account_index,
|
||||
"api_key_index": api_key_index,
|
||||
}, None
|
||||
|
||||
|
||||
async def main():
|
||||
config_file = "config.json"
|
||||
if len(sys.argv) > 1:
|
||||
config_file = sys.argv[1]
|
||||
|
||||
api_client = lighter.ApiClient(configuration=lighter.Configuration(host=BASE_URL))
|
||||
eth_acc = eth_account.Account.from_key(ETH_PRIVATE_KEY)
|
||||
eth_address = eth_acc.address
|
||||
|
||||
try:
|
||||
response = await lighter.AccountApi(api_client).accounts_by_l1_address(
|
||||
l1_address=eth_address
|
||||
)
|
||||
except lighter.ApiException as e:
|
||||
if e.data.message == "account not found":
|
||||
print(f"error: account not found for {eth_address}", file=__import__('sys').stderr)
|
||||
await api_client.close()
|
||||
return
|
||||
else:
|
||||
await api_client.close()
|
||||
raise e
|
||||
|
||||
if len(response.sub_accounts) == 0:
|
||||
print(f"error: no accounts found for {eth_address}", file=__import__('sys').stderr)
|
||||
await api_client.close()
|
||||
return
|
||||
|
||||
logging.info(f"Found {len(response.sub_accounts)} account(s)")
|
||||
|
||||
# don't do this async
|
||||
accounts = []
|
||||
for sub_account in response.sub_accounts:
|
||||
logging.info(f"Setting up account index: {sub_account.index}")
|
||||
result, err = await setup_account(
|
||||
ETH_PRIVATE_KEY,
|
||||
sub_account.index,
|
||||
BASE_URL,
|
||||
API_KEY_INDEX,
|
||||
)
|
||||
|
||||
if err is not None:
|
||||
logging.error(err)
|
||||
else:
|
||||
accounts.append(result)
|
||||
|
||||
if not accounts:
|
||||
print("error: failed to setup any accounts", file=__import__('sys').stderr)
|
||||
await api_client.close()
|
||||
return
|
||||
|
||||
with open(config_file, "w", encoding="utf-8") as f:
|
||||
json.dump({
|
||||
"BASE_URL": BASE_URL,
|
||||
"ACCOUNTS": accounts,
|
||||
}, f, ensure_ascii=False, indent=2)
|
||||
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,156 @@
|
||||
import asyncio
|
||||
import time
|
||||
from utils import default_example_setup, trim_exception
|
||||
|
||||
|
||||
# this example does the same thing as the send_batch_tx_ws.py example, but sends the TX over HTTP instead of WS
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
ask_tx_type, ask_tx_info, ask_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1001, # Unique identifier for this order
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=5000_00, # $5000
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing ask order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# intentionally pass api_key_index to the client.nonce_manager so it increases the nonce, without changing the API key.
|
||||
# in batch TXs, all TXs must come from the same API key.
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
bid_tx_type, bid_tx_info, bid_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1002, # Different unique identifier
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=1500_00, # $1500
|
||||
is_ask=False,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [ask_tx_type, bid_tx_type]
|
||||
tx_infos = [ask_tx_info, bid_tx_info]
|
||||
tx_hashes = [ask_tx_hash, bid_tx_hash]
|
||||
|
||||
try:
|
||||
response = await client.send_tx_batch(tx_types=tx_types, tx_infos=tx_infos)
|
||||
print(f"Batch transaction successful: {response} expected: {tx_hashes}")
|
||||
except Exception as e:
|
||||
print(f"Error sending batch transaction: {trim_exception(e)}")
|
||||
|
||||
# In case we want to see the changes in the UI, sleep a bit
|
||||
time.sleep(5)
|
||||
|
||||
# since this is a new batch, we can request a fresh API key
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
cancel_tx_type, cancel_tx_info, cancel_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1001, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# intentionally pass api_key_index to the client.nonce_manager so it increases the nonce, without changing the API key.
|
||||
# in batch TXs, all TXs must come from the same API key.
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
new_ask_tx_type, new_ask_tx_info, new_ask_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1003, # Different unique identifier
|
||||
base_amount=2000, # 0.2 ETH
|
||||
price=5500_00, # $5500
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [cancel_tx_type, new_ask_tx_type]
|
||||
tx_infos = [cancel_tx_info, new_ask_tx_info]
|
||||
tx_hashes = [cancel_tx_hash, new_ask_tx_hash]
|
||||
|
||||
try:
|
||||
response = await client.send_tx_batch(tx_types=tx_types, tx_infos=tx_infos)
|
||||
print(f"Batch transaction successful: {response} expected: {tx_hashes}")
|
||||
except Exception as e:
|
||||
print(f"Error sending batch transaction: {trim_exception(e)}")
|
||||
|
||||
# In case we want to see the changes in the UI, sleep a bit
|
||||
time.sleep(5)
|
||||
|
||||
# since this is a new batch, we can request a fresh API key
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
cancel_1_tx_type, cancel_1_tx_info, cancel_1_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1002, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (third batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
cancel_2_tx_type, cancel_2_tx_info, cancel_2_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1003, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (third batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [cancel_1_tx_type, cancel_2_tx_type]
|
||||
tx_infos = [cancel_1_tx_info, cancel_2_tx_info]
|
||||
tx_hashes = [cancel_1_tx_hash, cancel_2_tx_hash]
|
||||
|
||||
try:
|
||||
response = await client.send_tx_batch(tx_types=tx_types, tx_infos=tx_infos)
|
||||
print(f"Batch transaction successful: {response} expected: {tx_hashes}")
|
||||
except Exception as e:
|
||||
print(f"Error sending batch transaction: {trim_exception(e)}")
|
||||
|
||||
|
||||
# Clean up
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
# Run the async main function
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,150 @@
|
||||
import websockets
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from utils import default_example_setup, ws_send_batch_tx, trim_exception
|
||||
|
||||
|
||||
# this example does the same thing as the send_batch_tx_http.py example, but sends the TX over WS instead of HTTP
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 2048
|
||||
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
ask_tx_type, ask_tx_info, ask_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1001, # Unique identifier for this order
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=5000_00, # $5000
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing ask order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# intentionally pass api_key_index to the client.nonce_manager so it increases the nonce, without changing the API key.
|
||||
# in batch TXs, all TXs must come from the same API key.
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
bid_tx_type, bid_tx_info, bid_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1002, # Different unique identifier
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=1500_00, # $1500
|
||||
is_ask=False,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [ask_tx_type, bid_tx_type]
|
||||
tx_infos = [ask_tx_info, bid_tx_info]
|
||||
tx_hashes = [ask_tx_hash, bid_tx_hash]
|
||||
|
||||
await ws_send_batch_tx(ws_client, tx_types, tx_infos, tx_hashes)
|
||||
|
||||
# In case we want to see the changes in the UI, sleep a bit
|
||||
time.sleep(5)
|
||||
|
||||
# since this is a new batch, we can request a fresh API key
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
cancel_tx_type, cancel_tx_info, cancel_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1001, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# intentionally pass api_key_index to the client.nonce_manager so it increases the nonce, without changing the API key.
|
||||
# in batch TXs, all TXs must come from the same API key.
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
new_ask_tx_type, new_ask_tx_info, new_ask_tx_hash, error = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=1003, # Different unique identifier
|
||||
base_amount=2000, # 0.2 ETH
|
||||
price=5500_00, # $5500
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [cancel_tx_type, new_ask_tx_type]
|
||||
tx_infos = [cancel_tx_info, new_ask_tx_info]
|
||||
tx_hashes = [cancel_tx_hash, new_ask_tx_hash]
|
||||
|
||||
await ws_send_batch_tx(ws_client, tx_types, tx_infos, tx_hashes)
|
||||
|
||||
# In case we want to see the changes in the UI, sleep a bit
|
||||
time.sleep(5)
|
||||
|
||||
# since this is a new batch, we can request a fresh API key
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
cancel_1_tx_type, cancel_1_tx_info, cancel_1_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1002, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (third batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
cancel_2_tx_type, cancel_2_tx_info, cancel_2_tx_hash, error = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=1003, # the index of the order we want cancelled
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (third batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = [cancel_1_tx_type, cancel_2_tx_type]
|
||||
tx_infos = [cancel_1_tx_info, cancel_2_tx_info]
|
||||
tx_hashes = [cancel_1_tx_hash, cancel_2_tx_hash]
|
||||
|
||||
await ws_send_batch_tx(ws_client, tx_types, tx_infos, tx_hashes)
|
||||
|
||||
|
||||
# Clean up
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,138 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
import json
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 1
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
# Initialize configuration and clients
|
||||
configuration = lighter.Configuration(BASE_URL)
|
||||
api_client = lighter.ApiClient(configuration)
|
||||
transaction_api = lighter.TransactionApi(api_client)
|
||||
|
||||
# Initialize signer client
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX
|
||||
)
|
||||
|
||||
# Check client connection
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {trim_exception(err)}")
|
||||
return
|
||||
|
||||
# use next nonce for getting nonces
|
||||
next_nonce = await transaction_api.next_nonce(account_index=ACCOUNT_INDEX, api_key_index=API_KEY_INDEX)
|
||||
nonce_value = next_nonce.nonce
|
||||
|
||||
ask_tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1001, # Unique identifier for this order
|
||||
base_amount=100000,
|
||||
price=280000,
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value
|
||||
)
|
||||
nonce_value += 1
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# Sign second order
|
||||
bid_tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1002, # Different unique identifier
|
||||
base_amount=200000,
|
||||
price=200000,
|
||||
is_ask=False,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value
|
||||
)
|
||||
nonce_value += 1
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (first batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = json.dumps([client.TX_TYPE_CREATE_ORDER, client.TX_TYPE_CREATE_ORDER])
|
||||
tx_infos = json.dumps([ask_tx_info, bid_tx_info])
|
||||
|
||||
try:
|
||||
tx_hashes = await transaction_api.send_tx_batch(tx_types=tx_types, tx_infos=tx_infos)
|
||||
print(f"Batch transaction successful: {tx_hashes}")
|
||||
except Exception as e:
|
||||
print(f"Error sending batch transaction: {trim_exception(e)}")
|
||||
|
||||
# In case we want to see the changes in the UI, sleep a bit
|
||||
import time
|
||||
time.sleep(5)
|
||||
|
||||
cancel_tx_info, error = client.sign_cancel_order(
|
||||
market_index=0,
|
||||
order_index=1001, # the index of the order we want cancelled
|
||||
nonce=nonce_value
|
||||
)
|
||||
nonce_value += 1
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
# Sign second order
|
||||
new_ask_tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1003, # Different unique identifier
|
||||
base_amount=300000,
|
||||
price=310000,
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value
|
||||
)
|
||||
nonce_value += 1
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (second batch): {trim_exception(error)}")
|
||||
return
|
||||
|
||||
tx_types = json.dumps([client.TX_TYPE_CANCEL_ORDER, client.TX_TYPE_CREATE_ORDER])
|
||||
tx_infos = json.dumps([cancel_tx_info, new_ask_tx_info])
|
||||
|
||||
try:
|
||||
tx_hashes = await transaction_api.send_tx_batch(tx_types=tx_types, tx_infos=tx_infos)
|
||||
print(f"Batch 2 transaction successful: {tx_hashes}")
|
||||
except Exception as e:
|
||||
print(f"Error sending batch transaction 2: {trim_exception(e)}")
|
||||
|
||||
# Clean up
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
# Run the async main function
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,31 @@
|
||||
import logging
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
account_api = lighter.AccountApi(api_client)
|
||||
response = await account_api.account(by="index", value=str(client.account_index))
|
||||
if len(response.accounts) == 0:
|
||||
raise "No account found"
|
||||
|
||||
account = response.accounts[0]
|
||||
# Note: cross-account value does not take into account isolated positions, but total does
|
||||
print("=== perp assets ===")
|
||||
print(f"total: {account.total_asset_value} available: {account.available_balance}")
|
||||
print(f"cross: {account.cross_asset_value} isolated: {float(account.total_asset_value) - float(account.cross_asset_value)}")
|
||||
|
||||
# Spot Assets
|
||||
print("=== spot assets ===")
|
||||
for asset in account.assets:
|
||||
print(f"{asset.symbol} total: {asset.balance} available: {float(asset.balance) - float(asset.locked_balance)}")
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,53 @@
|
||||
import json
|
||||
import logging
|
||||
import asyncio
|
||||
import websockets
|
||||
|
||||
from lighter.models import WSAccountAssets
|
||||
from utils import default_example_setup, ws_subscribe, ws_ping
|
||||
|
||||
|
||||
async def consume_messages(ws):
|
||||
while True:
|
||||
msg_str = await ws.recv()
|
||||
if isinstance(msg_str, str):
|
||||
msg = json.loads(msg_str)
|
||||
else:
|
||||
raise msg_str
|
||||
|
||||
# handle ping here; if we receive, send pong
|
||||
if msg["type"] == "ping":
|
||||
await ws_ping(ws)
|
||||
continue
|
||||
|
||||
# handle account_all_assets updates -- just print stuff
|
||||
if msg["type"] == "subscribed/account_all_assets" or msg["type"] == "update/account_all_assets" :
|
||||
o = WSAccountAssets.from_dict(msg)
|
||||
for asset in o.assets.values():
|
||||
print(f"{asset.symbol} total: {asset.balance} available: {float(asset.balance) - float(asset.locked_balance)} accountId: {o.account_id}")
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
await ws_client.recv()
|
||||
|
||||
consume_task = asyncio.create_task(consume_messages(ws_client))
|
||||
|
||||
auth, _ = client.create_auth_token_with_expiry()
|
||||
await ws_subscribe(ws_client, f"account_all_assets/{client.account_index}", auth)
|
||||
|
||||
# wait a bit to print messages
|
||||
await asyncio.sleep(1000)
|
||||
|
||||
consume_task.cancel()
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,42 @@
|
||||
import logging
|
||||
import asyncio
|
||||
import lighter
|
||||
from lighter import Asset
|
||||
from utils import default_example_setup
|
||||
|
||||
# This example shows how to fetch order books and assets details
|
||||
# This information should be enough to be able to trade on Lighter
|
||||
# Select the market ID accordingly to the symbol.
|
||||
# For spot markets, the order book contains base asset (ETH) and quote asset (USDC)
|
||||
# You can use these to keep track of your inventory
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
orders_api = lighter.OrderApi(api_client)
|
||||
response = await orders_api.order_books()
|
||||
response.order_books.sort(key=lambda x: x.market_id)
|
||||
|
||||
# fetch all assets
|
||||
assets_response = await orders_api.asset_details()
|
||||
|
||||
assets_dict: dict[int, Asset] = {}
|
||||
for asset in assets_response.asset_details:
|
||||
assets_dict[asset.asset_id] = asset
|
||||
|
||||
for order_book in response.order_books:
|
||||
if order_book.market_type == 'perp':
|
||||
print(f'symbol={order_book.symbol} id={order_book.market_id} type={order_book.market_type} sizeDecimals={order_book.supported_size_decimals} priceDecimals={order_book.supported_price_decimals}')
|
||||
else:
|
||||
print(f'symbol={order_book.symbol} id={order_book.market_id} type={order_book.market_type} sizeDecimals={order_book.supported_size_decimals} priceDecimals={order_book.supported_price_decimals} baseAssetId={order_book.base_asset_id} quoteAssetId={order_book.quote_asset_id}')
|
||||
b = assets_dict[order_book.base_asset_id]
|
||||
q = assets_dict[order_book.quote_asset_id]
|
||||
print(f' baseAsset: symbol={b.symbol} assetId={b.asset_id} decimals={b.decimals} price={b.index_price} min_withdraw={b.min_withdrawal_amount}')
|
||||
print(f' quoteAsset: symbol={q.symbol} assetId={q.asset_id} decimals={q.decimals} price={q.index_price} min_withdraw={q.min_withdrawal_amount}')
|
||||
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,34 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
ETH_PRIVATE_KEY,
|
||||
to_account_index=client.account_index,
|
||||
asset_id=client.ASSET_ID_USDC,
|
||||
amount=1.234567, # decimals are added by sdk
|
||||
route_from=client.ROUTE_PERP,
|
||||
route_to=client.ROUTE_SPOT,
|
||||
fee=0,
|
||||
memo="0x" + "00" * 32,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
print(transfer_tx, response)
|
||||
|
||||
lev_tx, response, err = await client.update_leverage(4, client.CROSS_MARGIN_MODE, 3)
|
||||
print(lev_tx, response, err)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,34 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
ETH_PRIVATE_KEY,
|
||||
to_account_index=client.account_index,
|
||||
asset_id=client.ASSET_ID_USDC,
|
||||
amount=1.234567, # decimals are added by sdk
|
||||
route_from=client.ROUTE_SPOT,
|
||||
route_to=client.ROUTE_PERP,
|
||||
fee=0,
|
||||
memo="0x" + "00" * 32,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
print(transfer_tx, response)
|
||||
|
||||
lev_tx, response, err = await client.update_leverage(4, client.CROSS_MARGIN_MODE, 3)
|
||||
print(lev_tx, response, err)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,17 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
tx_info, response, err = await client.create_sub_account()
|
||||
print(tx_info, response, err)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
TO_ACCOUNT_INDEX = 281474976710649
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
ETH_PRIVATE_KEY,
|
||||
to_account_index=TO_ACCOUNT_INDEX,
|
||||
asset_id=client.ASSET_ID_ETH,
|
||||
amount=0.4, # decimals are added by sdk
|
||||
route_from=client.ROUTE_SPOT,
|
||||
route_to=client.ROUTE_SPOT,
|
||||
fee=0,
|
||||
memo="0x" + "00" * 32,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
print(transfer_tx, response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
TO_ACCOUNT_INDEX = 281474976710649
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
ETH_PRIVATE_KEY,
|
||||
to_account_index=TO_ACCOUNT_INDEX,
|
||||
asset_id=client.ASSET_ID_USDC,
|
||||
amount=100, # decimals are added by sdk
|
||||
route_from=client.ROUTE_PERP,
|
||||
route_to=client.ROUTE_SPOT,
|
||||
fee=0,
|
||||
memo="0x" + "00" * 32,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
print(transfer_tx, response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -3,15 +3,21 @@ import logging
|
||||
import time
|
||||
import eth_account
|
||||
import lighter
|
||||
from utils import save_api_key_config
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# this is a dummy private key which is registered on Testnet.
|
||||
# this is a dummy private key registered on Testnet.
|
||||
# It serves as a good example
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
API_KEY_INDEX = 3
|
||||
NUM_API_KEYS = 5
|
||||
|
||||
# If you set this to something other than None, the script will use that account index instead of using the master account index.
|
||||
# This is useful if you have multiple accounts on the same L1 address or are the owner of a public pool.
|
||||
# You need to use the private key associated to the master account or the owner of the public pool to change the API keys.
|
||||
ACCOUNT_INDEX = None
|
||||
|
||||
async def main():
|
||||
# verify that the account exists & fetch account index
|
||||
@@ -19,47 +25,58 @@ async def main():
|
||||
eth_acc = eth_account.Account.from_key(ETH_PRIVATE_KEY)
|
||||
eth_address = eth_acc.address
|
||||
|
||||
try:
|
||||
response = await lighter.AccountApi(api_client).accounts_by_l1_address(
|
||||
l1_address=eth_address
|
||||
)
|
||||
except lighter.ApiException as e:
|
||||
if e.data.message == "account not found":
|
||||
print(f"error: account not found for {eth_address}")
|
||||
return
|
||||
else:
|
||||
raise e
|
||||
|
||||
if len(response.sub_accounts) > 1:
|
||||
for sub_account in response.sub_accounts:
|
||||
print(f"found accountIndex: {sub_account.index}")
|
||||
|
||||
print("multiple accounts found, using the first one")
|
||||
account_index = response.sub_accounts[0].index
|
||||
if ACCOUNT_INDEX is not None:
|
||||
account_index = ACCOUNT_INDEX
|
||||
else:
|
||||
account_index = response.sub_accounts[0].index
|
||||
try:
|
||||
response = await lighter.AccountApi(api_client).accounts_by_l1_address(l1_address=eth_address)
|
||||
except lighter.ApiException as e:
|
||||
if e.data.message == "account not found":
|
||||
print(f"error: account not found for {eth_address}")
|
||||
return
|
||||
else:
|
||||
raise e
|
||||
|
||||
if len(response.sub_accounts) > 1:
|
||||
for sub_account in response.sub_accounts:
|
||||
print(f"found accountIndex: {sub_account.index}")
|
||||
|
||||
account = min(response.sub_accounts, key=lambda x: int(x.index))
|
||||
account_index = account.index
|
||||
print(f"multiple accounts found, using the master account {account_index}")
|
||||
else:
|
||||
account_index = response.sub_accounts[0].index
|
||||
|
||||
|
||||
# create a private/public key pair for the new API key
|
||||
# pass any string to be used as seed for create_api_key like
|
||||
# create_api_key("Hello world random seed to make things more secure")
|
||||
private_key, public_key, err = lighter.create_api_key()
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
private_keys = {}
|
||||
public_keys = []
|
||||
|
||||
for i in range(NUM_API_KEYS):
|
||||
private_key, public_key, err = lighter.create_api_key()
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
public_keys.append(public_key)
|
||||
private_keys[API_KEY_INDEX + i] = private_key
|
||||
|
||||
tx_client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=private_key,
|
||||
account_index=account_index,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
api_private_keys=private_keys,
|
||||
)
|
||||
|
||||
# change the API key
|
||||
response, err = await tx_client.change_api_key(
|
||||
eth_private_key=ETH_PRIVATE_KEY,
|
||||
new_pubkey=public_key,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
# change all API keys
|
||||
for i in range(NUM_API_KEYS):
|
||||
response, err = await tx_client.change_api_key(
|
||||
eth_private_key=ETH_PRIVATE_KEY,
|
||||
new_pubkey=public_keys[i],
|
||||
api_key_index=API_KEY_INDEX + i
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
# wait some time so that we receive the new API key in the response
|
||||
time.sleep(10)
|
||||
@@ -69,14 +86,7 @@ async def main():
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
print(
|
||||
f"""
|
||||
BASE_URL = '{BASE_URL}'
|
||||
API_KEY_PRIVATE_KEY = '{private_key}'
|
||||
ACCOUNT_INDEX = {account_index}
|
||||
API_KEY_INDEX = {API_KEY_INDEX}
|
||||
"""
|
||||
)
|
||||
save_api_key_config(BASE_URL, account_index, private_keys)
|
||||
|
||||
await tx_client.close()
|
||||
await api_client.close()
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
TO_ACCOUNT_INDEX = 9
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
info_api = lighter.InfoApi(api_client)
|
||||
|
||||
auth_token, err = client.create_auth_token_with_expiry()
|
||||
if err:
|
||||
raise Exception(f"Auth token failed: {err}")
|
||||
|
||||
fee_info = await info_api.transfer_fee_info(client.account_index, authorization=auth_token, auth=auth_token, to_account_index=TO_ACCOUNT_INDEX)
|
||||
|
||||
# You can find more notes on transfers in the README.md file, under `Transfer Notes`
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
eth_private_key=ETH_PRIVATE_KEY,
|
||||
to_account_index=TO_ACCOUNT_INDEX,
|
||||
asset_id=client.ASSET_ID_USDC,
|
||||
route_from=client.ROUTE_PERP,
|
||||
route_to=client.ROUTE_PERP,
|
||||
amount=5, # decimals are added by sdk
|
||||
fee=fee_info.transfer_fee_usdc,
|
||||
memo="0x" + "00" * 32,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
|
||||
print(transfer_tx, response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,47 +0,0 @@
|
||||
import asyncio
|
||||
import lighter
|
||||
|
||||
|
||||
from examples.secrets import BASE_URL, API_KEY_PRIVATE_KEY, ETH_PRIVATE_KEY
|
||||
|
||||
API_KEY_INDEX = 10
|
||||
TO_ACCOUNT_INDEX = 9
|
||||
ACCOUNT_INDEX = 10 # replace with your account_index
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
api_client = lighter.ApiClient(configuration=lighter.Configuration(host=BASE_URL))
|
||||
info_api = lighter.InfoApi(api_client)
|
||||
order_api = lighter.OrderApi(api_client)
|
||||
|
||||
auth_token, _ = client.create_auth_token_with_expiry()
|
||||
fee_info = await info_api.transfer_fee_info(ACCOUNT_INDEX, authorization=auth_token, auth=auth_token, to_account_index=TO_ACCOUNT_INDEX)
|
||||
print(fee_info)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
memo = "a"*32 # memo is a user message and it has to be exactly 32 bytes long
|
||||
transfer_tx, response, err = await client.transfer(
|
||||
ETH_PRIVATE_KEY,
|
||||
usdc_amount=100, # decimals are added by sdk
|
||||
to_account_index=TO_ACCOUNT_INDEX,
|
||||
fee=fee_info.transfer_fee_usdc,
|
||||
memo=memo,
|
||||
)
|
||||
if err != None:
|
||||
raise Exception(f"error transferring {err}")
|
||||
print(transfer_tx, response)
|
||||
|
||||
lev_tx, response, err = await client.update_leverage(4, client.CROSS_MARGIN_MODE, 3)
|
||||
print(lev_tx, response, err)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,100 @@
|
||||
from typing import Tuple, Optional
|
||||
import logging
|
||||
import json
|
||||
import websockets
|
||||
import lighter
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
def save_api_key_config(base_url, account_index, private_keys, config_file="./api_key_config.json"):
|
||||
with open(config_file, "w", encoding="utf-8") as f:
|
||||
json.dump({
|
||||
"baseUrl": base_url,
|
||||
"accountIndex": account_index,
|
||||
"privateKeys": private_keys,
|
||||
}, f, ensure_ascii=False, indent=2)
|
||||
|
||||
|
||||
def get_api_key_config(config_file="./api_key_config.json"):
|
||||
with open(config_file) as f:
|
||||
cfg = json.load(f)
|
||||
|
||||
private_keys_original = cfg["privateKeys"]
|
||||
private_key = {}
|
||||
for key in private_keys_original.keys():
|
||||
private_key[int(key)] = private_keys_original[key]
|
||||
|
||||
return cfg["baseUrl"], cfg["accountIndex"], private_key
|
||||
|
||||
|
||||
def default_example_setup(config_file="./api_key_config.json") -> Optional[Tuple[lighter.SignerClient, lighter.ApiClient, websockets.connect]]:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
base_url, account_index, private_keys = get_api_key_config(config_file)
|
||||
api_client = lighter.ApiClient(configuration=lighter.Configuration(host=base_url))
|
||||
client = lighter.SignerClient(
|
||||
url=base_url,
|
||||
account_index=account_index,
|
||||
api_private_keys=private_keys,
|
||||
)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {trim_exception(err)}")
|
||||
return
|
||||
|
||||
return client, api_client, websockets.connect(f"{base_url.replace('https', 'wss')}/stream")
|
||||
|
||||
|
||||
async def ws_ping(ws_client: websockets.ClientConnection):
|
||||
await ws_client.send(json.dumps({"type": "pong"}))
|
||||
|
||||
async def ws_subscribe(ws_client: websockets.ClientConnection, channel: str, auth: Optional[str] = None):
|
||||
if auth is None:
|
||||
await ws_client.send(json.dumps({"type": "subscribe", "channel": channel}))
|
||||
else:
|
||||
await ws_client.send(json.dumps({"type": "subscribe", "channel": channel, "auth": auth}))
|
||||
|
||||
async def ws_send_tx(ws_client: websockets.ClientConnection, tx_type, tx_info, tx_hash):
|
||||
# Note: you have the TX Hash from signing the TX
|
||||
# You can use this TX Hash to check the status of the TX later on
|
||||
# if the server generates a different hash, the signature will fail, so the hash will always be correct
|
||||
# because of this, the hash returned by the server will always be the same
|
||||
await ws_client.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "jsonapi/sendtx",
|
||||
"data": {
|
||||
"id": f"my_random_id_{12345678}", # optional helps id the response
|
||||
"tx_type": tx_type,
|
||||
"tx_info": json.loads(tx_info),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
print(f"expectedHash {tx_hash} response {await ws_client.recv()}")
|
||||
|
||||
|
||||
async def ws_send_batch_tx(ws_client: websockets.ClientConnection, tx_types, tx_infos, tx_hashes):
|
||||
# Note: you have the TX Hash from signing the TX
|
||||
# You can use this TX Hash to check the status of the TX later on
|
||||
# if the server generates a different hash, the signature will fail, so the hash will always be correct
|
||||
# because of this, the hash returned by the server will always be the same
|
||||
await ws_client.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "jsonapi/sendtxbatch",
|
||||
"data": {
|
||||
"id": f"my_random_id_{12345678}", # optional helps id the response
|
||||
"tx_types": json.dumps(tx_types),
|
||||
"tx_infos": json.dumps(tx_infos),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
print(f"expectedHash {tx_hashes} response {await ws_client.recv()}")
|
||||
@@ -0,0 +1,104 @@
|
||||
import asyncio
|
||||
import json
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
ETH_PRIVATE_KEY = "1234567812345678123456781234567812345678123456781234567812345678"
|
||||
WITHDRAW_ADDRESS = "0x0000..."
|
||||
AMOUNT_USDC = 5.0
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
auth_token, err = client.create_auth_token_with_expiry()
|
||||
if err:
|
||||
raise Exception(f"Auth token failed: {err}")
|
||||
|
||||
info_api = lighter.InfoApi(api_client)
|
||||
|
||||
try:
|
||||
# Get fast withdraw pool
|
||||
params = api_client.param_serialize(
|
||||
method='GET',
|
||||
resource_path='/api/v1/fastwithdraw/info',
|
||||
query_params=[('account_index', client.account_index)],
|
||||
header_params={'Authorization': auth_token}
|
||||
)
|
||||
response = await api_client.call_api(*params)
|
||||
await response.read()
|
||||
data = response.data
|
||||
assert data is not None
|
||||
|
||||
# get account to which to send money
|
||||
pool_info = json.loads(data.decode('utf-8'))
|
||||
if pool_info.get('code') != 200:
|
||||
raise Exception(f"Pool info failed: {pool_info.get('message')}")
|
||||
to_account = pool_info['to_account_index']
|
||||
print(f"Pool: {to_account}, Limit: {pool_info.get('withdraw_limit')}")
|
||||
|
||||
# get transfer fee
|
||||
fee_info = await info_api.transfer_fee_info(
|
||||
account_index=client.account_index,
|
||||
to_account_index=to_account,
|
||||
auth=auth_token
|
||||
)
|
||||
fee = fee_info.transfer_fee_usdc # this is already int
|
||||
|
||||
# Get Nonce & API key -- you can get this using HTTP call as well
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
|
||||
# Build memo (20-byte address + 12 zeros)
|
||||
addr_hex = WITHDRAW_ADDRESS.lower().removeprefix("0x")
|
||||
addr_bytes = bytes.fromhex(addr_hex)
|
||||
if len(addr_bytes) != 20:
|
||||
raise ValueError(f"Invalid address length: {len(addr_bytes)}")
|
||||
memo_list = list(addr_bytes + b"\x00" * 12)
|
||||
memo_hex = ''.join(format(b, '02x') for b in memo_list)
|
||||
|
||||
# create TX
|
||||
tx_type, tx_info_str, tx_hash, err = client.sign_transfer(
|
||||
eth_private_key=ETH_PRIVATE_KEY,
|
||||
to_account_index=to_account,
|
||||
asset_id=client.ASSET_ID_USDC,
|
||||
route_from=client.ROUTE_PERP,
|
||||
route_to=client.ROUTE_PERP,
|
||||
usdc_amount=int(AMOUNT_USDC) * 10 ** 6,
|
||||
fee=fee,
|
||||
memo=memo_hex,
|
||||
api_key_index=api_key_index,
|
||||
nonce=nonce
|
||||
)
|
||||
if err:
|
||||
raise Exception(f"L2 signing failed: {err}")
|
||||
|
||||
# Submit
|
||||
params = api_client.param_serialize(
|
||||
method='POST',
|
||||
resource_path='/api/v1/fastwithdraw',
|
||||
post_params=[
|
||||
('tx_info', tx_info_str),
|
||||
('to_address', WITHDRAW_ADDRESS)
|
||||
],
|
||||
header_params={
|
||||
'Authorization': auth_token,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
)
|
||||
response = await api_client.call_api(*params)
|
||||
await response.read()
|
||||
data = response.data
|
||||
assert data is not None
|
||||
result = json.loads(data.decode('utf-8'))
|
||||
|
||||
if result.get('code') == 200:
|
||||
print(f"✓ Success! TX: {result.get('tx_hash')}")
|
||||
else:
|
||||
raise Exception(f"Failed: {result.get('message')}")
|
||||
|
||||
finally:
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
AMOUNT = 5.0
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: There is no limit or fee for normal withdrawal
|
||||
withdraw_tx, response, err = await client.withdraw(
|
||||
asset_id=client.ASSET_ID_USDC, # change this to `client.ASSET_ID_ETH` to withdraw ETH. Also, change route_type to spot
|
||||
route_type=client.ROUTE_PERP, # change this to `client.ROUTE_SPOT` to withdraw from spot balance
|
||||
amount=AMOUNT,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f"error withdrawing {err}")
|
||||
|
||||
print(withdraw_tx, response)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,101 +0,0 @@
|
||||
import lighter
|
||||
import json
|
||||
import websockets
|
||||
import asyncio
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
# Alternatively, you can go to https://app.lighter.xyz/apikeys for mainnet api keys
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = (
|
||||
"0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
)
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 1
|
||||
|
||||
|
||||
async def ws_flow(tx_types, tx_infos):
|
||||
async with websockets.connect(f"{BASE_URL.replace('https', 'wss')}/stream") as ws:
|
||||
msg = await ws.recv()
|
||||
print("Received:", msg)
|
||||
|
||||
await ws.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "jsonapi/sendtxbatch",
|
||||
"data": {
|
||||
"id": f"my_random_batch_id_{12345678}", # optional, helps id the response
|
||||
"tx_types": json.dumps(tx_types),
|
||||
"tx_infos": json.dumps(tx_infos),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
print("Response:", await ws.recv())
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
configuration = lighter.Configuration(BASE_URL)
|
||||
api_client = lighter.ApiClient(configuration)
|
||||
transaction_api = lighter.TransactionApi(api_client)
|
||||
|
||||
# use next nonce for getting nonces
|
||||
next_nonce = await transaction_api.next_nonce(
|
||||
account_index=ACCOUNT_INDEX, api_key_index=API_KEY_INDEX
|
||||
)
|
||||
nonce_value = next_nonce.nonce
|
||||
|
||||
ask_tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1001, # Unique identifier for this order
|
||||
base_amount=100000,
|
||||
price=280000,
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value,
|
||||
)
|
||||
nonce_value += 1
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing first order (first batch): {error}")
|
||||
return
|
||||
|
||||
# Sign second order
|
||||
bid_tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1002, # Different unique identifier
|
||||
base_amount=200000,
|
||||
price=200000,
|
||||
is_ask=False,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value,
|
||||
)
|
||||
|
||||
if error is not None:
|
||||
print(f"Error signing second order (first batch): {error}")
|
||||
return
|
||||
|
||||
tx_types = [
|
||||
lighter.SignerClient.TX_TYPE_CREATE_ORDER,
|
||||
lighter.SignerClient.TX_TYPE_CREATE_ORDER,
|
||||
]
|
||||
tx_infos = [ask_tx_info, bid_tx_info]
|
||||
|
||||
await ws_flow(tx_types, tx_infos)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,74 +0,0 @@
|
||||
import lighter
|
||||
import json
|
||||
import websockets
|
||||
import asyncio
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
# Alternatively, you can go to https://app.lighter.xyz/apikeys for mainnet api keys
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = (
|
||||
"0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
)
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
async def ws_flow(tx_type, tx_info):
|
||||
async with websockets.connect(f"{BASE_URL.replace('https', 'wss')}/stream") as ws:
|
||||
msg = await ws.recv()
|
||||
print("Received:", msg)
|
||||
|
||||
await ws.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "jsonapi/sendtx",
|
||||
"data": {
|
||||
"id": f"my_random_id_{12345678}", # optional, helps id the response
|
||||
"tx_type": tx_type,
|
||||
"tx_info": json.loads(tx_info),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
print("Response:", await ws.recv())
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
configuration = lighter.Configuration(BASE_URL)
|
||||
api_client = lighter.ApiClient(configuration)
|
||||
transaction_api = lighter.TransactionApi(api_client)
|
||||
|
||||
next_nonce = await transaction_api.next_nonce(
|
||||
account_index=ACCOUNT_INDEX, api_key_index=API_KEY_INDEX
|
||||
)
|
||||
nonce_value = next_nonce.nonce
|
||||
|
||||
tx_info, error = client.sign_create_order(
|
||||
market_index=0,
|
||||
client_order_index=1002, # Different unique identifier
|
||||
base_amount=200000,
|
||||
price=200000,
|
||||
is_ask=False,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce_value,
|
||||
)
|
||||
if error is not None:
|
||||
print(f"Error signing order: {error}")
|
||||
return
|
||||
|
||||
await ws_flow(lighter.SignerClient.TX_TYPE_CREATE_ORDER, tx_info)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
git_host=$4
|
||||
|
||||
if [ "$git_host" = "" ]; then
|
||||
git_host="github.com"
|
||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
||||
fi
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="GIT_USER_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="GIT_REPO_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="Minor update"
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=$(git remote)
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
@@ -0,0 +1,184 @@
|
||||
# coding: utf-8
|
||||
|
||||
# flake8: noqa
|
||||
|
||||
"""
|
||||
zkLighter API
|
||||
|
||||
Public APIs for Lighter
|
||||
|
||||
The version of the OpenAPI document: 1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
__version__ = "1.0.0"
|
||||
|
||||
# import apis into sdk package
|
||||
from lighter.api.account_api import AccountApi
|
||||
from lighter.api.announcement_api import AnnouncementApi
|
||||
from lighter.api.block_api import BlockApi
|
||||
from lighter.api.bridge_api import BridgeApi
|
||||
from lighter.api.candlestick_api import CandlestickApi
|
||||
from lighter.api.funding_api import FundingApi
|
||||
from lighter.api.info_api import InfoApi
|
||||
from lighter.api.notification_api import NotificationApi
|
||||
from lighter.api.order_api import OrderApi
|
||||
from lighter.api.referral_api import ReferralApi
|
||||
from lighter.api.root_api import RootApi
|
||||
from lighter.api.transaction_api import TransactionApi
|
||||
|
||||
# import ApiClient
|
||||
from lighter.api_response import ApiResponse
|
||||
from lighter.api_client import ApiClient
|
||||
from lighter.configuration import Configuration
|
||||
from lighter.exceptions import OpenApiException
|
||||
from lighter.exceptions import ApiTypeError
|
||||
from lighter.exceptions import ApiValueError
|
||||
from lighter.exceptions import ApiKeyError
|
||||
from lighter.exceptions import ApiAttributeError
|
||||
from lighter.exceptions import ApiException
|
||||
|
||||
# import models into sdk package
|
||||
from lighter.models.account import Account
|
||||
from lighter.models.account_api_keys import AccountApiKeys
|
||||
from lighter.models.account_asset import AccountAsset
|
||||
from lighter.models.account_limits import AccountLimits
|
||||
from lighter.models.account_margin_stats import AccountMarginStats
|
||||
from lighter.models.account_market_stats import AccountMarketStats
|
||||
from lighter.models.account_metadata import AccountMetadata
|
||||
from lighter.models.account_metadatas import AccountMetadatas
|
||||
from lighter.models.account_pn_l import AccountPnL
|
||||
from lighter.models.account_position import AccountPosition
|
||||
from lighter.models.account_stats import AccountStats
|
||||
from lighter.models.account_trade_stats import AccountTradeStats
|
||||
from lighter.models.announcement import Announcement
|
||||
from lighter.models.announcements import Announcements
|
||||
from lighter.models.api_key import ApiKey
|
||||
from lighter.models.asset import Asset
|
||||
from lighter.models.asset_details import AssetDetails
|
||||
from lighter.models.block import Block
|
||||
from lighter.models.blocks import Blocks
|
||||
from lighter.models.bridge import Bridge
|
||||
from lighter.models.bridge_supported_network import BridgeSupportedNetwork
|
||||
from lighter.models.candlestick import Candlestick
|
||||
from lighter.models.candlesticks import Candlesticks
|
||||
from lighter.models.contract_address import ContractAddress
|
||||
from lighter.models.current_height import CurrentHeight
|
||||
from lighter.models.cursor import Cursor
|
||||
from lighter.models.daily_return import DailyReturn
|
||||
from lighter.models.deposit_history import DepositHistory
|
||||
from lighter.models.deposit_history_item import DepositHistoryItem
|
||||
from lighter.models.detailed_account import DetailedAccount
|
||||
from lighter.models.detailed_accounts import DetailedAccounts
|
||||
from lighter.models.detailed_candlestick import DetailedCandlestick
|
||||
from lighter.models.enriched_tx import EnrichedTx
|
||||
from lighter.models.exchange_stats import ExchangeStats
|
||||
from lighter.models.export_data import ExportData
|
||||
from lighter.models.funding import Funding
|
||||
from lighter.models.funding_rate import FundingRate
|
||||
from lighter.models.funding_rates import FundingRates
|
||||
from lighter.models.fundings import Fundings
|
||||
from lighter.models.l1_metadata import L1Metadata
|
||||
from lighter.models.l1_provider_info import L1ProviderInfo
|
||||
from lighter.models.liq_trade import LiqTrade
|
||||
from lighter.models.liquidation import Liquidation
|
||||
from lighter.models.liquidation_info import LiquidationInfo
|
||||
from lighter.models.liquidation_infos import LiquidationInfos
|
||||
from lighter.models.market_config import MarketConfig
|
||||
from lighter.models.next_nonce import NextNonce
|
||||
from lighter.models.order import Order
|
||||
from lighter.models.order_book import OrderBook
|
||||
from lighter.models.order_book_depth import OrderBookDepth
|
||||
from lighter.models.order_book_details import OrderBookDetails
|
||||
from lighter.models.order_book_orders import OrderBookOrders
|
||||
from lighter.models.order_book_stats import OrderBookStats
|
||||
from lighter.models.order_books import OrderBooks
|
||||
from lighter.models.orders import Orders
|
||||
from lighter.models.perps_market_stats import PerpsMarketStats
|
||||
from lighter.models.perps_order_book_detail import PerpsOrderBookDetail
|
||||
from lighter.models.pn_l_entry import PnLEntry
|
||||
from lighter.models.position_funding import PositionFunding
|
||||
from lighter.models.position_fundings import PositionFundings
|
||||
from lighter.models.price_level import PriceLevel
|
||||
from lighter.models.public_pool_info import PublicPoolInfo
|
||||
from lighter.models.public_pool_metadata import PublicPoolMetadata
|
||||
from lighter.models.public_pool_share import PublicPoolShare
|
||||
from lighter.models.referral_point_entry import ReferralPointEntry
|
||||
from lighter.models.referral_points import ReferralPoints
|
||||
from lighter.models.req_export_data import ReqExportData
|
||||
from lighter.models.req_get_account import ReqGetAccount
|
||||
from lighter.models.req_get_account_active_orders import ReqGetAccountActiveOrders
|
||||
from lighter.models.req_get_account_api_keys import ReqGetAccountApiKeys
|
||||
from lighter.models.req_get_account_by_l1_address import ReqGetAccountByL1Address
|
||||
from lighter.models.req_get_account_inactive_orders import ReqGetAccountInactiveOrders
|
||||
from lighter.models.req_get_account_limits import ReqGetAccountLimits
|
||||
from lighter.models.req_get_account_metadata import ReqGetAccountMetadata
|
||||
from lighter.models.req_get_account_pn_l import ReqGetAccountPnL
|
||||
from lighter.models.req_get_account_txs import ReqGetAccountTxs
|
||||
from lighter.models.req_get_asset_details import ReqGetAssetDetails
|
||||
from lighter.models.req_get_block import ReqGetBlock
|
||||
from lighter.models.req_get_block_txs import ReqGetBlockTxs
|
||||
from lighter.models.req_get_bridges_by_l1_addr import ReqGetBridgesByL1Addr
|
||||
from lighter.models.req_get_by_account import ReqGetByAccount
|
||||
from lighter.models.req_get_candlesticks import ReqGetCandlesticks
|
||||
from lighter.models.req_get_deposit_history import ReqGetDepositHistory
|
||||
from lighter.models.req_get_fast_withdraw_info import ReqGetFastWithdrawInfo
|
||||
from lighter.models.req_get_fundings import ReqGetFundings
|
||||
from lighter.models.req_get_l1_metadata import ReqGetL1Metadata
|
||||
from lighter.models.req_get_l1_tx import ReqGetL1Tx
|
||||
from lighter.models.req_get_latest_deposit import ReqGetLatestDeposit
|
||||
from lighter.models.req_get_liquidation_infos import ReqGetLiquidationInfos
|
||||
from lighter.models.req_get_next_nonce import ReqGetNextNonce
|
||||
from lighter.models.req_get_order_book_details import ReqGetOrderBookDetails
|
||||
from lighter.models.req_get_order_book_orders import ReqGetOrderBookOrders
|
||||
from lighter.models.req_get_order_books import ReqGetOrderBooks
|
||||
from lighter.models.req_get_position_funding import ReqGetPositionFunding
|
||||
from lighter.models.req_get_public_pools_metadata import ReqGetPublicPoolsMetadata
|
||||
from lighter.models.req_get_range_with_cursor import ReqGetRangeWithCursor
|
||||
from lighter.models.req_get_range_with_index import ReqGetRangeWithIndex
|
||||
from lighter.models.req_get_range_with_index_sortable import ReqGetRangeWithIndexSortable
|
||||
from lighter.models.req_get_recent_trades import ReqGetRecentTrades
|
||||
from lighter.models.req_get_referral_points import ReqGetReferralPoints
|
||||
from lighter.models.req_get_trades import ReqGetTrades
|
||||
from lighter.models.req_get_transfer_fee_info import ReqGetTransferFeeInfo
|
||||
from lighter.models.req_get_transfer_history import ReqGetTransferHistory
|
||||
from lighter.models.req_get_tx import ReqGetTx
|
||||
from lighter.models.req_get_withdraw_history import ReqGetWithdrawHistory
|
||||
from lighter.models.resp_change_account_tier import RespChangeAccountTier
|
||||
from lighter.models.resp_get_bridges_by_l1_addr import RespGetBridgesByL1Addr
|
||||
from lighter.models.resp_get_fast_bridge_info import RespGetFastBridgeInfo
|
||||
from lighter.models.resp_get_is_next_bridge_fast import RespGetIsNextBridgeFast
|
||||
from lighter.models.resp_public_pools_metadata import RespPublicPoolsMetadata
|
||||
from lighter.models.resp_send_tx import RespSendTx
|
||||
from lighter.models.resp_send_tx_batch import RespSendTxBatch
|
||||
from lighter.models.resp_update_kickback import RespUpdateKickback
|
||||
from lighter.models.resp_update_referral_code import RespUpdateReferralCode
|
||||
from lighter.models.resp_withdrawal_delay import RespWithdrawalDelay
|
||||
from lighter.models.result_code import ResultCode
|
||||
from lighter.models.risk_info import RiskInfo
|
||||
from lighter.models.risk_parameters import RiskParameters
|
||||
from lighter.models.share_price import SharePrice
|
||||
from lighter.models.simple_order import SimpleOrder
|
||||
from lighter.models.spot_market_stats import SpotMarketStats
|
||||
from lighter.models.spot_order_book_detail import SpotOrderBookDetail
|
||||
from lighter.models.status import Status
|
||||
from lighter.models.sub_accounts import SubAccounts
|
||||
from lighter.models.ticker import Ticker
|
||||
from lighter.models.trade import Trade
|
||||
from lighter.models.trades import Trades
|
||||
from lighter.models.transfer_fee_info import TransferFeeInfo
|
||||
from lighter.models.transfer_history import TransferHistory
|
||||
from lighter.models.transfer_history_item import TransferHistoryItem
|
||||
from lighter.models.tx import Tx
|
||||
from lighter.models.tx_hash import TxHash
|
||||
from lighter.models.tx_hashes import TxHashes
|
||||
from lighter.models.txs import Txs
|
||||
from lighter.models.validator_info import ValidatorInfo
|
||||
from lighter.models.withdraw_history import WithdrawHistory
|
||||
from lighter.models.withdraw_history_item import WithdrawHistoryItem
|
||||
from lighter.models.zk_lighter_info import ZkLighterInfo
|
||||
from lighter.ws_client import WsClient
|
||||
from lighter.signer_client import SignerClient, create_api_key
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user