Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
380 changes: 338 additions & 42 deletions chain_capabilities/solana/actions/actions.go

Large diffs are not rendered by default.

796 changes: 783 additions & 13 deletions chain_capabilities/solana/actions/actions_test.go

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions chain_capabilities/solana/actions/write_report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func createMocksAndCapability(t *testing.T, lggr logger.Logger) *testHelper {
mockTrInfo := NewTransmissionInfoProvider_mock(t)
mockClient := NewCREForwarderClient_mock(t)
service := &Solana{
SolanaService: mockSolanaService,
SolanaService: mocks.WrapSolanaService(mockSolanaService),
forwarderClient: mockClient,
transmissionInfoProvider: mockTrInfo,
beholderProcessor: NopBeholderProcessor{},
Expand Down Expand Up @@ -736,7 +736,7 @@ func TestGetFee(t *testing.T) {
mockSolanaService := mocks.NewSolanaService(t)

wr := &WriteReport{
SolanaService: mockSolanaService,
SolanaService: mocks.WrapSolanaService(mockSolanaService),
lggr: testLogger,
}

Expand All @@ -756,7 +756,7 @@ func TestGetFee(t *testing.T) {
mockSolanaService := mocks.NewSolanaService(t)

wr := &WriteReport{
SolanaService: mockSolanaService,
SolanaService: mocks.WrapSolanaService(mockSolanaService),
lggr: testLogger,
}

Expand All @@ -776,7 +776,7 @@ func TestGetFee(t *testing.T) {
mockSolanaService := mocks.NewSolanaService(t)

wr := &WriteReport{
SolanaService: mockSolanaService,
SolanaService: mocks.WrapSolanaService(mockSolanaService),
lggr: testLogger,
}

Expand Down
16 changes: 8 additions & 8 deletions chain_capabilities/solana/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/smartcontractkit/capabilities/chain_capabilities/solana

go 1.26.2
go 1.26.3

require (
github.com/gagliardetto/solana-go v1.14.0
Expand All @@ -9,10 +9,10 @@ require (
github.com/smartcontractkit/capabilities/chain_capabilities/common v0.0.0-20260615195421-fb87220e503f
github.com/smartcontractkit/capabilities/libs v0.0.0-20260609124022-2749e4a32bfb
github.com/smartcontractkit/chain-selectors v1.0.100
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260602135221-cc7a5b50532a
github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20260326180413-c69f27e37a13
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260526195338-adcf8013a1b7
github.com/smartcontractkit/chainlink-solana v1.1.2-0.20260420191419-ea62f88cbdb4
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260713160348-3e9ebef19093
github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20260521164805-26d78d5e1243
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260622152157-c8e129347b8b
github.com/smartcontractkit/chainlink-solana v1.3.1-0.20260710051325-0fdf1bb70f47
github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260421131224-c46cbfe7bc6c
github.com/smartcontractkit/libocr v0.0.0-20260403184524-b6409238958d
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -131,10 +131,10 @@ require (
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260317185256-d5f7db87ae70 // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260310183131-8d0f0e383288 // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260310183131-8d0f0e383288 // indirect
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260601211238-9f526774fef0 // indirect
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15 // indirect
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260626151909-052e55e62e62 // indirect
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20260521164805-26d78d5e1243 // indirect
github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260319180422-b5808c964785 // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260709145319-7782fb89eb16 // indirect
github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad // indirect
github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect
Expand Down
28 changes: 14 additions & 14 deletions chain_capabilities/solana/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 38 additions & 3 deletions chain_capabilities/solana/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
caperrors "github.com/smartcontractkit/chainlink-common/pkg/capabilities/errors"
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/solana"
solcapserver "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/solana/server"
capmon "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/monitoring"
)

const (
Expand Down Expand Up @@ -67,7 +68,7 @@ var _ solcapserver.ClientCapability = &capabilityGRPCService{}
func main() {
loopserver.ServeNew(CapabilityName, func(s *loop.Server) loop.StandardCapabilities {
return solcapserver.NewClientServer(&capabilityGRPCService{lggr: s.Logger.Named(CapabilityName), limitsFactory: s.LimitsFactory})
})
}, loop.WithOtelViews(append(consMetrics.MetricViews(), capmon.MetricViews()...)))
}

func (c *capabilityGRPCService) ChainSelector() uint64 {
Expand Down Expand Up @@ -103,6 +104,9 @@ func (c *capabilityGRPCService) Close() error {
if c.triggerService != nil {
closers = append(closers, c.triggerService)
}
if c.Solana != nil {
closers = append(closers, c.Solana)
}
return services.CloseAll(closers...)
}

Expand All @@ -125,6 +129,7 @@ func (c *capabilityGRPCService) Description() string {
func (c *capabilityGRPCService) Ready() error {
return nil
}

func (c *capabilityGRPCService) Initialise(ctx context.Context, dependencies core.StandardCapabilitiesDependencies) error {
c.lggr.Infof("Initialising %s", CapabilityName)

Expand All @@ -150,10 +155,17 @@ func (c *capabilityGRPCService) Initialise(ctx context.Context, dependencies cor
}

c.id = "solana" + ":ChainSelector:" + strconv.FormatUint(c.chainSelector, 10) + "@1.0.0"
c.CapabilityInfo = capabilities.CapabilityInfo{
ID: c.id,
CapabilityType: capabilities.CapabilityTypeCombined,
Description: c.Description(),
IsLocal: cfg.IsLocal,
}

var chainInfo types.ChainInfo
// protection for e2e tests when we run against local validator
if !cfg.IsLocal {
if cfg.IsLocal {
chainInfo = localChainInfo(cfg, c.chainSelector)
} else {
chainInfo, err = relayer.GetChainInfo(ctx)
if err != nil {
return fmt.Errorf("failed to fetch chain info for chainID %s from relayer: %w", cfg.ChainID, err)
Expand Down Expand Up @@ -270,6 +282,29 @@ func (s *capabilityGRPCService) setSelector(cfg *config.Config) error {
return nil
}

// localChainInfo builds monitoring labels for local CRE runs where the relayer
// cannot resolve chain metadata from a fixed genesis hash.
func localChainInfo(cfg *config.Config, chainSelector uint64) types.ChainInfo {
chainID := cfg.ChainID
if chainID == "" {
chainID = strconv.FormatUint(chainSelector, 10)
}

networkName := cfg.Network
if networkName == "" {
networkName = "local"
}

networkNameFull := networkName + "-local"

return types.ChainInfo{
FamilyName: "solana",
ChainID: chainID,
NetworkName: networkName,
NetworkNameFull: networkNameFull,
}
}

func (c *capabilityGRPCService) unmarshalConfig(configStr string) (*config.Config, error) {
var cfg config.Config
if err := json.Unmarshal([]byte(configStr), &cfg); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions chain_capabilities/solana/monitoring/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/smartcontractkit/chainlink-common/pkg/capabilities"
solanacappb "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/solana"
capmon "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/monitoring"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/types/chains/solana"

Expand All @@ -36,6 +37,18 @@ func NewMessageBuilder(chainInfo types.ChainInfo, capInfo capabilities.Capabilit
}
}

// CapabilityMetricsAttributes returns capability-scoped OTel labels for v2 action metrics.
func (m *MessageBuilder) CapabilityMetricsAttributes() []attribute.KeyValue {
return []attribute.KeyValue{
attribute.String(capmon.LabelChainFamilyName, capmon.ValOrUnknown(m.ChainInfo.FamilyName)),
attribute.String(capmon.LabelChainID, capmon.ValOrUnknown(m.ChainInfo.ChainID)),
attribute.String(capmon.LabelNetworkName, capmon.ValOrUnknown(m.ChainInfo.NetworkName)),
attribute.String(capmon.LabelNetworkNameFull, capmon.ValOrUnknown(m.ChainInfo.NetworkNameFull)),
attribute.String(capmon.LabelCapabilityType, capmon.ValOrUnknown(string(m.CapInfo.CapabilityType))),
attribute.String(capmon.LabelCapabilityID, capmon.ValOrUnknown(m.CapInfo.ID)),
}
}

func (m *MessageBuilder) BuildWriteReportTxFeeCalculationError(tc TelemetryContext, req *solcap.WriteReportRequest, signature solgo.Signature, cause string) ErrorMessage {
summary := "Failed to calculate transaction fee"
if !signature.IsZero() {
Expand Down
Loading
Loading