Skip to content

Commit

Permalink
First draft of a Solana client.
Browse files Browse the repository at this point in the history
  • Loading branch information
abourget committed Jul 31, 2020
0 parents commit abb3e99
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Solana library for Go
48 changes: 48 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package solana

import (
"context"

"github.com/ybbus/jsonrpc"
)

type Client struct {
rpcURL string
rpcClient jsonrpc.RPCClient
}

func NewClient(rpcURL string) *Client {
rpcClient := jsonrpc.NewClient(rpcURL)
return &Client{
rpcURL: rpcURL,
rpcClient: rpcClient,
}
}

func (c *Client) GetBalance(ctx context.Context, publicKey string, commitment CommitmentType) (out *GetBalanceRPCResult, err error) {
params := []interface{}{publicKey}
if commitment != "" {
params = append(params, string(commitment))
}

err = c.rpcClient.CallFor(&out, "getBalance", params...)
if err != nil {
return nil, err
}

return
}

func (c *Client) GetAccountInfo(ctx context.Context, publicKey string, commitment CommitmentType) (out *GetAccountInfoRPCResult, err error) {
params := []interface{}{publicKey}
if commitment != "" {
params = append(params, string(commitment))
}

err = c.rpcClient.CallFor(&out, "getAccountInfo", params...)
if err != nil {
return nil, err
}

return
}
23 changes: 23 additions & 0 deletions cmd/slnc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"context"
"fmt"
"log"

"github.com/davecgh/go-spew/spew"
"github.com/dfuse-io/solana-go"
)

func main() {
ctx := context.Background()

c := solana.NewClient("http://api.mainnet-beta.solana.com/rpc")
resp, err := c.GetAccountInfo(ctx, "14e9wAw5bMKUZC9vmV3t6axNhpiJsNWBXJBH2xfzFsws", "")
if err != nil {
log.Fatalln("failed", err)
}

spew.Dump(resp)
fmt.Println("Resp:", resp.Value)
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/dfuse-io/solana-go

go 1.14

require (
github.com/davecgh/go-spew v1.1.1
github.com/mr-tron/base58 v1.2.0
github.com/onsi/gomega v1.10.1 // indirect
github.com/ybbus/jsonrpc v2.1.2+incompatible
)
57 changes: 57 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
github.com/KeisukeYamashita/jsonrpc v1.0.1 h1:Ev+JDank4hSe9e1886g1nTGoL4d7R/YywgvmzkSoPg8=
github.com/KeisukeYamashita/jsonrpc v1.0.1/go.mod h1:v79c0nyITsAYIkWSj0oLL6DWUGwvIvPmDAolu5EdewY=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37 h1:marA1XQDC7N870zmSFIoHZpIUduK80USeY0Rkuflgp4=
github.com/sourcegraph/jsonrpc2 v0.0.0-20200429184054-15c2290dcb37/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo=
github.com/ybbus/jsonrpc v1.1.1 h1:43DAq5ijbxDPEXmlNpAwT74vFBR5VxQRqRWhWQPz9O0=
github.com/ybbus/jsonrpc v2.1.2+incompatible h1:V4mkE9qhbDQ92/MLMIhlhMSbz8jNXdagC3xBR5NDwaQ=
github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
80 changes: 80 additions & 0 deletions nativetypes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package solana

import (
"encoding/json"
"errors"
"strconv"

"github.com/mr-tron/base58"
)

///

type Base58 []byte

func (t Base58) MarshalJSON() ([]byte, error) {
return json.Marshal(base58.Encode(t))
}

func (t *Base58) UnmarshalJSON(data []byte) (err error) {
var s string
err = json.Unmarshal(data, &s)
if err != nil {
return
}

*t, err = base58.Decode(s)
return
}

func (t Base58) String() string {
return base58.Encode(t)
}

///

type U64 uint64

func (i U64) MarshalJSON() (data []byte, err error) {
if i > 0xffffffff {
encodedInt, err := json.Marshal(uint64(i))
if err != nil {
return nil, err
}
data = append([]byte{'"'}, encodedInt...)
data = append(data, '"')
return data, nil
}
return json.Marshal(uint64(i))
}

func (i *U64) UnmarshalJSON(data []byte) error {
if len(data) == 0 {
return errors.New("empty value")
}

if data[0] == '"' {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}

val, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return err
}

*i = U64(val)

return nil
}

var v uint64
if err := json.Unmarshal(data, &v); err != nil {
return err
}

*i = U64(v)

return nil
}
41 changes: 41 additions & 0 deletions rpctypes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package solana

type ContactInfo struct {
Pubkey string `json:"pubkey"`
Gossip string `json:"gossip,omitempty"`
TPU string `json:"tpu,omitempty"`
RPC string `json:"rpc,omitempty"`
Version string `json:"version,omitempty"`
}

type RPCContext struct {
Context struct {
Slot U64
} `json:"context,omitempty"`
}
type GetBalanceRPCResult struct {
RPCContext
Value U64 `json:"value"`
}

type GetAccountInfoRPCResult struct {
RPCContext
Value *AccountInfoResult `json:"value"`
}
type AccountInfoResult struct {
Executable bool `json:"executable"`
Owner string `json:"owner"`
Lamports U64 `json:"lamports"`
Data Base58 `json:"data"`
RentEpoch U64 `json:"rentEpoch"`
}

type CommitmentType string

const (
CommitmentMax = CommitmentType("max")
CommitmentRecent = CommitmentType("recent")
CommitmentRoot = CommitmentType("root")
CommitmentSingle = CommitmentType("single")
CommitmentSingleGossip = CommitmentType("singleGossip")
)

0 comments on commit abb3e99

Please sign in to comment.