Skip to content
Merged
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
25 changes: 13 additions & 12 deletions cmd/sncli/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package cli

import (
"context"
"fmt"
"log"
"os"
"fmt"
"time"

"github.com/BurntSushi/toml"
Expand All @@ -23,7 +23,7 @@ const (
// defaultConfigFileName is the default path to the configuration file.
defaultConfigFileName = "config.toml"

// defaultConfigFolder is the default folder for configuration files.
// defaultConfigFolder is the default folder for configuration files.
defaultConfigFolder = "~/.sncli"
)

Expand Down Expand Up @@ -74,9 +74,9 @@ func (c *CLI) loadCLIConfig() error {
_, err := toml.DecodeFile(path, &c.CfgOpts)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("Config file not found at %s", path)
return fmt.Errorf("config file not found at %s", path)
}
return fmt.Errorf("Failed to load config from %s: %v", path, err)
return fmt.Errorf("failed to load config from %s: %v", path, err)
}
c.ConfigPath = path

Expand Down Expand Up @@ -120,9 +120,8 @@ func (c *CLI) Initialize() error {
// Create Lumera client adapter
c.SdkConfig = sdkcfg.NewConfig(
sdkcfg.AccountConfig{
LocalCosmosAddress: c.CfgOpts.Keyring.LocalAddress,
KeyName: c.CfgOpts.Keyring.KeyName,
Keyring: c.kr,
KeyName: c.CfgOpts.Keyring.KeyName,
Keyring: c.kr,
},
sdkcfg.LumeraConfig{
GRPCAddr: c.CfgOpts.Lumera.GRPCAddr,
Expand Down Expand Up @@ -167,18 +166,20 @@ func (c *CLI) snClientInit() {
GrpcEndpoint: c.CfgOpts.Supernode.GRPCEndpoint,
}

clientFactory := sdknet.NewClientFactory(
clientFactory, err := sdknet.NewClientFactory(
context.Background(),
sdklog.NewNoopLogger(),
c.kr,
c.lumeraClient,
sdknet.FactoryConfig{
LocalCosmosAddress: c.CfgOpts.Keyring.LocalAddress,
PeerType: 1, // Simplenode
KeyName: c.SdkConfig.Account.KeyName,
PeerType: 1, // Simplenode
},
)
if err != nil {
log.Fatalf("Failed to create client factory: %v", err)
}

var err error
c.snClient, err = clientFactory.CreateClient(context.Background(), supernode)
if err != nil {
log.Fatalf("Supernode client init failed: %v", err)
Expand All @@ -190,4 +191,4 @@ func (c *CLI) P2PPing(timeout time.Duration) error {
return fmt.Errorf("P2P: not initialized")
}
return c.p2p.Ping(timeout)
}
}
2 changes: 1 addition & 1 deletion cmd/sncli/cli/cmd_get_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func (c *CLI) GetSupernodeStatus() error {

resp, err := c.snClient.GetSupernodeStatus(context.Background())
if err != nil {
return fmt.Errorf("Get supernode status failed: %v", err)
return fmt.Errorf("get supernode status failed: %v", err)
}
fmt.Println("Supernode Status:")
fmt.Printf(" Version: %s\n", resp.Version)
Expand Down
2 changes: 1 addition & 1 deletion cmd/sncli/cli/cmd_health_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func (c *CLI) HealthCheck() error {

resp, err := c.snClient.HealthCheck(context.Background())
if err != nil {
return fmt.Errorf("Supernode health check failed: %v", err)
return fmt.Errorf("supernode health check failed: %v", err)
}
fmt.Println("✅ Health status:", resp.Status)
return nil
Expand Down
19 changes: 2 additions & 17 deletions cmd/sncli/cli/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import (
"os"
"path/filepath"
"strings"
"net"
"strconv"
"fmt"
)

func NormalizePath(path string) string {
Expand All @@ -17,11 +14,11 @@ func NormalizePath(path string) string {
if strings.HasPrefix(path, "~") {
home, err := os.UserHomeDir()
if err != nil {
log.Fatalf("Unable to resolve home directory: %v", err)
log.Fatalf("unable to resolve home directory: %v", err)
}
path = filepath.Join(home, path[1:])
}
path = filepath.Clean(path)
path = filepath.Clean(path)
return path
}

Expand All @@ -34,15 +31,3 @@ func processConfigPath(path string) string {
path = filepath.Clean(path)
return path
}

func splitHostPort(hp string) (string, int, error) {
host, portStr, err := net.SplitHostPort(hp)
if err != nil {
return "", 0, err
}
p, err := strconv.Atoi(portStr)
if err != nil || p <= 0 || p > 65535 {
return "", 0, fmt.Errorf("invalid port: %s", portStr)
}
return host, p, nil
}
2 changes: 1 addition & 1 deletion cmd/sncli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ replace (

require (
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c
github.com/LumeraProtocol/lumera v1.8.0
github.com/LumeraProtocol/lumera v1.8.4
github.com/LumeraProtocol/supernode/v2 v2.3.88
github.com/cosmos/cosmos-sdk v0.53.0
github.com/spf13/cobra v1.10.1
Expand Down
4 changes: 2 additions & 2 deletions cmd/sncli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/LumeraProtocol/lumera v1.8.0 h1:0t5/6qOSs9wKti7utPAWo9Jq8wk2X+L/eEaH8flk/Hc=
github.com/LumeraProtocol/lumera v1.8.0/go.mod h1:38uAZxxleZyXaWKbqOQKwjw7CSX92lTxdF+B7c4SRPw=
github.com/LumeraProtocol/lumera v1.8.4 h1:6XzLS9gd0m3lOnppNS05WuZx4VCBEGvUN/KpVkSjqro=
github.com/LumeraProtocol/lumera v1.8.4/go.mod h1:twrSLfuXcHvmfQoN5e02Bg7rfeevUjF34SVqEJIvH1E=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
Expand Down
4 changes: 0 additions & 4 deletions sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ import (

// Account configuration
accountConfig := config.AccountConfig{
LocalCosmosAddress: "lumera1abc...", // Your cosmos address
KeyName: "my-key", // Key name in keyring
Keyring: keyring, // Cosmos SDK keyring instance
// PeerType is optional - defaults to SIMPLENODE when omitted (recommended for most users)
Expand All @@ -98,7 +97,6 @@ if err := sdkConfig.Validate(); err != nil {
### Required Fields

**AccountConfig:**
- `LocalCosmosAddress`: Your Lumera cosmos address (e.g., "lumera1abc...")
- `KeyName`: Name of the key in your keyring
- `Keyring`: Initialized Cosmos SDK keyring containing your keys
- `PeerType`: Peer type from securekeyx (optional, defaults to SIMPLENODE when left empty, which is suitable for most use cases)
Expand Down Expand Up @@ -129,7 +127,6 @@ kr, err := keyring.New("app-name", "file", "/path/to/keys", nil)
```go
config := config.NewConfig(
config.AccountConfig{
LocalCosmosAddress: "lumera1...",
KeyName: "my-key",
Keyring: keyring,
},
Expand Down Expand Up @@ -158,7 +155,6 @@ import (

// Set up configuration
accountConfig := config.AccountConfig{
LocalCosmosAddress: "lumera1...", // Your cosmos address
KeyName: "your-key", // Name of the key in your keyring
Keyring: keyring, // Cosmos SDK keyring instance
}
Expand Down
28 changes: 24 additions & 4 deletions sdk/action/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type ClientImpl struct {
logger log.Logger
keyring keyring.Keyring
lumeraClient lumera.Client
signerAddr string
}

// Verify interface compliance at compile time
Expand All @@ -71,6 +72,11 @@ func NewClient(ctx context.Context, config config.Config, logger log.Logger) (Cl
logger = log.NewNoopLogger()
}

addr, err := keyringpkg.GetAddress(config.Account.Keyring, config.Account.KeyName)
if err != nil {
return nil, fmt.Errorf("resolve signer address: %w", err)
}

// Create lumera client once
lumeraClient, err := lumera.NewAdapter(ctx,
lumera.ConfigParams{
Expand All @@ -96,6 +102,7 @@ func NewClient(ctx context.Context, config config.Config, logger log.Logger) (Cl
logger: logger,
keyring: config.Account.Keyring,
lumeraClient: lumeraClient,
signerAddr: addr.String(),
}, nil
}

Expand Down Expand Up @@ -196,10 +203,14 @@ func (c *ClientImpl) GetSupernodeStatus(ctx context.Context, supernodeAddress st
}

// Create network client factory
clientFactory := net.NewClientFactory(ctx, c.logger, c.keyring, c.lumeraClient, net.FactoryConfig{
LocalCosmosAddress: c.config.Account.LocalCosmosAddress,
PeerType: c.config.Account.PeerType,
clientFactory, err := net.NewClientFactory(ctx, c.logger, c.keyring, c.lumeraClient, net.FactoryConfig{
KeyName: c.config.Account.KeyName,
PeerType: c.config.Account.PeerType,
})
if err != nil {
c.logger.Error(ctx, "Failed to create client factory", "error", err)
return nil, fmt.Errorf("failed to create client factory: %w", err)
}

// Create client for the specific supernode
supernodeClient, err := clientFactory.CreateClient(ctx, lumeraSupernode)
Expand Down Expand Up @@ -278,13 +289,18 @@ func (c *ClientImpl) BuildCascadeMetadataFromFile(ctx context.Context, filePath
// Create signatures from the layout struct
// get bech32 address for this key

indexSignatureFormat, _, err := cascadekit.CreateSignaturesWithKeyringADR36(
indexSignatureFormat, _, err := cascadekit.CreateSignaturesWithKeyring(
layout,
c.keyring,
c.config.Account.KeyName,
ic,
max,
)

if err != nil {
return actiontypes.CascadeMetadata{}, "", "", fmt.Errorf("create signatures: %w", err)
}

// Compute data hash (blake3) as base64 using a streaming file hash to avoid loading entire file
h, err := utils.Blake3HashFile(filePath)
if err != nil {
Expand Down Expand Up @@ -350,3 +366,7 @@ func (c *ClientImpl) GenerateDownloadSignature(ctx context.Context, actionID, cr
}
return base64.StdEncoding.EncodeToString(sig), nil
}

func (c *ClientImpl) signerAddress() string {
return c.signerAddr
}
9 changes: 3 additions & 6 deletions sdk/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import (

// AccountConfig holds peer-to-peer addresses, ports, etc.
type AccountConfig struct {
LocalCosmosAddress string
KeyName string
Keyring cosmoskeyring.Keyring
PeerType securekeyx.PeerType
KeyName string
Keyring cosmoskeyring.Keyring
PeerType securekeyx.PeerType
}

// LumeraConfig wraps all chain-specific dials.
Expand All @@ -35,8 +34,6 @@ func NewConfig(account AccountConfig, lumera LumeraConfig) Config {

func (c Config) Validate() error {
switch {
case c.Account.LocalCosmosAddress == "":
return errors.New("config: Network.LocalCosmosAddress is required")
case c.Lumera.GRPCAddr == "":
return errors.New("config: Lumera.GRPCAddr is required")
case c.Lumera.ChainID == "":
Expand Down
21 changes: 15 additions & 6 deletions sdk/net/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (
"github.com/LumeraProtocol/supernode/v2/sdk/adapters/lumera"
"github.com/LumeraProtocol/supernode/v2/sdk/log"

keyringpkg "github.com/LumeraProtocol/supernode/v2/pkg/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
)

// FactoryConfig contains configuration for the ClientFactory
type FactoryConfig struct {
LocalCosmosAddress string
PeerType securekeyx.PeerType
KeyName string
PeerType securekeyx.PeerType
}

// ClientFactory creates and manages supernode clients
Expand All @@ -25,16 +26,23 @@ type ClientFactory struct {
clientOptions *client.ClientOptions
config FactoryConfig
lumeraClient lumera.Client
signerAddr string
}

// NewClientFactory creates a new client factory with the provided dependencies
func NewClientFactory(ctx context.Context, logger log.Logger, keyring keyring.Keyring, lumeraClient lumera.Client, config FactoryConfig) *ClientFactory {
func NewClientFactory(ctx context.Context, logger log.Logger, keyring keyring.Keyring, lumeraClient lumera.Client, config FactoryConfig) (*ClientFactory, error) {
if logger == nil {
logger = log.NewNoopLogger()
}

logger.Debug(ctx, "Creating supernode client factory",
"localAddress", config.LocalCosmosAddress)
addr, err := keyringpkg.GetAddress(keyring, config.KeyName)
if err != nil {
logger.Error(ctx, "failed to resolve signer address from keyring",
map[string]interface{}{"key_name": config.KeyName, "error": err.Error()},
)

return nil, fmt.Errorf("resolve signer address from keyring: %w", err)
}

// Tuned for 1GB max files with 4MB chunks
// Reduce in-flight memory by aligning windows and msg sizes to chunk size.
Expand All @@ -52,7 +60,8 @@ func NewClientFactory(ctx context.Context, logger log.Logger, keyring keyring.Ke
clientOptions: opts,
config: config,
lumeraClient: lumeraClient,
}
signerAddr: addr.String(),
}, nil
}

// CreateClient creates a client for a specific supernode
Expand Down
13 changes: 8 additions & 5 deletions sdk/net/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/LumeraProtocol/supernode/v2/sdk/log"

pb "github.com/LumeraProtocol/supernode/v2/gen/supernode"
keyringpkg "github.com/LumeraProtocol/supernode/v2/pkg/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"google.golang.org/grpc"
"google.golang.org/grpc/health/grpc_health_v1"
Expand Down Expand Up @@ -49,19 +50,21 @@ func NewSupernodeClient(ctx context.Context, logger log.Logger, keyring keyring.
if keyring == nil {
return nil, fmt.Errorf("keyring cannot be nil")
}
if factoryConfig.LocalCosmosAddress == "" {
return nil, fmt.Errorf("local cosmos address cannot be empty")
}

if factoryConfig.PeerType == 0 {
factoryConfig.PeerType = securekeyx.Simplenode
}

addr, err := keyringpkg.GetAddress(keyring, factoryConfig.KeyName)
if err != nil {
return nil, fmt.Errorf("resolve signer address: %w", err)
}

// Create client credentials
clientCreds, err := ltc.NewClientCreds(&ltc.ClientOptions{
CommonOptions: ltc.CommonOptions{
Keyring: keyring,
LocalIdentity: factoryConfig.LocalCosmosAddress,
LocalIdentity: addr.String(),
PeerType: factoryConfig.PeerType,
Validator: lumeraClient,
},
Expand All @@ -78,7 +81,7 @@ func NewSupernodeClient(ctx context.Context, logger log.Logger, keyring keyring.

logger.Debug(ctx, "Preparing to connect to supernode securely",
"endpoint", targetSupernode.GrpcEndpoint, "target_id", targetSupernode.CosmosAddress,
"local_id", factoryConfig.LocalCosmosAddress, "peer_type", factoryConfig.PeerType)
"local_id", addr.String(), "peer_type", factoryConfig.PeerType)

// Use provided client options or defaults
options := clientOptions
Expand Down
Loading