mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 09:18:08 +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:
@@ -1,4 +0,0 @@
|
|||||||
.idea
|
|
||||||
vendor
|
|
||||||
build/*
|
|
||||||
!build/.keep
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# lighter-go
|
|
||||||
|
|
||||||
In its current form, this repo serves as a starting point for anyone who wants to trade on Lighter using GO.
|
|
||||||
It covers all the signing procedures in order to trade on Lighter with an API key.
|
|
||||||
Minimal HTTP calls are implemented
|
|
||||||
On chain support, like depositing on Ethereum or modifying an API key directly with an Ethereum Tx are not supported yet.
|
|
||||||
|
|
||||||
At the moment, its main purpose is to offer visibility on the code behind the precompiled libraries used by the Python SDK.
|
|
||||||
If you'd like to compile your own binaries, the commands are in the `justfile`
|
|
||||||
@@ -1,659 +0,0 @@
|
|||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/elliottech/lighter-go/signer"
|
|
||||||
"github.com/elliottech/lighter-go/types/txtypes"
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
gFp5 "github.com/elliottech/poseidon_crypto/field/goldilocks_quintic_extension"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TransactOpts struct {
|
|
||||||
FromAccountIndex *int64
|
|
||||||
ApiKeyIndex *uint8
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce *int64
|
|
||||||
DryRun bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublicKey = gFp5.Element
|
|
||||||
|
|
||||||
type ChangePubKeyReq struct {
|
|
||||||
PubKey [40]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type TransferTxReq struct {
|
|
||||||
ToAccountIndex int64
|
|
||||||
USDCAmount int64
|
|
||||||
Fee int64
|
|
||||||
Memo [32]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type WithdrawTxReq struct {
|
|
||||||
USDCAmount uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateOrderTxReq struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
ClientOrderIndex int64
|
|
||||||
BaseAmount int64
|
|
||||||
Price uint32
|
|
||||||
IsAsk uint8
|
|
||||||
Type uint8
|
|
||||||
TimeInForce uint8
|
|
||||||
ReduceOnly uint8
|
|
||||||
TriggerPrice uint32
|
|
||||||
OrderExpiry int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateGroupedOrdersTxReq struct {
|
|
||||||
GroupingType uint8
|
|
||||||
Orders []*CreateOrderTxReq
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModifyOrderTxReq struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
Index int64
|
|
||||||
BaseAmount int64
|
|
||||||
Price uint32
|
|
||||||
TriggerPrice uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type CancelOrderTxReq struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
Index int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type CancelAllOrdersTxReq struct {
|
|
||||||
TimeInForce uint8
|
|
||||||
Time int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreatePublicPoolTxReq struct {
|
|
||||||
OperatorFee int64
|
|
||||||
InitialTotalShares int64
|
|
||||||
MinOperatorShareRate int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdatePublicPoolTxReq struct {
|
|
||||||
PublicPoolIndex int64
|
|
||||||
Status uint8
|
|
||||||
OperatorFee int64
|
|
||||||
MinOperatorShareRate int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type MintSharesTxReq struct {
|
|
||||||
PublicPoolIndex int64
|
|
||||||
ShareAmount int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type BurnSharesTxReq struct {
|
|
||||||
PublicPoolIndex int64
|
|
||||||
ShareAmount int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateLeverageTxReq struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
InitialMarginFraction uint16
|
|
||||||
MarginMode uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateMarginTxReq struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
USDCAmount int64
|
|
||||||
Direction uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructAuthToken(key signer.Signer, deadline time.Time, ops *TransactOpts) (string, error) {
|
|
||||||
if ops.FromAccountIndex == nil {
|
|
||||||
return "", fmt.Errorf("missing FromAccountIndex")
|
|
||||||
}
|
|
||||||
if ops.ApiKeyIndex == nil {
|
|
||||||
return "", fmt.Errorf("missing ApiKeyIndex")
|
|
||||||
}
|
|
||||||
message := fmt.Sprintf("%v:%v:%v", deadline.Unix(), *ops.FromAccountIndex, *ops.ApiKeyIndex)
|
|
||||||
|
|
||||||
msgInField, err := g.ArrayFromCanonicalLittleEndianBytes([]byte(message))
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to convert bytes to field element. message: %s, error: %w", message, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash := p2.HashToQuinticExtension(msgInField).ToLittleEndianBytes()
|
|
||||||
|
|
||||||
signatureBytes, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
signature := ethCommon.Bytes2Hex(signatureBytes)
|
|
||||||
|
|
||||||
return fmt.Sprintf("%v:%v", message, signature), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructChangePubKeyTx(key signer.Signer, lighterChainId uint32, tx *ChangePubKeyReq, ops *TransactOpts) (*txtypes.L2ChangePubKeyTxInfo, error) {
|
|
||||||
convertedTx := ConvertChangePubKeyTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructCreateSubAccountTx(key signer.Signer, lighterChainId uint32, ops *TransactOpts) (*txtypes.L2CreateSubAccountTxInfo, error) {
|
|
||||||
convertedTx := ConvertCreateSubAccountTx(ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructCreatePublicPoolTx(key signer.Signer, lighterChainId uint32, tx *CreatePublicPoolTxReq, ops *TransactOpts) (*txtypes.L2CreatePublicPoolTxInfo, error) {
|
|
||||||
convertedTx := ConvertCreatePublicPoolTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructUpdatePublicPoolTx(key signer.Signer, lighterChainId uint32, tx *UpdatePublicPoolTxReq, ops *TransactOpts) (*txtypes.L2UpdatePublicPoolTxInfo, error) {
|
|
||||||
convertedTx := ConvertUpdatePublicPoolTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructWithdrawTx(key signer.Signer, lighterChainId uint32, tx *WithdrawTxReq, ops *TransactOpts) (*txtypes.L2WithdrawTxInfo, error) {
|
|
||||||
convertedTx := ConvertWithdrawTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructCreateOrderTx(key signer.Signer, lighterChainId uint32, tx *CreateOrderTxReq, ops *TransactOpts) (*txtypes.L2CreateOrderTxInfo, error) {
|
|
||||||
convertedTx := ConvertCreateOrderTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructL2CreateGroupedOrdersTx(key signer.Signer, lighterChainId uint32, tx *CreateGroupedOrdersTxReq, ops *TransactOpts) (*txtypes.L2CreateGroupedOrdersTxInfo, error) {
|
|
||||||
convertedTx := ConvertCreateGroupedOrdersTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructL2CancelOrderTx(key signer.Signer, lighterChainId uint32, tx *CancelOrderTxReq, ops *TransactOpts) (*txtypes.L2CancelOrderTxInfo, error) {
|
|
||||||
convertedTx := ConvertCancelOrderTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructL2ModifyOrderTx(key signer.Signer, lighterChainId uint32, tx *ModifyOrderTxReq, ops *TransactOpts) (*txtypes.L2ModifyOrderTxInfo, error) {
|
|
||||||
convertedTx := ConvertModifyOrderTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructL2CancelAllOrdersTx(key signer.Signer, lighterChainId uint32, tx *CancelAllOrdersTxReq, ops *TransactOpts) (*txtypes.L2CancelAllOrdersTxInfo, error) {
|
|
||||||
convertedTx := ConvertCancelAllOrdersTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructTransferTx(key signer.Signer, lighterChainId uint32, tx *TransferTxReq, ops *TransactOpts) (*txtypes.L2TransferTxInfo, error) {
|
|
||||||
convertedTx := ConvertTransferTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructMintSharesTx(key signer.Signer, lighterChainId uint32, tx *MintSharesTxReq, ops *TransactOpts) (*txtypes.L2MintSharesTxInfo, error) {
|
|
||||||
convertedTx := ConvertMintSharesTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructBurnSharesTx(key signer.Signer, lighterChainId uint32, tx *BurnSharesTxReq, ops *TransactOpts) (*txtypes.L2BurnSharesTxInfo, error) {
|
|
||||||
convertedTx := ConvertBurnSharesTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructUpdateLeverageTx(key signer.Signer, lighterChainId uint32, tx *UpdateLeverageTxReq, ops *TransactOpts) (*txtypes.L2UpdateLeverageTxInfo, error) {
|
|
||||||
convertedTx := ConvertUpdateLeverageTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConstructUpdateMarginTx(key signer.Signer, lighterChainId uint32, tx *UpdateMarginTxReq, ops *TransactOpts) (*txtypes.L2UpdateMarginTxInfo, error) {
|
|
||||||
convertedTx := ConvertUpdateMarginTx(tx, ops)
|
|
||||||
err := convertedTx.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
|
||||||
convertedTx.Sig = signature
|
|
||||||
return convertedTx, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertTransferTx(tx *TransferTxReq, ops *TransactOpts) *txtypes.L2TransferTxInfo {
|
|
||||||
return &txtypes.L2TransferTxInfo{
|
|
||||||
FromAccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
ToAccountIndex: tx.ToAccountIndex,
|
|
||||||
USDCAmount: tx.USDCAmount,
|
|
||||||
Fee: tx.Fee,
|
|
||||||
Memo: tx.Memo,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCreateOrderTx(tx *CreateOrderTxReq, ops *TransactOpts) *txtypes.L2CreateOrderTxInfo {
|
|
||||||
return &txtypes.L2CreateOrderTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
OrderInfo: &txtypes.OrderInfo{MarketIndex: tx.MarketIndex,
|
|
||||||
ClientOrderIndex: tx.ClientOrderIndex,
|
|
||||||
BaseAmount: tx.BaseAmount,
|
|
||||||
Price: tx.Price,
|
|
||||||
IsAsk: tx.IsAsk,
|
|
||||||
Type: tx.Type,
|
|
||||||
TimeInForce: tx.TimeInForce,
|
|
||||||
ReduceOnly: tx.ReduceOnly,
|
|
||||||
TriggerPrice: tx.TriggerPrice,
|
|
||||||
OrderExpiry: tx.OrderExpiry,
|
|
||||||
},
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCreateGroupedOrdersTx(tx *CreateGroupedOrdersTxReq, ops *TransactOpts) *txtypes.L2CreateGroupedOrdersTxInfo {
|
|
||||||
ret := &txtypes.L2CreateGroupedOrdersTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
GroupingType: tx.GroupingType,
|
|
||||||
Orders: []*txtypes.OrderInfo{},
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, order := range tx.Orders {
|
|
||||||
ret.Orders = append(ret.Orders, &txtypes.OrderInfo{
|
|
||||||
MarketIndex: order.MarketIndex,
|
|
||||||
ClientOrderIndex: order.ClientOrderIndex,
|
|
||||||
BaseAmount: order.BaseAmount,
|
|
||||||
Price: order.Price,
|
|
||||||
IsAsk: order.IsAsk,
|
|
||||||
Type: order.Type,
|
|
||||||
TimeInForce: order.TimeInForce,
|
|
||||||
ReduceOnly: order.ReduceOnly,
|
|
||||||
TriggerPrice: order.TriggerPrice,
|
|
||||||
OrderExpiry: order.OrderExpiry,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCancelOrderTx(tx *CancelOrderTxReq, ops *TransactOpts) *txtypes.L2CancelOrderTxInfo {
|
|
||||||
return &txtypes.L2CancelOrderTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
MarketIndex: tx.MarketIndex,
|
|
||||||
Index: tx.Index,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertModifyOrderTx(tx *ModifyOrderTxReq, ops *TransactOpts) *txtypes.L2ModifyOrderTxInfo {
|
|
||||||
return &txtypes.L2ModifyOrderTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
MarketIndex: tx.MarketIndex,
|
|
||||||
Index: tx.Index,
|
|
||||||
BaseAmount: tx.BaseAmount,
|
|
||||||
Price: tx.Price,
|
|
||||||
TriggerPrice: tx.TriggerPrice,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCancelAllOrdersTx(tx *CancelAllOrdersTxReq, ops *TransactOpts) *txtypes.L2CancelAllOrdersTxInfo {
|
|
||||||
return &txtypes.L2CancelAllOrdersTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
TimeInForce: tx.TimeInForce,
|
|
||||||
Time: tx.Time,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertWithdrawTx(tx *WithdrawTxReq, ops *TransactOpts) *txtypes.L2WithdrawTxInfo {
|
|
||||||
return &txtypes.L2WithdrawTxInfo{
|
|
||||||
FromAccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
USDCAmount: tx.USDCAmount,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertChangePubKeyTx(tx *ChangePubKeyReq, ops *TransactOpts) *txtypes.L2ChangePubKeyTxInfo {
|
|
||||||
return &txtypes.L2ChangePubKeyTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
PubKey: tx.PubKey[:],
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCreateSubAccountTx(ops *TransactOpts) *txtypes.L2CreateSubAccountTxInfo {
|
|
||||||
return &txtypes.L2CreateSubAccountTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertCreatePublicPoolTx(tx *CreatePublicPoolTxReq, ops *TransactOpts) *txtypes.L2CreatePublicPoolTxInfo {
|
|
||||||
return &txtypes.L2CreatePublicPoolTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
OperatorFee: tx.OperatorFee,
|
|
||||||
InitialTotalShares: tx.InitialTotalShares,
|
|
||||||
MinOperatorShareRate: tx.MinOperatorShareRate,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertUpdatePublicPoolTx(tx *UpdatePublicPoolTxReq, ops *TransactOpts) *txtypes.L2UpdatePublicPoolTxInfo {
|
|
||||||
return &txtypes.L2UpdatePublicPoolTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
PublicPoolIndex: tx.PublicPoolIndex,
|
|
||||||
Status: tx.Status,
|
|
||||||
OperatorFee: tx.OperatorFee,
|
|
||||||
MinOperatorShareRate: tx.MinOperatorShareRate,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertMintSharesTx(tx *MintSharesTxReq, ops *TransactOpts) *txtypes.L2MintSharesTxInfo {
|
|
||||||
return &txtypes.L2MintSharesTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
PublicPoolIndex: tx.PublicPoolIndex,
|
|
||||||
ShareAmount: tx.ShareAmount,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertBurnSharesTx(tx *BurnSharesTxReq, ops *TransactOpts) *txtypes.L2BurnSharesTxInfo {
|
|
||||||
return &txtypes.L2BurnSharesTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
PublicPoolIndex: tx.PublicPoolIndex,
|
|
||||||
ShareAmount: tx.ShareAmount,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertUpdateLeverageTx(tx *UpdateLeverageTxReq, ops *TransactOpts) *txtypes.L2UpdateLeverageTxInfo {
|
|
||||||
return &txtypes.L2UpdateLeverageTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
MarketIndex: tx.MarketIndex,
|
|
||||||
InitialMarginFraction: tx.InitialMarginFraction,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ConvertUpdateMarginTx(tx *UpdateMarginTxReq, ops *TransactOpts) *txtypes.L2UpdateMarginTxInfo {
|
|
||||||
return &txtypes.L2UpdateMarginTxInfo{
|
|
||||||
AccountIndex: *ops.FromAccountIndex,
|
|
||||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
|
||||||
MarketIndex: tx.MarketIndex,
|
|
||||||
USDCAmount: tx.USDCAmount,
|
|
||||||
Direction: tx.Direction,
|
|
||||||
ExpiredAt: ops.ExpiredAt,
|
|
||||||
Nonce: *ops.Nonce,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2BurnSharesTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2BurnSharesTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
PublicPoolIndex int64
|
|
||||||
ShareAmount int64
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2BurnSharesTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2BurnShares
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2BurnSharesTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2BurnSharesTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2BurnSharesTxInfo) Validate() error {
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicPoolIndex
|
|
||||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ShareAmount < MinPoolSharesToMintOrBurn {
|
|
||||||
return ErrPoolBurnShareAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ShareAmount > MaxPoolSharesToMintOrBurn {
|
|
||||||
return ErrPoolBurnShareAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2BurnSharesTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 8)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2BurnShares))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ShareAmount))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CancelAllOrdersTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2CancelAllOrdersTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
TimeInForce uint8
|
|
||||||
Time int64
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CancelAllOrders
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelAllOrdersTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex && txInfo.ApiKeyIndex != NilApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeInForce and Time
|
|
||||||
switch txInfo.TimeInForce {
|
|
||||||
case ImmediateCancelAll:
|
|
||||||
if txInfo.Time != NilOrderExpiry {
|
|
||||||
return ErrCancelAllTimeisNotNill
|
|
||||||
}
|
|
||||||
case ScheduledCancelAll:
|
|
||||||
if txInfo.Time < MinOrderExpiry || txInfo.Time > MaxOrderExpiry {
|
|
||||||
return ErrCancelAllTimeIsNotInRange
|
|
||||||
}
|
|
||||||
case AbortScheduledCancelAll:
|
|
||||||
if txInfo.Time != 0 {
|
|
||||||
return ErrCancelAllTimeIsNotInRange
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ErrInvalidCancelAllTimeInForce
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelAllOrdersTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 8)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CancelAllOrders))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.TimeInForce)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Time))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CancelOrderTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2CancelOrderTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
MarketIndex uint8
|
|
||||||
Index int64 // Client Order Index or Order Index of the order to cancel
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelOrderTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CancelOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelOrderTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelOrderTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelOrderTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex
|
|
||||||
if txInfo.MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index
|
|
||||||
if txInfo.Index < MinClientOrderIndex && txInfo.Index < MinOrderIndex {
|
|
||||||
return ErrOrderIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.Index > MaxClientOrderIndex && txInfo.Index > MaxOrderIndex {
|
|
||||||
return ErrOrderIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CancelOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 7)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CancelOrder))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Index))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
templateChangePubKey = "Register Lighter Account\n\npubkey: 0x%s\nnonce: %s\naccount index: %s\napi key index: %s\nOnly sign this message for a trusted client!"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getHex10FromUint64(value uint64) string {
|
|
||||||
v := hexutil.EncodeUint64(value)
|
|
||||||
v = strings.Replace(v, "0x", "", 1)
|
|
||||||
|
|
||||||
// Make sure result has fixed bytes
|
|
||||||
vBytes := []byte(v)
|
|
||||||
if len(vBytes) < 16 {
|
|
||||||
toAppend := make([]byte, 16-len(vBytes))
|
|
||||||
for i := range toAppend {
|
|
||||||
toAppend[i] = 48
|
|
||||||
}
|
|
||||||
vBytes = append(toAppend, vBytes...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("0x%s", string(vBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2ChangePubKeyTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2ChangePubKeyTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
PubKey []byte
|
|
||||||
L1Sig string
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2ChangePubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if !IsValidPubKey(txInfo.PubKey) {
|
|
||||||
return ErrPubKeyInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) GetL1SignatureBody() string {
|
|
||||||
signatureBody := fmt.Sprintf(templateChangePubKey,
|
|
||||||
common.Bytes2Hex(txInfo.PubKey),
|
|
||||||
getHex10FromUint64(uint64(txInfo.Nonce)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.AccountIndex)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.ApiKeyIndex)),
|
|
||||||
)
|
|
||||||
return signatureBody
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ChangePubKeyTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 11)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2ChangePubKey))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
|
|
||||||
pubKeyFieldElems, err := g.ArrayFromCanonicalLittleEndianBytes(txInfo.PubKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to convert bytes to field element. bytes: %v, error: %w", txInfo.PubKey, err)
|
|
||||||
}
|
|
||||||
elems = append(elems, pubKeyFieldElems...)
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
curve "github.com/elliottech/poseidon_crypto/curve/ecgfp5"
|
|
||||||
schnorr "github.com/elliottech/poseidon_crypto/signature/schnorr"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
Signature = schnorr.Signature
|
|
||||||
PrivateKey = curve.ECgFp5Scalar
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
NilApiKeyIndex = MaxApiKeyIndex + 1
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
TxTypeL2ChangePubKey = 8
|
|
||||||
TxTypeL2CreateSubAccount = 9
|
|
||||||
TxTypeL2CreatePublicPool = 10
|
|
||||||
TxTypeL2UpdatePublicPool = 11
|
|
||||||
TxTypeL2Transfer = 12
|
|
||||||
TxTypeL2Withdraw = 13
|
|
||||||
TxTypeL2CreateOrder = 14
|
|
||||||
TxTypeL2CancelOrder = 15
|
|
||||||
TxTypeL2CancelAllOrders = 16
|
|
||||||
TxTypeL2ModifyOrder = 17
|
|
||||||
TxTypeL2MintShares = 18
|
|
||||||
TxTypeL2BurnShares = 19
|
|
||||||
TxTypeL2UpdateLeverage = 20
|
|
||||||
|
|
||||||
TxTypeInternalClaimOrder = 21
|
|
||||||
TxTypeInternalCancelOrder = 22
|
|
||||||
TxTypeInternalDeleverage = 23
|
|
||||||
TxTypeInternalExitPosition = 24
|
|
||||||
TxTypeInternalCancelAllOrders = 25
|
|
||||||
TxTypeInternalLiquidatePosition = 26
|
|
||||||
TxTypeInternalCreateOrder = 27
|
|
||||||
|
|
||||||
TxTypeL2CreateGroupedOrders = 28
|
|
||||||
TxTypeL2UpdateMargin = 29
|
|
||||||
)
|
|
||||||
|
|
||||||
// Order Type
|
|
||||||
const (
|
|
||||||
// User set order types
|
|
||||||
LimitOrder = iota
|
|
||||||
MarketOrder = 1
|
|
||||||
StopLossOrder = 2
|
|
||||||
StopLossLimitOrder = 3
|
|
||||||
TakeProfitOrder = 4
|
|
||||||
TakeProfitLimitOrder = 5
|
|
||||||
TWAPOrder = 6
|
|
||||||
|
|
||||||
// Internal order types
|
|
||||||
TWAPSubOrder = 7
|
|
||||||
LiquidationOrder = 8
|
|
||||||
|
|
||||||
ApiMaxOrderType = TWAPOrder
|
|
||||||
)
|
|
||||||
|
|
||||||
// Order Time-In-Force
|
|
||||||
const (
|
|
||||||
ImmediateOrCancel = iota
|
|
||||||
GoodTillTime = 1
|
|
||||||
PostOnly = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// Grouping Type
|
|
||||||
const (
|
|
||||||
GroupingType = 0
|
|
||||||
GroupingType_OneTriggersTheOther = 1
|
|
||||||
GroupingType_OneCancelsTheOther = 2
|
|
||||||
GroupingType_OneTriggersAOneCancelsTheOther = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cancel All Orders Time-In-Force
|
|
||||||
const (
|
|
||||||
ImmediateCancelAll = iota
|
|
||||||
ScheduledCancelAll = 1
|
|
||||||
AbortScheduledCancelAll = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HashLength int = 32
|
|
||||||
|
|
||||||
OneUSDC = 1000000
|
|
||||||
|
|
||||||
FeeTick int64 = 1_000_000
|
|
||||||
MarginFractionTick int64 = 10_000
|
|
||||||
ShareTick int64 = 10_000
|
|
||||||
|
|
||||||
MinAccountIndex int64 = 0
|
|
||||||
MaxAccountIndex int64 = 281474976710654 // (1 << 48) - 2
|
|
||||||
MinApiKeyIndex uint8 = 0
|
|
||||||
MaxApiKeyIndex uint8 = 254 // (1 << 8) - 2
|
|
||||||
MaxMasterAccountIndex int64 = 140737488355327 // (1 << 47) - 1
|
|
||||||
|
|
||||||
MinMarketIndex uint8 = 0
|
|
||||||
MaxMarketIndex uint8 = 254 // (1 << 8) - 2
|
|
||||||
|
|
||||||
MaxInvestedPublicPoolCount int64 = 16
|
|
||||||
InitialPoolShareValue int64 = 1_000 // 0.001 USDC
|
|
||||||
MinInitialTotalShares int64 = 1_000 * (OneUSDC / InitialPoolShareValue) // 1,000 USDC worth of shares
|
|
||||||
MaxInitialTotalShares int64 = 1_000_000_000 * (OneUSDC / InitialPoolShareValue) // 1,000,000,000 USDC worth of shares
|
|
||||||
MaxPoolShares int64 = (1 << 60) - 1
|
|
||||||
MaxBurntShareUSDCValue int64 = (1 << 60) - 1
|
|
||||||
|
|
||||||
MaxPoolEntryUSDC = (1 << 56) - 1 // 2^56 - 1 max USDC to invest in a pool
|
|
||||||
MinPoolSharesToMintOrBurn int64 = 1
|
|
||||||
MaxPoolSharesToMintOrBurn int64 = (1 << 60) - 1
|
|
||||||
|
|
||||||
MinNonce int64 = 0
|
|
||||||
|
|
||||||
MinOrderNonce int64 = 0
|
|
||||||
MaxOrderNonce int64 = (1 << 48) - 1
|
|
||||||
|
|
||||||
NilClientOrderIndex int64 = 0
|
|
||||||
NilOrderIndex int64 = 0
|
|
||||||
|
|
||||||
MinClientOrderIndex int64 = 1
|
|
||||||
MaxClientOrderIndex int64 = (1 << 48) - 1
|
|
||||||
|
|
||||||
MinOrderIndex int64 = MaxClientOrderIndex + 1
|
|
||||||
MaxOrderIndex int64 = (1 << 56) - 1
|
|
||||||
|
|
||||||
MinOrderBaseAmount int64 = 1
|
|
||||||
MaxOrderBaseAmount int64 = (1 << 48) - 1
|
|
||||||
NilOrderBaseAmount int64 = 0
|
|
||||||
|
|
||||||
NilOrderPrice uint32 = 0
|
|
||||||
MinOrderPrice uint32 = 1
|
|
||||||
MaxOrderPrice uint32 = (1 << 32) - 1
|
|
||||||
|
|
||||||
MinOrderCancelAllPeriod int64 = 1000 * 60 * 5 // 5 minutes
|
|
||||||
MaxOrderCancelAllPeriod int64 = 1000 * 60 * 60 * 24 * 15 // 15 days
|
|
||||||
|
|
||||||
NilOrderExpiry int64 = 0
|
|
||||||
MinOrderExpiry int64 = 1
|
|
||||||
MaxOrderExpiry int64 = math.MaxInt64
|
|
||||||
|
|
||||||
MinOrderExpiryPeriod int64 = 1000 * 60 * 5 // 5 minutes
|
|
||||||
MaxOrderExpiryPeriod int64 = 1000 * 60 * 60 * 24 * 30 // 30 days
|
|
||||||
|
|
||||||
NilOrderTriggerPrice uint32 = 0
|
|
||||||
MinOrderTriggerPrice uint32 = 1
|
|
||||||
MaxOrderTriggerPrice uint32 = (1 << 32) - 1
|
|
||||||
|
|
||||||
MaxGroupedOrderCount int64 = 3
|
|
||||||
|
|
||||||
MaxTimestamp = (1 << 48) - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MaxExchangeUSDC = (1 << 60) - 1
|
|
||||||
|
|
||||||
MinTransferAmount int64 = 1
|
|
||||||
MaxTransferAmount int64 = MaxExchangeUSDC
|
|
||||||
|
|
||||||
MinWithdrawalAmount uint64 = 1
|
|
||||||
MaxWithdrawalAmount uint64 = MaxExchangeUSDC
|
|
||||||
)
|
|
||||||
|
|
||||||
// Margin Modes
|
|
||||||
const (
|
|
||||||
CrossMargin = iota
|
|
||||||
IsolatedMargin = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RemoveFromIsolatedMargin = 0
|
|
||||||
AddToIsolatedMargin = 1
|
|
||||||
)
|
|
||||||
@@ -1,336 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CreateGroupedOrdersTxInfo)(nil)
|
|
||||||
|
|
||||||
// !!! Ensure that if primary order is reduce only, all child orders are also reduce only
|
|
||||||
// !!! Otherwise CancelPositionTiedAccountOrders flow breaks
|
|
||||||
type L2CreateGroupedOrdersTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
GroupingType uint8
|
|
||||||
|
|
||||||
Orders []*OrderInfo
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CreateGroupedOrders
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(txInfo.Orders) == 0 || len(txInfo.Orders) > int(MaxGroupedOrderCount) {
|
|
||||||
return ErrOrderGroupSizeInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex for first order
|
|
||||||
if txInfo.Orders[0].MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.Orders[0].MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform range checks for all orders
|
|
||||||
for _, order := range txInfo.Orders {
|
|
||||||
// MarketIndex
|
|
||||||
if order.MarketIndex != txInfo.Orders[0].MarketIndex {
|
|
||||||
return ErrMarketIndexMismatch
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOrderIndex
|
|
||||||
if order.ClientOrderIndex != NilClientOrderIndex {
|
|
||||||
return ErrClientOrderIndexNotNil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseAmount
|
|
||||||
if order.ReduceOnly != 1 && order.BaseAmount == NilOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooLow
|
|
||||||
}
|
|
||||||
if order.BaseAmount != NilOrderBaseAmount && order.BaseAmount < MinOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooLow
|
|
||||||
}
|
|
||||||
if order.BaseAmount > MaxOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Price
|
|
||||||
if order.Price < MinOrderPrice {
|
|
||||||
return ErrPriceTooLow
|
|
||||||
}
|
|
||||||
if order.Price > MaxOrderPrice {
|
|
||||||
return ErrPriceTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAsk
|
|
||||||
if order.IsAsk != 0 && order.IsAsk != 1 {
|
|
||||||
return ErrIsAskInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeInForce
|
|
||||||
if order.TimeInForce != ImmediateOrCancel && order.TimeInForce != GoodTillTime && order.TimeInForce != PostOnly {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReduceOnly
|
|
||||||
if order.ReduceOnly != 0 && order.ReduceOnly != 1 {
|
|
||||||
return ErrOrderReduceOnlyInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderExpiry
|
|
||||||
if (order.OrderExpiry < MinOrderExpiry || order.OrderExpiry > MaxOrderExpiry) && order.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerPrice
|
|
||||||
if (order.TriggerPrice < MinOrderTriggerPrice || order.TriggerPrice > MaxOrderTriggerPrice) && order.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
switch txInfo.GroupingType {
|
|
||||||
case GroupingType_OneCancelsTheOther:
|
|
||||||
return txInfo.ValidateOCO()
|
|
||||||
case GroupingType_OneTriggersTheOther:
|
|
||||||
return txInfo.ValidateOTO()
|
|
||||||
case GroupingType_OneTriggersAOneCancelsTheOther:
|
|
||||||
return txInfo.ValidateOTOCO()
|
|
||||||
default:
|
|
||||||
return ErrGroupingTypeInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateParentOrder(order *OrderInfo) error {
|
|
||||||
switch order.Type {
|
|
||||||
case MarketOrder:
|
|
||||||
if order.TimeInForce != ImmediateOrCancel {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
} else if order.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
} else if order.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
}
|
|
||||||
case LimitOrder:
|
|
||||||
if order.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if order.TimeInForce == ImmediateOrCancel && order.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
} else if order.TimeInForce != ImmediateOrCancel && order.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ErrOrderTypeInvalid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateChildOrder(order *OrderInfo) error {
|
|
||||||
switch order.Type {
|
|
||||||
case StopLossOrder, TakeProfitOrder:
|
|
||||||
if order.TimeInForce != ImmediateOrCancel {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
} else if order.TriggerPrice == NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if order.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
case StopLossLimitOrder, TakeProfitLimitOrder:
|
|
||||||
if order.TriggerPrice == NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if order.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ErrOrderTypeInvalid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateSiblingOrders(orders []*OrderInfo) error {
|
|
||||||
if len(orders) != 2 {
|
|
||||||
return ErrOrderGroupSizeInvalid
|
|
||||||
}
|
|
||||||
slFlag := false
|
|
||||||
tpFlag := false
|
|
||||||
for _, order := range orders {
|
|
||||||
err := txInfo.ValidateChildOrder(order)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if order.Type == StopLossOrder || order.Type == StopLossLimitOrder {
|
|
||||||
slFlag = true
|
|
||||||
} else if order.Type == TakeProfitOrder || order.Type == TakeProfitLimitOrder {
|
|
||||||
tpFlag = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !slFlag || !tpFlag {
|
|
||||||
return ErrOrderTypeInvalid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOCO() error {
|
|
||||||
if len(txInfo.Orders) != 2 {
|
|
||||||
return ErrOrderGroupSizeInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure both orders base sizes are same
|
|
||||||
if txInfo.Orders[0].BaseAmount != txInfo.Orders[1].BaseAmount {
|
|
||||||
return ErrBaseAmountsNotEqual
|
|
||||||
}
|
|
||||||
|
|
||||||
// Orders should be in the same direction
|
|
||||||
if txInfo.Orders[0].IsAsk != txInfo.Orders[1].IsAsk {
|
|
||||||
return ErrIsAskInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure both orders are reduce only
|
|
||||||
if txInfo.Orders[0].ReduceOnly != 1 || txInfo.Orders[1].ReduceOnly != 1 {
|
|
||||||
return ErrOrderReduceOnlyInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure both orders have the same non-nil expiry
|
|
||||||
if txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return txInfo.ValidateSiblingOrders(txInfo.Orders)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOTO() error {
|
|
||||||
if len(txInfo.Orders) != 2 {
|
|
||||||
return ErrOrderGroupSizeInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure child order base size is 0
|
|
||||||
if txInfo.Orders[1].BaseAmount != NilOrderBaseAmount {
|
|
||||||
return ErrBaseAmountNotNil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Orders should be in the opposite direction
|
|
||||||
if txInfo.Orders[0].IsAsk == txInfo.Orders[1].IsAsk {
|
|
||||||
return ErrIsAskInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure if expiries are not nil, they are the same
|
|
||||||
if txInfo.Orders[0].OrderExpiry != NilOrderExpiry &&
|
|
||||||
txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
err := txInfo.ValidateParentOrder(txInfo.Orders[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return txInfo.ValidateChildOrder(txInfo.Orders[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOTOCO() error {
|
|
||||||
if len(txInfo.Orders) != 3 {
|
|
||||||
return ErrOrderGroupSizeInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure child orders base size is 0
|
|
||||||
if txInfo.Orders[1].BaseAmount != NilOrderBaseAmount || txInfo.Orders[2].BaseAmount != NilOrderBaseAmount {
|
|
||||||
return ErrBaseAmountNotNil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primary and child orders should be in the oppsite direction
|
|
||||||
if txInfo.Orders[0].IsAsk == txInfo.Orders[1].IsAsk || txInfo.Orders[0].IsAsk == txInfo.Orders[2].IsAsk {
|
|
||||||
return ErrIsAskInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure child orders has the same expiry
|
|
||||||
if txInfo.Orders[1].OrderExpiry != txInfo.Orders[2].OrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure if expiries are not nil, they are the same
|
|
||||||
if txInfo.Orders[0].OrderExpiry != NilOrderExpiry &&
|
|
||||||
txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
err := txInfo.ValidateParentOrder(txInfo.Orders[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return txInfo.ValidateSiblingOrders(txInfo.Orders[1:])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateGroupedOrdersTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 11)
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CreateGroupedOrders))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.GroupingType)))
|
|
||||||
|
|
||||||
aggregatedOrderHash := p2.EmptyHashOut()
|
|
||||||
for index, order := range txInfo.Orders {
|
|
||||||
orderHash := p2.HashNoPad([]g.Element{
|
|
||||||
g.FromUint32(uint32(order.MarketIndex)),
|
|
||||||
g.FromInt64(order.ClientOrderIndex),
|
|
||||||
g.FromInt64(order.BaseAmount),
|
|
||||||
g.FromUint32(order.Price),
|
|
||||||
g.FromUint32(uint32(order.IsAsk)),
|
|
||||||
g.FromUint32(uint32(order.Type)),
|
|
||||||
g.FromUint32(uint32(order.TimeInForce)),
|
|
||||||
g.FromUint32(uint32(order.ReduceOnly)),
|
|
||||||
g.FromUint32(order.TriggerPrice),
|
|
||||||
g.FromInt64(order.OrderExpiry),
|
|
||||||
})
|
|
||||||
if index == 0 {
|
|
||||||
aggregatedOrderHash = orderHash
|
|
||||||
} else {
|
|
||||||
aggregatedOrderHash = p2.HashNToOne([]p2.HashOut{aggregatedOrderHash, orderHash})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elems = append(elems, aggregatedOrderHash[:]...)
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CreateOrderTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2CreateOrderTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
*OrderInfo
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateOrderTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CreateOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateOrderTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateOrderTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateOrderTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex
|
|
||||||
if txInfo.MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOrderIndex
|
|
||||||
if txInfo.ClientOrderIndex != NilClientOrderIndex {
|
|
||||||
if txInfo.ClientOrderIndex < MinClientOrderIndex {
|
|
||||||
return ErrClientOrderIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ClientOrderIndex > MaxClientOrderIndex {
|
|
||||||
return ErrClientOrderIndexTooHigh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseAmount
|
|
||||||
if txInfo.ReduceOnly != 1 && txInfo.BaseAmount == NilOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.BaseAmount != NilOrderBaseAmount && txInfo.BaseAmount < MinOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.BaseAmount > MaxOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Price
|
|
||||||
if txInfo.Price < MinOrderPrice {
|
|
||||||
return ErrPriceTooLow
|
|
||||||
}
|
|
||||||
if txInfo.Price > MaxOrderPrice {
|
|
||||||
return ErrPriceTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAsk
|
|
||||||
if txInfo.IsAsk != 0 && txInfo.IsAsk != 1 {
|
|
||||||
return ErrIsAskInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.TimeInForce != ImmediateOrCancel && txInfo.TimeInForce != GoodTillTime && txInfo.TimeInForce != PostOnly {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ReduceOnly != 0 && txInfo.ReduceOnly != 1 {
|
|
||||||
return ErrOrderReduceOnlyInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txInfo.OrderExpiry < MinOrderExpiry || txInfo.OrderExpiry > MaxOrderExpiry) && txInfo.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
switch txInfo.Type {
|
|
||||||
case MarketOrder:
|
|
||||||
if txInfo.TimeInForce != ImmediateOrCancel {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
} else if txInfo.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
} else if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
}
|
|
||||||
case LimitOrder:
|
|
||||||
if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if txInfo.TimeInForce == ImmediateOrCancel && txInfo.OrderExpiry != NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
} else if txInfo.TimeInForce != ImmediateOrCancel && txInfo.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
case StopLossOrder, TakeProfitOrder:
|
|
||||||
if txInfo.TimeInForce != ImmediateOrCancel {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
} else if txInfo.TriggerPrice == NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
case StopLossLimitOrder, TakeProfitLimitOrder:
|
|
||||||
if txInfo.TriggerPrice == NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
case TWAPOrder:
|
|
||||||
if txInfo.TimeInForce != GoodTillTime {
|
|
||||||
return ErrOrderTimeInForceInvalid
|
|
||||||
} else if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
|
||||||
return ErrOrderExpiryInvalid
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return ErrOrderTypeInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerPrice
|
|
||||||
if (txInfo.TriggerPrice < MinOrderTriggerPrice || txInfo.TriggerPrice > MaxOrderTriggerPrice) && txInfo.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 16)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CreateOrder))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ClientOrderIndex))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.BaseAmount))
|
|
||||||
elems = append(elems, g.FromUint32(txInfo.Price))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.IsAsk)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.Type)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.TimeInForce)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ReduceOnly)))
|
|
||||||
elems = append(elems, g.FromUint32(txInfo.TriggerPrice))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.OrderExpiry))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CreatePublicPoolTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2CreatePublicPoolTxInfo struct {
|
|
||||||
AccountIndex int64 // Master account index
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
OperatorFee int64
|
|
||||||
InitialTotalShares int64
|
|
||||||
MinOperatorShareRate int64
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CreatePublicPool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreatePublicPoolTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxMasterAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperatorFee
|
|
||||||
if txInfo.OperatorFee < 0 || txInfo.OperatorFee > FeeTick {
|
|
||||||
return ErrInvalidPoolOperatorFee
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitialTotalShares
|
|
||||||
if txInfo.InitialTotalShares <= 0 {
|
|
||||||
return ErrPoolInitialTotalSharesTooLow
|
|
||||||
}
|
|
||||||
if txInfo.InitialTotalShares > MaxInitialTotalShares {
|
|
||||||
return ErrPoolInitialTotalSharesTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MinOperatorShareRate
|
|
||||||
if txInfo.MinOperatorShareRate < 0 {
|
|
||||||
return ErrPoolMinOperatorShareRateTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MinOperatorShareRate > ShareTick {
|
|
||||||
return ErrPoolMinOperatorShareRateTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreatePublicPoolTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 9)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CreatePublicPool))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.OperatorFee))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.InitialTotalShares))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.MinOperatorShareRate))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2CreateSubAccountTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2CreateSubAccountTxInfo struct {
|
|
||||||
AccountIndex int64 // Master account index
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2CreateSubAccount
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateSubAccountTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2CreateSubAccountTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 6)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2CreateSubAccount))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrAccountIndexTooLow = fmt.Errorf("AccountIndex should not be less than %d", MinAccountIndex)
|
|
||||||
ErrAccountIndexTooHigh = fmt.Errorf("AccountIndex should not be larger than %d", MaxAccountIndex)
|
|
||||||
ErrNonceTooLow = fmt.Errorf("AccountNonce should not be less than %d", MinNonce)
|
|
||||||
ErrInvalidCancelAllTimeInForce = fmt.Errorf("CancelAllTimeInForce is invalid")
|
|
||||||
ErrOrderReduceOnlyInvalid = fmt.Errorf("ReduceOnly is invalid")
|
|
||||||
ErrOrderTriggerPriceInvalid = fmt.Errorf("TriggerPrice is invalid")
|
|
||||||
ErrOrderExpiryInvalid = fmt.Errorf("OrderExpiry is invalid")
|
|
||||||
ErrExpiredAtInvalid = fmt.Errorf("ExpiredAt is invalid")
|
|
||||||
ErrCancelAllTimeIsNotInRange = fmt.Errorf("CancelAllTime should be larger than 0 and not larger than %d", MaxOrderExpiry)
|
|
||||||
ErrCancelAllTimeisNotNill = fmt.Errorf("CancelAllTime should be nil")
|
|
||||||
ErrPubKeyInvalid = fmt.Errorf("PubKey is invalid")
|
|
||||||
ErrToAccountIndexTooLow = fmt.Errorf("ToAccountIndex should not be less than %d", MinAccountIndex)
|
|
||||||
ErrToAccountIndexTooHigh = fmt.Errorf("ToAccountIndex should not be larger than %d", MaxAccountIndex)
|
|
||||||
ErrFromAccountIndexTooLow = fmt.Errorf("FromAccountIndex should not be less than %d", MinAccountIndex)
|
|
||||||
ErrFromAccountIndexTooHigh = fmt.Errorf("FromAccountIndex should not be larger than %d", MaxAccountIndex)
|
|
||||||
ErrApiKeyIndexTooLow = fmt.Errorf("ApiKeyIndex should not be less than %d", MinApiKeyIndex)
|
|
||||||
ErrApiKeyIndexTooHigh = fmt.Errorf("ApiKeyIndex should not be larger than %d", MaxApiKeyIndex)
|
|
||||||
ErrPublicPoolIndexTooLow = fmt.Errorf("PublicPoolIndex should not be less than %d", MinAccountIndex)
|
|
||||||
ErrPublicPoolIndexTooHigh = fmt.Errorf("PublicPoolIndex should not be larger than %d", MaxAccountIndex)
|
|
||||||
ErrInvalidPoolOperatorFee = fmt.Errorf("PoolOperatorFee should be larger than 0 and not larger than %d", FeeTick)
|
|
||||||
ErrInvalidPoolStatus = fmt.Errorf("PoolStatus should be either 0 or 1")
|
|
||||||
ErrPoolInitialTotalSharesTooLow = fmt.Errorf("PoolInitialTotalShares should be larger than %d", MinInitialTotalShares)
|
|
||||||
ErrPoolInitialTotalSharesTooHigh = fmt.Errorf("PoolInitialTotalShares should not be larger than %d", MaxInitialTotalShares)
|
|
||||||
ErrPoolMinOperatorShareRateTooLow = fmt.Errorf("PoolMinOperatorShareRate should be larger than 0")
|
|
||||||
ErrPoolMinOperatorShareRateTooHigh = fmt.Errorf("PoolMinOperatorShareRate should not be larger than %d", ShareTick)
|
|
||||||
ErrPoolMintShareAmountTooLow = fmt.Errorf("PoolMintShareAmount should be larger than %d", MinPoolSharesToMintOrBurn)
|
|
||||||
ErrPoolMintShareAmountTooHigh = fmt.Errorf("PoolMintShareAmount should not be larger than %d", MaxPoolSharesToMintOrBurn)
|
|
||||||
ErrPoolBurnShareAmountTooLow = fmt.Errorf("PoolBurnShareAmount should be larger than %d", MinPoolSharesToMintOrBurn)
|
|
||||||
ErrPoolBurnShareAmountTooHigh = fmt.Errorf("PoolBurnShareAmount should not be larger than %d", MaxPoolSharesToMintOrBurn)
|
|
||||||
ErrWithdrawalAmountTooLow = fmt.Errorf("WithdrawalAmount should be larger than %d", MinWithdrawalAmount)
|
|
||||||
ErrWithdrawalAmountTooHigh = fmt.Errorf("WithdrawalAmount should not be larger than %d", MaxWithdrawalAmount)
|
|
||||||
ErrTransferAmountTooLow = fmt.Errorf("TransferAmount should be larger than %d", MinTransferAmount)
|
|
||||||
ErrTransferAmountTooHigh = fmt.Errorf("TransferAmount should not be larger than %d", MaxTransferAmount)
|
|
||||||
ErrMarketIndexTooLow = fmt.Errorf("MarketIndex should not be less than %d", MinMarketIndex)
|
|
||||||
ErrMarketIndexTooHigh = fmt.Errorf("MarketIndex should not be larger than %d", MaxMarketIndex)
|
|
||||||
ErrMarketIndexMismatch = fmt.Errorf("MarketIndex should match the market index of the order")
|
|
||||||
ErrInitialMarginFractionTooLow = fmt.Errorf("InitialMarginFraction should not be less than %d", 0)
|
|
||||||
ErrInitialMarginFractionTooHigh = fmt.Errorf("InitialMarginFraction should not be larger than %d", MarginFractionTick)
|
|
||||||
ErrClientOrderIndexTooLow = fmt.Errorf("ClientOrderIndex should not be less than %d", MinClientOrderIndex)
|
|
||||||
ErrClientOrderIndexTooHigh = fmt.Errorf("ClientOrderIndex should not be larger than %d", MaxClientOrderIndex)
|
|
||||||
ErrClientOrderIndexNotNil = fmt.Errorf("ClientOrderIndex should be nil")
|
|
||||||
ErrOrderIndexTooLow = fmt.Errorf("OrderIndex should not be less than %d", MinOrderIndex)
|
|
||||||
ErrOrderIndexTooHigh = fmt.Errorf("OrderIndex should not be larger than %d", MaxOrderIndex)
|
|
||||||
ErrBaseAmountTooLow = fmt.Errorf("BaseAmount should not be less than %d", MinOrderBaseAmount)
|
|
||||||
ErrBaseAmountTooHigh = fmt.Errorf("BaseAmount should not be larger than %d", MaxOrderBaseAmount)
|
|
||||||
ErrBaseAmountsNotEqual = fmt.Errorf("BaseAmounts should be equal")
|
|
||||||
ErrBaseAmountNotNil = fmt.Errorf("BaseAmount should be nil")
|
|
||||||
ErrPriceTooLow = fmt.Errorf("OrderPrice should not be less than %d", MinOrderPrice)
|
|
||||||
ErrPriceTooHigh = fmt.Errorf("OrderPrice should not be larger than %d", MaxOrderPrice)
|
|
||||||
ErrIsAskInvalid = fmt.Errorf("IsAsk should be 0 or 1")
|
|
||||||
ErrOrderTypeInvalid = fmt.Errorf("OrderType is not valid")
|
|
||||||
ErrOrderTimeInForceInvalid = fmt.Errorf("OrderTimeInForce is not valid")
|
|
||||||
ErrGroupingTypeInvalid = fmt.Errorf("GroupingType is not valid")
|
|
||||||
ErrOrderGroupSizeInvalid = fmt.Errorf("OrderGroupSize is not valid")
|
|
||||||
ErrInvalidSignature = fmt.Errorf("TxSignature is invalid")
|
|
||||||
ErrInvalidMarginMode = fmt.Errorf("MarginMode is not valid")
|
|
||||||
ErrCancelModeInvalid = fmt.Errorf("CancelMode is not valid")
|
|
||||||
ErrInvalidUpdateMarginDirection = fmt.Errorf("Margin movement direction is not valid")
|
|
||||||
ErrTransferFeeNegative = fmt.Errorf("Transfer fee is negative")
|
|
||||||
ErrTransferFeeTooHigh = fmt.Errorf("Transfer fee is higher than %d", MaxTransferAmount)
|
|
||||||
)
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
|
|
||||||
type TxInfo interface {
|
|
||||||
GetTxType() uint8
|
|
||||||
|
|
||||||
GetTxInfo() (string, error)
|
|
||||||
|
|
||||||
// GetTxHash returns the hash that was signed when creating this transaction.
|
|
||||||
// The hash coincides with the TxHash received from Lighter after submitting this Tx.
|
|
||||||
// It can be used to get the TxHash in advance, or to double-check the correctness of the SDK.
|
|
||||||
// As this hash is signed by the ApiKey, if the value differs than the one computed by the server,
|
|
||||||
// it'll result in an invalid signature.
|
|
||||||
// Returns empty string if the Tx is not signed.
|
|
||||||
GetTxHash() string
|
|
||||||
|
|
||||||
Validate() error
|
|
||||||
|
|
||||||
Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderInfo struct {
|
|
||||||
MarketIndex uint8
|
|
||||||
|
|
||||||
ClientOrderIndex int64
|
|
||||||
|
|
||||||
BaseAmount int64
|
|
||||||
Price uint32
|
|
||||||
IsAsk uint8
|
|
||||||
|
|
||||||
Type uint8
|
|
||||||
TimeInForce uint8
|
|
||||||
ReduceOnly uint8
|
|
||||||
TriggerPrice uint32
|
|
||||||
OrderExpiry int64
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2MintSharesTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2MintSharesTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
PublicPoolIndex int64
|
|
||||||
ShareAmount int64
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2MintSharesTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2MintShares
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2MintSharesTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2MintSharesTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2MintSharesTxInfo) Validate() error {
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicPoolIndex
|
|
||||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ShareAmount < MinPoolSharesToMintOrBurn {
|
|
||||||
return ErrPoolMintShareAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ShareAmount > MaxPoolSharesToMintOrBurn {
|
|
||||||
return ErrPoolMintShareAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2MintSharesTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 8)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2MintShares))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ShareAmount))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2ModifyOrderTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2ModifyOrderTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
MarketIndex uint8
|
|
||||||
Index int64 // Client Order Index or Order Index of the order to modify
|
|
||||||
BaseAmount int64
|
|
||||||
Price uint32
|
|
||||||
TriggerPrice uint32
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ModifyOrderTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2ModifyOrder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ModifyOrderTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ModifyOrderTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ModifyOrderTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex
|
|
||||||
if txInfo.MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index
|
|
||||||
if txInfo.Index < MinClientOrderIndex && txInfo.Index < MinOrderIndex {
|
|
||||||
return ErrClientOrderIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.Index > MaxClientOrderIndex && txInfo.Index > MaxOrderIndex {
|
|
||||||
return ErrClientOrderIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseAmount
|
|
||||||
if txInfo.BaseAmount != NilOrderBaseAmount && txInfo.BaseAmount < MinOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.BaseAmount > MaxOrderBaseAmount {
|
|
||||||
return ErrBaseAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Price
|
|
||||||
if txInfo.Price < MinOrderPrice {
|
|
||||||
return ErrPriceTooLow
|
|
||||||
}
|
|
||||||
if txInfo.Price > MaxOrderPrice {
|
|
||||||
return ErrPriceTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerPrice
|
|
||||||
if (txInfo.TriggerPrice < MinOrderTriggerPrice || txInfo.TriggerPrice > MaxOrderTriggerPrice) && txInfo.TriggerPrice != NilOrderTriggerPrice {
|
|
||||||
return ErrOrderTriggerPriceInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2ModifyOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 11)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2ModifyOrder))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Index))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.BaseAmount))
|
|
||||||
elems = append(elems, g.FromUint32(txInfo.Price))
|
|
||||||
elems = append(elems, g.FromUint32(txInfo.TriggerPrice))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
const templateTransfer = "Transfer\n\nnonce: %s\nfrom: %s\napi key: %s\nto: %s\namount: %s\nfee: %s\nmemo: %s\nOnly sign this message for a trusted client!"
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2TransferTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2TransferTxInfo struct {
|
|
||||||
FromAccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
ToAccountIndex int64
|
|
||||||
USDCAmount int64 // USDCAmount is given with 6 decimals
|
|
||||||
Fee int64
|
|
||||||
Memo [32]byte
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) Validate() error {
|
|
||||||
// plus one for treasury account
|
|
||||||
if txInfo.FromAccountIndex < MinAccountIndex+1 {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.FromAccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ToAccountIndex < MinAccountIndex+1 {
|
|
||||||
return ErrToAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ToAccountIndex > MaxAccountIndex {
|
|
||||||
return ErrToAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.USDCAmount <= 0 {
|
|
||||||
return ErrTransferAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.USDCAmount > MaxTransferAmount {
|
|
||||||
return ErrTransferAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Fee < 0 {
|
|
||||||
return ErrTransferFeeNegative
|
|
||||||
}
|
|
||||||
if txInfo.Fee > MaxTransferAmount {
|
|
||||||
return ErrTransferFeeTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2Transfer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 11)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2Transfer))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.FromAccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ToAccountIndex))
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.Fee)&0xFFFFFFFF)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.Fee)>>32)) //nolint:gosec
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2TransferTxInfo) GetL1SignatureBody() string {
|
|
||||||
hexMemo := hex.EncodeToString(txInfo.Memo[:])
|
|
||||||
hexMemo = strings.Replace(hexMemo, "0x", "", 1)
|
|
||||||
|
|
||||||
signatureBody := fmt.Sprintf(
|
|
||||||
templateTransfer,
|
|
||||||
|
|
||||||
getHex10FromUint64(uint64(txInfo.Nonce)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.FromAccountIndex)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.ApiKeyIndex)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.ToAccountIndex)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.USDCAmount)),
|
|
||||||
getHex10FromUint64(uint64(txInfo.Fee)),
|
|
||||||
hexMemo,
|
|
||||||
)
|
|
||||||
return signatureBody
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2UpdateLeverageTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2UpdateLeverageTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
MarketIndex uint8
|
|
||||||
InitialMarginFraction uint16
|
|
||||||
MarginMode uint8
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2UpdateLeverage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateLeverageTxInfo) Validate() error {
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex
|
|
||||||
if txInfo.MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitialMarginFraction
|
|
||||||
if txInfo.InitialMarginFraction <= 0 {
|
|
||||||
return ErrInitialMarginFractionTooLow
|
|
||||||
}
|
|
||||||
if txInfo.InitialMarginFraction > uint16(MarginFractionTick) { //nolint:gosec
|
|
||||||
return ErrInitialMarginFractionTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.MarginMode != CrossMargin && txInfo.MarginMode != IsolatedMargin {
|
|
||||||
return ErrInvalidMarginMode
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateLeverageTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 9)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2UpdateLeverage))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(int64(txInfo.MarketIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(int64(txInfo.InitialMarginFraction)))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarginMode)))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2UpdateMarginTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2UpdateMarginTxInfo struct {
|
|
||||||
AccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
MarketIndex uint8
|
|
||||||
USDCAmount int64
|
|
||||||
Direction uint8
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateMarginTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2UpdateMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateMarginTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateMarginTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateMarginTxInfo) Validate() error {
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketIndex
|
|
||||||
if txInfo.MarketIndex < MinMarketIndex {
|
|
||||||
return ErrMarketIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MarketIndex > MaxMarketIndex {
|
|
||||||
return ErrMarketIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.USDCAmount <= 0 {
|
|
||||||
return ErrTransferAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.USDCAmount > MaxTransferAmount {
|
|
||||||
return ErrTransferAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Direction != RemoveFromIsolatedMargin && txInfo.Direction != AddToIsolatedMargin {
|
|
||||||
return ErrInvalidUpdateMarginDirection
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdateMarginTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 10)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2UpdateMargin))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(int64(txInfo.MarketIndex)))
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.Direction)))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2UpdatePublicPoolTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2UpdatePublicPoolTxInfo struct {
|
|
||||||
AccountIndex int64 // Master account index
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
PublicPoolIndex int64
|
|
||||||
|
|
||||||
Status uint8
|
|
||||||
OperatorFee int64
|
|
||||||
MinOperatorShareRate int64
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2UpdatePublicPool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdatePublicPoolTxInfo) Validate() error {
|
|
||||||
// AccountIndex
|
|
||||||
if txInfo.AccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.AccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicPoolIndex
|
|
||||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
|
||||||
return ErrPublicPoolIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status
|
|
||||||
if txInfo.Status != 0 && txInfo.Status != 1 {
|
|
||||||
return ErrInvalidPoolStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperatorFee
|
|
||||||
if txInfo.OperatorFee < 0 || txInfo.OperatorFee > FeeTick {
|
|
||||||
return ErrInvalidPoolOperatorFee
|
|
||||||
}
|
|
||||||
|
|
||||||
// MinOperatorShareRate
|
|
||||||
if txInfo.MinOperatorShareRate < 0 {
|
|
||||||
return ErrPoolMinOperatorShareRateTooLow
|
|
||||||
}
|
|
||||||
if txInfo.MinOperatorShareRate > ShareTick {
|
|
||||||
return ErrPoolMinOperatorShareRateTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nonce
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2UpdatePublicPoolTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 10)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2UpdatePublicPool))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.Status)))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.OperatorFee))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.MinOperatorShareRate))
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import "encoding/json"
|
|
||||||
|
|
||||||
func IsValidPubKey(bytes []byte) bool {
|
|
||||||
if len(bytes) != 40 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return !isZeroByteSlice(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isZeroByteSlice(bytes []byte) bool {
|
|
||||||
for _, s := range bytes {
|
|
||||||
if s != 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTxInfo(tx interface{}) (string, error) {
|
|
||||||
txInfoBytes, err := json.Marshal(tx)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(txInfoBytes), nil
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
package txtypes
|
|
||||||
|
|
||||||
import (
|
|
||||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
|
||||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ TxInfo = (*L2WithdrawTxInfo)(nil)
|
|
||||||
|
|
||||||
type L2WithdrawTxInfo struct {
|
|
||||||
FromAccountIndex int64
|
|
||||||
ApiKeyIndex uint8
|
|
||||||
|
|
||||||
USDCAmount uint64 // USDCAmount is given with 6 decimals
|
|
||||||
|
|
||||||
ExpiredAt int64
|
|
||||||
Nonce int64
|
|
||||||
Sig []byte
|
|
||||||
SignedHash string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2WithdrawTxInfo) Validate() error {
|
|
||||||
if txInfo.FromAccountIndex < MinAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.FromAccountIndex > MaxAccountIndex {
|
|
||||||
return ErrFromAccountIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApiKeyIndex
|
|
||||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooLow
|
|
||||||
}
|
|
||||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
|
||||||
return ErrApiKeyIndexTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.USDCAmount == 0 {
|
|
||||||
return ErrWithdrawalAmountTooLow
|
|
||||||
}
|
|
||||||
if txInfo.USDCAmount > MaxWithdrawalAmount {
|
|
||||||
return ErrWithdrawalAmountTooHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.Nonce < MinNonce {
|
|
||||||
return ErrNonceTooLow
|
|
||||||
}
|
|
||||||
|
|
||||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
|
||||||
return ErrExpiredAtInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2WithdrawTxInfo) GetTxType() uint8 {
|
|
||||||
return TxTypeL2Withdraw
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2WithdrawTxInfo) GetTxInfo() (string, error) {
|
|
||||||
return getTxInfo(txInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2WithdrawTxInfo) GetTxHash() string {
|
|
||||||
return txInfo.SignedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txInfo *L2WithdrawTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
|
||||||
elems := make([]g.Element, 0, 8)
|
|
||||||
|
|
||||||
elems = append(elems, g.FromUint32(lighterChainId))
|
|
||||||
elems = append(elems, g.FromUint32(TxTypeL2Withdraw))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
|
||||||
|
|
||||||
elems = append(elems, g.FromInt64(txInfo.FromAccountIndex))
|
|
||||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
|
||||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
|
||||||
|
|
||||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
|
||||||
}
|
|
||||||
@@ -69,3 +69,8 @@ openapi-generator-cli.jar
|
|||||||
.idea
|
.idea
|
||||||
|
|
||||||
examples/secrets.py
|
examples/secrets.py
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
api_key_config.json
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
docs/Account.md
|
docs/Account.md
|
||||||
docs/AccountApi.md
|
docs/AccountApi.md
|
||||||
docs/AccountApiKeys.md
|
docs/AccountApiKeys.md
|
||||||
|
docs/AccountAsset.md
|
||||||
docs/AccountLimits.md
|
docs/AccountLimits.md
|
||||||
docs/AccountMarginStats.md
|
docs/AccountMarginStats.md
|
||||||
docs/AccountMarketStats.md
|
docs/AccountMarketStats.md
|
||||||
@@ -14,9 +15,12 @@ docs/Announcement.md
|
|||||||
docs/AnnouncementApi.md
|
docs/AnnouncementApi.md
|
||||||
docs/Announcements.md
|
docs/Announcements.md
|
||||||
docs/ApiKey.md
|
docs/ApiKey.md
|
||||||
|
docs/Asset.md
|
||||||
|
docs/AssetDetails.md
|
||||||
docs/Block.md
|
docs/Block.md
|
||||||
docs/BlockApi.md
|
docs/BlockApi.md
|
||||||
docs/Blocks.md
|
docs/Blocks.md
|
||||||
|
docs/Bridge.md
|
||||||
docs/BridgeApi.md
|
docs/BridgeApi.md
|
||||||
docs/BridgeSupportedNetwork.md
|
docs/BridgeSupportedNetwork.md
|
||||||
docs/Candlestick.md
|
docs/Candlestick.md
|
||||||
@@ -46,28 +50,27 @@ docs/LiqTrade.md
|
|||||||
docs/Liquidation.md
|
docs/Liquidation.md
|
||||||
docs/LiquidationInfo.md
|
docs/LiquidationInfo.md
|
||||||
docs/LiquidationInfos.md
|
docs/LiquidationInfos.md
|
||||||
docs/MarketInfo.md
|
docs/MarketConfig.md
|
||||||
docs/NextNonce.md
|
docs/NextNonce.md
|
||||||
docs/NotificationApi.md
|
docs/NotificationApi.md
|
||||||
docs/Order.md
|
docs/Order.md
|
||||||
docs/OrderApi.md
|
docs/OrderApi.md
|
||||||
docs/OrderBook.md
|
docs/OrderBook.md
|
||||||
docs/OrderBookDepth.md
|
docs/OrderBookDepth.md
|
||||||
docs/OrderBookDetail.md
|
|
||||||
docs/OrderBookDetails.md
|
docs/OrderBookDetails.md
|
||||||
docs/OrderBookOrders.md
|
docs/OrderBookOrders.md
|
||||||
docs/OrderBookStats.md
|
docs/OrderBookStats.md
|
||||||
docs/OrderBooks.md
|
docs/OrderBooks.md
|
||||||
docs/Orders.md
|
docs/Orders.md
|
||||||
|
docs/PerpsMarketStats.md
|
||||||
|
docs/PerpsOrderBookDetail.md
|
||||||
docs/PnLEntry.md
|
docs/PnLEntry.md
|
||||||
docs/PositionFunding.md
|
docs/PositionFunding.md
|
||||||
docs/PositionFundings.md
|
docs/PositionFundings.md
|
||||||
docs/PriceLevel.md
|
docs/PriceLevel.md
|
||||||
docs/PublicPool.md
|
|
||||||
docs/PublicPoolInfo.md
|
docs/PublicPoolInfo.md
|
||||||
docs/PublicPoolMetadata.md
|
docs/PublicPoolMetadata.md
|
||||||
docs/PublicPoolShare.md
|
docs/PublicPoolShare.md
|
||||||
docs/PublicPools.md
|
|
||||||
docs/ReferralApi.md
|
docs/ReferralApi.md
|
||||||
docs/ReferralPointEntry.md
|
docs/ReferralPointEntry.md
|
||||||
docs/ReferralPoints.md
|
docs/ReferralPoints.md
|
||||||
@@ -81,8 +84,10 @@ docs/ReqGetAccountLimits.md
|
|||||||
docs/ReqGetAccountMetadata.md
|
docs/ReqGetAccountMetadata.md
|
||||||
docs/ReqGetAccountPnL.md
|
docs/ReqGetAccountPnL.md
|
||||||
docs/ReqGetAccountTxs.md
|
docs/ReqGetAccountTxs.md
|
||||||
|
docs/ReqGetAssetDetails.md
|
||||||
docs/ReqGetBlock.md
|
docs/ReqGetBlock.md
|
||||||
docs/ReqGetBlockTxs.md
|
docs/ReqGetBlockTxs.md
|
||||||
|
docs/ReqGetBridgesByL1Addr.md
|
||||||
docs/ReqGetByAccount.md
|
docs/ReqGetByAccount.md
|
||||||
docs/ReqGetCandlesticks.md
|
docs/ReqGetCandlesticks.md
|
||||||
docs/ReqGetDepositHistory.md
|
docs/ReqGetDepositHistory.md
|
||||||
@@ -97,7 +102,6 @@ docs/ReqGetOrderBookDetails.md
|
|||||||
docs/ReqGetOrderBookOrders.md
|
docs/ReqGetOrderBookOrders.md
|
||||||
docs/ReqGetOrderBooks.md
|
docs/ReqGetOrderBooks.md
|
||||||
docs/ReqGetPositionFunding.md
|
docs/ReqGetPositionFunding.md
|
||||||
docs/ReqGetPublicPools.md
|
|
||||||
docs/ReqGetPublicPoolsMetadata.md
|
docs/ReqGetPublicPoolsMetadata.md
|
||||||
docs/ReqGetRangeWithCursor.md
|
docs/ReqGetRangeWithCursor.md
|
||||||
docs/ReqGetRangeWithIndex.md
|
docs/ReqGetRangeWithIndex.md
|
||||||
@@ -110,10 +114,14 @@ docs/ReqGetTransferHistory.md
|
|||||||
docs/ReqGetTx.md
|
docs/ReqGetTx.md
|
||||||
docs/ReqGetWithdrawHistory.md
|
docs/ReqGetWithdrawHistory.md
|
||||||
docs/RespChangeAccountTier.md
|
docs/RespChangeAccountTier.md
|
||||||
|
docs/RespGetBridgesByL1Addr.md
|
||||||
docs/RespGetFastBridgeInfo.md
|
docs/RespGetFastBridgeInfo.md
|
||||||
|
docs/RespGetIsNextBridgeFast.md
|
||||||
docs/RespPublicPoolsMetadata.md
|
docs/RespPublicPoolsMetadata.md
|
||||||
docs/RespSendTx.md
|
docs/RespSendTx.md
|
||||||
docs/RespSendTxBatch.md
|
docs/RespSendTxBatch.md
|
||||||
|
docs/RespUpdateKickback.md
|
||||||
|
docs/RespUpdateReferralCode.md
|
||||||
docs/RespWithdrawalDelay.md
|
docs/RespWithdrawalDelay.md
|
||||||
docs/ResultCode.md
|
docs/ResultCode.md
|
||||||
docs/RiskInfo.md
|
docs/RiskInfo.md
|
||||||
@@ -121,6 +129,8 @@ docs/RiskParameters.md
|
|||||||
docs/RootApi.md
|
docs/RootApi.md
|
||||||
docs/SharePrice.md
|
docs/SharePrice.md
|
||||||
docs/SimpleOrder.md
|
docs/SimpleOrder.md
|
||||||
|
docs/SpotMarketStats.md
|
||||||
|
docs/SpotOrderBookDetail.md
|
||||||
docs/Status.md
|
docs/Status.md
|
||||||
docs/SubAccounts.md
|
docs/SubAccounts.md
|
||||||
docs/Ticker.md
|
docs/Ticker.md
|
||||||
@@ -160,6 +170,7 @@ lighter/exceptions.py
|
|||||||
lighter/models/__init__.py
|
lighter/models/__init__.py
|
||||||
lighter/models/account.py
|
lighter/models/account.py
|
||||||
lighter/models/account_api_keys.py
|
lighter/models/account_api_keys.py
|
||||||
|
lighter/models/account_asset.py
|
||||||
lighter/models/account_limits.py
|
lighter/models/account_limits.py
|
||||||
lighter/models/account_margin_stats.py
|
lighter/models/account_margin_stats.py
|
||||||
lighter/models/account_market_stats.py
|
lighter/models/account_market_stats.py
|
||||||
@@ -172,8 +183,11 @@ lighter/models/account_trade_stats.py
|
|||||||
lighter/models/announcement.py
|
lighter/models/announcement.py
|
||||||
lighter/models/announcements.py
|
lighter/models/announcements.py
|
||||||
lighter/models/api_key.py
|
lighter/models/api_key.py
|
||||||
|
lighter/models/asset.py
|
||||||
|
lighter/models/asset_details.py
|
||||||
lighter/models/block.py
|
lighter/models/block.py
|
||||||
lighter/models/blocks.py
|
lighter/models/blocks.py
|
||||||
|
lighter/models/bridge.py
|
||||||
lighter/models/bridge_supported_network.py
|
lighter/models/bridge_supported_network.py
|
||||||
lighter/models/candlestick.py
|
lighter/models/candlestick.py
|
||||||
lighter/models/candlesticks.py
|
lighter/models/candlesticks.py
|
||||||
@@ -199,26 +213,25 @@ lighter/models/liq_trade.py
|
|||||||
lighter/models/liquidation.py
|
lighter/models/liquidation.py
|
||||||
lighter/models/liquidation_info.py
|
lighter/models/liquidation_info.py
|
||||||
lighter/models/liquidation_infos.py
|
lighter/models/liquidation_infos.py
|
||||||
lighter/models/market_info.py
|
lighter/models/market_config.py
|
||||||
lighter/models/next_nonce.py
|
lighter/models/next_nonce.py
|
||||||
lighter/models/order.py
|
lighter/models/order.py
|
||||||
lighter/models/order_book.py
|
lighter/models/order_book.py
|
||||||
lighter/models/order_book_depth.py
|
lighter/models/order_book_depth.py
|
||||||
lighter/models/order_book_detail.py
|
|
||||||
lighter/models/order_book_details.py
|
lighter/models/order_book_details.py
|
||||||
lighter/models/order_book_orders.py
|
lighter/models/order_book_orders.py
|
||||||
lighter/models/order_book_stats.py
|
lighter/models/order_book_stats.py
|
||||||
lighter/models/order_books.py
|
lighter/models/order_books.py
|
||||||
lighter/models/orders.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/pn_l_entry.py
|
||||||
lighter/models/position_funding.py
|
lighter/models/position_funding.py
|
||||||
lighter/models/position_fundings.py
|
lighter/models/position_fundings.py
|
||||||
lighter/models/price_level.py
|
lighter/models/price_level.py
|
||||||
lighter/models/public_pool.py
|
|
||||||
lighter/models/public_pool_info.py
|
lighter/models/public_pool_info.py
|
||||||
lighter/models/public_pool_metadata.py
|
lighter/models/public_pool_metadata.py
|
||||||
lighter/models/public_pool_share.py
|
lighter/models/public_pool_share.py
|
||||||
lighter/models/public_pools.py
|
|
||||||
lighter/models/referral_point_entry.py
|
lighter/models/referral_point_entry.py
|
||||||
lighter/models/referral_points.py
|
lighter/models/referral_points.py
|
||||||
lighter/models/req_export_data.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_metadata.py
|
||||||
lighter/models/req_get_account_pn_l.py
|
lighter/models/req_get_account_pn_l.py
|
||||||
lighter/models/req_get_account_txs.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.py
|
||||||
lighter/models/req_get_block_txs.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_by_account.py
|
||||||
lighter/models/req_get_candlesticks.py
|
lighter/models/req_get_candlesticks.py
|
||||||
lighter/models/req_get_deposit_history.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_book_orders.py
|
||||||
lighter/models/req_get_order_books.py
|
lighter/models/req_get_order_books.py
|
||||||
lighter/models/req_get_position_funding.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_public_pools_metadata.py
|
||||||
lighter/models/req_get_range_with_cursor.py
|
lighter/models/req_get_range_with_cursor.py
|
||||||
lighter/models/req_get_range_with_index.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_tx.py
|
||||||
lighter/models/req_get_withdraw_history.py
|
lighter/models/req_get_withdraw_history.py
|
||||||
lighter/models/resp_change_account_tier.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_fast_bridge_info.py
|
||||||
|
lighter/models/resp_get_is_next_bridge_fast.py
|
||||||
lighter/models/resp_public_pools_metadata.py
|
lighter/models/resp_public_pools_metadata.py
|
||||||
lighter/models/resp_send_tx.py
|
lighter/models/resp_send_tx.py
|
||||||
lighter/models/resp_send_tx_batch.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/resp_withdrawal_delay.py
|
||||||
lighter/models/result_code.py
|
lighter/models/result_code.py
|
||||||
lighter/models/risk_info.py
|
lighter/models/risk_info.py
|
||||||
lighter/models/risk_parameters.py
|
lighter/models/risk_parameters.py
|
||||||
lighter/models/share_price.py
|
lighter/models/share_price.py
|
||||||
lighter/models/simple_order.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/status.py
|
||||||
lighter/models/sub_accounts.py
|
lighter/models/sub_accounts.py
|
||||||
lighter/models/ticker.py
|
lighter/models/ticker.py
|
||||||
@@ -291,4 +311,19 @@ lighter/rest.py
|
|||||||
setup.cfg
|
setup.cfg
|
||||||
test-requirements.txt
|
test-requirements.txt
|
||||||
test/__init__.py
|
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
|
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():
|
async def main():
|
||||||
client = lighter.ApiClient()
|
client = lighter.ApiClient()
|
||||||
|
try:
|
||||||
account_api = lighter.AccountApi(client)
|
account_api = lighter.AccountApi(client)
|
||||||
account = await account_api.get_account(by="index", value="1")
|
account = await account_api.account(by="index", value="1")
|
||||||
print(account)
|
print(account)
|
||||||
|
finally:
|
||||||
|
await client.close() # Make sure connection is cleanly closed
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(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** | |
|
**l1_address** | **str** | |
|
||||||
**cancel_all_time** | **int** | |
|
**cancel_all_time** | **int** | |
|
||||||
**total_order_count** | **int** | |
|
**total_order_count** | **int** | |
|
||||||
**total_isolated_order_count** | **int** | |
|
|
||||||
**pending_order_count** | **int** | |
|
**pending_order_count** | **int** | |
|
||||||
**available_balance** | **str** | |
|
**available_balance** | **str** | |
|
||||||
**status** | **int** | |
|
**status** | **int** | |
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ Method | HTTP request | Description
|
|||||||
[**liquidations**](AccountApi.md#liquidations) | **GET** /api/v1/liquidations | liquidations
|
[**liquidations**](AccountApi.md#liquidations) | **GET** /api/v1/liquidations | liquidations
|
||||||
[**pnl**](AccountApi.md#pnl) | **GET** /api/v1/pnl | pnl
|
[**pnl**](AccountApi.md#pnl) | **GET** /api/v1/pnl | pnl
|
||||||
[**position_funding**](AccountApi.md#position_funding) | **GET** /api/v1/positionFunding | positionFunding
|
[**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
|
[**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)
|
[[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**
|
# **public_pools_metadata**
|
||||||
> RespPublicPoolsMetadata public_pools_metadata(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
> 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** | |
|
**code** | **int** | |
|
||||||
**message** | **str** | | [optional]
|
**message** | **str** | | [optional]
|
||||||
**max_llp_percentage** | **int** | |
|
**max_llp_percentage** | **int** | |
|
||||||
|
**max_llp_amount** | **str** | |
|
||||||
**user_tier** | **str** | |
|
**user_tier** | **str** | |
|
||||||
|
**can_create_public_pool** | **bool** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ Name | Type | Description | Notes
|
|||||||
**title** | **str** | |
|
**title** | **str** | |
|
||||||
**content** | **str** | |
|
**content** | **str** | |
|
||||||
**created_at** | **int** | |
|
**created_at** | **int** | |
|
||||||
|
**expired_at** | **int** | |
|
||||||
|
|
||||||
## Example
|
## 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
|
## Properties
|
||||||
@@ -7,25 +7,24 @@ Name | Type | Description | Notes
|
|||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**code** | **int** | |
|
**code** | **int** | |
|
||||||
**message** | **str** | | [optional]
|
**message** | **str** | | [optional]
|
||||||
**total** | **int** | |
|
**asset_details** | [**List[Asset]**](Asset.md) | |
|
||||||
**public_pools** | [**List[PublicPool]**](PublicPool.md) | |
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from lighter.models.public_pools import PublicPools
|
from lighter.models.asset_details import AssetDetails
|
||||||
|
|
||||||
# TODO update the JSON string below
|
# TODO update the JSON string below
|
||||||
json = "{}"
|
json = "{}"
|
||||||
# create an instance of PublicPools from a JSON string
|
# create an instance of AssetDetails from a JSON string
|
||||||
public_pools_instance = PublicPools.from_json(json)
|
asset_details_instance = AssetDetails.from_json(json)
|
||||||
# print the JSON string representation of the object
|
# print the JSON string representation of the object
|
||||||
print(PublicPools.to_json())
|
print(AssetDetails.to_json())
|
||||||
|
|
||||||
# convert the object into a dict
|
# convert the object into a dict
|
||||||
public_pools_dict = public_pools_instance.to_dict()
|
asset_details_dict = asset_details_instance.to_dict()
|
||||||
# create an instance of PublicPools from a dict
|
# create an instance of AssetDetails from a dict
|
||||||
public_pools_from_dict = PublicPools.from_dict(public_pools_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)
|
[[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
|
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
|
[**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**
|
# **fastbridge_info**
|
||||||
> RespGetFastBridgeInfo fastbridge_info()
|
> RespGetFastBridgeInfo fastbridge_info()
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
|||||||
**high** | **float** | |
|
**high** | **float** | |
|
||||||
**low** | **float** | |
|
**low** | **float** | |
|
||||||
**close** | **float** | |
|
**close** | **float** | |
|
||||||
|
**open_raw** | **float** | |
|
||||||
|
**high_raw** | **float** | |
|
||||||
|
**low_raw** | **float** | |
|
||||||
|
**close_raw** | **float** | |
|
||||||
**volume0** | **float** | |
|
**volume0** | **float** | |
|
||||||
**volume1** | **float** | |
|
**volume1** | **float** | |
|
||||||
**last_trade_id** | **int** | |
|
**last_trade_id** | **int** | |
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**id** | **str** | |
|
**id** | **str** | |
|
||||||
|
**asset_id** | **int** | |
|
||||||
**amount** | **str** | |
|
**amount** | **str** | |
|
||||||
**timestamp** | **int** | |
|
**timestamp** | **int** | |
|
||||||
**status** | **str** | |
|
**status** | **str** | |
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ Name | Type | Description | Notes
|
|||||||
**l1_address** | **str** | |
|
**l1_address** | **str** | |
|
||||||
**cancel_all_time** | **int** | |
|
**cancel_all_time** | **int** | |
|
||||||
**total_order_count** | **int** | |
|
**total_order_count** | **int** | |
|
||||||
**total_isolated_order_count** | **int** | |
|
|
||||||
**pending_order_count** | **int** | |
|
**pending_order_count** | **int** | |
|
||||||
**available_balance** | **str** | |
|
**available_balance** | **str** | |
|
||||||
**status** | **int** | |
|
**status** | **int** | |
|
||||||
@@ -23,6 +22,7 @@ Name | Type | Description | Notes
|
|||||||
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
||||||
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
||||||
**positions** | [**List[AccountPosition]**](AccountPosition.md) | |
|
**positions** | [**List[AccountPosition]**](AccountPosition.md) | |
|
||||||
|
**assets** | [**List[AccountAsset]**](AccountAsset.md) | |
|
||||||
**total_asset_value** | **str** | |
|
**total_asset_value** | **str** | |
|
||||||
**cross_asset_value** | **str** | |
|
**cross_asset_value** | **str** | |
|
||||||
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
|||||||
**high** | **float** | |
|
**high** | **float** | |
|
||||||
**low** | **float** | |
|
**low** | **float** | |
|
||||||
**close** | **float** | |
|
**close** | **float** | |
|
||||||
|
**open_raw** | **float** | |
|
||||||
|
**high_raw** | **float** | |
|
||||||
|
**low_raw** | **float** | |
|
||||||
|
**close_raw** | **float** | |
|
||||||
**volume0** | **float** | |
|
**volume0** | **float** | |
|
||||||
**volume1** | **float** | |
|
**volume1** | **float** | |
|
||||||
**last_trade_id** | **int** | |
|
**last_trade_id** | **int** | |
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Name | Type | Description | Notes
|
|||||||
**executed_at** | **int** | |
|
**executed_at** | **int** | |
|
||||||
**sequence_index** | **int** | |
|
**sequence_index** | **int** | |
|
||||||
**parent_hash** | **str** | |
|
**parent_hash** | **str** | |
|
||||||
|
**api_key_index** | **int** | |
|
||||||
**committed_at** | **int** | |
|
**committed_at** | **int** | |
|
||||||
**verified_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** | |
|
**to_cancel_order_id_0** | **str** | |
|
||||||
**block_height** | **int** | |
|
**block_height** | **int** | |
|
||||||
**timestamp** | **int** | |
|
**timestamp** | **int** | |
|
||||||
|
**created_at** | **int** | |
|
||||||
|
**updated_at** | **int** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Method | HTTP request | Description
|
|||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
[**account_active_orders**](OrderApi.md#account_active_orders) | **GET** /api/v1/accountActiveOrders | accountActiveOrders
|
[**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
|
[**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
|
[**exchange_stats**](OrderApi.md#exchange_stats) | **GET** /api/v1/exchangeStats | exchangeStats
|
||||||
[**export**](OrderApi.md#export) | **GET** /api/v1/export | export
|
[**export**](OrderApi.md#export) | **GET** /api/v1/export | export
|
||||||
[**order_book_details**](OrderApi.md#order_book_details) | **GET** /api/v1/orderBookDetails | orderBookDetails
|
[**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)
|
[[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**
|
# **exchange_stats**
|
||||||
> ExchangeStats 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)
|
[[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**
|
# **order_book_details**
|
||||||
> OrderBookDetails order_book_details(market_id=market_id)
|
> OrderBookDetails order_book_details(market_id=market_id, filter=filter)
|
||||||
|
|
||||||
orderBookDetails
|
orderBookDetails
|
||||||
|
|
||||||
@@ -343,10 +413,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
|||||||
# Create an instance of the API class
|
# Create an instance of the API class
|
||||||
api_instance = lighter.OrderApi(api_client)
|
api_instance = lighter.OrderApi(api_client)
|
||||||
market_id = 255 # int | (optional) (default to 255)
|
market_id = 255 # int | (optional) (default to 255)
|
||||||
|
filter = all # str | (optional) (default to all)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# orderBookDetails
|
# 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")
|
print("The response of OrderApi->order_book_details:\n")
|
||||||
pprint(api_response)
|
pprint(api_response)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -361,6 +432,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------- | ------------- | ------------- | -------------
|
------------- | ------------- | ------------- | -------------
|
||||||
**market_id** | **int**| | [optional] [default to 255]
|
**market_id** | **int**| | [optional] [default to 255]
|
||||||
|
**filter** | **str**| | [optional] [default to all]
|
||||||
|
|
||||||
### Return type
|
### 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)
|
[[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**
|
# **order_books**
|
||||||
> OrderBooks order_books(market_id=market_id)
|
> OrderBooks order_books(market_id=market_id, filter=filter)
|
||||||
|
|
||||||
orderBooks
|
orderBooks
|
||||||
|
|
||||||
@@ -483,10 +555,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
|||||||
# Create an instance of the API class
|
# Create an instance of the API class
|
||||||
api_instance = lighter.OrderApi(api_client)
|
api_instance = lighter.OrderApi(api_client)
|
||||||
market_id = 255 # int | (optional) (default to 255)
|
market_id = 255 # int | (optional) (default to 255)
|
||||||
|
filter = all # str | (optional) (default to all)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# orderBooks
|
# 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")
|
print("The response of OrderApi->order_books:\n")
|
||||||
pprint(api_response)
|
pprint(api_response)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -501,6 +574,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------- | ------------- | ------------- | -------------
|
------------- | ------------- | ------------- | -------------
|
||||||
**market_id** | **int**| | [optional] [default to 255]
|
**market_id** | **int**| | [optional] [default to 255]
|
||||||
|
**filter** | **str**| | [optional] [default to all]
|
||||||
|
|
||||||
### Return type
|
### 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)
|
[[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 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
|
trades
|
||||||
|
|
||||||
@@ -633,10 +707,13 @@ async with lighter.ApiClient(configuration) as api_client:
|
|||||||
cursor = 'cursor_example' # str | (optional)
|
cursor = 'cursor_example' # str | (optional)
|
||||||
var_from = -1 # int | (optional) (default to -1)
|
var_from = -1 # int | (optional) (default to -1)
|
||||||
ask_filter = -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:
|
try:
|
||||||
# trades
|
# 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")
|
print("The response of OrderApi->trades:\n")
|
||||||
pprint(api_response)
|
pprint(api_response)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -661,6 +738,9 @@ Name | Type | Description | Notes
|
|||||||
**cursor** | **str**| | [optional]
|
**cursor** | **str**| | [optional]
|
||||||
**var_from** | **int**| | [optional] [default to -1]
|
**var_from** | **int**| | [optional] [default to -1]
|
||||||
**ask_filter** | **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
|
### Return type
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
|||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**symbol** | **str** | |
|
**symbol** | **str** | |
|
||||||
**market_id** | **int** | |
|
**market_id** | **int** | |
|
||||||
|
**market_type** | **str** | |
|
||||||
|
**base_asset_id** | **int** | |
|
||||||
|
**quote_asset_id** | **int** | |
|
||||||
**status** | **str** | |
|
**status** | **str** | |
|
||||||
**taker_fee** | **str** | |
|
**taker_fee** | **str** | |
|
||||||
**maker_fee** | **str** | |
|
**maker_fee** | **str** | |
|
||||||
**liquidation_fee** | **str** | |
|
**liquidation_fee** | **str** | |
|
||||||
**min_base_amount** | **str** | |
|
**min_base_amount** | **str** | |
|
||||||
**min_quote_amount** | **str** | |
|
**min_quote_amount** | **str** | |
|
||||||
|
**order_quote_limit** | **str** | |
|
||||||
**supported_size_decimals** | **int** | |
|
**supported_size_decimals** | **int** | |
|
||||||
**supported_price_decimals** | **int** | |
|
**supported_price_decimals** | **int** | |
|
||||||
**supported_quote_decimals** | **int** | |
|
**supported_quote_decimals** | **int** | |
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Name | Type | Description | Notes
|
|||||||
**asks** | [**List[PriceLevel]**](PriceLevel.md) | |
|
**asks** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||||
**bids** | [**List[PriceLevel]**](PriceLevel.md) | |
|
**bids** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||||
**offset** | **int** | |
|
**offset** | **int** | |
|
||||||
|
**nonce** | **int** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ Name | Type | Description | Notes
|
|||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**code** | **int** | |
|
**code** | **int** | |
|
||||||
**message** | **str** | | [optional]
|
**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
|
## Example
|
||||||
|
|
||||||
|
|||||||
+12
-8
@@ -1,14 +1,18 @@
|
|||||||
# MarketInfo
|
# PerpsMarketStats
|
||||||
|
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
|
**symbol** | **str** | |
|
||||||
**market_id** | **int** | |
|
**market_id** | **int** | |
|
||||||
**index_price** | **str** | |
|
**index_price** | **str** | |
|
||||||
**mark_price** | **str** | |
|
**mark_price** | **str** | |
|
||||||
**open_interest** | **str** | |
|
**open_interest** | **str** | |
|
||||||
|
**open_interest_limit** | **str** | |
|
||||||
|
**funding_clamp_small** | **str** | |
|
||||||
|
**funding_clamp_big** | **str** | |
|
||||||
**last_trade_price** | **str** | |
|
**last_trade_price** | **str** | |
|
||||||
**current_funding_rate** | **str** | |
|
**current_funding_rate** | **str** | |
|
||||||
**funding_rate** | **str** | |
|
**funding_rate** | **str** | |
|
||||||
@@ -22,19 +26,19 @@ Name | Type | Description | Notes
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from lighter.models.market_info import MarketInfo
|
from lighter.models.perps_market_stats import PerpsMarketStats
|
||||||
|
|
||||||
# TODO update the JSON string below
|
# TODO update the JSON string below
|
||||||
json = "{}"
|
json = "{}"
|
||||||
# create an instance of MarketInfo from a JSON string
|
# create an instance of PerpsMarketStats from a JSON string
|
||||||
market_info_instance = MarketInfo.from_json(json)
|
perps_market_stats_instance = PerpsMarketStats.from_json(json)
|
||||||
# print the JSON string representation of the object
|
# print the JSON string representation of the object
|
||||||
print(MarketInfo.to_json())
|
print(PerpsMarketStats.to_json())
|
||||||
|
|
||||||
# convert the object into a dict
|
# convert the object into a dict
|
||||||
market_info_dict = market_info_instance.to_dict()
|
perps_market_stats_dict = perps_market_stats_instance.to_dict()
|
||||||
# create an instance of MarketInfo from a dict
|
# create an instance of PerpsMarketStats from a dict
|
||||||
market_info_from_dict = MarketInfo.from_dict(market_info_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)
|
[[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
|
## Properties
|
||||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
|||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**symbol** | **str** | |
|
**symbol** | **str** | |
|
||||||
**market_id** | **int** | |
|
**market_id** | **int** | |
|
||||||
|
**market_type** | **str** | |
|
||||||
|
**base_asset_id** | **int** | |
|
||||||
|
**quote_asset_id** | **int** | |
|
||||||
**status** | **str** | |
|
**status** | **str** | |
|
||||||
**taker_fee** | **str** | |
|
**taker_fee** | **str** | |
|
||||||
**maker_fee** | **str** | |
|
**maker_fee** | **str** | |
|
||||||
**liquidation_fee** | **str** | |
|
**liquidation_fee** | **str** | |
|
||||||
**min_base_amount** | **str** | |
|
**min_base_amount** | **str** | |
|
||||||
**min_quote_amount** | **str** | |
|
**min_quote_amount** | **str** | |
|
||||||
|
**order_quote_limit** | **str** | |
|
||||||
**supported_size_decimals** | **int** | |
|
**supported_size_decimals** | **int** | |
|
||||||
**supported_price_decimals** | **int** | |
|
**supported_price_decimals** | **int** | |
|
||||||
**supported_quote_decimals** | **int** | |
|
**supported_quote_decimals** | **int** | |
|
||||||
@@ -32,23 +36,24 @@ Name | Type | Description | Notes
|
|||||||
**daily_price_change** | **float** | |
|
**daily_price_change** | **float** | |
|
||||||
**open_interest** | **float** | |
|
**open_interest** | **float** | |
|
||||||
**daily_chart** | **Dict[str, float]** | |
|
**daily_chart** | **Dict[str, float]** | |
|
||||||
|
**market_config** | [**MarketConfig**](MarketConfig.md) | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from lighter.models.order_book_detail import OrderBookDetail
|
from lighter.models.perps_order_book_detail import PerpsOrderBookDetail
|
||||||
|
|
||||||
# TODO update the JSON string below
|
# TODO update the JSON string below
|
||||||
json = "{}"
|
json = "{}"
|
||||||
# create an instance of OrderBookDetail from a JSON string
|
# create an instance of PerpsOrderBookDetail from a JSON string
|
||||||
order_book_detail_instance = OrderBookDetail.from_json(json)
|
perps_order_book_detail_instance = PerpsOrderBookDetail.from_json(json)
|
||||||
# print the JSON string representation of the object
|
# print the JSON string representation of the object
|
||||||
print(OrderBookDetail.to_json())
|
print(PerpsOrderBookDetail.to_json())
|
||||||
|
|
||||||
# convert the object into a dict
|
# convert the object into a dict
|
||||||
order_book_detail_dict = order_book_detail_instance.to_dict()
|
perps_order_book_detail_dict = perps_order_book_detail_instance.to_dict()
|
||||||
# create an instance of OrderBookDetail from a dict
|
# create an instance of PerpsOrderBookDetail from a dict
|
||||||
order_book_detail_from_dict = OrderBookDetail.from_dict(order_book_detail_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)
|
[[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** | |
|
**timestamp** | **int** | |
|
||||||
**trade_pnl** | **float** | |
|
**trade_pnl** | **float** | |
|
||||||
|
**trade_spot_pnl** | **float** | |
|
||||||
**inflow** | **float** | |
|
**inflow** | **float** | |
|
||||||
**outflow** | **float** | |
|
**outflow** | **float** | |
|
||||||
|
**spot_outflow** | **float** | |
|
||||||
|
**spot_inflow** | **float** | |
|
||||||
**pool_pnl** | **float** | |
|
**pool_pnl** | **float** | |
|
||||||
**pool_inflow** | **float** | |
|
**pool_inflow** | **float** | |
|
||||||
**pool_outflow** | **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** | |
|
**total_shares** | **int** | |
|
||||||
**operator_shares** | **int** | |
|
**operator_shares** | **int** | |
|
||||||
**annual_percentage_yield** | **float** | |
|
**annual_percentage_yield** | **float** | |
|
||||||
|
**sharpe_ratio** | **float** | |
|
||||||
**daily_returns** | [**List[DailyReturn]**](DailyReturn.md) | |
|
**daily_returns** | [**List[DailyReturn]**](DailyReturn.md) | |
|
||||||
**share_prices** | [**List[SharePrice]**](SharePrice.md) | |
|
**share_prices** | [**List[SharePrice]**](SharePrice.md) | |
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ Name | Type | Description | Notes
|
|||||||
**code** | **int** | |
|
**code** | **int** | |
|
||||||
**message** | **str** | | [optional]
|
**message** | **str** | | [optional]
|
||||||
**account_index** | **int** | |
|
**account_index** | **int** | |
|
||||||
|
**created_at** | **int** | |
|
||||||
|
**master_account_index** | **int** | |
|
||||||
**account_type** | **int** | |
|
**account_type** | **int** | |
|
||||||
**name** | **str** | |
|
**name** | **str** | |
|
||||||
**l1_address** | **str** | |
|
**l1_address** | **str** | |
|
||||||
**annual_percentage_yield** | **float** | |
|
**annual_percentage_yield** | **float** | |
|
||||||
|
**sharpe_ratio** | **float** | |
|
||||||
**status** | **int** | |
|
**status** | **int** | |
|
||||||
**operator_fee** | **str** | |
|
**operator_fee** | **str** | |
|
||||||
**total_asset_value** | **str** | |
|
**total_asset_value** | **str** | |
|
||||||
|
|||||||
@@ -4,9 +4,86 @@ All URIs are relative to *https://mainnet.zklighter.elliot.ai*
|
|||||||
|
|
||||||
Method | HTTP request | Description
|
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_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**
|
# **referral_points**
|
||||||
> ReferralPoints referral_points(account_index, authorization=authorization, auth=auth)
|
> 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)
|
[[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
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**l1_address** | **str** | |
|
**l1_address** | **str** | |
|
||||||
**total_points** | **int** | |
|
**total_points** | **float** | |
|
||||||
**week_points** | **int** | |
|
**week_points** | **float** | |
|
||||||
**total_reward_points** | **int** | |
|
**total_reward_points** | **float** | |
|
||||||
**week_reward_points** | **int** | |
|
**week_reward_points** | **float** | |
|
||||||
**reward_point_multiplier** | **str** | |
|
**reward_point_multiplier** | **str** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**referrals** | [**List[ReferralPointEntry]**](ReferralPointEntry.md) | |
|
**referrals** | [**List[ReferralPointEntry]**](ReferralPointEntry.md) | |
|
||||||
**user_total_points** | **int** | |
|
**user_total_points** | **float** | |
|
||||||
**user_last_week_points** | **int** | |
|
**user_last_week_points** | **float** | |
|
||||||
**user_total_referral_reward_points** | **int** | |
|
**user_total_referral_reward_points** | **float** | |
|
||||||
**user_last_week_referral_reward_points** | **int** | |
|
**user_last_week_referral_reward_points** | **float** | |
|
||||||
**reward_point_multiplier** | **str** | |
|
**reward_point_multiplier** | **str** | |
|
||||||
|
|
||||||
## Example
|
## 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
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**market_id** | **int** | | [optional]
|
**market_id** | **int** | | [optional]
|
||||||
|
**filter** | **str** | | [optional] [default to 'all']
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**market_id** | **int** | | [optional]
|
**market_id** | **int** | | [optional]
|
||||||
|
**filter** | **str** | | [optional] [default to 'all']
|
||||||
|
|
||||||
## Example
|
## 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]
|
**cursor** | **str** | | [optional]
|
||||||
**var_from** | **int** | | [optional] [default to -1]
|
**var_from** | **int** | | [optional] [default to -1]
|
||||||
**ask_filter** | **int** | | [optional]
|
**ask_filter** | **int** | | [optional]
|
||||||
|
**role** | **str** | | [optional] [default to 'all']
|
||||||
|
**type** | **str** | | [optional] [default to 'all']
|
||||||
**limit** | **int** | |
|
**limit** | **int** | |
|
||||||
|
**aggregate** | **bool** | | [optional] [default to False]
|
||||||
|
|
||||||
## Example
|
## 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]
|
**message** | **str** | | [optional]
|
||||||
**tx_hash** | **str** | |
|
**tx_hash** | **str** | |
|
||||||
**predicted_execution_time_ms** | **int** | |
|
**predicted_execution_time_ms** | **int** | |
|
||||||
|
**volume_quota_remaining** | **int** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
|
|||||||
**message** | **str** | | [optional]
|
**message** | **str** | | [optional]
|
||||||
**tx_hash** | **List[str]** | |
|
**tx_hash** | **List[str]** | |
|
||||||
**predicted_execution_time_ms** | **int** | |
|
**predicted_execution_time_ms** | **int** | |
|
||||||
|
**volume_quota_remaining** | **int** | |
|
||||||
|
|
||||||
## Example
|
## 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** | |
|
**usd_amount** | **str** | |
|
||||||
**ask_id** | **int** | |
|
**ask_id** | **int** | |
|
||||||
**bid_id** | **int** | |
|
**bid_id** | **int** | |
|
||||||
|
**ask_client_id** | **int** | |
|
||||||
|
**bid_client_id** | **int** | |
|
||||||
**ask_account_id** | **int** | |
|
**ask_account_id** | **int** | |
|
||||||
**bid_account_id** | **int** | |
|
**bid_account_id** | **int** | |
|
||||||
**is_maker_ask** | **bool** | |
|
**is_maker_ask** | **bool** | |
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**id** | **str** | |
|
**id** | **str** | |
|
||||||
|
**asset_id** | **int** | |
|
||||||
**amount** | **str** | |
|
**amount** | **str** | |
|
||||||
**timestamp** | **int** | |
|
**timestamp** | **int** | |
|
||||||
**type** | **str** | |
|
**type** | **str** | |
|
||||||
@@ -13,6 +14,8 @@ Name | Type | Description | Notes
|
|||||||
**to_l1_address** | **str** | |
|
**to_l1_address** | **str** | |
|
||||||
**from_account_index** | **int** | |
|
**from_account_index** | **int** | |
|
||||||
**to_account_index** | **int** | |
|
**to_account_index** | **int** | |
|
||||||
|
**from_route** | **str** | |
|
||||||
|
**to_route** | **str** | |
|
||||||
**tx_hash** | **str** | |
|
**tx_hash** | **str** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ Name | Type | Description | Notes
|
|||||||
**executed_at** | **int** | |
|
**executed_at** | **int** | |
|
||||||
**sequence_index** | **int** | |
|
**sequence_index** | **int** | |
|
||||||
**parent_hash** | **str** | |
|
**parent_hash** | **str** | |
|
||||||
|
**api_key_index** | **int** | |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**id** | **str** | |
|
**id** | **str** | |
|
||||||
|
**asset_id** | **int** | |
|
||||||
**amount** | **str** | |
|
**amount** | **str** | |
|
||||||
**timestamp** | **int** | |
|
**timestamp** | **int** | |
|
||||||
**status** | **str** | |
|
**status** | **str** | |
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
api_key_config.json
|
||||||
@@ -6,17 +6,151 @@
|
|||||||
- the eth private key will only be used in the Py SDK to sign a message
|
- 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 required in order to trade on the platform
|
||||||
- the eth private key is not passed to the binary
|
- 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 API key config is saved in a local file `./api_key_config.json`
|
||||||
- the output should look like
|
|
||||||
```
|
## Start trading on testnet
|
||||||
BASE_URL = 'https://testnet.zklighter.elliot.ai'
|
- `create_modify_cancel_order_http.py`
|
||||||
API_KEY_PRIVATE_KEY = '0xea5d2eca5be67eca056752eaf27b173518b8a5550117c09d2b58c7ea7d306cc4426f913ccf27ab19'
|
- creates an ask (sell) order for 0.1 ETH @ $4050
|
||||||
ACCOUNT_INDEX = 595
|
- modified the order and increases the size to 0.11 ETH and increases the price to $4100
|
||||||
API_KEY_INDEX = 1
|
- 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
|
||||||
- start trading using
|
|
||||||
- `create_cancel_order.py` has an example which created an order on testnet & cancels it
|
- `create_modify_cancel_order_ws.py`
|
||||||
- you'll need to set up both your account index, api key index & API Key private key
|
- 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
|
## Setup steps for mainnet
|
||||||
- deposit money on Lighter to create an account first
|
- 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 asyncio
|
||||||
import logging
|
from utils import default_example_setup
|
||||||
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]
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
client = lighter.SignerClient(
|
client, api_client, _ = default_example_setup()
|
||||||
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_limited_slippage(market_index=0, client_order_index=0, base_amount=30000000,
|
# 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)
|
# 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,
|
tx = await client.create_market_order_if_slippage(
|
||||||
max_slippage=0.01, is_ask=True, ideal_price=300000)
|
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)
|
print("Create Order Tx:", tx)
|
||||||
await client.close()
|
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 asyncio
|
||||||
import lighter
|
from utils import default_example_setup
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
client = lighter.SignerClient(
|
client, api_client, _ = default_example_setup()
|
||||||
url=BASE_URL,
|
|
||||||
private_key=KEYS[5],
|
|
||||||
account_index=ACCOUNT_INDEX,
|
|
||||||
api_key_index=5,
|
|
||||||
max_api_key_index=7,
|
|
||||||
private_keys=KEYS,
|
|
||||||
)
|
|
||||||
|
|
||||||
err = client.check_client()
|
# create 20 orders. The client will use as many API keys as it was configured.
|
||||||
if err is not None:
|
|
||||||
print(f"CheckClient error: {err}")
|
|
||||||
return
|
|
||||||
|
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
res_tuple = await client.create_order(
|
res_tuple = await client.create_order(
|
||||||
market_index=0,
|
market_index=0,
|
||||||
client_order_index=123 + i,
|
client_order_index=123 + i,
|
||||||
base_amount=100000 + i,
|
base_amount=1000 + i, # 0.1 ETH + dust
|
||||||
price=385000 + i,
|
price=3850_00 + i,
|
||||||
is_ask=True,
|
is_ask=True,
|
||||||
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
|
order_type=client.ORDER_TYPE_LIMIT,
|
||||||
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||||
reduce_only=0,
|
reduce_only=False,
|
||||||
trigger_price=0,
|
trigger_price=0,
|
||||||
)
|
)
|
||||||
print(res_tuple)
|
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__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ async def transaction_apis(client: lighter.ApiClient):
|
|||||||
# await print_api(transaction_instance.tx, by="sequence_index", value="5")
|
# await print_api(transaction_instance.tx, by="sequence_index", value="5")
|
||||||
await print_api(transaction_instance.txs, index=0, limit=2)
|
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():
|
async def main():
|
||||||
client = lighter.ApiClient(configuration=lighter.Configuration(host="https://testnet.zklighter.elliot.ai"))
|
client = lighter.ApiClient(configuration=lighter.Configuration(host="https://testnet.zklighter.elliot.ai"))
|
||||||
@@ -84,6 +88,7 @@ async def main():
|
|||||||
await candlestick_apis(client)
|
await candlestick_apis(client)
|
||||||
await order_apis(client)
|
await order_apis(client)
|
||||||
await transaction_apis(client)
|
await transaction_apis(client)
|
||||||
|
await funding_apis(client)
|
||||||
await client.close()
|
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()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user