client

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2026 License: Apache-2.0 Imports: 43 Imported by: 0

Documentation

Overview

Package client is the kit's chain-access layer: one Client interface served by two transports — gRPC against an exchange-run node (NewGRPC) and a CometBFT-RPC fallback that tunnels service queries through abci_query (NewCometRPC; R4/R8) — plus a health-checked failover wrapper (NewFailover) and the network-manifest loader (LoadManifest).

Index

Constants

View Source
const SupportedManifestSchemaMajor = 1

SupportedManifestSchemaMajor is the network.yaml contract major this loader understands (contracts/network-manifest.md); unknown majors are rejected.

Variables

View Source
var (
	// ErrUnsupported is returned when the target node or transport cannot
	// serve the operation (e.g. TxsByAddress on a node without sovr.txquery,
	// BlockResults over pure gRPC).
	ErrUnsupported = errors.New("operation not supported by this node or transport")

	// ErrSimulateUnavailable is returned by Simulate when the tunneled
	// cosmos.tx.v1beta1.Service routes are not registered on the node (node
	// runs without grpc.enable/api.enable — R4) or when a prior Probe
	// determined the tx service is not routable.
	ErrSimulateUnavailable = errors.New("simulate unavailable: tx service not routable on this node")

	// ErrNotFound is returned for lookups whose subject does not exist
	// (unknown account, unindexed tx hash).
	ErrNotFound = errors.New("not found")
)
View Source
var (
	// ErrManifestSchemaVersion — schema_version has an unknown major.
	ErrManifestSchemaVersion = errors.New("unsupported manifest schema_version")
	// ErrManifestPlaceholder — a value is TBD / REPLACE_* (SC-007).
	ErrManifestPlaceholder = errors.New("placeholder value in manifest")
	// ErrManifestMissingField — a required value is empty or absent.
	ErrManifestMissingField = errors.New("missing required manifest value")
	// ErrManifestInvalid — the file is not parseable as the contract schema.
	ErrManifestInvalid = errors.New("invalid manifest")
)

Functions

This section is empty.

Types

type Block

type Block struct {
	ChainID       string
	Height        int64
	Hash          []byte
	Time          time.Time
	LastBlockHash []byte
	AppHash       []byte
	Txs           [][]byte
}

Block is the transport-neutral block header view the kit consumes.

type BlockResults

type BlockResults struct {
	Height              int64
	TxResults           []TxExecResult
	FinalizeBlockEvents []Event
	AppHash             []byte
}

type BroadcastMode

type BroadcastMode string

BroadcastMode selects the CheckTx wait behaviour. Empty means BroadcastSync.

const (
	BroadcastSync  BroadcastMode = "sync"
	BroadcastAsync BroadcastMode = "async"
)

type BroadcastResult

type BroadcastResult struct {
	TxHash    string
	Code      uint32
	Codespace string
	RawLog    string
	Accepted  bool
}

BroadcastResult distinguishes CheckTx-rejected from accepted: Accepted is true iff CheckTx passed (Code == 0). A CheckTx rejection is a result, not a transport error.

type Client

type Client interface {
	Account(ctx context.Context, addr string) (accountNumber, sequence uint64, err error)
	Balance(ctx context.Context, addr, denom string) (sdkmath.Int, error)
	AllBalances(ctx context.Context, addr string) (sdk.Coins, error)
	DenomMetadata(ctx context.Context, denom string) (*bankv1beta1.Metadata, error)
	Tx(ctx context.Context, hash string) (*TxInfo, error)
	BlockByHeight(ctx context.Context, height int64) (*Block, error)
	LatestBlock(ctx context.Context) (*Block, error)
	BlockResults(ctx context.Context, height int64) (*BlockResults, error)
	NodeStatus(ctx context.Context) (*NodeStatus, error)
	Simulate(ctx context.Context, txBytes []byte) (*SimulateResult, error)
	Broadcast(ctx context.Context, txBytes []byte, mode BroadcastMode) (*BroadcastResult, error)
	GlobalFeeParams(ctx context.Context) (*globalfeev1.Params, error)
	// TxsByAddress returns merged sender-OR-recipient history for addr.
	// Optional TxsByAddressOptions may set order_by and UTC start_date/end_date
	// (YYYY-MM-DD) matching sovr.txquery.v1.GetTxsByAddressRequest.
	TxsByAddress(ctx context.Context, addr string, page *query.PageRequest, opts ...TxsByAddressOptions) (*txqueryv1.GetTxsByAddressResponse, error)
	Probe(ctx context.Context) (ProbeResult, error)
	Close() error
}

