Added parsed transaction support

This commit is contained in:
Julien Cassis 2020-11-11 14:38:52 -05:00
parent d82bfc7ad3
commit 37d477eadf
7 changed files with 125 additions and 31 deletions

1
go.mod
View File

@ -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
View File

@ -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=

View File

@ -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",

View File

@ -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())
}

View File

@ -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