From 3b3760f0eb164693be6bad149715a4ff2b6d3204 Mon Sep 17 00:00:00 2001 From: Vladimir Shchukin Date: Thu, 23 Oct 2025 08:40:03 -0400 Subject: [PATCH 1/2] initial proposal --- pkg/types/chains/solana/lp_types.go | 157 ++++++++++++++ pkg/types/chains/solana/solana.go | 320 +++++++++++++++++++++++++++- pkg/types/relayer.go | 24 +++ 3 files changed, 499 insertions(+), 2 deletions(-) create mode 100644 pkg/types/chains/solana/lp_types.go diff --git a/pkg/types/chains/solana/lp_types.go b/pkg/types/chains/solana/lp_types.go new file mode 100644 index 0000000000..65698febad --- /dev/null +++ b/pkg/types/chains/solana/lp_types.go @@ -0,0 +1,157 @@ +package solana + +import "time" + +const EventSignatureLength = 8 + +type EventSignature [EventSignatureLength]byte + +type EventIdl EventIDLTypes + +type EventIDLTypes struct { + Event IdlEvent + Types IdlTypeDefSlice +} + +type IdlEvent struct { + Name string `json:"name"` + Fields []IdlEventField `json:"fields"` +} + +type IdlEventField struct { + Name string `json:"name"` + Type IdlType `json:"type"` + Index bool `json:"index"` +} + +type IdlTypeDefSlice []IdlTypeDef + +type IdlTypeDef struct { + Name string `json:"name"` + Type IdlTypeDefTy `json:"type"` +} + +type IdlTypeDefTy struct { + Kind IdlTypeDefTyKind `json:"kind"` + + Fields *IdlTypeDefStruct `json:"fields,omitempty"` + Variants IdlEnumVariantSlice `json:"variants,omitempty"` + Codec string `json:"codec,omitempty"` +} + +type IdlField struct { + Name string `json:"name"` + Docs []string `json:"docs"` // @custom + Type IdlType `json:"type"` +} + +type IdlEnumVariantSlice []IdlEnumVariant + +type IdlEnumVariant struct { + Name string `json:"name"` + Docs []string `json:"docs"` // @custom + Fields *IdlEnumFields `json:"fields,omitempty"` +} + +type IdlEnumFields struct { + IdlEnumFieldsNamed *IdlEnumFieldsNamed + IdlEnumFieldsTuple *IdlEnumFieldsTuple +} + +type IdlEnumFieldsNamed []IdlField + +type IdlEnumFieldsTuple []IdlType + +type IdlTypeDefStruct = []IdlField + +// Wrapper type: +type IdlType struct { + AsString IdlTypeAsString + AsIdlTypeVec *IdlTypeVec + asIdlTypeOption *IdlTypeOption + AsIdlTypeDefined *IdlTypeDefined + AsIdlTypeArray *IdlTypeArray +} +type IdlTypeAsString string + +const ( + IdlTypeBool IdlTypeAsString = "bool" + IdlTypeU8 IdlTypeAsString = "u8" + IdlTypeI8 IdlTypeAsString = "i8" + IdlTypeU16 IdlTypeAsString = "u16" + IdlTypeI16 IdlTypeAsString = "i16" + IdlTypeU32 IdlTypeAsString = "u32" + IdlTypeI32 IdlTypeAsString = "i32" + IdlTypeU64 IdlTypeAsString = "u64" + IdlTypeI64 IdlTypeAsString = "i64" + IdlTypeU128 IdlTypeAsString = "u128" + IdlTypeI128 IdlTypeAsString = "i128" + IdlTypeBytes IdlTypeAsString = "bytes" + IdlTypeString IdlTypeAsString = "string" + IdlTypePublicKey IdlTypeAsString = "publicKey" + + // Custom additions: + IdlTypeUnixTimestamp IdlTypeAsString = "unixTimestamp" + IdlTypeHash IdlTypeAsString = "hash" + IdlTypeDuration IdlTypeAsString = "duration" +) + +type IdlTypeVec struct { + Vec IdlType `json:"vec"` +} + +type IdlTypeOption struct { + Option IdlType `json:"option"` +} + +// User defined type. +type IdlTypeDefined struct { + Defined string `json:"defined"` +} + +// Wrapper type: +type IdlTypeArray struct { + Thing IdlType + Num int +} + +type IdlTypeDefTyKind string + +const ( + IdlTypeDefTyKindStruct IdlTypeDefTyKind = "struct" + IdlTypeDefTyKindEnum IdlTypeDefTyKind = "enum" + IdlTypeDefTyKindCustom IdlTypeDefTyKind = "custom" +) + +type SubKeyPaths [][]string + +// matches cache-filter +// this filter defines what logs should be cached +// cached logs can be retrieved with [types.SolanaService.QueryLogsFromCache] +type LPFilterQuery struct { + Name string + Address PublicKey + EventName string + EventSig EventSignature + StartingBlock int64 + EventIdl EventIdl + SubkeyPaths SubKeyPaths + Retention time.Duration + MaxLogsKept int64 + IncludeReverted bool +} + +// matches lp-parsed solana logs +type Log struct { + ChainID string + LogIndex int64 + BlockHash Hash + BlockNumber int64 + BlockTimestamp time.Time + Address PublicKey + EventSig EventSignature + TxHash Signature + Data []byte + SequenceNum int64 + Error *string +} diff --git a/pkg/types/chains/solana/solana.go b/pkg/types/chains/solana/solana.go index fd7b795a96..c955726534 100644 --- a/pkg/types/chains/solana/solana.go +++ b/pkg/types/chains/solana/solana.go @@ -1,14 +1,330 @@ package solana +import ( + "context" + "math/big" + + "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" +) + const ( PublicKeyLength = 32 + SignatureLength = 64 ) -// represents solana-style AccountsMeta +// represents solana-go PublicKey +type PublicKey [PublicKeyLength]byte + +// represents solana-go Signature +type Signature [SignatureLength]byte + +// represents solana-go Hash +type Hash PublicKey + +// represents solana-go AccountsMeta type AccountMeta struct { - PublicKey [PublicKeyLength]byte + PublicKey PublicKey IsWritable bool IsSigner bool } +// represents solana-go AccountMetaSlice type AccountMetaSlice []*AccountMeta + +// represents solana-go EncodingType +type EncodingType string + +const ( + EncodingBase58 EncodingType = "base58" // limited to Account data of less than 129 bytes + EncodingBase64 EncodingType = "base64" // will return base64 encoded data for Account data of any size + EncodingBase64Zstd EncodingType = "base64+zstd" // compresses the Account data using Zstandard and base64-encodes the result + + // attempts to use program-specific state parsers to + // return more human-readable and explicit account state data. + // If "jsonParsed" is requested but a parser cannot be found, + // the field falls back to "base64" encoding, detectable when the data field is type . + // Cannot be used if specifying dataSlice parameters (offset, length). + EncodingJSONParsed EncodingType = "jsonParsed" + + EncodingJSON EncodingType = "json" // NOTE: you're probably looking for EncodingJSONParsed +) + +// represents solana-go DataSlice +type DataSlice struct { + Offset *uint64 + Length *uint64 +} + +// represents solana-go GetAccountInfoOpts +type GetAccountInfoOpts struct { + // Encoding for Account data. + // Either "base58" (slow), "base64", "base64+zstd", or "jsonParsed". + // - "base58" is limited to Account data of less than 129 bytes. + // - "base64" will return base64 encoded data for Account data of any size. + // - "base64+zstd" compresses the Account data using Zstandard and base64-encodes the result. + // - "jsonParsed" encoding attempts to use program-specific state parsers to return more + // human-readable and explicit account state data. If "jsonParsed" is requested but a parser + // cannot be found, the field falls back to "base64" encoding, + // detectable when the data field is type . + // + // This parameter is optional. + Encoding EncodingType + + // Commitment requirement. + // + // This parameter is optional. Default value is Finalized + ConfidenceLevel primitives.ConfidenceLevel + + // dataSlice parameters for limiting returned account data: + // Limits the returned account data using the provided offset and length fields; + // only available for "base58", "base64" or "base64+zstd" encodings. + // + // This parameter is optional. + DataSlice *DataSlice + + // The minimum slot that the request can be evaluated at. + // This parameter is optional. + MinContextSlot *uint64 +} + +type Context struct { + Slot uint64 +} + +// represents solana-go RPCContext +type RPCContext struct { + Context Context +} + +// represents solana-go Account +type Account struct { + // Number of lamports assigned to this account + Lamports uint64 + + // Pubkey of the program this account has been assigned to + Owner PublicKey + + // Data associated with the account, either as encoded binary data or JSON format {: }, depending on encoding parameter + Data []byte // TODO + + // Boolean indicating if the account contains a program (and is strictly read-only) + Executable bool + + // The epoch at which this account will next owe rent + RentEpoch *big.Int + + // The amount of storage space required to store the token account + Space uint64 +} + +// represents solana-go TransactionDetailsType +type TransactionDetailsType string + +const ( + TransactionDetailsFull TransactionDetailsType = "full" + TransactionDetailsSignatures TransactionDetailsType = "signatures" + TransactionDetailsNone TransactionDetailsType = "none" + TransactionDetailsAccounts TransactionDetailsType = "accounts" +) + +type TransactionVersion int + +const ( + LegacyTransactionVersion TransactionVersion = -1 + legacyVersion = `"legacy"` +) + +type TransactionWithMeta struct { + // The slot this transaction was processed in. + Slot uint64 + + // Estimated production time, as Unix timestamp (seconds since the Unix epoch) + // of when the transaction was processed. + // Nil if not available. + BlockTime *UnixTimeSeconds + + Transaction *DataBytesOrJSON `json:"transaction"` + + // Transaction status metadata object + Meta *TransactionMeta `json:"meta,omitempty"` + Version TransactionVersion `json:"version"` +} + +// represents solana-go GetBlockOpts +type GetBlockOpts struct { + // Encoding for each returned Transaction, either "json", "jsonParsed", "base58" (slow), "base64". + // If parameter not provided, the default encoding is "json". + // - "jsonParsed" encoding attempts to use program-specific instruction parsers to return + // more human-readable and explicit data in the transaction.message.instructions list. + // - If "jsonParsed" is requested but a parser cannot be found, the instruction falls back + // to regular JSON encoding (accounts, data, and programIdIndex fields). + // + // This parameter is optional. + Encoding EncodingType + + // Level of transaction detail to return. + // If parameter not provided, the default detail level is "full". + // + // This parameter is optional. + TransactionDetails TransactionDetailsType + + // Whether to populate the rewards array. + // If parameter not provided, the default includes rewards. + // + // This parameter is optional. + Rewards *bool + + // "processed" is not supported. + // If parameter not provided, the default is "finalized". + // + // This parameter is optional. + ConfidenceLevel primitives.ConfidenceLevel + + // Max transaction version to return in responses. + // If the requested block contains a transaction with a higher version, an error will be returned. + MaxSupportedTransactionVersion *uint64 +} + +var ( + MaxSupportedTransactionVersion0 uint64 = 0 + MaxSupportedTransactionVersion1 uint64 = 1 +) + +// UnixTimeSeconds represents a UNIX second-resolution timestamp. +type UnixTimeSeconds int64 + +type GetMultipleAccountsOpts GetAccountInfoOpts + +type GetAccountInfoRequest struct { + Account PublicKey + Opts *GetAccountInfoOpts +} + +type GetAccountInfoReply struct { + RPCContext + Value *Account +} + +type GetMultipleAccountsRequest struct { + Accounts []PublicKey + Opts *GetMultipleAccountsOpts +} + +type GetMultipleAccountsReply struct { + RPCContext + Value []*Account +} + +type GetBlockTimeRequest struct { + //TODO +} + +type GetBlockTimeReply struct { + //TODO +} + +type GetBalanceRequest struct { + Addr PublicKey + ConfidenceLevel primitives.ConfidenceLevel +} + +type GetBalanceReply struct { + // Balance in lamports + Value uint64 +} + +type GetBlockRequest struct { + Slot uint64 + Opts *GetBlockOpts +} + +type GetBlockReply struct { + // The blockhash of this block. + Blockhash Hash + + // The blockhash of this block's parent; + // if the parent block is not available due to ledger cleanup, + // this field will return "11111111111111111111111111111111". + PreviousBlockhash Hash + + // The slot index of this block's parent. + ParentSlot uint64 + + // Present if "full" transaction details are requested. + Transactions []TransactionWithMeta + + // Present if "signatures" are requested for transaction details; + // an array of signatures, corresponding to the transaction order in the block. + Signatures []Signature + + // Estimated production time, as Unix timestamp (seconds since the Unix epoch). + // Nil if not available. + BlockTime *int64 + + // The number of blocks beneath this block. + BlockHeight *UnixTimeSeconds +} + +type GetBlockHeightRequest struct { + // TODO +} + +type GetBlockHeightReply struct { + // TODO +} + +type GetTransactionRequest struct { + // TODO +} + +type GetTransactionReply struct { + //TODO +} + +type GetFeeForMessageRequest struct { + //TODO +} + +type GetFeeForMessageReply struct { + //TODO +} + +type GetLatestBlockhashRequest struct { + // TODO +} + +type GetLatestBlockhashReply struct { + // TODO +} + +type Client interface { + GetAccountInfoWithOpts(ctx context.Context, req GetAccountInfoRequest) (*GetAccountInfoReply, error) + GetMultipleAccountsWithOpts(ctx context.Context, req GetMultipleAccountsRequest) (*GetMultipleAccountsReply, error) + GetBalance(ctx context.Context, req GetBalanceRequest) (*GetBalanceReply, error) + GetBlock(ctx context.Context, req GetBlockRequest) (*GetBlockReply, error) + GetBlockHeight(ctx context.Context, req GetBlockRequest) (*GetBlockHeightReply, error) + GetBlockTime(ctx context.Context, req GetBlockTimeRequest) (*GetBlockTimeReply, error) + GetTransaction(ctx context.Context, req GetTransactionRequest) (*GetTransactionReply, error) + GetFeeForMessage(ctx context.Context, req GetFeeForMessageRequest) (*GetFeeForMessageReply, error) + GetLatestBlockHash(ctx context.Context, req GetLatestBlockhashRequest) (*GetLatestBlockhashReply, error) +} + +type SubmitTransactionRequest struct { + Receiver PublicKey + + // base64 encoded transaction + Payload string +} + +// TransactionStatus is the result of the transaction sent to the chain +type TransactionStatus int + +const ( +// TODO define TransactionStatus enum +) + +type SubmitTransactionReply struct { + Signature Signature + IdempotencyKey string + Status TransactionStatus +} diff --git a/pkg/types/relayer.go b/pkg/types/relayer.go index f6112b948a..59aa8a1668 100644 --- a/pkg/types/relayer.go +++ b/pkg/types/relayer.go @@ -11,6 +11,7 @@ import ( "google.golang.org/grpc/status" "github.com/smartcontractkit/chainlink-common/pkg/types/chains/evm" + "github.com/smartcontractkit/chainlink-common/pkg/types/chains/solana" "github.com/smartcontractkit/chainlink-common/pkg/types/chains/ton" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" @@ -224,6 +225,29 @@ type TONService interface { UnregisterFilter(ctx context.Context, name string) error } +type SolanaService interface { + solana.Client + + SubmitTransaction(ctx context.Context, req solana.SubmitTransactionRequest) (*solana.SubmitTransactionReply, error) + + // RegisterLogTracking registers a persistent log filter for tracking and caching logs + // based on the provided filter parameters. Once registered, matching logs will be collected + // over time and stored in a cache for future querying. + // noop guaranteed when filter.Name exists + RegisterLogTracking(ctx context.Context, req solana.LPFilterQuery) error + + // UnregisterLogTracking removes a previously registered log filter by its name. + // After removal, logs matching this filter will no longer be collected or cached. + // noop guaranteed when filterName doesn't exist + UnregisterLogTracking(ctx context.Context, filterName string) error + + // QueryTrackedLogs retrieves logs from the log storage based on the provided + // query expression, sorting, and confidence level. It only returns logs that were + // collected through previously registered log filters. + QueryTrackedLogs(ctx context.Context, filterQuery []query.Expression, + limitAndSort query.LimitAndSort, confidenceLevel primitives.ConfidenceLevel) ([]*solana.Log, error) +} + // Relayer extends ChainService with providers for each product. type Relayer interface { ChainService From 7bd93c6cd4d3174133cd1c98bbe8651fdec6c0eb Mon Sep 17 00:00:00 2001 From: Vladimir Shchukin Date: Mon, 27 Oct 2025 07:11:15 -0400 Subject: [PATCH 2/2] define solana client types --- pkg/types/chains/solana/solana.go | 200 +++++++++++++++++++-------- pkg/types/chains/solana/txm_types.go | 31 +++++ pkg/types/relayer.go | 8 ++ 3 files changed, 185 insertions(+), 54 deletions(-) create mode 100644 pkg/types/chains/solana/txm_types.go diff --git a/pkg/types/chains/solana/solana.go b/pkg/types/chains/solana/solana.go index c955726534..ff2ff22b77 100644 --- a/pkg/types/chains/solana/solana.go +++ b/pkg/types/chains/solana/solana.go @@ -3,8 +3,6 @@ package solana import ( "context" "math/big" - - "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" ) const ( @@ -49,6 +47,25 @@ const ( EncodingJSON EncodingType = "json" // NOTE: you're probably looking for EncodingJSONParsed ) +// represents solana-go CommitmentType +type CommitmentType string + +const ( + // The node will query the most recent block confirmed by supermajority + // of the cluster as having reached maximum lockout, + // meaning the cluster has recognized this block as finalized. + CommitmentFinalized CommitmentType = "finalized" + + // The node will query the most recent block that has been voted on by supermajority of the cluster. + // - It incorporates votes from gossip and replay. + // - It does not count votes on descendants of a block, only direct votes on that block. + // - This confirmation level also upholds "optimistic confirmation" guarantees in release 1.3 and onwards. + CommitmentConfirmed CommitmentType = "confirmed" + + // The node will query its most recent block. Note that the block may still be skipped by the cluster. + CommitmentProcessed CommitmentType = "processed" +) + // represents solana-go DataSlice type DataSlice struct { Offset *uint64 @@ -73,7 +90,7 @@ type GetAccountInfoOpts struct { // Commitment requirement. // // This parameter is optional. Default value is Finalized - ConfidenceLevel primitives.ConfidenceLevel + Commitment CommitmentType // dataSlice parameters for limiting returned account data: // Limits the returned account data using the provided offset and length fields; @@ -105,7 +122,7 @@ type Account struct { Owner PublicKey // Data associated with the account, either as encoded binary data or JSON format {: }, depending on encoding parameter - Data []byte // TODO + Data *DataBytesOrJSON // Boolean indicating if the account contains a program (and is strictly read-only) Executable bool @@ -134,6 +151,14 @@ const ( legacyVersion = `"legacy"` ) +type ConfirmationStatusType string + +const ( + ConfirmationStatusProcessed ConfirmationStatusType = "processed" + ConfirmationStatusConfirmed ConfirmationStatusType = "confirmed" + ConfirmationStatusFinalized ConfirmationStatusType = "finalized" +) + type TransactionWithMeta struct { // The slot this transaction was processed in. Slot uint64 @@ -143,11 +168,12 @@ type TransactionWithMeta struct { // Nil if not available. BlockTime *UnixTimeSeconds - Transaction *DataBytesOrJSON `json:"transaction"` + // Encoded Transaction + Transaction *DataBytesOrJSON + // JSON encoded solana-go TransactionMeta + MetaJSON []byte - // Transaction status metadata object - Meta *TransactionMeta `json:"meta,omitempty"` - Version TransactionVersion `json:"version"` + Version TransactionVersion } // represents solana-go GetBlockOpts @@ -178,7 +204,7 @@ type GetBlockOpts struct { // If parameter not provided, the default is "finalized". // // This parameter is optional. - ConfidenceLevel primitives.ConfidenceLevel + Commitment CommitmentType // Max transaction version to return in responses. // If the requested block contains a transaction with a higher version, an error will be returned. @@ -195,6 +221,36 @@ type UnixTimeSeconds int64 type GetMultipleAccountsOpts GetAccountInfoOpts +type SimulateTransactionAccountsOpts struct { + // (optional) Encoding for returned Account data, + // either "base64" (default), "base64+zstd" or "jsonParsed". + // - "jsonParsed" encoding attempts to use program-specific state parsers + // to return more human-readable and explicit account state data. + // If "jsonParsed" is requested but a parser cannot be found, + // the field falls back to binary encoding, detectable when + // the data field is type . + Encoding EncodingType + + // An array of accounts to return. + Addresses []PublicKey +} + +type SimulateTXOpts struct { + // If true the transaction signatures will be verified + // (default: false, conflicts with ReplaceRecentBlockhash) + SigVerify bool + + // Commitment level to simulate the transaction at. + // (default: "finalized"). + Commitment CommitmentType + + // If true the transaction recent blockhash will be replaced with the most recent blockhash. + // (default: false, conflicts with SigVerify) + ReplaceRecentBlockhash bool + + Accounts *SimulateTransactionAccountsOpts +} + type GetAccountInfoRequest struct { Account PublicKey Opts *GetAccountInfoOpts @@ -215,17 +271,9 @@ type GetMultipleAccountsReply struct { Value []*Account } -type GetBlockTimeRequest struct { - //TODO -} - -type GetBlockTimeReply struct { - //TODO -} - type GetBalanceRequest struct { - Addr PublicKey - ConfidenceLevel primitives.ConfidenceLevel + Addr PublicKey + Commitment CommitmentType } type GetBalanceReply struct { @@ -238,6 +286,15 @@ type GetBlockRequest struct { Opts *GetBlockOpts } +// Will contain a AsJSON if the requested encoding is `solana.EncodingJSON` +// (which is also the default when the encoding is not specified), +// or a `AsDecodedBinary` in case of EncodingBase58, EncodingBase64. +type DataBytesOrJSON struct { + RawDataEncoding EncodingType + AsDecodedBinary []byte + AsJSON []byte +} + type GetBlockReply struct { // The blockhash of this block. Blockhash Hash @@ -259,72 +316,107 @@ type GetBlockReply struct { // Estimated production time, as Unix timestamp (seconds since the Unix epoch). // Nil if not available. - BlockTime *int64 + BlockTime *UnixTimeSeconds // The number of blocks beneath this block. - BlockHeight *UnixTimeSeconds + BlockHeight *uint64 } -type GetBlockHeightRequest struct { - // TODO +type GetSlotHeightRequest struct { + Commitment CommitmentType } -type GetBlockHeightReply struct { - // TODO +type GetSlotHeightReply struct { + Height uint64 } type GetTransactionRequest struct { - // TODO + Signature Signature } type GetTransactionReply struct { - //TODO + // Encoded TransactionResultEnvelope + Transaction []byte + + // JSON encoded TransactionMeta + Meta []byte } type GetFeeForMessageRequest struct { - //TODO + // base64 encoded message + Message string + Commitment CommitmentType } type GetFeeForMessageReply struct { - //TODO + // The amount in lamports the network will charge for a particular message + Fee uint64 } type GetLatestBlockhashRequest struct { - // TODO + Commitment CommitmentType } type GetLatestBlockhashReply struct { - // TODO + RPCContext + Hash Signature + LastValidBlockHeight uint64 } -type Client interface { - GetAccountInfoWithOpts(ctx context.Context, req GetAccountInfoRequest) (*GetAccountInfoReply, error) - GetMultipleAccountsWithOpts(ctx context.Context, req GetMultipleAccountsRequest) (*GetMultipleAccountsReply, error) - GetBalance(ctx context.Context, req GetBalanceRequest) (*GetBalanceReply, error) - GetBlock(ctx context.Context, req GetBlockRequest) (*GetBlockReply, error) - GetBlockHeight(ctx context.Context, req GetBlockRequest) (*GetBlockHeightReply, error) - GetBlockTime(ctx context.Context, req GetBlockTimeRequest) (*GetBlockTimeReply, error) - GetTransaction(ctx context.Context, req GetTransactionRequest) (*GetTransactionReply, error) - GetFeeForMessage(ctx context.Context, req GetFeeForMessageRequest) (*GetFeeForMessageReply, error) - GetLatestBlockHash(ctx context.Context, req GetLatestBlockhashRequest) (*GetLatestBlockhashReply, error) +type SimulateTXRequest struct { + Receiver PublicKey + EncodedTransaction string + Opts *SimulateTXOpts } -type SubmitTransactionRequest struct { - Receiver PublicKey +type SimulateTXReply struct { + // Error if transaction failed, null if transaction succeeded. + Err *string + + // Array of log messages the transaction instructions output during execution, + // null if simulation failed before the transaction was able to execute + // (for example due to an invalid blockhash or signature verification failure) + Logs []string + + // Array of accounts with the same length as the accounts.addresses array in the request. + Accounts []*Account - // base64 encoded transaction - Payload string + // The number of compute budget units consumed during the processing of this transaction. + UnitsConsumed *uint64 } -// TransactionStatus is the result of the transaction sent to the chain -type TransactionStatus int +type GetSignatureStatusesRequest struct { + Sigs []Signature +} -const ( -// TODO define TransactionStatus enum -) +type GetSignatureStatusesResult struct { + // The slot the transaction was processed. + Slot uint64 `json:"slot"` -type SubmitTransactionReply struct { - Signature Signature - IdempotencyKey string - Status TransactionStatus + // Number of blocks since signature confirmation, + // null if rooted or finalized by a supermajority of the cluster. + Confirmations *uint64 `json:"confirmations"` + + // Error if transaction failed, null if transaction succeeded. + Err *string + + // The transaction's cluster confirmation status; either processed, confirmed, or finalized. + ConfirmationStatus ConfirmationStatusType `json:"confirmationStatus"` +} + +type GetSignatureStatusesReply struct { + Results []GetSignatureStatusesResult +} + +type Client interface { + GetBalance(ctx context.Context, req GetBalanceRequest) (*GetBalanceReply, error) + GetAccountInfoWithOpts(ctx context.Context, req GetAccountInfoRequest) (*GetAccountInfoReply, error) + GetMultipleAccountsWithOpts(ctx context.Context, req GetMultipleAccountsRequest) (*GetMultipleAccountsReply, error) + GetBlock(ctx context.Context, req GetBlockRequest) (*GetBlockReply, error) + GetSlotHeight(ctx context.Context, req GetSlotHeightRequest) (*GetSlotHeightReply, error) + GetTransaction(ctx context.Context, req GetTransactionRequest) (*GetTransactionReply, error) + GetFeeForMessage(ctx context.Context, req GetFeeForMessageRequest) (*GetFeeForMessageReply, error) + GetLatestBlockhash(ctx context.Context, req GetLatestBlockhashRequest) (*GetLatestBlockhashReply, error) + GetSignatureStatuses(ctx context.Context, req GetSignatureStatusesRequest) (*GetSignatureStatusesReply, error) + SimulateTX(ctx context.Context, req SimulateTXRequest) (*SimulateTXReply, error) } diff --git a/pkg/types/chains/solana/txm_types.go b/pkg/types/chains/solana/txm_types.go new file mode 100644 index 0000000000..5426a8e08c --- /dev/null +++ b/pkg/types/chains/solana/txm_types.go @@ -0,0 +1,31 @@ +package solana + +type SubmitTransactionRequest struct { + Receiver PublicKey + EncodedTransaction string // base64 encoded transaction +} + +// TransactionStatus is the result of the transaction sent to the chain +type TransactionStatus int + +const ( + // Transaction processing failed due to a network issue, RPC issue, or other fatal error + TxFatal TransactionStatus = iota + // Transaction was sent successfully to the chain but the program execution was aborted + TxAborted + // Transaction was sent successfully to the chain, program was succesfully executed and mined into a block. + TxSuccess +) + +type ComputeConfig struct { + // Default to nil. If not specified the value configured in GasEstimator will be used + ComputeLimit *uint32 + // Default to nil. If not specified the value configured in GasEstimator will be used + ComputeMaxPrice *uint64 +} + +type SubmitTransactionReply struct { + Signature Signature + IdempotencyKey string + Status TransactionStatus +} diff --git a/pkg/types/relayer.go b/pkg/types/relayer.go index 59aa8a1668..7319217a38 100644 --- a/pkg/types/relayer.go +++ b/pkg/types/relayer.go @@ -228,6 +228,7 @@ type TONService interface { type SolanaService interface { solana.Client + // Submits a transaction to the chain. It will return once the transaction is finalized or an error occurs. SubmitTransaction(ctx context.Context, req solana.SubmitTransactionRequest) (*solana.SubmitTransactionReply, error) // RegisterLogTracking registers a persistent log filter for tracking and caching logs @@ -256,6 +257,9 @@ type Relayer interface { EVM() (EVMService, error) // TON returns TONService that provides access to TON specific functionalities TON() (TONService, error) + + Solana() (SolanaService, error) + // NewContractWriter returns a new ContractWriter. // The format of config depends on the implementation. NewContractWriter(ctx context.Context, config []byte) (ContractWriter, error) @@ -342,6 +346,10 @@ func (u *UnimplementedRelayer) TON() (TONService, error) { return nil, status.Errorf(codes.Unimplemented, "method TON not implemented") } +func (u *UnimplementedRelayer) Solana() (SolanaService, error) { + return nil, status.Errorf(codes.Unimplemented, "method TON not implemented") +} + func (u *UnimplementedRelayer) NewContractWriter(ctx context.Context, config []byte) (ContractWriter, error) { return nil, status.Errorf(codes.Unimplemented, "method NewContractWriter not implemented") }