Client is the single interface both transports satisfy (contract: go-client-api.md §client).

func NewCometRPC

func NewCometRPC(rpcURL string, opts ...Option) (Client, error)

NewCometRPC connects to a node's CometBFT RPC endpoint (port 26657) — the fallback transport (R4/R8). Service queries are tunneled via abci_query with proto-marshaled requests; broadcast uses broadcast_tx_sync/async; blocks, block results, tx lookup, and status are native JSON-RPC routes. The JSON-RPC core is kit-local (unary HTTP POST, CometBFT wire encoding via libs/json) so the transport stays free of websocket dependencies.

func NewGRPC

func NewGRPC(target string, opts ...Option) (Client, error)

NewGRPC connects to an exchange-run node's gRPC endpoint (port 9090). Transport security defaults to insecure (exchange-local node); supply TLS credentials via WithGRPCDialOptions.

type CompareItem

type CompareItem struct {
	Kind         CompareKind
	Match        bool
	Primary      string
	Secondary    string
	PrimaryErr   string
	SecondaryErr string
}

CompareItem is one per-check verdict. On a side error the item is a mismatch with the error recorded; a Tx both sides agree is absent matches.

type CompareKind

type CompareKind string
const (
	CompareHeight          CompareKind = "height"
	CompareBlockHash       CompareKind = "block_hash"
	CompareTxResult        CompareKind = "tx_result"
	CompareAccountSequence CompareKind = "account_sequence"
	CompareBalance         CompareKind = "balance"
)

type CompareRequest

type CompareRequest struct {
	Height bool
	// HeightTolerance is the allowed |primary-secondary| latest-height gap
	// before the height item counts as a mismatch. 0 = exact.
	HeightTolerance int64
	// BlockHashAtHeight compares BlockByHeight(h).Hash. 0 = skip.
	BlockHashAtHeight int64
	// TxHash compares Tx(hash) code+height. "" = skip.
	TxHash string
	// SequenceAddress compares Account(addr) sequence. "" = skip.
	SequenceAddress string
	// BalanceAddress + BalanceDenom compare Balance(addr, denom). "" = skip.
	BalanceAddress string
	BalanceDenom   string
}

CompareRequest selects which FR-044 disagreement checks to run. Zero-valued selectors are skipped.

type CompareResult

type CompareResult struct {
	Items []CompareItem
}

func (*CompareResult) AllMatch

func (r *CompareResult) AllMatch() bool

func (*CompareResult) Mismatches

func (r *CompareResult) Mismatches() []CompareItem

type Event

type Event struct {
	Type       string
	Attributes []EventAttribute
}

type EventAttribute

type EventAttribute struct {
	Key   string
	Value string
	Index bool
}

type Failover

type Failover struct {
	// contains filtered or unexported fields
}

Failover serves every Client call from the active node, retrying transport failures against the health-checked standby, and promotes the standby after FailureThreshold consecutive active failures. Compare implements the FR-044 two-node disagreement checks.

func NewFailover

func NewFailover(primary, secondary Client, policy FailoverPolicy) *Failover

NewFailover wraps two clients. The returned *Failover satisfies Client.

func (*Failover) Account

func (f *Failover) Account(ctx context.Context, addr string) (uint64, uint64, error)

func (*Failover) AllBalances

func (f *Failover) AllBalances(ctx context.Context, addr string) (sdk.Coins, error)

func (*Failover) Balance

func (f *Failover) Balance(ctx context.Context, addr, denom string) (sdkmath.Int, error)

func (*Failover) BlockByHeight

func (f *Failover) BlockByHeight(ctx context.Context, height int64) (*Block, error)

func (*Failover) BlockResults

func (f *Failover) BlockResults(ctx context.Context, height int64) (*BlockResults, error)

func (*Failover) Broadcast

func (f *Failover) Broadcast(ctx context.Context, txBytes []byte, mode BroadcastMode) (*BroadcastResult, error)

Broadcast is not retried on the standby: a transport error after handing bytes to a node leaves the tx possibly in its mempool, and a blind resend can only be judged by the caller's sequence machinery.

func (*Failover) Close

func (f *Failover) Close() error

func (*Failover) Compare

func (f *Failover) Compare(ctx context.Context, req CompareRequest) (*CompareResult, error)

Compare runs the selected checks against primary and secondary directly (ignoring the active/standby designation).

func (*Failover) DenomMetadata

func (f *Failover) DenomMetadata(ctx context.Context, denom string) (*bankv1beta1.Metadata, error)

func (*Failover) GlobalFeeParams

func (f *Failover) GlobalFeeParams(ctx context.Context) (*globalfeev1.Params, error)

func (*Failover) LatestBlock

func (f *Failover) LatestBlock(ctx context.Context) (*Block, error)

func (*Failover) NodeStatus

func (f *Failover) NodeStatus(ctx context.Context) (*NodeStatus, error)

func (*Failover) Probe

func (f *Failover) Probe(ctx context.Context) (ProbeResult, error)

func (*Failover) Simulate

func (f *Failover) Simulate(ctx context.Context, txBytes []byte) (*SimulateResult, error)

func (*Failover) Tx

func (f *Failover) Tx(ctx context.Context, hash string) (*TxInfo, error)

func (*Failover) TxsByAddress

type FailoverPolicy

type FailoverPolicy struct {
	// FailureThreshold is the number of consecutive active-client failures
	// before the standby is promoted to active. Default 3.
	FailureThreshold int
	// HealthCheckTimeout bounds the standby NodeStatus health check performed
	// before serving a failed call from the standby. Default 5s.
	HealthCheckTimeout time.Duration
}

FailoverPolicy tunes the wrapper. Zero values take the defaults.

type ManifestEndpoint

type ManifestEndpoint struct {
	Kind     string `yaml:"kind"`
	URL      string `yaml:"url"`
	Provider string `yaml:"provider"`
}

type ManifestError

type ManifestError struct {
	Path   string
	Detail string
	// contains filtered or unexported fields
}

ManifestError is a typed per-field validation failure; Unwrap yields one of the ErrManifest* sentinels for errors.Is matching.

func (*ManifestError) Error

func (e *ManifestError) Error() string

func (*ManifestError) Unwrap

func (e *ManifestError) Unwrap() error

type ManifestFees

type ManifestFees struct {
	MinimumGasPrice          string `yaml:"minimum_gas_price"`
	RecommendedGasPrice      string `yaml:"recommended_gas_price"`
	RecommendedGasAdjustment string `yaml:"recommended_gas_adjustment"`
}

type ManifestGenesis

type ManifestGenesis struct {
	SHA256 string `yaml:"sha256"`
	File   string `yaml:"file"`
}
type ManifestLinks struct {
	Explorer    string  `yaml:"explorer"`
	Faucet      *string `yaml:"faucet"`
	StatusPage  *string `yaml:"status_page"`
	RegistryDir string  `yaml:"registry_dir"`
}

type ManifestPeers

type ManifestPeers struct {
	Seeds           []string `yaml:"seeds"`
	PersistentPeers []string `yaml:"persistent_peers"`
}

type ManifestPorts

type ManifestPorts struct {
	P2P     int `yaml:"p2p"`
	RPC     int `yaml:"rpc"`
	GRPC    int `yaml:"grpc"`
	REST    int `yaml:"rest"`
	Metrics int `yaml:"metrics"`
}

type ManifestVersions

type ManifestVersions struct {
	SDK           string `yaml:"sdk"`
	CometBFT      string `yaml:"cometbft"`
	IBCGo         string `yaml:"ibc_go"`
	CosmwasmWasmd string `yaml:"cosmwasm_wasmd"`
	Go            string `yaml:"go"`
	App           string `yaml:"app"`
}

type NetworkManifest

