dione/rpc/solana/solana.go

102 lines
2.6 KiB
Go

package solana
import (
"encoding/json"
"fmt"
"log"
"github.com/Secured-Finance/dione/rpc/types"
stypes "github.com/Secured-Finance/dione/rpc/solana/types"
ws "github.com/dgrr/fastws"
"github.com/shengdoushi/base58"
"github.com/sirupsen/logrus"
"github.com/valyala/fasthttp"
)
var solanaAlphabet = base58.BitcoinAlphabet
type SolanaClient struct {
url string
ws string
}
type SubParams struct {
Encoding string `json:"encoding"`
}
func NewSubParam(encoding string) *SubParams {
return &SubParams{
Encoding: encoding,
}
}
// NewSolanaClient creates a new solana client structure.
func NewSolanaClient() *SolanaClient {
return &SolanaClient{
url: "http://devnet.solana.com:8899/",
ws: "ws://devnet.solana.com:8900/",
}
}
func (c *SolanaClient) GetTransaction(txHash string) ([]byte, error) {
req := fasthttp.AcquireRequest()
req.SetRequestURI(c.url)
req.Header.SetMethod("POST")
req.Header.SetContentType("application/json")
requestBody := types.NewRPCRequestBody("getConfirmedTransaction")
requestBody.Params = append(requestBody.Params, txHash, "json")
body, err := json.Marshal(requestBody)
if err != nil {
return nil, fmt.Errorf("Failed to marshal request body %v", err)
}
req.AppendBody(body)
resp := fasthttp.AcquireResponse()
client := &fasthttp.Client{}
if err = client.Do(req, resp); err != nil {
logrus.Warn("Failed to construct solana node rpc request", err)
return nil, err
}
bodyBytes := resp.Body()
logrus.Debugf("Solana RPC reply: %v", string(bodyBytes))
return bodyBytes, nil
}
func (c *SolanaClient) subscribeOnProgram(programID string) {
conn, err := ws.Dial(c.ws)
if err != nil {
log.Fatalln("Can't establish connection with Solana websocket: ", err)
}
defer conn.Close()
requestBody := types.NewRPCRequestBody("programSubscribe")
requestBody.Params = append(requestBody.Params, programID)
p := NewSubParam("jsonParsed")
requestBody.Params = append(requestBody.Params, p)
body, err := json.Marshal(requestBody)
logrus.Info(string(body))
if err != nil {
logrus.Errorf("Couldn't unmarshal parameters to request body %v", err)
}
subscriptionID, err := conn.Write(body)
if err != nil {
logrus.Errorf("Couldn't send a websocket request to Solana node %v", err)
}
logrus.Info("Websocket established with ProgramID:", programID)
logrus.Info("Subscription ID to drop websocket connection:", subscriptionID)
var msg []byte
var parsedSub *stypes.Subscription
for {
_, msg, err = conn.ReadMessage(msg[:0])
if err != nil {
break
}
json.Unmarshal(msg, &parsedSub)
logrus.Info("Subscription: ", parsedSub)
// 2) Save data from oracle event in redis cache
// 3) Start mining of Solana oracle event
}
}