Added parsed transaction support
This commit is contained in:
parent
d82bfc7ad3
commit
37d477eadf
1
go.mod
1
go.mod
|
@ -30,4 +30,5 @@ require (
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
golang.org/x/tools v0.0.0-20200601175630-2caf76543d99 // indirect
|
golang.org/x/tools v0.0.0-20200601175630-2caf76543d99 // indirect
|
||||||
google.golang.org/api v0.15.0
|
google.golang.org/api v0.15.0
|
||||||
|
gotest.tools v2.2.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
1
go.sum
1
go.sum
|
@ -607,6 +607,7 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
|
@ -118,6 +118,21 @@ func (c *Client) GetAccountDataIn(ctx context.Context, account solana.PublicKey,
|
||||||
return struc.Unpack(bytes.NewReader(resp.Value.Data), inVar)
|
return struc.Unpack(bytes.NewReader(resp.Value.Data), inVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetConfirmedTransaction(ctx context.Context, signature string) (out TransactionParsed, err error) {
|
||||||
|
params := []interface{}{signature, "jsonParsed"}
|
||||||
|
|
||||||
|
err = c.rpcClient.CallFor(&out, "getConfirmedTransaction", params...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetConfirmedSignaturesForAddress2(ctx context.Context, address solana.PublicKey, opts *GetConfirmedSignaturesForAddress2Opts) (out GetConfirmedSignaturesForAddress2Result, err error) {
|
||||||
|
|
||||||
|
params := []interface{}{address.String(), opts}
|
||||||
|
|
||||||
|
err = c.rpcClient.CallFor(&out, "getConfirmedSignaturesForAddress2", params...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) GetProgramAccounts(ctx context.Context, publicKey solana.PublicKey, opts *GetProgramAccountsOpts) (out GetProgramAccountsResult, err error) {
|
func (c *Client) GetProgramAccounts(ctx context.Context, publicKey solana.PublicKey, opts *GetProgramAccountsOpts) (out GetProgramAccountsResult, err error) {
|
||||||
obj := map[string]interface{}{
|
obj := map[string]interface{}{
|
||||||
"encoding": "base64",
|
"encoding": "base64",
|
||||||
|
|
|
@ -20,6 +20,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gotest.tools/assert"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/dfuse-io/solana-go"
|
"github.com/dfuse-io/solana-go"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -38,5 +42,41 @@ func TestClient_GetAccountInfo(t *testing.T) {
|
||||||
d, err = json.MarshalIndent(accInfo, "", " ")
|
d, err = json.MarshalIndent(accInfo, "", " ")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Println(string(d))
|
fmt.Println(string(d))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_GetConfirmedSignaturesForAddress2(t *testing.T) {
|
||||||
|
c := NewClient("http://api.mainnet-beta.solana.com:80/rpc")
|
||||||
|
account := solana.MustPublicKeyFromBase58("CG1XSWuXo2rw2SuHTRc54nihKvLKh4wMYi7oF3487LYt")
|
||||||
|
accInfo, err := c.GetConfirmedSignaturesForAddress2(context.Background(), account, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
d, err := json.MarshalIndent(accInfo, "", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
fmt.Println(string(d))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClient_GetConfirmedTransaction(t *testing.T) {
|
||||||
|
zlog, _ = zap.NewDevelopment()
|
||||||
|
c := NewClient("http://api.mainnet-beta.solana.com:80/rpc")
|
||||||
|
c.Debug = true
|
||||||
|
signature := "53hoZ98EsCMA6L63GWM65M3Bd3WqA4LxD8bcJkbKoKWhbJFqX9M1WZ4fSjt8bYyZn21NwNnV2A25zirBni9Qk6LR"
|
||||||
|
trx, err := c.GetConfirmedTransaction(context.Background(), signature)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
d, err := json.MarshalIndent(trx, "", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
fmt.Println(string(d))
|
||||||
|
|
||||||
|
assert.Equal(t, false, trx.Transaction.Message.Instructions[0].IsParsed())
|
||||||
|
|
||||||
|
signature = "4ZK6ofUodMP8NrB8RGkKFpXWVKMk5eqjkBTbq7DKiDu34gbdrpgctJHp3cU79ZGEBgTaohbjy56KJwhraVmgYq9i"
|
||||||
|
trx, err = c.GetConfirmedTransaction(context.Background(), signature)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
d, err = json.MarshalIndent(trx, "", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
fmt.Println(string(d))
|
||||||
|
|
||||||
|
assert.Equal(t, true, trx.Transaction.Message.Instructions[0].IsParsed())
|
||||||
|
}
|
||||||
|
|
87
rpc/types.go
87
rpc/types.go
|
@ -18,33 +18,19 @@ import (
|
||||||
"github.com/dfuse-io/solana-go"
|
"github.com/dfuse-io/solana-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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 {
|
type RPCContext struct {
|
||||||
Context struct {
|
Context struct {
|
||||||
Slot solana.U64
|
Slot solana.U64
|
||||||
} `json:"context,omitempty"`
|
} `json:"context,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
type GetBalanceResult struct {
|
type GetBalanceResult struct {
|
||||||
RPCContext
|
RPCContext
|
||||||
Value solana.U64 `json:"value"`
|
Value solana.U64 `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
type GetSlotResult solana.U64
|
type GetSlotResult solana.U64
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
type GetRecentBlockhashResult struct {
|
type GetRecentBlockhashResult struct {
|
||||||
RPCContext
|
RPCContext
|
||||||
Value BlockhashResult `json:"value"`
|
Value BlockhashResult `json:"value"`
|
||||||
|
@ -59,8 +45,6 @@ type FeeCalculator struct {
|
||||||
LamportsPerSignature solana.U64 `json:"lamportsPerSignature"`
|
LamportsPerSignature solana.U64 `json:"lamportsPerSignature"`
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
type GetConfirmedBlockResult struct {
|
type GetConfirmedBlockResult struct {
|
||||||
Blockhash solana.PublicKey `json:"blockhash"`
|
Blockhash solana.PublicKey `json:"blockhash"`
|
||||||
PreviousBlockhash solana.PublicKey `json:"previousBlockhash"` // could be zeroes if ledger was clean-up and this is unavailable
|
PreviousBlockhash solana.PublicKey `json:"previousBlockhash"` // could be zeroes if ledger was clean-up and this is unavailable
|
||||||
|
@ -80,6 +64,11 @@ type TransactionWithMeta struct {
|
||||||
Meta *TransactionMeta `json:"meta,omitempty"`
|
Meta *TransactionMeta `json:"meta,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TransactionParsed struct {
|
||||||
|
Transaction *ParsedTransaction `json:"transaction"`
|
||||||
|
Meta *TransactionMeta `json:"meta,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type TransactionMeta struct {
|
type TransactionMeta struct {
|
||||||
Err interface{} `json:"err"`
|
Err interface{} `json:"err"`
|
||||||
Fee solana.U64 `json:"fee"`
|
Fee solana.U64 `json:"fee"`
|
||||||
|
@ -87,7 +76,12 @@ type TransactionMeta struct {
|
||||||
PostBalances []solana.U64 `json:"postBalances"`
|
PostBalances []solana.U64 `json:"postBalances"`
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
type TransactionSignature struct {
|
||||||
|
Err interface{} `json:"err,omitempty"`
|
||||||
|
Memo string `json:"memo,omitempty"`
|
||||||
|
Signature string `json:"signature,omitempty"`
|
||||||
|
Slot solana.U64 `json:"slot,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type GetAccountInfoResult struct {
|
type GetAccountInfoResult struct {
|
||||||
RPCContext
|
RPCContext
|
||||||
|
@ -102,12 +96,6 @@ type Account struct {
|
||||||
RentEpoch solana.U64 `json:"rentEpoch"`
|
RentEpoch solana.U64 `json:"rentEpoch"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyedAccount struct {
|
|
||||||
Pubkey solana.PublicKey `json:"pubkey"`
|
|
||||||
Account *Account `json:"account"`
|
|
||||||
}
|
|
||||||
type GetProgramAccountsResult []*KeyedAccount
|
|
||||||
|
|
||||||
type GetProgramAccountsOpts struct {
|
type GetProgramAccountsOpts struct {
|
||||||
Commitment CommitmentType `json:"commitment,omitempty"`
|
Commitment CommitmentType `json:"commitment,omitempty"`
|
||||||
|
|
||||||
|
@ -115,6 +103,21 @@ type GetProgramAccountsOpts struct {
|
||||||
Filters []RPCFilter `json:"filters,omitempty"`
|
Filters []RPCFilter `json:"filters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetProgramAccountsResult []*KeyedAccount
|
||||||
|
|
||||||
|
type KeyedAccount struct {
|
||||||
|
Pubkey solana.PublicKey `json:"pubkey"`
|
||||||
|
Account *Account `json:"account"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetConfirmedSignaturesForAddress2Opts struct {
|
||||||
|
Limit uint64 `json:"limit,omitempty"`
|
||||||
|
Before string `json:"limit,omitempty"`
|
||||||
|
Until string `json:"until,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetConfirmedSignaturesForAddress2Result []*TransactionSignature
|
||||||
|
|
||||||
type RPCFilter struct {
|
type RPCFilter struct {
|
||||||
Memcmp *RPCFilterMemcmp `json:"memcmp,omitempty"`
|
Memcmp *RPCFilterMemcmp `json:"memcmp,omitempty"`
|
||||||
DataSize solana.U64 `json:"dataSize,omitempty"`
|
DataSize solana.U64 `json:"dataSize,omitempty"`
|
||||||
|
@ -125,8 +128,6 @@ type RPCFilterMemcmp struct {
|
||||||
Bytes solana.Base58 `json:"bytes"`
|
Bytes solana.Base58 `json:"bytes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
type CommitmentType string
|
type CommitmentType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -136,3 +137,39 @@ const (
|
||||||
CommitmentSingle = CommitmentType("single")
|
CommitmentSingle = CommitmentType("single")
|
||||||
CommitmentSingleGossip = CommitmentType("singleGossip")
|
CommitmentSingleGossip = CommitmentType("singleGossip")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/// Parsed Transaction
|
||||||
|
|
||||||
|
type ParsedTransaction struct {
|
||||||
|
Signatures []solana.Signature `json:"signatures"`
|
||||||
|
Message Message `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
AccountKeys []*AccountKey `json:"accountKeys"`
|
||||||
|
RecentBlockhash solana.PublicKey/* TODO: change to Hash */ `json:"recentBlockhash"`
|
||||||
|
Instructions []ParsedInstruction `json:"instructions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountKey struct {
|
||||||
|
PublicKey solana.PublicKey `json:"pubkey"`
|
||||||
|
Signer bool `json:"signer"`
|
||||||
|
Writable bool `json:"writable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParsedInstruction struct {
|
||||||
|
Accounts []solana.PublicKey `json:"accounts,omitempty"`
|
||||||
|
Data solana.Base58 `json:"data,omitempty"`
|
||||||
|
Parsed *InstructionInfo `json:"parsed,omitempty"`
|
||||||
|
Program string `json:"program,omitempty"`
|
||||||
|
ProgramID solana.PublicKey `json:"programId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InstructionInfo struct {
|
||||||
|
Info map[string]interface{} `json:"info"`
|
||||||
|
InstructionType string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ParsedInstruction) IsParsed() bool {
|
||||||
|
return p.Parsed != nil
|
||||||
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue