add: solana rpc, solana program subscription, miner beacon entries usage, fixed DioneStaking smart contract

This commit is contained in:
bahadylbekov 2020-11-13 17:04:10 +03:00
parent 4435868b42
commit 2551affae0
14 changed files with 217 additions and 65 deletions

View File

@ -64,13 +64,19 @@ func (m *Miner) MineTask(ctx context.Context, base *MiningBase, mb *MinerBase) (
logrus.Debug("attempting to mine the task at epoch: ", round)
prevEntry := mb.PrevBeaconEntry
bvals := mb.BeaconEntries
ticket, err := m.computeTicket(ctx, &prevEntry, base, mb)
rbase := prevEntry
if len(bvals) > 0 {
rbase = bvals[len(bvals)-1]
}
ticket, err := m.computeTicket(ctx, &rbase, base, mb)
if err != nil {
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
}
winner, err := IsRoundWinner(ctx, round, m.address, prevEntry, mb, m.api)
winner, err := IsRoundWinner(ctx, round, m.address, rbase, mb, m.api)
if err != nil {
return nil, xerrors.Errorf("failed to check if we win next round: %w", err)
}

2
docs/task-mining.md Normal file
View File

@ -0,0 +1,2 @@
# Mining in Dione network

View File

@ -2,7 +2,7 @@
Task is a computational unit in Dione oracle network. Miners computes the tasks by getting requests from Dione smart contracts on Ethereum chain and making cross-chain operations.
Every task has it's own epoch, miner address who computed the task information corresponding the Dione mining operations, payload that represents the state from another blockchain network, it's own signature etc. (Task types and origin types would be added shortly)
Every task has it's own epoch, miner address who computed the task, information corresponding the Dione mining operations, payload that represents the state from another blockchain network, it's own signature etc. (Task types and origin types would be added shortly)
```
type DioneTask struct {

View File

@ -106,15 +106,9 @@ contract DioneStaking is Ownable, ReentrancyGuard {
return _totalStake;
}
// disabled for security reason
// function minerStake(address _minerAddr) external view returns (uint256) {
// MinerInfo storage miner = minerInfo[_minerAddr];
// return miner.amount;
// }
function minerStake() external view returns (uint256) {
MinerInfo storage miner = minerInfo[msg.sender];
return miner.amount;
function minerStake(address _minerAddr) external view returns (uint256) {
MinerInfo storage miner = minerInfo[_minerAddr];
return miner.amount;
}
// Update miner reward in DIONE tokens, only can be executed by owner of the contract

4
go.mod
View File

@ -10,6 +10,7 @@ require (
github.com/cespare/cp v1.1.1 // indirect
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
github.com/dgrr/fastws v1.0.0
github.com/drand/drand v1.2.1
github.com/drand/kyber v1.1.5
github.com/elastic/gosigar v0.10.5 // indirect
@ -46,6 +47,7 @@ require (
github.com/raulk/clock v1.1.0
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/shengdoushi/base58 v1.0.0
github.com/sirupsen/logrus v1.7.0
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/spf13/viper v1.7.1
@ -54,12 +56,12 @@ require (
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
github.com/stretchr/testify v1.6.1
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
github.com/valyala/fasthttp v1.17.0
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
google.golang.org/protobuf v1.25.0 // indirect

20
go.sum
View File

@ -41,6 +41,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@ -151,6 +153,8 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdo
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrr/fastws v1.0.0 h1:FOSkzHJncrhAVUYtJkgT/mJ40wNom9RHpyWd5rPTFDI=
github.com/dgrr/fastws v1.0.0/go.mod h1:myCByhzpoGTt2o2yOaY3hkYf1htJFrdUURbaGsqfxGc=
github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
@ -469,6 +473,9 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -934,6 +941,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sercand/kuberesolver v2.1.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
github.com/sercand/kuberesolver v2.4.0+incompatible h1:WE2OlRf6wjLxHwNkkFLQGaZcVLEXjMjBPjjEU5vksH8=
github.com/sercand/kuberesolver v2.4.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
github.com/shengdoushi/base58 v1.0.0 h1:tGe4o6TmdXFJWoI31VoSWvuaKxf0Px3gqa3sUWhAxBs=
github.com/shengdoushi/base58 v1.0.0/go.mod h1:m5uIILfzcKMw6238iWAhP4l3s5+uXyF3+bJKUNhAL9I=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8=
@ -1018,6 +1027,12 @@ github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E=
github.com/valyala/fasthttp v1.17.0 h1:P8/koH4aSnJ4xbd0cUUFEGQs3jQqIxoDDyRQrUiAkqg=
github.com/valyala/fasthttp v1.17.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w=
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
@ -1181,6 +1196,7 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
@ -1188,6 +1204,7 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1260,12 +1277,15 @@ golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c h1:38q6VNPWR010vN82/SB121GujZNIfAUb4YttE2rhGuc=
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201027140754-0fcbb8f4928c h1:2+jF2APAgFgXJnYOQGDGGiRvvEo6OhqZGQf46n9xgEw=
golang.org/x/sys v0.0.0-20201027140754-0fcbb8f4928c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View File

@ -0,0 +1,27 @@
package models
import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
)
type FilecoinMsg struct {
Version uint64
To address.Address
From address.Address
Nonce uint64
Value abi.TokenAmount
GasLimit int64
GasFeeCap abi.TokenAmount
GasPremium abi.TokenAmount
Method abi.MethodNum
Params []byte
}
type FilMsgSignature *crypto.Signature

View File

@ -1,36 +0,0 @@
package rpc
import (
"bytes"
"fmt"
"net/http"
)
type infuraClient struct {
url string
apiKey string
network string
}
// NewInfuraClient returns a new infuraClient.
func NewInfuraClient(apiKey string, network string) Client {
return &infuraClient{
url: fmt.Sprintf("https://%s.infura.io/v3", network),
apiKey: apiKey,
network: network,
}
}
// HandleRequest implements the `Client` interface.
func (infura *infuraClient) HandleRequest(r *http.Request, data []byte) (*http.Response, error) {
apiKey := infura.apiKey
if apiKey == "" {
return nil, fmt.Errorf("Can't find any infura API keys")
}
client := http.Client{}
req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", infura.url, apiKey), bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Failed to construct Infura post request: %v", err)
}
return client.Do(req)
}

View File

@ -13,22 +13,6 @@ type LotusClient struct {
jwt string
}
type RequestBody struct {
Jsonrpc string
Method string
Params []string
ID int
}
func NewRequestBody(method string) *RequestBody {
return &RequestBody{
Jsonrpc: "2.0",
Method: method,
Params: []string{},
ID: 0,
}
}
// NewClient returns a new client.
func NewLotusClient(host string, token string) *LotusClient {
return &LotusClient{

View File

@ -2,6 +2,22 @@ package rpc
import "net/http"
type RequestBody struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params []string `json:"params"`
ID int `json:"id"`
}
func NewRequestBody(method string) *RequestBody {
return &RequestBody{
Jsonrpc: "2.0",
Method: method,
Params: []string{},
ID: 0,
}
}
type Client interface {
HandleRequest(r *http.Request, data []byte) (*http.Response, error)
}

89
solana/client.go Normal file
View File

@ -0,0 +1,89 @@
package solana
import (
"encoding/json"
"fmt"
"log"
"github.com/Secured-Finance/dione/rpc"
types "github.com/Secured-Finance/dione/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
}
// 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) (*fasthttp.Response, error) {
req := fasthttp.AcquireRequest()
req.SetRequestURI(c.url)
req.Header.SetMethod("POST")
req.Header.SetContentType("application/json")
requestBody := rpc.NewRequestBody("getConfirmedTransaction")
requestBody.Params = append(requestBody.Params, txHash, "base58")
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.Info(string(bodyBytes))
return resp, nil
}
func (c *SolanaClient) subsctibeOnProgram(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 := rpc.NewRequestBody("programSubscribe")
requestBody.Params = append(requestBody.Params, programID)
body, err := json.Marshal(requestBody)
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 *types.Subscription
for {
_, msg, err = conn.ReadMessage(msg[:0])
if err != nil {
break
}
json.Unmarshal(msg, &parsedSub)
logrus.Info("Subscription: ", parsedSub)
// TODO: 1) Unmarshal base58 data to program structure in order to read data
// 2) Save data from oracle event in redis cache
// 3) Start mining of Solana oracle event
}
}

6
solana/types/error.go Normal file
View File

@ -0,0 +1,6 @@
package types
type Error struct {
Code int64 `json:"code"`
Message string `json:"message"`
}

8
solana/types/response.go Normal file
View File

@ -0,0 +1,8 @@
package types
type SolanaResponse struct {
Jsonrpc string `json:"jsonrpc"`
Result []byte `json:"result"`
Error Error `json:"error"`
ID int64 `json:"id"`
}

View File

@ -0,0 +1,34 @@
package types
type Subscription struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params Params `json:"params"`
}
type Params struct {
Result Result `json:"result"`
Subscription int `json:"subscription"`
}
type Result struct {
Context Context `json:"context"`
Value Value `json:"value"`
}
type Context struct {
Slot int `json:"slot"`
}
type Value struct {
Pubkey string `json:"pubkey"`
Account Account `json:"account"`
}
type Account struct {
Data string `json:"data"`
Executable bool `json:"executable"`
Lamports int `json:"lamports"`
Owner string `json:"owner"`
RentEpoch int `json:"rentEpoch"`
}