Skip to content

Commit

Permalink
Added parsed transaction support
Browse files Browse the repository at this point in the history
  • Loading branch information
jubeless committed Nov 11, 2020
1 parent d82bfc7 commit 37d477e
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 31 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ require (
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/tools v0.0.0-20200601175630-2caf76543d99 // indirect
google.golang.org/api v0.15.0
gotest.tools v2.2.0+incompatible
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
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=
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=
Expand Down
15 changes: 15 additions & 0 deletions rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ func (c *Client) GetAccountDataIn(ctx context.Context, account solana.PublicKey,
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) {
obj := map[string]interface{}{
"encoding": "base64",
Expand Down
40 changes: 40 additions & 0 deletions rpc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (
"fmt"
"testing"

"gotest.tools/assert"

"go.uber.org/zap"

"github.com/dfuse-io/solana-go"
"github.com/stretchr/testify/require"
)
Expand All @@ -38,5 +42,41 @@ func TestClient_GetAccountInfo(t *testing.T) {
d, err = json.MarshalIndent(accInfo, "", " ")
require.NoError(t, err)
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 changes: 62 additions & 25 deletions rpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,19 @@ import (
"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 {
Context struct {
Slot solana.U64
} `json:"context,omitempty"`
}

///

type GetBalanceResult struct {
RPCContext
Value solana.U64 `json:"value"`
}

///

type GetSlotResult solana.U64

///

type GetRecentBlockhashResult struct {
RPCContext
Value BlockhashResult `json:"value"`
Expand All @@ -59,8 +45,6 @@ type FeeCalculator struct {
LamportsPerSignature solana.U64 `json:"lamportsPerSignature"`
}

///

type GetConfirmedBlockResult struct {
Blockhash solana.PublicKey `json:"blockhash"`
PreviousBlockhash solana.PublicKey `json:"previousBlockhash"` // could be zeroes if ledger was clean-up and this is unavailable
Expand All @@ -80,14 +64,24 @@ type TransactionWithMeta struct {
Meta *TransactionMeta `json:"meta,omitempty"`
}

type TransactionParsed struct {
Transaction *ParsedTransaction `json:"transaction"`
Meta *TransactionMeta `json:"meta,omitempty"`
}

type TransactionMeta struct {
Err interface{} `json:"err"`
Fee solana.U64 `json:"fee"`
PreBalances []solana.U64 `json:"preBalances"`
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 {
RPCContext
Expand All @@ -102,19 +96,28 @@ type Account struct {
RentEpoch solana.U64 `json:"rentEpoch"`
}

type KeyedAccount struct {
Pubkey solana.PublicKey `json:"pubkey"`
Account *Account `json:"account"`
}
type GetProgramAccountsResult []*KeyedAccount

type GetProgramAccountsOpts struct {
Commitment CommitmentType `json:"commitment,omitempty"`

// Filter on accounts, implicit AND between filters
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 {
Memcmp *RPCFilterMemcmp `json:"memcmp,omitempty"`
DataSize solana.U64 `json:"dataSize,omitempty"`
Expand All @@ -125,8 +128,6 @@ type RPCFilterMemcmp struct {
Bytes solana.Base58 `json:"bytes"`
}

///

type CommitmentType string

const (
Expand All @@ -136,3 +137,39 @@ const (
CommitmentSingle = CommitmentType("single")
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
}
6 changes: 3 additions & 3 deletions serum/rice-box.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions token/rice-box.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ func init() {
// define files
file2 := &embedded.EmbeddedFile{
Filename: "mainnet-tokens.json",
FileModTime: time.Unix(1604945427, 0),
FileModTime: time.Unix(1604945295, 0),

Content: string("[\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x476c5E26a75bd202a9683ffD34359C0CC15be0fF/logo.png\",\n \"mintAddress\": \"SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt\",\n \"tokenName\": \"Serum\",\n \"tokenSymbol\": \"SRM\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x476c5E26a75bd202a9683ffD34359C0CC15be0fF/logo.png\",\n \"mintAddress\": \"MSRMcoVyrFxnSgo5uXwone5SKcGhT1KEJMFEkMEWf9L\",\n \"tokenName\": \"MegaSerum\",\n \"tokenSymbol\": \"MSRM\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/bitcoin/info/logo.png\",\n \"mintAddress\": \"9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E\",\n \"tokenName\": \"Wrapped Bitcoin\",\n \"tokenSymbol\": \"BTC\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png\",\n \"mintAddress\": \"2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk\",\n \"tokenName\": \"Wrapped Ethereum\",\n \"tokenSymbol\": \"ETH\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/f3ffd0b9ae2165336279ce2f8db1981a55ce30f8/blockchains/ethereum/assets/0x50D1c9771902476076eCFc8B2A83Ad6b9355a4c9/logo.png\",\n \"mintAddress\": \"AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3\",\n \"tokenName\": \"Wrapped FTT\",\n \"tokenSymbol\": \"FTT\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e/logo.png\",\n \"mintAddress\": \"3JSf5tPeuscJGtaCp5giEiDhv51gQ4v3zWg8DGgyLfAB\",\n \"tokenName\": \"Wrapped YFI\",\n \"tokenSymbol\": \"YFI\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x514910771AF9Ca656af840dff83E8264EcF986CA/logo.png\",\n \"mintAddress\": \"CWE8jPTUYhdCTZYWPTe1o5DFqfdjzWKc9WKz6rSjQUdG\",\n \"tokenName\": \"Wrapped Chainlink\",\n \"tokenSymbol\": \"LINK\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ripple/info/logo.png\",\n \"mintAddress\": \"Ga2AXHpfAF6mv2ekZwcsJFqu7wB4NV331qNH7fW9Nst8\",\n \"tokenName\": \"Wrapped XRP\",\n \"tokenSymbol\": \"XRP\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/f3ffd0b9ae2165336279ce2f8db1981a55ce30f8/blockchains/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png\",\n \"mintAddress\": \"BQcdHdAQW1hczDbBi9hiegXAR7A98Q9jx3X3iBBBDiq4\",\n \"tokenName\": \"Wrapped USDT\",\n \"tokenSymbol\": \"USDT\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/f3ffd0b9ae2165336279ce2f8db1981a55ce30f8/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png\",\n \"mintAddress\": \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n \"tokenName\": \"USD Coin\",\n \"tokenSymbol\": \"USDC\"\n },\n {\n \"deprecated\": true,\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/f3ffd0b9ae2165336279ce2f8db1981a55ce30f8/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png\",\n \"mintAddress\": \"BXXkv6z8ykpG1yuvUDPgh732wzVHB69RnB9YgSYh3itW\",\n \"tokenName\": \"Wrapped USDC\",\n \"tokenSymbol\": \"WUSDC\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6B3595068778DD592e39A122f4f5a5cF09C90fE2/logo.png\",\n \"mintAddress\": \"AR1Mtgh7zAtxuxGd2XPovXPVjcSdY3i4rQYisNadjfKy\",\n \"tokenName\": \"Wrapped SUSHI\",\n \"tokenSymbol\": \"SUSHI\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/6996a371cd02f516506a8f092eeb29888501447c/blockchains/nuls/assets/NULSd6HgyZkiqLnBzTaeSQfx1TNg2cqbzq51h/logo.png\",\n \"mintAddress\": \"CsZ5LZkDS7h9TDKjrbL7VAwQZ9nsRu8vJLhRYfmGaN8K\",\n \"tokenName\": \"Wrapped ALEPH\",\n \"tokenSymbol\": \"ALEPH\"\n },\n {\n \"icon\": \"https://github.com/trustwallet/assets/raw/b0ab88654fe64848da80d982945e4db06e197d4f/blockchains/ethereum/assets/0x8CE9137d39326AD0cD6491fb5CC0CbA0e089b6A9/logo.png\",\n \"mintAddress\": \"SF3oTvfWzEP3DTwGSvUXRrGTvr75pdZNnBLAH9bzMuX\",\n \"tokenName\": \"Wrapped SXP\",\n \"tokenSymbol\": \"SXP\"\n },\n {\n \"mintAddress\": \"BtZQfWqDGbk9Wf2rXEiWyQBdBY1etnUUn6zEphvVS7yN\",\n \"tokenName\": \"Wrapped HGET\",\n \"tokenSymbol\": \"HGET\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/4c82c2a409f18a4dd96a504f967a55a8fe47026d/blockchains/smartchain/assets/0xd4CB328A82bDf5f03eB737f37Fa6B370aef3e888/logo.png\",\n \"mintAddress\": \"5Fu5UUgbjpUvdBveb3a1JTNirL8rXtiYeSMWvKjtUNQv\",\n \"tokenName\": \"Wrapped CREAM\",\n \"tokenSymbol\": \"CREAM\"\n },\n {\n \"mintAddress\": \"873KLxCbz7s9Kc4ZzgYRtNmhfkQrhfyWGZJBmyCbC3ei\",\n \"tokenName\": \"Wrapped UBXT\",\n \"tokenSymbol\": \"UBXT\"\n },\n {\n \"mintAddress\": \"HqB7uswoVg4suaQiDP3wjxob1G5WdZ144zhdStwMCq7e\",\n \"tokenName\": \"Wrapped HNT\",\n \"tokenSymbol\": \"HNT\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/6e375e4e5fb0ffe09ed001bae1ef8ca1d6c86034/blockchains/ethereum/assets/0xf8C3527CC04340b208C854E985240c02F7B7793f/logo.png\",\n \"mintAddress\": \"9S4t2NEAiJVMvPdRYKVrfJpBafPBLtvbvyS3DecojQHw\",\n \"tokenName\": \"Wrapped FRONT\",\n \"tokenSymbol\": \"FRONT\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/878dcab0fab90e6593bcb9b7d941be4915f287dc/blockchains/ethereum/assets/0xb2734a4Cec32C81FDE26B0024Ad3ceB8C9b34037/logo.png\",\n \"mintAddress\": \"6WNVCuxCGJzNjmMZoKyhZJwvJ5tYpsLyAtagzYASqBoF\",\n \"tokenName\": \"Wrapped AKRO\",\n \"tokenSymbol\": \"AKRO\"\n },\n {\n \"mintAddress\": \"DJafV9qemGp7mLMEn5wrfqaFwxsbLgUsGVS16zKRk9kc\",\n \"tokenName\": \"Wrapped HXRO\",\n \"tokenSymbol\": \"HXRO\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/08d734b5e6ec95227dc50efef3a9cdfea4c398a1/blockchains/ethereum/assets/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/logo.png\",\n \"mintAddress\": \"DEhAasscXF4kEGxFgJ3bq4PpVGp5wyUxMRvn6TzGVHaw\",\n \"tokenName\": \"Wrapped UNI\",\n \"tokenSymbol\": \"UNI\"\n },\n {\n \"mintAddress\": \"GeDS162t9yGJuLEHPWXXGrb1zwkzinCgRwnT8vHYjKza\",\n \"tokenName\": \"Wrapped MATH\",\n \"tokenSymbol\": \"MATH\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/08d734b5e6ec95227dc50efef3a9cdfea4c398a1/blockchains/tomochain/info/logo.png\",\n \"mintAddress\": \"GXMvfY2jpQctDqZ9RoU3oWPhufKiCcFEfchvYumtX7jd\",\n \"tokenName\": \"Wrapped TOMO\",\n \"tokenSymbol\": \"TOMO\"\n },\n {\n \"icon\": \"https://raw.githubusercontent.com/trustwallet/assets/2d2491130e6beda208ba4fc6df028a82a0106ab6/blockchains/ethereum/assets/0xB1f66997A5760428D3a87D68b90BfE0aE64121cC/logo.png\",\n \"mintAddress\": \"EqWCKXfs3x47uVosDpTRgFniThL9Y8iCztJaapxbEaVX\",\n \"tokenName\": \"Wrapped LUA\",\n \"tokenSymbol\": \"LUA\"\n }\n]\n"),
}

// define dirs
dir1 := &embedded.EmbeddedDir{
Filename: "",
DirModTime: time.Unix(1604945427, 0),
DirModTime: time.Unix(1604945295, 0),
ChildFiles: []*embedded.EmbeddedFile{
file2, // "mainnet-tokens.json"

Expand All @@ -32,7 +32,7 @@ func init() {
// register embeddedBox
embedded.RegisterEmbeddedBox(`mints-data`, &embedded.EmbeddedBox{
Name: `mints-data`,
Time: time.Unix(1604945427, 0),
Time: time.Unix(1604945295, 0),
Dirs: map[string]*embedded.EmbeddedDir{
"": dir1,
},
Expand Down

0 comments on commit 37d477e

Please sign in to comment.