github.com/gagliardetto/solana-go@v1.11.0/rpc/ws/accountSubscribe.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ws 16 17 import ( 18 "github.com/gagliardetto/solana-go" 19 "github.com/gagliardetto/solana-go/rpc" 20 ) 21 22 type AccountResult struct { 23 Context struct { 24 Slot uint64 25 } `json:"context"` 26 Value struct { 27 rpc.Account 28 } `json:"value"` 29 } 30 31 // AccountSubscribe subscribes to an account to receive notifications 32 // when the lamports or data for a given account public key changes. 33 func (cl *Client) AccountSubscribe( 34 account solana.PublicKey, 35 commitment rpc.CommitmentType, 36 ) (*AccountSubscription, error) { 37 return cl.AccountSubscribeWithOpts( 38 account, 39 commitment, 40 "", 41 ) 42 } 43 44 // AccountSubscribe subscribes to an account to receive notifications 45 // when the lamports or data for a given account public key changes. 46 func (cl *Client) AccountSubscribeWithOpts( 47 account solana.PublicKey, 48 commitment rpc.CommitmentType, 49 encoding solana.EncodingType, 50 ) (*AccountSubscription, error) { 51 52 params := []interface{}{account.String()} 53 conf := map[string]interface{}{ 54 "encoding": "base64", 55 } 56 if commitment != "" { 57 conf["commitment"] = commitment 58 } 59 if encoding != "" { 60 conf["encoding"] = encoding 61 } 62 63 genSub, err := cl.subscribe( 64 params, 65 conf, 66 "accountSubscribe", 67 "accountUnsubscribe", 68 func(msg []byte) (interface{}, error) { 69 var res AccountResult 70 err := decodeResponseFromMessage(msg, &res) 71 return &res, err 72 }, 73 ) 74 if err != nil { 75 return nil, err 76 } 77 return &AccountSubscription{ 78 sub: genSub, 79 }, nil 80 } 81 82 type AccountSubscription struct { 83 sub *Subscription 84 } 85 86 func (sw *AccountSubscription) Recv() (*AccountResult, error) { 87 select { 88 case d := <-sw.sub.stream: 89 return d.(*AccountResult), nil 90 case err := <-sw.sub.err: 91 return nil, err 92 } 93 } 94 95 func (sw *AccountSubscription) Err() <-chan error { 96 return sw.sub.err 97 } 98 99 func (sw *AccountSubscription) Response() <-chan *AccountResult { 100 typedChan := make(chan *AccountResult, 1) 101 go func(ch chan *AccountResult) { 102 // TODO: will this subscription yield more than one result? 103 d, ok := <-sw.sub.stream 104 if !ok { 105 return 106 } 107 ch <- d.(*AccountResult) 108 }(typedChan) 109 return typedChan 110 } 111 112 func (sw *AccountSubscription) Unsubscribe() { 113 sw.sub.Unsubscribe() 114 }