type NetworkManifest struct {
	SchemaVersion            int                `yaml:"schema_version"`
	NetworkName              string             `yaml:"network_name"`
	NetworkType              string             `yaml:"network_type"`
	ChainID                  string             `yaml:"chain_id"`
	DaemonName               string             `yaml:"daemon_name"`
	NodeHome                 string             `yaml:"node_home"`
	AccountPrefix            string             `yaml:"account_prefix"`
	ValidatorOperatorPrefix  string             `yaml:"validator_operator_prefix"`
	ValidatorConsensusPrefix string             `yaml:"validator_consensus_prefix"`
	BaseDenom                string             `yaml:"base_denom"`
	DisplayDenom             string             `yaml:"display_denom"`
	DisplayExponent          int                `yaml:"display_exponent"`
	Symbol                   string             `yaml:"symbol"`
	AccountKeyAlgorithm      string             `yaml:"account_key_algorithm"`
	ConsensusKeyAlgorithm    string             `yaml:"consensus_key_algorithm"`
	Slip44CoinType           int                `yaml:"slip44_coin_type"`
	Versions                 ManifestVersions   `yaml:"versions"`
	Fees                     ManifestFees       `yaml:"fees"`
	Ports                    ManifestPorts      `yaml:"ports"`
	Genesis                  ManifestGenesis    `yaml:"genesis"`
	Endpoints                []ManifestEndpoint `yaml:"endpoints"`
	Peers                    ManifestPeers      `yaml:"peers"`
	Links                    ManifestLinks      `yaml:"links"`
	Divergences              []string           `yaml:"divergences"`
}

NetworkManifest is the parsed network/<net>/network.yaml (contracts/network-manifest.md, schema_version 1).

func LoadManifest

func LoadManifest(path string) (*NetworkManifest, error)

LoadManifest reads and validates a network.yaml. Any schema-major mismatch, placeholder value, or missing required value fails with a typed error (errors.Is against the ErrManifest* sentinels).

func ParseManifest

func ParseManifest(data []byte) (*NetworkManifest, error)

ParseManifest is LoadManifest on in-memory bytes.

type NodeStatus

type NodeStatus struct {
	ChainID         string
	LatestHeight    int64
	LatestBlockTime time.Time
	LatestBlockHash []byte
	AppHash         []byte
	CatchingUp      bool
	EarliestHeight  int64
}

NodeStatus is the transport-neutral node health view. EarliestHeight is 0 when the transport cannot report it (gRPC).

type Option

type Option func(*options)

func WithChainID

func WithChainID(chainID string) Option

WithChainID sets the chain_id label on emitted metrics.

func WithGRPCDialOptions

func WithGRPCDialOptions(dialOpts ...grpc.DialOption) Option

WithGRPCDialOptions appends dial options for NewGRPC (TLS credentials, test dialers). Ignored by NewCometRPC.

func WithHTTPClient

func WithHTTPClient(hc *nethttp.Client) Option

WithHTTPClient sets the HTTP client the CometBFT-RPC transport uses. Ignored by NewGRPC.

func WithLogger

func WithLogger(l *slog.Logger) Option

func WithMetrics

func WithMetrics(s *metrics.Set) Option

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout bounds every individual call. Zero disables the bound.

type ProbeResult

type ProbeResult struct {
	NodeReachable     bool
	TxServiceRoutable bool
}

ProbeResult distinguishes "node reachable" from "tx service routable" (R4: the tunneled cosmos.tx.v1beta1.Service routes require grpc.enable or api.enable on the node).

type SimulateResult

type SimulateResult struct {
	GasWanted uint64
	GasUsed   uint64
}

type TxExecResult

type TxExecResult struct {
	Code      uint32
	Codespace string
	Data      []byte
	Log       string
	GasWanted int64
	GasUsed   int64
	Events    []Event
}

TxExecResult is one tx's execution result inside BlockResults.

type TxInfo

type TxInfo struct {
	Hash      string
	Height    int64
	Code      uint32
	Codespace string
	RawLog    string
	GasWanted int64
	GasUsed   int64
	TxBytes   []byte
	Events    []Event
}

type TxsByAddressOptions

type TxsByAddressOptions struct {
	// OrderBy is passed through to the chain query. ORDER_BY_UNSPECIFIED
	// (zero) leaves the server default (ASC).
	OrderBy txtypes.OrderBy
	// StartDate is an inclusive lower bound as YYYY-MM-DD (UTC). Empty = none.
	StartDate string
	// EndDate is an inclusive upper bound as YYYY-MM-DD (UTC). Empty = none.
	EndDate string
}

TxsByAddressOptions are optional filters for Client.TxsByAddress. Zero value keeps server defaults (ASC order, no date window).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL