github.com/gagliardetto/solana-go@v1.11.0/programs/serum/rpc.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // This file has been modified by github.com/gagliardetto 3 // 4 // Copyright 2020 dfuse Platform Inc. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package serum 19 20 import ( 21 "bytes" 22 "context" 23 "fmt" 24 25 rice "github.com/GeertJohan/go.rice" 26 bin "github.com/gagliardetto/binary" 27 "github.com/gagliardetto/solana-go" 28 "github.com/gagliardetto/solana-go/rpc" 29 "github.com/gagliardetto/solana-go/rpc/ws" 30 "go.uber.org/zap" 31 ) 32 33 //go:generate rice embed-go 34 35 // TODO: hit the chain and 36 func KnownMarket() ([]*MarketMeta, error) { 37 box := rice.MustFindBox("data").MustBytes("markets.json") 38 if box == nil { 39 return nil, fmt.Errorf("unable to retrieve known markets") 40 } 41 42 dec := json.NewDecoder(bytes.NewReader(box)) 43 var markets []*MarketMeta 44 err := dec.Decode(&markets) 45 if err != nil { 46 return nil, fmt.Errorf("unable to decode known markets: %w", err) 47 } 48 return markets, nil 49 } 50 51 func FetchOpenOrders(ctx context.Context, rpcCli *rpc.Client, openOrdersAddr solana.PublicKey) (*OpenOrdersMeta, error) { 52 acctInfo, err := rpcCli.GetAccountInfo(ctx, openOrdersAddr) 53 if err != nil { 54 return nil, fmt.Errorf("unable to get open orders account:%w", err) 55 } 56 57 openOrdersMeta := &OpenOrdersMeta{} 58 59 if err := openOrdersMeta.OpenOrders.Decode(acctInfo.Value.Data.GetBinary()); err != nil { 60 return nil, fmt.Errorf("decoding market v2: %w", err) 61 } 62 63 return openOrdersMeta, nil 64 } 65 66 func FetchMarket(ctx context.Context, rpcCli *rpc.Client, marketAddr solana.PublicKey) (*MarketMeta, error) { 67 acctInfo, err := rpcCli.GetAccountInfo(ctx, marketAddr) 68 if err != nil { 69 return nil, fmt.Errorf("unable to get market account:%w", err) 70 } 71 72 meta := &MarketMeta{ 73 Address: marketAddr, 74 } 75 76 dataLen := len(acctInfo.Value.Data.GetBinary()) 77 switch dataLen { 78 // case 380: 79 // // if err := meta.MarketV1.Decode(acctInfo.Value.Data); err != nil { 80 // // return nil, fmt.Errorf("decoding market v1: %w", err) 81 // // } 82 // return nil, fmt.Errorf("Unsupported market version, w/ data length of 380") 83 84 case 388: 85 if err := meta.MarketV2.Decode(acctInfo.Value.Data.GetBinary()); err != nil { 86 return nil, fmt.Errorf("decoding market v2: %w", err) 87 } 88 89 default: 90 return nil, fmt.Errorf("unsupported market data length: %d", dataLen) 91 } 92 93 if err := rpcCli.GetAccountDataInto(ctx, meta.MarketV2.QuoteMint, &meta.QuoteMint); err != nil { 94 return nil, fmt.Errorf("getting quote mint: %w", err) 95 } 96 97 if err := rpcCli.GetAccountDataInto(ctx, meta.MarketV2.BaseMint, &meta.BaseMint); err != nil { 98 return nil, fmt.Errorf("getting base token: %w", err) 99 } 100 101 return meta, nil 102 } 103 104 func StreamOpenOrders(client *ws.Client) error { 105 sub, err := client.ProgramSubscribe(DEXProgramIDV2, rpc.CommitmentSingleGossip) 106 if err != nil { 107 return fmt.Errorf("unable to subscribe to programID %q: %w", DEXProgramIDV2, err) 108 } 109 count := 0 110 for { 111 d, err := sub.Recv() 112 if err != nil { 113 return fmt.Errorf("received error from programID subscription: %w", err) 114 } 115 res := d 116 117 var f *AccountFlag 118 err = bin.NewBinDecoder(res.Value.Account.Data.GetBinary()).Decode(&f) 119 if err != nil { 120 fmt.Println("***********************************", err) 121 zlog.Debug("unable to decoce account flag for account... skipping", 122 zap.Stringer("account_address", res.Value.Pubkey), 123 ) 124 continue 125 } 126 fmt.Printf("%d - %s\n", count, f.String()) 127 count++ 128 } 129 }