diff --git a/client/rpc_get_account_info.go b/client/rpc_get_account_info.go index c4126fb5..762e09a6 100644 --- a/client/rpc_get_account_info.go +++ b/client/rpc_get_account_info.go @@ -3,6 +3,7 @@ package client import ( "context" "encoding/base64" + "encoding/json" "fmt" "github.com/portto/solana-go-sdk/common" @@ -41,14 +42,35 @@ func convertAccountInfo(v rpc.AccountInfo) (AccountInfo, error) { }, nil } +func convertAccountInfoWithData(v rpc.AccountInfoWithData) (AccountInfo, error) { + if v == (rpc.AccountInfoWithData{}) { + return AccountInfo{}, nil + } + rawData, err := json.Marshal(v.Data) + if err != nil { + return AccountInfo{}, fmt.Errorf("failed to base64 decode data") + } + return AccountInfo{ + Lamports: v.Lamports, + Owner: common.PublicKeyFromString(v.Owner), + Executable: v.Executable, + RentEpoch: v.RentEpoch, + Data: rawData, + }, nil +} + type GetAccountInfoConfig struct { + Encoding rpc.AccountEncoding Commitment rpc.Commitment DataSlice *rpc.DataSlice } func (c GetAccountInfoConfig) toRpc() rpc.GetAccountInfoConfig { + if c.Encoding == "" { + c.Encoding = rpc.AccountEncodingBase64 + } return rpc.GetAccountInfoConfig{ - Encoding: rpc.AccountEncodingBase64, + Encoding: c.Encoding, Commitment: c.Commitment, DataSlice: c.DataSlice, } @@ -66,6 +88,14 @@ func (c *Client) GetAccountInfo(ctx context.Context, base58Addr string) (Account // GetAccountInfoWithConfig return account's info func (c *Client) GetAccountInfoWithConfig(ctx context.Context, base58Addr string, cfg GetAccountInfoConfig) (AccountInfo, error) { + if cfg.Encoding == rpc.AccountEncodingJsonParsed { + return process( + func() (rpc.JsonRpcResponse[rpc.ValueWithContext[rpc.AccountInfo]], error) { + return c.RpcClient.GetAccountInfoWithConfig(ctx, base58Addr, cfg.toRpc()) + }, + convertGetAccountInfoWithData, + ) + } return process( func() (rpc.JsonRpcResponse[rpc.ValueWithContext[rpc.AccountInfo]], error) { return c.RpcClient.GetAccountInfoWithConfig(ctx, base58Addr, cfg.toRpc()) @@ -78,7 +108,7 @@ func (c *Client) GetAccountInfoWithConfig(ctx context.Context, base58Addr string func (c *Client) GetAccountInfoAndContext(ctx context.Context, base58Addr string) (rpc.ValueWithContext[AccountInfo], error) { return process( func() (rpc.JsonRpcResponse[rpc.ValueWithContext[rpc.AccountInfo]], error) { - return c.RpcClient.GetAccountInfoWithConfig(ctx, base58Addr, GetAccountInfoConfig{}.toRpc()) + return c.RpcClient.GetAccountInfoWithConfig(ctx, base58Addr, GetAccountInfoConfig{Encoding: rpc.AccountEncodingBase64}.toRpc()) }, convertGetAccountInfoAndContext, ) @@ -98,6 +128,10 @@ func convertGetAccountInfo(v rpc.ValueWithContext[rpc.AccountInfo]) (AccountInfo return convertAccountInfo(v.Value) } +func convertGetAccountInfoWithData(v rpc.ValueWithContext[rpc.AccountInfoWithData]) (AccountInfo, error) { + return convertAccountInfoWithData(v.Value) +} + func convertGetAccountInfoAndContext(v rpc.ValueWithContext[rpc.AccountInfo]) (rpc.ValueWithContext[AccountInfo], error) { accountInfo, err := convertGetAccountInfo(v) if err != nil { diff --git a/rpc/types.go b/rpc/types.go index 9e32e541..eb71f915 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -46,6 +46,33 @@ type AccountInfo struct { Executable bool `json:"executable"` } +type AccountInfoWithData struct { + Lamports uint64 `json:"lamports"` + Owner string `json:"owner"` + Executable bool `json:"executable"` + RentEpoch uint64 `json:"rentEpoch"` + Data DataResultValue `json:"data"` +} + +type DataResultValue struct { + Program string `json:"program"` + Space uint64 `json:"space"` + Parsed ParseStruct `json:"parsed"` +} + +type ParseStruct struct { + Type string `json:"type"` + Info InfoStruct `json:"info"` +} + +type InfoStruct struct { + IsNative bool `json:"isNative"` + Mint string `json:"mint"` + Owner string `json:"owner"` + State string `json:"state"` + TokenAmount interface{} `json:"tokenAmount"` +} + type TokenAccountBalance struct { Amount string `json:"amount"` Decimals uint8 `json:"decimals"`