Added new instructions
This commit is contained in:
parent
ffd9fc2e14
commit
fd950b41cc
|
@ -65,7 +65,7 @@ var getSPLTokenCmd = &cobra.Command{
|
|||
text.EncoderColorCyan.Print("Address: ")
|
||||
fmt.Println(keyedAcct.Pubkey.String())
|
||||
|
||||
text.EncoderColorCyan.Print("Owner: ")
|
||||
text.EncoderColorCyan.Print("OpenOrders: ")
|
||||
fmt.Println(keyedAcct.Account.Owner.String())
|
||||
|
||||
text.EncoderColorCyan.Print("Lamports: ")
|
||||
|
|
|
@ -76,6 +76,9 @@ var InstructionDefVariant = bin.NewVariantDefinition(bin.Uint32TypeIDEncoding, [
|
|||
{"cancel_order", (*InstructionCancelOrder)(nil)},
|
||||
{"settle_funds", (*InstructionSettleFunds)(nil)},
|
||||
{"cancel_order_by_client_id", (*InstructionCancelOrderByClientId)(nil)},
|
||||
{"disable_market", (*InstructionDisableMarketAccounts)(nil)},
|
||||
{"sweep_fees", (*InstructionSweepFees)(nil)},
|
||||
{"new_order_v2", (*InstructionNewOrderV2)(nil)},
|
||||
})
|
||||
|
||||
type InitializeMarketAccounts struct {
|
||||
|
@ -115,7 +118,7 @@ type NewOrderAccounts struct {
|
|||
OpenOrders *solana.AccountMeta `text:"linear,notype"`
|
||||
RequestQueue *solana.AccountMeta `text:"linear,notype"`
|
||||
Payer *solana.AccountMeta `text:"linear,notype"`
|
||||
Owner *solana.AccountMeta `text:"linear,notype"`
|
||||
Owner *solana.AccountMeta `text:"linear,notype"` // The owner of the open orders, i.e. the trader
|
||||
CoinVault *solana.AccountMeta `text:"linear,notype"`
|
||||
PCVault *solana.AccountMeta `text:"linear,notype"`
|
||||
SPLTokenProgram *solana.AccountMeta `text:"linear,notype"`
|
||||
|
@ -124,7 +127,7 @@ type NewOrderAccounts struct {
|
|||
}
|
||||
|
||||
type InstructionNewOrder struct {
|
||||
Side uint32
|
||||
Side Side
|
||||
LimitPrice uint64
|
||||
MaxQuantity uint64
|
||||
OrderType OrderType
|
||||
|
@ -300,7 +303,7 @@ type CancelOrderByClientIdAccounts struct {
|
|||
type InstructionCancelOrderByClientId struct {
|
||||
ClientID uint64
|
||||
|
||||
Accounts *CancelOrderByClientIdAccounts
|
||||
Accounts *CancelOrderByClientIdAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionCancelOrderByClientId) SetAccounts(accounts []*solana.AccountMeta, instructionActIdx []uint8) error {
|
||||
|
@ -316,3 +319,107 @@ func (i *InstructionCancelOrderByClientId) SetAccounts(accounts []*solana.Accoun
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
type DisableMarketAccounts struct {
|
||||
Market *solana.AccountMeta `text:"linear,notype"`
|
||||
DisableAuthority *solana.AccountMeta `text:"linear,notype"`
|
||||
}
|
||||
|
||||
type InstructionDisableMarketAccounts struct {
|
||||
Accounts *DisableMarketAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionDisableMarketAccounts) SetAccounts(accounts []*solana.AccountMeta, instructionActIdx []uint8) error {
|
||||
if len(instructionActIdx) < 2 {
|
||||
return fmt.Errorf("insuficient account, Disable Market requires at-least 2 accounts not %d", len(accounts))
|
||||
}
|
||||
|
||||
i.Accounts = &DisableMarketAccounts{
|
||||
Market: accounts[instructionActIdx[0]],
|
||||
DisableAuthority: accounts[instructionActIdx[1]],
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SweepFeesAccounts struct {
|
||||
Market *solana.AccountMeta `text:"linear,notype"`
|
||||
PCVault *solana.AccountMeta `text:"linear,notype"`
|
||||
FeeSweepingAuthority *solana.AccountMeta `text:"linear,notype"`
|
||||
FeeReceivableAccount *solana.AccountMeta `text:"linear,notype"`
|
||||
VaultSigner *solana.AccountMeta `text:"linear,notype"`
|
||||
SPLTokenProgram *solana.AccountMeta `text:"linear,notype"`
|
||||
}
|
||||
|
||||
type InstructionSweepFees struct {
|
||||
Accounts *SweepFeesAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionSweepFees) SetAccounts(accounts []*solana.AccountMeta, instructionActIdx []uint8) error {
|
||||
if len(instructionActIdx) < 6 {
|
||||
return fmt.Errorf("insuficient account, Sweep Fees requires at-least 6 accounts not %d", len(accounts))
|
||||
}
|
||||
|
||||
i.Accounts = &SweepFeesAccounts{
|
||||
Market: accounts[instructionActIdx[0]],
|
||||
PCVault: accounts[instructionActIdx[1]],
|
||||
FeeSweepingAuthority: accounts[instructionActIdx[2]],
|
||||
FeeReceivableAccount: accounts[instructionActIdx[3]],
|
||||
VaultSigner: accounts[instructionActIdx[4]],
|
||||
SPLTokenProgram: accounts[instructionActIdx[5]],
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type NewOrderV2Accounts struct {
|
||||
Market *solana.AccountMeta `text:"linear,notype"` // the market
|
||||
OpenOrders *solana.AccountMeta `text:"linear,notype"` // the OpenOrders account to use
|
||||
RequestQueue *solana.AccountMeta `text:"linear,notype"` // the request queue
|
||||
Payer *solana.AccountMeta `text:"linear,notype"` // the (coin or price currency) account paying for the order
|
||||
Owner *solana.AccountMeta `text:"linear,notype"` // owner of the OpenOrders account
|
||||
CoinVault *solana.AccountMeta `text:"linear,notype"` // coin vault
|
||||
PCVault *solana.AccountMeta `text:"linear,notype"` // pc vault
|
||||
SPLTokenProgram *solana.AccountMeta `text:"linear,notype"` // spl token program
|
||||
RentSysvar *solana.AccountMeta `text:"linear,notype"` // the rent sysvar
|
||||
FeeDiscount *solana.AccountMeta `text:"linear,notype"` // (optional) the (M)SRM account used for fee discounts
|
||||
}
|
||||
|
||||
type SelfTradeBehavior uint32
|
||||
|
||||
const (
|
||||
SelfTradeBehaviorDecrementTake = iota
|
||||
SelfTradeBehaviorCancelProvide
|
||||
)
|
||||
|
||||
type InstructionNewOrderV2 struct {
|
||||
Side Side
|
||||
LimitPrice uint64
|
||||
MaxQuantity uint64
|
||||
OrderType OrderType
|
||||
ClientID uint64
|
||||
SelfTradeBehavior SelfTradeBehavior
|
||||
|
||||
Accounts *NewOrderV2Accounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionNewOrderV2) SetAccounts(accounts []*solana.AccountMeta, instructionActIdx []uint8) error {
|
||||
if len(instructionActIdx) < 10 {
|
||||
return fmt.Errorf("insuficient account, New Order V2 requires at-least 10 accounts not %d", len(accounts))
|
||||
}
|
||||
|
||||
i.Accounts = &NewOrderV2Accounts{
|
||||
Market: accounts[instructionActIdx[0]],
|
||||
OpenOrders: accounts[instructionActIdx[1]],
|
||||
RequestQueue: accounts[instructionActIdx[2]],
|
||||
Payer: accounts[instructionActIdx[3]],
|
||||
Owner: accounts[instructionActIdx[4]],
|
||||
CoinVault: accounts[instructionActIdx[5]],
|
||||
PCVault: accounts[instructionActIdx[6]],
|
||||
SPLTokenProgram: accounts[instructionActIdx[7]],
|
||||
RentSysvar: accounts[instructionActIdx[8]],
|
||||
FeeDiscount: accounts[instructionActIdx[9]],
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,18 +4,68 @@ import (
|
|||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
bin "github.com/dfuse-io/binary"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDecodeInstruction(t *testing.T) {
|
||||
x := `00020000000500`
|
||||
data, err := hex.DecodeString(x)
|
||||
require.NoError(t, err)
|
||||
var instruction *Instruction
|
||||
err = bin.NewDecoder(data).Decode(&instruction)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, instruction.Version, uint8(0))
|
||||
tests := []struct {
|
||||
name string
|
||||
hexData string
|
||||
expectInstruction *Instruction
|
||||
}{
|
||||
{
|
||||
name: "New Order",
|
||||
hexData: "000900000001000000b80600000000000010eb09000000000000000000168106e091da511601000000",
|
||||
expectInstruction: &Instruction{
|
||||
BaseVariant: bin.BaseVariant{
|
||||
TypeID: 9,
|
||||
Impl: &InstructionNewOrderV2{
|
||||
Side: SideAsk,
|
||||
LimitPrice: 1720,
|
||||
MaxQuantity: 650000,
|
||||
OrderType: OrderTypeLimit,
|
||||
ClientID: 1608306862011613462,
|
||||
SelfTradeBehavior: SelfTradeBehaviorCancelProvide,
|
||||
},
|
||||
},
|
||||
Version: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Match Order",
|
||||
hexData: "0002000000ffff",
|
||||
expectInstruction: &Instruction{
|
||||
BaseVariant: bin.BaseVariant{
|
||||
TypeID: 2,
|
||||
Impl: &InstructionMatchOrder{
|
||||
Limit: 65535,
|
||||
},
|
||||
},
|
||||
Version: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Settle Funds",
|
||||
hexData: "0005000000",
|
||||
expectInstruction: &Instruction{
|
||||
BaseVariant: bin.BaseVariant{
|
||||
TypeID: 5,
|
||||
Impl: &InstructionSettleFunds{},
|
||||
},
|
||||
Version: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
data, err := hex.DecodeString(test.hexData)
|
||||
require.NoError(t, err)
|
||||
var instruction *Instruction
|
||||
err = bin.NewDecoder(data).Decode(&instruction)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.expectInstruction, instruction)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,25 +90,10 @@ func (s SideLayout) getSide() SideLayoutType {
|
|||
return SideLayoutTypeUnknown
|
||||
}
|
||||
|
||||
type OrderType string
|
||||
type OrderType uint32
|
||||
|
||||
const (
|
||||
OrderTypeUnknown OrderType = "UNKNOWN"
|
||||
OrderTypeLimit OrderType = "LIMIT"
|
||||
OrderTypeImmediateOrCancel OrderType = "IMMEDIATE_OR_CANCEL"
|
||||
OrderTypePostOnly OrderType = "POST_ONLY"
|
||||
OrderTypeLimit = OrderType(0)
|
||||
OrderTypeImmediateOrCancel
|
||||
OrderTypePostOnly
|
||||
)
|
||||
|
||||
type OrderTypeLayout uint32
|
||||
|
||||
func (o OrderTypeLayout) getOrderType() OrderType {
|
||||
switch o {
|
||||
case 0:
|
||||
return OrderTypeLimit
|
||||
case 1:
|
||||
return OrderTypeImmediateOrCancel
|
||||
case 2:
|
||||
return OrderTypePostOnly
|
||||
}
|
||||
return OrderTypeUnknown
|
||||
}
|
||||
|
|
|
@ -55,11 +55,20 @@ type Request struct {
|
|||
Padding [4]byte `json:"-"`
|
||||
MaxCoinQtyOrCancelId bin.Uint64
|
||||
NativePCQtyLocked bin.Uint64
|
||||
OrderId bin.Uint128
|
||||
Owner [4]bin.Uint64
|
||||
OrderID bin.Uint128
|
||||
OpenOrders [4]bin.Uint64 // this is the openOrder address
|
||||
ClientOrderID bin.Uint64
|
||||
}
|
||||
|
||||
func (r *Request) Equal(other *Request) bool {
|
||||
//return (r.OrderID.Hi == other.OrderID.Hi && r.OrderID.Lo == other.OrderID.Lo) &&
|
||||
// (r.MaxCoinQtyOrCancelId == other.MaxCoinQtyOrCancelId) &&
|
||||
// (r.NativePCQtyLocked == other.NativePCQtyLocked)
|
||||
return (r.OrderID.Hi == other.OrderID.Hi && r.OrderID.Lo == other.OrderID.Lo) &&
|
||||
(r.MaxCoinQtyOrCancelId == other.MaxCoinQtyOrCancelId) &&
|
||||
(r.NativePCQtyLocked == other.NativePCQtyLocked)
|
||||
}
|
||||
|
||||
type EventQueue struct {
|
||||
SerumPadding [5]byte `json:"-"`
|
||||
|
||||
|
@ -80,7 +89,7 @@ func (q *EventQueue) Decode(data []byte) error {
|
|||
type EventFlag uint8
|
||||
|
||||
const (
|
||||
EventFlagFill = RequestFlag(1 << iota)
|
||||
EventFlagFill = EventFlag(1 << iota)
|
||||
EventFlagOut
|
||||
EventFlagBid
|
||||
EventFlagMaker
|
||||
|
@ -106,6 +115,10 @@ type Event struct {
|
|||
ClientOrderID uint64
|
||||
}
|
||||
|
||||
func (e *Event) Equal(other *Event) bool {
|
||||
return e.OrderID.Hi == other.OrderID.Hi && e.OrderID.Lo == other.OrderID.Lo
|
||||
}
|
||||
|
||||
func (e *Event) Side() EventSide {
|
||||
if Has(uint8(e.Flag), uint8(EventFlagBid)) {
|
||||
return EventSideBid
|
||||
|
|
|
@ -61,6 +61,13 @@ func (a *AccountFlag) String() string {
|
|||
return fmt.Sprintf("%s %s", status, account_type)
|
||||
}
|
||||
|
||||
type Side uint32
|
||||
|
||||
const (
|
||||
SideBid = iota
|
||||
SideAsk
|
||||
)
|
||||
|
||||
type MarketV2 struct {
|
||||
SerumPadding [5]byte `json:"-"`
|
||||
AccountFlags AccountFlag
|
||||
|
|
|
@ -45,7 +45,7 @@ func Test_AccountSubscribe(t *testing.T) {
|
|||
return
|
||||
}
|
||||
text.NewEncoder(os.Stdout).Encode(data, nil)
|
||||
fmt.Println("Owner: ", data.(*AccountResult).Value.Account.Owner)
|
||||
fmt.Println("OpenOrders: ", data.(*AccountResult).Value.Account.Owner)
|
||||
fmt.Println("data: ", data.(*AccountResult).Value.Account.Data)
|
||||
return
|
||||
|
||||
|
|
Loading…
Reference in New Issue