added get transaction cli cmd with decoded instruction for serum and system.
This commit is contained in:
parent
57107bb989
commit
965d5a64c0
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2020 dfuse Platform Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/dfuse-io/solana-go"
|
||||
"github.com/dfuse-io/solana-go/rpc"
|
||||
_ "github.com/dfuse-io/solana-go/serum"
|
||||
_ "github.com/dfuse-io/solana-go/system"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var getTransactionsCmd = &cobra.Command{
|
||||
Use: "transactions {account}",
|
||||
Short: "Retrieve transaction for a specific account",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client := getClient()
|
||||
ctx := context.Background()
|
||||
|
||||
address := args[0]
|
||||
pubKey, err := solana.PublicKeyFromBase58(address)
|
||||
errorCheck("public key", err)
|
||||
|
||||
csList, err := client.GetConfirmedSignaturesForAddress2(ctx, pubKey, &rpc.GetConfirmedSignaturesForAddress2Opts{
|
||||
Limit: 10,
|
||||
Before: "",
|
||||
Until: "",
|
||||
})
|
||||
|
||||
errorCheck("getting confirm transaction:", err)
|
||||
|
||||
for _, cs := range csList {
|
||||
fmt.Println("-----------------------------------------------------------------------------------------------")
|
||||
fmt.Println("Transaction: ", cs.Signature)
|
||||
fmt.Println("Slot: ", cs.Slot)
|
||||
fmt.Println("Memo: ", cs.Memo)
|
||||
|
||||
ct, err := client.GetConfirmedTransaction(ctx, cs.Signature)
|
||||
errorCheck("confirm transaction", err)
|
||||
if ct.Meta.Err != nil {
|
||||
fmt.Println("ERROR:", ct.Meta.Err)
|
||||
// for k, _ := range ct.Meta.Err
|
||||
}
|
||||
fmt.Println("account count:", len(ct.Transaction.Message.AccountKeys))
|
||||
|
||||
fmt.Print("\nInstructions:\n-------------\n\n")
|
||||
for _, i := range ct.Transaction.Message.Instructions {
|
||||
id, err := ct.Transaction.ResolveProgramIDIndex(i.ProgramIDIndex)
|
||||
errorCheck("resolving programID", err)
|
||||
decoder := solana.InstructionDecoderRegistry[id.String()]
|
||||
if decoder == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
decoded, err := decoder(ct.Transaction.Message.AccountKeys, &i)
|
||||
fmt.Printf("%s\n\n", decoded)
|
||||
}
|
||||
fmt.Print("End of transaction\n\n")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
getCmd.AddCommand(getTransactionsCmd)
|
||||
}
|
|
@ -16,6 +16,7 @@ package solana
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
bin "github.com/dfuse-io/binary"
|
||||
)
|
||||
|
@ -26,6 +27,10 @@ type AccountMeta struct {
|
|||
IsWritable bool
|
||||
}
|
||||
|
||||
func (a *AccountMeta) String() string {
|
||||
return fmt.Sprintf("%s Signer: %t Writable: %t", a.PublicKey.String(), a.IsSigner, a.IsWritable)
|
||||
}
|
||||
|
||||
type Instruction struct {
|
||||
ProgramID PublicKey
|
||||
Accounts []AccountMeta
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package solana
|
||||
|
||||
type AccountSettable interface {
|
||||
SetAccounts(accounts []PublicKey)
|
||||
SetAccounts(accounts []PublicKey) error
|
||||
}
|
||||
|
|
12
registry.go
12
registry.go
|
@ -1,23 +1,25 @@
|
|||
package solana
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type InstructionDecoder func([]PublicKey, *CompiledInstruction) (interface{}, error)
|
||||
|
||||
var instructionDecoderRegistry = map[string]InstructionDecoder{}
|
||||
var InstructionDecoderRegistry = map[string]InstructionDecoder{}
|
||||
|
||||
func RegisterInstructionDecoder(programID PublicKey, decoder InstructionDecoder) {
|
||||
p := programID.String()
|
||||
if _, found := instructionDecoderRegistry[p]; found {
|
||||
if _, found := InstructionDecoderRegistry[p]; found {
|
||||
panic(fmt.Sprintf("unable to re-register instruction decoder for program %q", p))
|
||||
}
|
||||
instructionDecoderRegistry[p] = decoder
|
||||
InstructionDecoderRegistry[p] = decoder
|
||||
}
|
||||
|
||||
func DecodeInstruction(programID PublicKey, accounts []PublicKey, inst *CompiledInstruction) (interface{}, error) {
|
||||
p := programID.String()
|
||||
|
||||
decoder, found := instructionDecoderRegistry[p]
|
||||
decoder, found := InstructionDecoderRegistry[p]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unknown programID, cannot find any instruction decoder %q", p)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func registryDecodeInstruction(accounts []solana.PublicKey, rawInstruction *sola
|
|||
}
|
||||
|
||||
func DecodeInstruction(accounts []solana.PublicKey, compiledInstruction *solana.CompiledInstruction) (*Instruction, error) {
|
||||
var inst *Instruction
|
||||
var inst Instruction
|
||||
if err := bin.NewDecoder(compiledInstruction.Data).Decode(&inst); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode instruction for serum program: %w", err)
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func DecodeInstruction(accounts []solana.PublicKey, compiledInstruction *solana.
|
|||
v.SetAccounts(accounts)
|
||||
}
|
||||
|
||||
return inst, nil
|
||||
return &inst, nil
|
||||
}
|
||||
|
||||
type Instruction struct {
|
||||
|
@ -39,6 +39,10 @@ type Instruction struct {
|
|||
Version uint8
|
||||
}
|
||||
|
||||
func (i *Instruction) String() string {
|
||||
return fmt.Sprintf("%s", i.Impl)
|
||||
}
|
||||
|
||||
func (i *Instruction) UnmarshalBinary(decoder *bin.Decoder) (err error) {
|
||||
i.Version, err = decoder.ReadUint8()
|
||||
if err != nil {
|
||||
|
@ -93,11 +97,11 @@ func (i *InstructionInitializeMarket) SetAccounts(accounts []solana.PublicKey) e
|
|||
return fmt.Errorf("insuficient account, Initialize Market requires at-least 8 accounts not %d", len(accounts))
|
||||
}
|
||||
i.Accounts = &InitializeMarketAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, true},
|
||||
SPLCoinToken: solana.AccountMeta{accounts[5], false, true},
|
||||
SPLPriceToken: solana.AccountMeta{accounts[6], false, true},
|
||||
CoinMint: solana.AccountMeta{accounts[7], false, false},
|
||||
PriceMint: solana.AccountMeta{accounts[8], false, false},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0], IsWritable: true},
|
||||
SPLCoinToken: solana.AccountMeta{PublicKey: accounts[5], IsWritable: true},
|
||||
SPLPriceToken: solana.AccountMeta{PublicKey: accounts[6], IsWritable: true},
|
||||
CoinMint: solana.AccountMeta{PublicKey: accounts[7]},
|
||||
PriceMint: solana.AccountMeta{PublicKey: accounts[8]},
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -115,34 +119,61 @@ type NewOrderAccounts struct {
|
|||
SRMDiscountAccount *solana.AccountMeta
|
||||
}
|
||||
|
||||
func (a *NewOrderAccounts) String() string {
|
||||
out := a.Market.String() + " Market\n"
|
||||
out += a.OpenOrders.String() + " OpenOrders\n"
|
||||
out += a.RequestQueue.String() + " RequestQueue\n"
|
||||
out += a.Payer.String() + " Payer\n"
|
||||
out += a.Owner.String() + " Owner\n"
|
||||
out += a.CoinVault.String() + " CoinVault\n"
|
||||
out += a.PCVault.String() + " PCVault\n"
|
||||
out += a.SPLTokenProgram.String() + " SPLTokenProgram\n"
|
||||
out += a.Rent.String() + " Rent\n"
|
||||
out += a.SRMDiscountAccount.String() + " SRMDiscountAccount"
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type InstructionNewOrder struct {
|
||||
Side uint32
|
||||
Side Side
|
||||
LimitPrice uint64
|
||||
MaxQuantity uint64
|
||||
OrderType uint32
|
||||
OrderType OrderType
|
||||
ClientID uint64
|
||||
|
||||
Accounts *NewOrderAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionNewOrder) String() string {
|
||||
out := "New Order\n"
|
||||
out += fmt.Sprintf("Side: %q OrderType: %q Limit price: %d Max Quantity: %d Client ID: %d\n", i.Side, i.OrderType, i.LimitPrice, i.MaxQuantity, i.ClientID)
|
||||
out += "Accounts:\n"
|
||||
|
||||
if i.Accounts != nil {
|
||||
out += i.Accounts.String()
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (i *InstructionNewOrder) SetAccounts(accounts []solana.PublicKey) error {
|
||||
if len(accounts) < 9 {
|
||||
return fmt.Errorf("insuficient account, New Order requires at-least 10 accounts not %d", len(accounts))
|
||||
}
|
||||
i.Accounts = &NewOrderAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, true},
|
||||
OpenOrders: solana.AccountMeta{accounts[1], false, true},
|
||||
RequestQueue: solana.AccountMeta{accounts[2], false, true},
|
||||
Payer: solana.AccountMeta{accounts[3], false, true},
|
||||
Owner: solana.AccountMeta{accounts[4], true, false},
|
||||
CoinVault: solana.AccountMeta{accounts[5], false, true},
|
||||
PCVault: solana.AccountMeta{accounts[6], false, true},
|
||||
SPLTokenProgram: solana.AccountMeta{accounts[7], false, false},
|
||||
Rent: solana.AccountMeta{accounts[8], false, false},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0], IsWritable: true},
|
||||
OpenOrders: solana.AccountMeta{PublicKey: accounts[1], IsWritable: true},
|
||||
RequestQueue: solana.AccountMeta{PublicKey: accounts[2], IsWritable: true},
|
||||
Payer: solana.AccountMeta{PublicKey: accounts[3], IsWritable: true},
|
||||
Owner: solana.AccountMeta{PublicKey: accounts[4], IsSigner: true},
|
||||
CoinVault: solana.AccountMeta{PublicKey: accounts[5], IsWritable: true},
|
||||
PCVault: solana.AccountMeta{PublicKey: accounts[6], IsWritable: true},
|
||||
SPLTokenProgram: solana.AccountMeta{PublicKey: accounts[7]},
|
||||
Rent: solana.AccountMeta{PublicKey: accounts[8]},
|
||||
}
|
||||
|
||||
if len(accounts) >= 10 {
|
||||
i.Accounts.SRMDiscountAccount = &solana.AccountMeta{accounts[9], false, true}
|
||||
i.Accounts.SRMDiscountAccount = &solana.AccountMeta{PublicKey: accounts[9], IsWritable: true}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -158,6 +189,17 @@ type MatchOrderAccounts struct {
|
|||
PCFeeReceivable solana.AccountMeta
|
||||
}
|
||||
|
||||
func (a *MatchOrderAccounts) String() string {
|
||||
out := a.Market.String() + " Market\n"
|
||||
out += a.RequestQueue.String() + " RequestQueue\n"
|
||||
out += a.EventQueue.String() + " EventQueue\n"
|
||||
out += a.Bids.String() + " Bids\n"
|
||||
out += a.Asks.String() + " Asks\n"
|
||||
out += a.CoinFeeReceivable.String() + " CoinFeeReceivable\n"
|
||||
out += a.PCFeeReceivable.String() + " PCFeeReceivable"
|
||||
return out
|
||||
}
|
||||
|
||||
type InstructionMatchOrder struct {
|
||||
Limit uint16
|
||||
|
||||
|
@ -166,20 +208,32 @@ type InstructionMatchOrder struct {
|
|||
|
||||
func (i *InstructionMatchOrder) SetAccounts(accounts []solana.PublicKey) error {
|
||||
if len(accounts) < 7 {
|
||||
return fmt.Errorf("insuficient account, Match Order requires at-least 7 accounts not %d", len(accounts))
|
||||
return fmt.Errorf("insuficient account, Match Order requires at-least 7 accounts not %d\n", len(accounts))
|
||||
}
|
||||
i.Accounts = &MatchOrderAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, true},
|
||||
RequestQueue: solana.AccountMeta{accounts[1], false, true},
|
||||
EventQueue: solana.AccountMeta{accounts[2], false, true},
|
||||
Bids: solana.AccountMeta{accounts[3], false, true},
|
||||
Asks: solana.AccountMeta{accounts[4], false, true},
|
||||
CoinFeeReceivable: solana.AccountMeta{accounts[5], false, true},
|
||||
PCFeeReceivable: solana.AccountMeta{accounts[6], false, true},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0], IsWritable: true},
|
||||
RequestQueue: solana.AccountMeta{PublicKey: accounts[1], IsWritable: true},
|
||||
EventQueue: solana.AccountMeta{PublicKey: accounts[2], IsWritable: true},
|
||||
Bids: solana.AccountMeta{PublicKey: accounts[3], IsWritable: true},
|
||||
Asks: solana.AccountMeta{PublicKey: accounts[4], IsWritable: true},
|
||||
CoinFeeReceivable: solana.AccountMeta{PublicKey: accounts[5], IsWritable: true},
|
||||
PCFeeReceivable: solana.AccountMeta{PublicKey: accounts[6], IsWritable: true},
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *InstructionMatchOrder) String() string {
|
||||
out := "Match Order\n"
|
||||
out += fmt.Sprintf("Limit: %d\n", i.Limit)
|
||||
out += "Accounts:\n"
|
||||
|
||||
if i.Accounts != nil {
|
||||
out += i.Accounts.String()
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type ConsumeEventsAccounts struct {
|
||||
OpenOrders []solana.AccountMeta
|
||||
Market solana.AccountMeta
|
||||
|
@ -199,14 +253,14 @@ func (i *InstructionConsumeEvents) SetAccounts(accounts []solana.PublicKey) erro
|
|||
return fmt.Errorf("insuficient account, Consume Events requires at-least 4 accounts not %d", len(accounts))
|
||||
}
|
||||
i.Accounts = &ConsumeEventsAccounts{
|
||||
Market: solana.AccountMeta{accounts[len(accounts)-4], false, true},
|
||||
EventQueue: solana.AccountMeta{accounts[len(accounts)-3], false, true},
|
||||
CoinFeeReceivable: solana.AccountMeta{accounts[len(accounts)-2], false, true},
|
||||
PCFeeReceivable: solana.AccountMeta{accounts[len(accounts)-1], false, true},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[len(accounts)-4], IsWritable: true},
|
||||
EventQueue: solana.AccountMeta{PublicKey: accounts[len(accounts)-3], IsWritable: true},
|
||||
CoinFeeReceivable: solana.AccountMeta{PublicKey: accounts[len(accounts)-2], IsWritable: true},
|
||||
PCFeeReceivable: solana.AccountMeta{PublicKey: accounts[len(accounts)-1], IsWritable: true},
|
||||
}
|
||||
|
||||
for itr := 0; itr < len(accounts)-4; itr++ {
|
||||
i.Accounts.OpenOrders = append(i.Accounts.OpenOrders, solana.AccountMeta{accounts[itr], false, true})
|
||||
i.Accounts.OpenOrders = append(i.Accounts.OpenOrders, solana.AccountMeta{PublicKey: accounts[itr], IsWritable: true})
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -219,6 +273,14 @@ type CancelOrderAccounts struct {
|
|||
Owner solana.AccountMeta
|
||||
}
|
||||
|
||||
func (a *CancelOrderAccounts) String() string {
|
||||
out := a.Market.String() + " Market\n"
|
||||
out += a.OpenOrders.String() + " OpenOrders\n"
|
||||
out += a.RequestQueue.String() + " RequestQueue\n"
|
||||
out += a.Owner.String() + " Owner"
|
||||
return out
|
||||
}
|
||||
|
||||
type InstructionCancelOrder struct {
|
||||
Side uint32
|
||||
OrderID bin.Uint128
|
||||
|
@ -228,15 +290,27 @@ type InstructionCancelOrder struct {
|
|||
Accounts *CancelOrderAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionCancelOrder) String() string {
|
||||
out := "Cancel Order\n"
|
||||
out += fmt.Sprintf("Side: %q Order ID: %q Open Orders: %s Slot: %d\n", i.Side, i.OrderID, i.OpenOrders.String(), i.OpenOrderSlot)
|
||||
out += "Accounts:\n"
|
||||
|
||||
if i.Accounts != nil {
|
||||
out += i.Accounts.String()
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (i *InstructionCancelOrder) SetAccounts(accounts []solana.PublicKey) error {
|
||||
if len(accounts) < 4 {
|
||||
return fmt.Errorf("insuficient account, Cancel Order requires at-least 4 accounts not %d", len(accounts))
|
||||
return fmt.Errorf("insuficient account, Cancel Order requires at-least 4 accounts not %d\n", len(accounts))
|
||||
}
|
||||
i.Accounts = &CancelOrderAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, false},
|
||||
OpenOrders: solana.AccountMeta{accounts[1], false, true},
|
||||
RequestQueue: solana.AccountMeta{accounts[2], false, true},
|
||||
Owner: solana.AccountMeta{accounts[3], true, false},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0]},
|
||||
OpenOrders: solana.AccountMeta{PublicKey: accounts[1], IsWritable: true},
|
||||
RequestQueue: solana.AccountMeta{PublicKey: accounts[2], IsWritable: true},
|
||||
Owner: solana.AccountMeta{PublicKey: accounts[3], IsSigner: true},
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -255,28 +329,52 @@ type SettleFundsAccounts struct {
|
|||
ReferrerPCWallet *solana.AccountMeta
|
||||
}
|
||||
|
||||
func (a *SettleFundsAccounts) String() string {
|
||||
out := a.Market.String() + " Market\n"
|
||||
out += a.OpenOrders.String() + " OpenOrders\n"
|
||||
out += a.Owner.String() + " Owner\n"
|
||||
out += a.CoinVault.String() + " CoinVault\n"
|
||||
out += a.PCVault.String() + " PCVault\n"
|
||||
out += a.CoinWallet.String() + " CoinWallet\n"
|
||||
out += a.PCWallet.String() + " PCWallet\n"
|
||||
out += a.Signer.String() + " Signer\n"
|
||||
out += a.SPLTokenProgram.String() + " SPLTokenProgram\n"
|
||||
out += a.ReferrerPCWallet.String() + " ReferrerPCWallet"
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type InstructionSettleFunds struct {
|
||||
Accounts *SettleFundsAccounts `bin:"-"`
|
||||
}
|
||||
|
||||
func (i *InstructionSettleFunds) String() string {
|
||||
out := "Settle Funds\n"
|
||||
out += "Accounts:\n"
|
||||
if i.Accounts != nil {
|
||||
out += i.Accounts.String()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (i *InstructionSettleFunds) SetAccounts(accounts []solana.PublicKey) error {
|
||||
if len(accounts) < 9 {
|
||||
return fmt.Errorf("insuficient account, Settle Funds requires at-least 10 accounts not %d", len(accounts))
|
||||
}
|
||||
i.Accounts = &SettleFundsAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, true},
|
||||
OpenOrders: solana.AccountMeta{accounts[1], false, true},
|
||||
Owner: solana.AccountMeta{accounts[2], true, false},
|
||||
CoinVault: solana.AccountMeta{accounts[3], false, true},
|
||||
PCVault: solana.AccountMeta{accounts[4], false, true},
|
||||
CoinWallet: solana.AccountMeta{accounts[5], false, true},
|
||||
PCWallet: solana.AccountMeta{accounts[6], false, true},
|
||||
Signer: solana.AccountMeta{accounts[7], false, false},
|
||||
SPLTokenProgram: solana.AccountMeta{accounts[8], false, false},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0], IsWritable: true},
|
||||
OpenOrders: solana.AccountMeta{PublicKey: accounts[1], IsWritable: true},
|
||||
Owner: solana.AccountMeta{PublicKey: accounts[2], IsSigner: true},
|
||||
CoinVault: solana.AccountMeta{PublicKey: accounts[3], IsWritable: true},
|
||||
PCVault: solana.AccountMeta{PublicKey: accounts[4], IsWritable: true},
|
||||
CoinWallet: solana.AccountMeta{PublicKey: accounts[5], IsWritable: true},
|
||||
PCWallet: solana.AccountMeta{PublicKey: accounts[6], IsWritable: true},
|
||||
Signer: solana.AccountMeta{PublicKey: accounts[7]},
|
||||
SPLTokenProgram: solana.AccountMeta{PublicKey: accounts[8]},
|
||||
}
|
||||
|
||||
if len(accounts) >= 10 {
|
||||
i.Accounts.ReferrerPCWallet = &solana.AccountMeta{accounts[9], false, true}
|
||||
i.Accounts.ReferrerPCWallet = &solana.AccountMeta{PublicKey: accounts[9], IsWritable: true}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -289,37 +387,57 @@ type CancelOrderByClientIdAccounts struct {
|
|||
Owner solana.AccountMeta
|
||||
}
|
||||
|
||||
func (a *CancelOrderByClientIdAccounts) String() string {
|
||||
out := a.Market.String() + " Market\n"
|
||||
out += a.OpenOrders.String() + " OpenOrders\n"
|
||||
out += a.RequestQueue.String() + " RequestQueue\n"
|
||||
out += a.Owner.String() + " Owner"
|
||||
return out
|
||||
}
|
||||
|
||||
type InstructionCancelOrderByClientId struct {
|
||||
ClientID uint64
|
||||
|
||||
Accounts *CancelOrderByClientIdAccounts
|
||||
}
|
||||
|
||||
func (i *InstructionCancelOrderByClientId) String() string {
|
||||
out := "Cancel Order by Client\n"
|
||||
out += fmt.Sprintf("ClientID: %d\n", i.ClientID)
|
||||
out += "Accounts:\n"
|
||||
|
||||
if i.Accounts != nil {
|
||||
out += i.Accounts.String()
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (i *InstructionCancelOrderByClientId) SetAccounts(accounts []solana.PublicKey) error {
|
||||
if len(accounts) < 4 {
|
||||
return fmt.Errorf("insuficient account, Cancel Order By Client Id requires at-least 4 accounts not %d", len(accounts))
|
||||
}
|
||||
i.Accounts = &CancelOrderByClientIdAccounts{
|
||||
Market: solana.AccountMeta{accounts[0], false, false},
|
||||
OpenOrders: solana.AccountMeta{accounts[1], false, true},
|
||||
RequestQueue: solana.AccountMeta{accounts[2], false, true},
|
||||
Owner: solana.AccountMeta{accounts[3], true, false},
|
||||
Market: solana.AccountMeta{PublicKey: accounts[0]},
|
||||
OpenOrders: solana.AccountMeta{PublicKey: accounts[1], IsWritable: true},
|
||||
RequestQueue: solana.AccountMeta{PublicKey: accounts[2], IsWritable: true},
|
||||
Owner: solana.AccountMeta{PublicKey: accounts[3], IsSigner: true},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SideLayoutType string
|
||||
type SideType string
|
||||
|
||||
const (
|
||||
SideLayoutTypeUnknown SideLayoutType = "UNKNOWN"
|
||||
SideLayoutTypeBid SideLayoutType = "BID"
|
||||
SideLayoutTypeAsk SideLayoutType = "ASK"
|
||||
SideLayoutTypeUnknown SideType = "UNKNOWN"
|
||||
SideLayoutTypeBid SideType = "BID"
|
||||
SideLayoutTypeAsk SideType = "ASK"
|
||||
)
|
||||
|
||||
type SideLayout uint32
|
||||
type Side uint32
|
||||
|
||||
func (s SideLayout) getSide() SideLayoutType {
|
||||
func (s Side) getSide() SideType {
|
||||
switch s {
|
||||
case 0:
|
||||
return SideLayoutTypeBid
|
||||
|
@ -329,18 +447,22 @@ func (s SideLayout) getSide() SideLayoutType {
|
|||
return SideLayoutTypeUnknown
|
||||
}
|
||||
|
||||
type OrderType string
|
||||
func (s Side) String() string {
|
||||
return string(s.getSide())
|
||||
}
|
||||
|
||||
type OrderTypeString string
|
||||
|
||||
const (
|
||||
OrderTypeUnknown OrderType = "UNKNOWN"
|
||||
OrderTypeLimit OrderType = "LIMIT"
|
||||
OrderTypeImmediateOrCancel OrderType = "IMMEDIATE_OR_CANCEL"
|
||||
OrderTypePostOnly OrderType = "POST_ONLY"
|
||||
OrderTypeUnknown OrderTypeString = "UNKNOWN"
|
||||
OrderTypeLimit OrderTypeString = "LIMIT"
|
||||
OrderTypeImmediateOrCancel OrderTypeString = "IMMEDIATE_OR_CANCEL"
|
||||
OrderTypePostOnly OrderTypeString = "POST_ONLY"
|
||||
)
|
||||
|
||||
type OrderTypeLayout uint32
|
||||
type OrderType uint32
|
||||
|
||||
func (o OrderTypeLayout) getOrderType() OrderType {
|
||||
func (o OrderType) getOrderType() OrderTypeString {
|
||||
switch o {
|
||||
case 0:
|
||||
return OrderTypeLimit
|
||||
|
@ -351,3 +473,6 @@ func (o OrderTypeLayout) getOrderType() OrderType {
|
|||
}
|
||||
return OrderTypeUnknown
|
||||
}
|
||||
func (t OrderType) String() string {
|
||||
return string(t.getOrderType())
|
||||
}
|
||||
|
|
|
@ -18,3 +18,7 @@ func TestDecodeInstruction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
fmt.Println(instruction)
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ import (
|
|||
solana "github.com/dfuse-io/solana-go"
|
||||
)
|
||||
|
||||
var SYSTEM_PROGRAM_ID = solana.MustPublicKeyFromBase58("11111111111111111111111111111111")
|
||||
var PROGRAM_ID = solana.MustPublicKeyFromBase58("11111111111111111111111111111111")
|
||||
|
||||
func init() {
|
||||
solana.RegisterInstructionDecoder(SYSTEM_PROGRAM_ID, registryDecodeInstruction)
|
||||
solana.RegisterInstructionDecoder(PROGRAM_ID, registryDecodeInstruction)
|
||||
}
|
||||
|
||||
func registryDecodeInstruction(accounts []solana.PublicKey, rawInstruction *solana.CompiledInstruction) (interface{}, error) {
|
||||
|
@ -35,8 +35,8 @@ func registryDecodeInstruction(accounts []solana.PublicKey, rawInstruction *sola
|
|||
return inst, nil
|
||||
}
|
||||
|
||||
func DecodeInstruction(accounts []solana.PublicKey, compiledInstruction *solana.CompiledInstruction) (*SystemInstruction, error) {
|
||||
var inst *SystemInstruction
|
||||
func DecodeInstruction(accounts []solana.PublicKey, compiledInstruction *solana.CompiledInstruction) (*Instruction, error) {
|
||||
var inst *Instruction
|
||||
if err := bin.NewDecoder(compiledInstruction.Data).Decode(&inst); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode instruction for serum program: %w", err)
|
||||
}
|
||||
|
@ -48,20 +48,22 @@ func DecodeInstruction(accounts []solana.PublicKey, compiledInstruction *solana.
|
|||
return inst, nil
|
||||
}
|
||||
|
||||
type SystemInstruction struct {
|
||||
//Type bin.Varuint16
|
||||
//Variant interface{}
|
||||
type Instruction struct {
|
||||
bin.BaseVariant
|
||||
}
|
||||
|
||||
var SystemInstructionImplDef = bin.NewVariantDefinition(bin.Uint32TypeIDEncoding, []bin.VariantType{
|
||||
func (i *Instruction) String() string {
|
||||
return fmt.Sprintf("%s", i.Impl)
|
||||
}
|
||||
|
||||
var InstructionImplDef = bin.NewVariantDefinition(bin.Uint32TypeIDEncoding, []bin.VariantType{
|
||||
{"create_account", (*CreateAccount)(nil)},
|
||||
{"assign", (*Assign)(nil)},
|
||||
{"transfer", (*Transfer)(nil)},
|
||||
})
|
||||
|
||||
func (i *SystemInstruction) UnmarshalBinary(decoder *bin.Decoder) error {
|
||||
return i.BaseVariant.UnmarshalBinaryVariant(decoder, SystemInstructionImplDef)
|
||||
func (i *Instruction) UnmarshalBinary(decoder *bin.Decoder) error {
|
||||
return i.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef)
|
||||
}
|
||||
|
||||
type CreateAccount struct {
|
||||
|
@ -71,16 +73,34 @@ type CreateAccount struct {
|
|||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *CreateAccount) String() string {
|
||||
out := "Create Account\n"
|
||||
out += fmt.Sprintf("Lamports: %d, space: %d, Owner: %s", i.Lamports, i.Space, i.Owner.String())
|
||||
return out
|
||||
}
|
||||
|
||||
type Assign struct {
|
||||
// prefixed with byte 0x01
|
||||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *Assign) String() string {
|
||||
out := "Assign\n"
|
||||
out += fmt.Sprintf("Owner: %s", i.Owner.String())
|
||||
return out
|
||||
}
|
||||
|
||||
type Transfer struct {
|
||||
// Prefixed with byte 0x02
|
||||
Lamports bin.Uint64
|
||||
}
|
||||
|
||||
func (t *Transfer) String() string {
|
||||
out := "Transfer\n"
|
||||
out += fmt.Sprintf("Lamports: %d", t.Lamports)
|
||||
return out
|
||||
}
|
||||
|
||||
type CreateAccountWithSeed struct {
|
||||
// Prefixed with byte 0x03
|
||||
Base solana.PublicKey
|
||||
|
@ -91,30 +111,66 @@ type CreateAccountWithSeed struct {
|
|||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *CreateAccountWithSeed) String() string {
|
||||
out := "Create Account With Seed\n"
|
||||
out += fmt.Sprintf("Base: %s SeedSize: %d Seed: %s Lamports: %d Space: %d Owner: %s", i.Base, i.SeedSize, i.Seed, i.Lamports, i.Space, i.Owner.String())
|
||||
return out
|
||||
}
|
||||
|
||||
type AdvanceNonceAccount struct {
|
||||
// Prefix with 0x04
|
||||
}
|
||||
|
||||
func (i *AdvanceNonceAccount) String() string {
|
||||
out := "Advance Nonce Account\n"
|
||||
out += "Accounts:"
|
||||
return out
|
||||
}
|
||||
|
||||
type WithdrawNonceAccount struct {
|
||||
// Prefix with 0x05
|
||||
Lamports bin.Uint64
|
||||
}
|
||||
|
||||
func (i *WithdrawNonceAccount) String() string {
|
||||
out := "Withdraw Nonce Account\n"
|
||||
out += fmt.Sprintf("Lamports: %d", i.Lamports)
|
||||
return out
|
||||
}
|
||||
|
||||
type InitializeNonceAccount struct {
|
||||
// Prefix with 0x06
|
||||
AuthorizedAccount solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *InitializeNonceAccount) String() string {
|
||||
out := "Initialize Nonce Account\n"
|
||||
out += fmt.Sprintf("AuthorizedAccount: %s", i.AuthorizedAccount.String())
|
||||
return out
|
||||
}
|
||||
|
||||
type AuthorizeNonceAccount struct {
|
||||
// Prefix with 0x07
|
||||
AuthorizeAccount solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *AuthorizeNonceAccount) String() string {
|
||||
out := "Authorize Nonce Account\n"
|
||||
out += fmt.Sprintf("AuthorizedAccount: %s", i.AuthorizeAccount.String())
|
||||
return out
|
||||
}
|
||||
|
||||
type Allocate struct {
|
||||
// Prefix with 0x08
|
||||
Space bin.Uint64
|
||||
}
|
||||
|
||||
func (i *Allocate) String() string {
|
||||
out := "Allocate"
|
||||
out += fmt.Sprintf("Space: %d", i.Space)
|
||||
return out
|
||||
}
|
||||
|
||||
type AllocateWithSeed struct {
|
||||
// Prefixed with byte 0x09
|
||||
Base solana.PublicKey
|
||||
|
@ -124,6 +180,12 @@ type AllocateWithSeed struct {
|
|||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *AllocateWithSeed) String() string {
|
||||
out := "Allocate With Seed\n"
|
||||
out += fmt.Sprintf("Base: %s SeedSize: %d Seed: %s Space: %d Owner: %s", i.Base, i.SeedSize, i.Seed, i.Owner)
|
||||
return out
|
||||
}
|
||||
|
||||
type AssignWithSeed struct {
|
||||
// Prefixed with byte 0x0a
|
||||
Base solana.PublicKey
|
||||
|
@ -131,3 +193,9 @@ type AssignWithSeed struct {
|
|||
Seed string
|
||||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
func (i *AssignWithSeed) String() string {
|
||||
out := "Assign With Seed\n"
|
||||
out += fmt.Sprintf("Base: %s SeedSize: %d Seed: %s Owner: %s", i.Base, i.SeedSize, i.Seed, i.Owner)
|
||||
return out
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue