Documentation
¶
Overview ¶
Package pulseclient connects to the Pulse wire-v2 Solana transaction feed over QUIC.
A Client owns one QUIC connection and permits exactly one initial feed subscription. Create another Client for another feed or tier; use the subscription's UpdateFilter method to change the active filter in place. The default vote predicate delivers non-vote transactions; true selects vote transactions only. Receiving both requires two connections.
Connect verifies the endpoint certificate with the target hostname and the system trust store by default. Private certificate authorities can use WithRootCAs, WithServerName, or an additional WithSPKIPinSHA256 constraint. The only way to disable verification is the explicitly named WithInsecureTLSForLocalDevelopment option, which is enforced to literal loopback targets before dialing.
SubscribeSigFirst receives unordered QUIC datagrams. Its bounded local queue evicts the oldest item when a caller falls behind; QueueStats and Gaps expose pressure and provisional wire loss. SubscribeFull receives ordered frames on one QUIC stream. Ordered transport does not imply end-to-end losslessness: an upstream server queue can discard a transaction before it reaches that stream.
QUIC application closes are returned as *TerminalError, preserving the application code and reason. CloseInfo.Retry provides the reconnect policy; callers must not treat every terminal error as retryable.
Index ¶
- Constants
- Variables
- func ComputeBudgetProgramID() [32]byte
- func ComputeUnitLimit(tx *FullTx) (limit uint32, ok bool)
- func ComputeUnitPrice(tx *FullTx) (price uint64, ok bool)
- func EncodeDGHeartbeat(buf []byte, serverTsMs, highestSeq uint64)
- func EncodeDGSigFirst(buf []byte, slot, seq uint64, sig *[64]byte)
- func EncodeFrameTx(ft *FullTx, altIncomplete bool, loadedWritable, loadedReadonly [][32]byte) []byte
- func EncodeFullTx(ft *FullTx) []byte
- func FeePayer(tx *FullTx) (feePayer [32]byte, ok bool)
- func ProgramIDs(tx *FullTx) [][32]byte
- func StaticWritableAccounts(tx *FullTx) [][32]byte
- type Ack
- type AddressTableLookup
- type ApplicationCloseCode
- type Client
- type CloseInfo
- type Datagram
- type DatagramHeartbeat
- type Filter
- type Frame
- type FrameHeartbeat
- type FullSub
- type FullTx
- type FullTxV2
- type InsecureTLSTargetError
- type Instruction
- type Option
- func WithAckTimeout(timeout time.Duration) Option
- func WithInsecureTLSForLocalDevelopment() Option
- func WithPreambleTimeout(timeout time.Duration) Option
- func WithRootCAs(roots *x509.CertPool) Option
- func WithSPKIPinSHA256(pin []byte) Option
- func WithServerName(name string) Option
- func WithSigQueueCapacity(capacity int) Option
- func WithToken(token string) Option
- type QueueStats
- type RejectedError
- type RetryClass
- type SigFirst
- type SigFirstItem
- type SigFirstSub
- func (s *SigFirstSub) Dropped() uint64
- func (s *SigFirstSub) Gaps() uint64
- func (s *SigFirstSub) Next(ctx context.Context) (SigFirstItem, error)
- func (s *SigFirstSub) QueueStats() QueueStats
- func (s *SigFirstSub) Queued() int
- func (s *SigFirstSub) UpdateFilter(ctx context.Context, f Filter) (*Ack, error)
- type TerminalError
- type UnknownDatagram
- type UnknownFrame
- type VersionMismatchError
Constants ¶
const ( MsgTx uint8 = 1 MsgHeartbeat uint8 = 2 // MsgShed is assigned to shed notices, which wire v2 does not emit. MsgShed uint8 = 3 )
Frame message types.
const ( TLVLoadedWritable uint8 = 1 TLVLoadedReadonly uint8 = 2 TLVServerTsMs uint8 = 3 TLVHighestSeq uint8 = 4 )
TLV trailer types.
const ( DGSigFirst uint8 = 1 DGHeartbeat uint8 = 2 )
Datagram types.
const ( // DGSigFirstMin is `u8 type | u64 slot | u64 seq | 64B signature`. DGSigFirstMin = 1 + 8 + 8 + 64 // DGHeartbeatMin is `u8 type | u64 server_ts_ms | u64 highest_seq`. DGHeartbeatMin = 1 + 8 + 8 )
Minimum datagram lengths, by type. Each type declares a MINIMUM length, not an exact one: a known type that is long enough parses and trailing bytes are ignored, which is what lets a later wire version add a field without breaking this decoder.
const AckTimeout = 10 * time.Second
AckTimeout bounds the complete control round-trip: opening the stream, writing the message, and waiting for the server's acknowledgement.
Without it, a peer that accepts the control stream and then neither writes nor closes leaves Subscribe* blocked forever: the connection itself is healthy, so no connection-level error is ever raised to release the read. The server acks as soon as admission completes, so ten seconds is headroom for a slow link rather than an expected admission delay.
const FlagAltIncomplete uint8 = 0x01
FlagAltIncomplete: the ALT address set on this MsgTx frame may be incomplete. Not a TLV-presence bitmap — a per-frame boolean.
const MaxFullTxBody = 1 << 16
MaxFullTxBody is the 64 KiB cap applied after a v2 frame's message-type and flags bytes. For a v2 transaction this includes the positional transaction payload and its complete TLV trailer; DecodeFullTx applies the same cap to a standalone positional body.
const NoSeqAssigned uint64 = ^uint64(0)
NoSeqAssigned is the wire sentinel for a heartbeat's HighestSeq meaning "nothing has been assigned to this subscriber yet". 0 is the first assigned sequence number and cannot also represent "none".
const Preamble = "PLS2\x02\x00"
Preamble is the immutable six-byte value written once at the head of every full-tx unidirectional stream, before any frame: "PLS2", the version, then a reserved flags byte. A v1 stream's first byte is always 0x00 (the high byte of a u32 big-endian length prefix on a frame capped at 64 KiB), so the non-zero magic is unambiguous. A client can identify a non-v1 server from the first byte.
const PreambleTimeout = 10 * time.Second
PreambleTimeout bounds the wait for the full-tx stream and its six-byte wire-v2 preamble. A peer that acknowledges the subscription but never opens or writes the stream must not leave SubscribeFull blocked forever.
const SigQueueLen = 4096
SigQueueLen is the depth of the SDK's internal sig-first handoff queue.
It exists because quic-go holds only 128 datagrams and drops new arrivals once that buffer fills. The SDK therefore drains quic-go continuously into this queue instead of leaving datagrams there until the caller happens to call Next.
const WireVersion = 2
WireVersion is the wire protocol version carried by the stream preamble.
Variables ¶
var ( // ErrNilRootCAs is returned when WithRootCAs is given a nil pool. ErrNilRootCAs = errors.New("pulseclient: root CA pool must not be nil") // ErrInvalidSPKIPin is returned when an SPKI SHA-256 pin isn't 32 bytes. ErrInvalidSPKIPin = errors.New("pulseclient: SPKI SHA-256 pin must be exactly 32 bytes") // ErrInvalidTimeout is returned when a configured protocol wait is not positive. ErrInvalidTimeout = errors.New("pulseclient: timeout must be greater than zero") // ErrInvalidQueueCapacity is returned when the sig-first queue capacity is not positive. ErrInvalidQueueCapacity = errors.New("pulseclient: sig-first queue capacity must be greater than zero") // ErrConflictingTLSOptions is returned when custom trust or certificate // pinning is combined with the explicitly insecure local-development mode. ErrConflictingTLSOptions = errors.New("pulseclient: custom trust or SPKI pinning cannot be combined with insecure local-development TLS") // ErrInsecureTLSNonLoopback is returned when the local-development-only // insecure TLS option is used with a target outside the loopback interface. ErrInsecureTLSNonLoopback = errors.New("pulseclient: insecure local-development TLS requires a loopback target") )
var ErrAlreadySubscribed = errors.New("pulseclient: this connection already has an initial subscription")
ErrAlreadySubscribed is returned when a Client is used for a second initial subscription. Pulse selects one feed and tier from the first control message; later control messages are filter updates, not new subscriptions.
var ErrBadFrame = errors.New("pulseclient: malformed full-tx frame")
ErrBadFrame is returned when a full-tx body, v2 frame, or v2 datagram does not match the documented layout (truncated, oversized, or malformed).
var ErrBadPreamble = errors.New("pulseclient: bad stream preamble: this server is not speaking pulse wire v2")
ErrBadPreamble is returned when the full-tx stream's opening bytes do not match Preamble. The peer is not serving wire v2, or the stream was corrupted in transit. It remains distinct from ErrBadFrame so callers can identify a protocol mismatch during setup.
var ErrMissingNegotiatedVersion = errors.New("pulseclient: initial acknowledgement omitted the negotiated wire version")
ErrMissingNegotiatedVersion is returned when the initial success ack omits v. Sig-first datagrams carry no per-message version marker, so accepting such an ack would start decoding without proof that the server selected wire v2.
Functions ¶
func ComputeBudgetProgramID ¶
func ComputeBudgetProgramID() [32]byte
ComputeBudgetProgramID returns the 32-byte program ID for ComputeBudget111111111111111111111111111111. It returns a value copy, so callers cannot mutate the package's derived-field matching invariant.
func ComputeUnitLimit ¶
ComputeUnitLimit returns the explicit SetComputeUnitLimit (discriminator 2) only. ok is false when the transaction set no limit; no implicit per-instruction default is applied.
func ComputeUnitPrice ¶
ComputeUnitPrice returns micro-lamports per compute unit from SetComputeUnitPrice (discriminator 3). ok is false when the transaction set no price — NOT zero.
func EncodeDGHeartbeat ¶
EncodeDGHeartbeat encodes a heartbeat datagram into buf, which must be exactly DGHeartbeatMin bytes.
func EncodeDGSigFirst ¶
EncodeDGSigFirst encodes a sig-first datagram into buf, which must be exactly DGSigFirstMin bytes.
func EncodeFrameTx ¶
func EncodeFrameTx(ft *FullTx, altIncomplete bool, loadedWritable, loadedReadonly [][32]byte) []byte
EncodeFrameTx encodes a v2 transaction frame: msg_type | flags | v1 body | TLV trailer. The v1 body is reused byte-for-byte; only the framing around it is new. Pass nil/empty slices for a non-enriched subscriber — the trailer is then empty and the frame costs two bytes more than v1.
func EncodeFullTx ¶
EncodeFullTx is the inverse of DecodeFullTx for the Pulse wire-v2 positional transaction layout.
func FeePayer ¶
FeePayer is always the first account key. ok is false for a transaction with no account keys.
func ProgramIDs ¶
ProgramIDs returns every program the transaction invokes, in first-use order, deduplicated. Solana forbids an ALT-sourced program id, so this is complete without any lookup-table resolution.
func StaticWritableAccounts ¶
StaticWritableAccounts returns writable accounts drawn from the STATIC key array only. ALT-loaded writables arrive separately in the frame's LoadedWritable TLV.
Types ¶
type Ack ¶
type Ack struct {
Type string `json:"type,omitempty"`
OK bool `json:"ok"`
Reason string `json:"reason,omitempty"`
Code *ApplicationCloseCode `json:"code,omitempty"`
// V is required on the FIRST control message's ack: the wire
// version the server actually negotiated
// (min(client's declared v, the server's max)). Updates normally omit it;
// when present it must match the established wire version.
V *int `json:"v,omitempty"`
}
Ack is a parsed `{"type":"ack","ok":bool,...}` control-channel envelope — the server's answer to any control message (first or update).
type AddressTableLookup ¶
type AddressTableLookup struct {
AccountKey [32]byte
WritableIndexes []byte
ReadonlyIndexes []byte
}
AddressTableLookup is a v0 address-table lookup.
type ApplicationCloseCode ¶
type ApplicationCloseCode uint64
ApplicationCloseCode is a Pulse QUIC application close code.
const ( CloseNormal ApplicationCloseCode = 0 CloseInvalidControl ApplicationCloseCode = 1 CloseUnauthenticated ApplicationCloseCode = 2 CloseQuotaExceeded ApplicationCloseCode = 3 CloseUnsupportedVersion ApplicationCloseCode = 4 CloseTierNotEntitled ApplicationCloseCode = 5 )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a connected Pulse client. A QUIC connection can carry exactly one initial feed subscription; call UpdateFilter on that subscription for later changes, or create another Client for another feed.
func Connect ¶
Connect dials a Pulse server over QUIC with ALPN "pulse". By default it verifies the server certificate against the target hostname and system root store. Use WithRootCAs, WithServerName, or WithSPKIPinSHA256 for private certificate authorities or additional pinning. Verification can only be disabled with the explicitly named WithInsecureTLSForLocalDevelopment option.
func ConnectWithToken ¶
func ConnectWithToken(ctx context.Context, addr string, token string, options ...Option) (*Client, error)
ConnectWithToken is the token-oriented form of Connect. Additional options configure TLS and protocol bounds. New code may prefer Connect(ctx, addr, WithToken(token), ...).
func (*Client) SubscribeFull ¶
SubscribeFull selects the ordered full-tx stream. fields requests enrichment groups (currently just "alt", which adds each frame's ALT-loaded addresses). Ordered QUIC delivery does not guarantee that an upstream server queue never discards a transaction before it is written to this stream.
The stream's 6-byte preamble is read and verified before the subscription is returned. A mismatch returns ErrBadPreamble.
func (*Client) SubscribeSigFirst ¶
SubscribeSigFirst selects the sig-first DATAGRAM tier. This tier has no enrichment fields; use SubscribeFull when loaded-address enrichment is required.
type CloseInfo ¶
type CloseInfo struct {
Code ApplicationCloseCode
Reason string
Remote bool
Retry RetryClass
}
CloseInfo is the structured information carried by a QUIC application close. Retry is derived from Code, not from the human-readable Reason.
func CloseInfoFromError ¶
CloseInfoFromError returns Pulse close information from err, including when the terminal error has been wrapped with operation context.
func (CloseInfo) NeedsCredentialChange ¶
NeedsCredentialChange reports whether reconnecting requires a corrected or newly-authorized token.
type Datagram ¶
type Datagram interface {
// contains filtered or unexported methods
}
Datagram is a decoded v2 QUIC datagram: exactly one of SigFirst, DatagramHeartbeat, or UnknownDatagram.
func DecodeDatagram ¶
DecodeDatagram decodes a datagram by its type tag.
Each type declares a MINIMUM length, not an exact one: a known type that is long enough parses, and trailing bytes are ignored. A type this decoder does not recognize is returned as UnknownDatagram rather than an error — that is a deliberate skip. A known type that is too short to parse, or an empty datagram, is rejected as ErrBadFrame: that is the one case a caller must treat as "not decodable", not "a future field I don't understand yet".
type DatagramHeartbeat ¶
DatagramHeartbeat is a decoded v2 heartbeat datagram (sig-first tier).
type Filter ¶
type Filter struct {
AccountInclude []string `json:"account_include,omitempty"`
AccountExclude []string `json:"account_exclude,omitempty"`
AccountRequired []string `json:"account_required,omitempty"`
// Vote is the Yellowstone-compatible vote predicate. nil and *false select
// non-vote transactions; *true selects vote transactions only. The
// predicate ANDs with the account ones, so e.g.
// account_include=[Vote111…] with Vote=*false yields the empty set.
Vote *bool `json:"vote,omitempty"`
}
Filter is the account/vote predicate model the server applies. With no account predicates, the zero value subscribes to every non-vote transaction.
func Accounts ¶
Accounts returns a filter matching transactions that touch any of the given base58 pubkeys / program ids. With the default vote predicate, only matching non-vote transactions are delivered.
func AllNonVoteTxs ¶
func AllNonVoteTxs() Filter
AllNonVoteTxs returns a filter matching every non-vote transaction. Pulse's omitted vote predicate defaults to false, so a single subscription never means both vote and non-vote transactions.
func (Filter) WithVote ¶
WithVote sets the Yellowstone-compatible vote predicate. true restricts the subscription to vote transactions only; false restricts it to non-vote transactions only. An omitted predicate also defaults to non-votes. To receive both categories, use two Clients and merge their subscriptions. It returns a copy, so it composes with Accounts.
type Frame ¶
type Frame interface {
// contains filtered or unexported methods
}
Frame is a decoded v2 stream frame: exactly one of FullTxV2, FrameHeartbeat, or UnknownFrame.
func DecodeFrame ¶
DecodeFrame decodes one v2 frame (the caller has already stripped the u32 big-endian length prefix). Bounds-checked; never panics. A msg_type this decoder does not recognize is returned as UnknownFrame rather than an error — that is a deliberate skip, not a failure.
type FrameHeartbeat ¶
FrameHeartbeat is a decoded v2 heartbeat frame (full-tx tier).
type FullSub ¶
type FullSub struct {
// contains filtered or unexported fields
}
FullSub is a live full-tx subscription.
func (*FullSub) Heartbeat ¶
Heartbeat returns the most recent heartbeat observed on this stream: (serverTsMs, highestSeq). highestSeq == NoSeqAssigned means the server has not assigned this subscriber a transaction yet. ok is false when no heartbeat has arrived at all yet (a busy stream can go a long time without one — the server resets its heartbeat timer on every real send).
Unlike SigFirstSub.Gaps, the full-tx wire carries no per-frame sequence number, so this SDK cannot compute a numeric gap count for this tier — highestSeq is the raw signal a caller can compare against its own received-frame count if it wants that.
func (*FullSub) Next ¶
Next awaits the next transaction frame. UnknownFrame message types are skipped transparently — a client must never error on a message kind it does not recognize — and FrameHeartbeat frames update FullSub.Heartbeat instead of being returned. Only a *FullTxV2 is ever handed back here. It returns io.EOF at a clean end of stream. A QUIC application close is returned as *TerminalError with its code and reason.
func (*FullSub) UpdateFilter ¶
UpdateFilter updates the active filter/enrichment fields live (opens a fresh control stream) and returns the server's parsed ack, or a *RejectedError if the server refused it. The tier cannot change after the first control message — this always sends full=false and no token, which the server accepts unconditionally on any control message but the first.
type FullTx ¶
type FullTx struct {
Slot uint64
Versioned bool
NumRequiredSignatures uint32
NumReadonlySignedAccounts uint32
NumReadonlyUnsignedAccount uint32
RecentBlockhash [32]byte
Signatures [][64]byte
AccountKeys [][32]byte
Instructions []Instruction
AddressTableLookups []AddressTableLookup
}
FullTx is a fully-decoded transaction (the full-tx tier payload).
func DecodeFullTx ¶
DecodeFullTx decodes a full-tx body. It is strict: bounds-checked, rejects truncation and trailing garbage, and never panics.
type FullTxV2 ¶
type FullTxV2 struct {
Tx FullTx
AltIncomplete bool
LoadedWritable [][32]byte
LoadedReadonly [][32]byte
}
FullTxV2 is a decoded v2 transaction frame: the v1 body plus its v2 additions.
type InsecureTLSTargetError ¶
type InsecureTLSTargetError struct {
Host string
}
InsecureTLSTargetError reports a non-loopback target rejected before dialing because WithInsecureTLSForLocalDevelopment was configured.
func (*InsecureTLSTargetError) Error ¶
func (e *InsecureTLSTargetError) Error() string
func (*InsecureTLSTargetError) Unwrap ¶
func (e *InsecureTLSTargetError) Unwrap() error
type Instruction ¶
Instruction is a compiled instruction within a transaction.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option configures Connect.
Options are validated before any network connection is attempted.
func WithAckTimeout ¶
WithAckTimeout changes the maximum duration of a control-message round trip. The default is AckTimeout. A caller context with an earlier deadline wins.
func WithInsecureTLSForLocalDevelopment ¶
func WithInsecureTLSForLocalDevelopment() Option
WithInsecureTLSForLocalDevelopment disables certificate and hostname verification. It is intentionally explicit and is rejected before dialing unless the target is localhost, 127.0.0.0/8, or ::1. Never use it with a production token or endpoint.
func WithPreambleTimeout ¶
WithPreambleTimeout changes the maximum wait for the full-tx stream and its wire-v2 preamble. The default is PreambleTimeout. A caller context with an earlier deadline wins.
func WithRootCAs ¶
WithRootCAs replaces the system trust store with roots for this connection. The pool is cloned before use. To add a private CA while retaining public roots, start with x509.SystemCertPool, append the CA, and pass that pool here.
func WithSPKIPinSHA256 ¶
WithSPKIPinSHA256 requires the leaf certificate's SubjectPublicKeyInfo to match the supplied SHA-256 digest in addition to normal chain and hostname verification. The pin is copied before use.
func WithServerName ¶
WithServerName overrides the DNS name used for certificate verification and SNI. By default Connect derives it from the target host. This is useful when dialing an IP address whose certificate is issued for a DNS name.
func WithSigQueueCapacity ¶
WithSigQueueCapacity changes the bounded sig-first handoff queue capacity. The default is SigQueueLen. Use SigFirstSub.QueueStats to observe pressure.
type QueueStats ¶
QueueStats is a point-in-time snapshot of the bounded sig-first handoff queue. Dropped is cumulative for the subscription.
type RejectedError ¶
type RejectedError struct{ Reason string }
RejectedError is returned when the server answers a control message with `{"ok":false,...}`. It carries the server's stated Reason so a caller learns *why* a subscribe or UpdateFilter call was refused, rather than getting no error and simply receiving nothing forever.
func (*RejectedError) Error ¶
func (e *RejectedError) Error() string
type RetryClass ¶
type RetryClass uint8
RetryClass describes what must change before reconnecting after a terminal Pulse error.
const ( // RetryUnknown means the server used an application close code this SDK // doesn't recognize. Callers should fail closed instead of looping. RetryUnknown RetryClass = iota // RetryNormal means the peer closed normally. Reconnect only when the // application intends to continue consuming the feed. RetryNormal // RetryNever means an unchanged reconnect cannot succeed. It covers invalid // control messages, unsupported protocol versions, and tier entitlement. RetryNever // RetryAfterCredentialChange means the token must be supplied, replaced, or // re-authorized before reconnecting. RetryAfterCredentialChange // RetryTransient means the same request may be retried with bounded backoff. RetryTransient )
func ClassifyCloseCode ¶
func ClassifyCloseCode(code ApplicationCloseCode) RetryClass
ClassifyCloseCode returns the reconnect policy for a Pulse application close code. Unknown codes fail closed and return RetryUnknown.
func (RetryClass) String ¶
func (r RetryClass) String() string
type SigFirstItem ¶
SigFirstItem is one sig-first delivery: the transaction's slot, this subscriber's per-connection sequence number (see SigFirstSub.Gaps), and its signature.
type SigFirstSub ¶
type SigFirstSub struct {
// contains filtered or unexported fields
}
SigFirstSub is a live sig-first subscription.
A goroutine drains the connection into a bounded queue as fast as the network delivers. When a slow Next loop fills the queue, the oldest items are evicted and counted by Dropped.
func (*SigFirstSub) Dropped ¶
func (s *SigFirstSub) Dropped() uint64
Dropped reports how many items were evicted because the caller's Next loop fell behind. Export it: it is the only signal that this is happening, and no kernel or NIC counter will show it.
func (*SigFirstSub) Gaps ¶
func (s *SigFirstSub) Gaps() uint64
Gaps is a provisional loss indicator: item-to-item Seq gaps plus trailing loss revealed by a heartbeat's HighestSeq. NoSeqAssigned on the wire never contributes to this counter.
It can OVER-report under reordering. QUIC DATAGRAMs are unordered by definition, so a scalar high-watermark cannot distinguish "this seq is late" from "this seq is lost" at the moment a later one arrives out of order — it charges one provisional gap on that jump, and never reverses the charge if the late item shows up afterward. A perfectly lossless but reordered stream can therefore report Gaps() > 0. Treat this as "loss happened, or reordering did" rather than an exact count of sequence numbers that never arrived on the wire at all.
func (*SigFirstSub) Next ¶
func (s *SigFirstSub) Next(ctx context.Context) (SigFirstItem, error)
Next blocks for the next SigFirstItem. A clean datagram source end returns io.EOF; a QUIC application close returns *TerminalError with its code and reason; ctx.Err() is returned if ctx ends first.
Do the work for each item elsewhere. This call should be a drain loop: every microsecond spent between two Next calls is queue depth.
func (*SigFirstSub) QueueStats ¶
func (s *SigFirstSub) QueueStats() QueueStats
QueueStats returns the queue capacity, current depth, and cumulative number of evicted items. Sustained depth near Capacity is a backpressure warning.
func (*SigFirstSub) Queued ¶
func (s *SigFirstSub) Queued() int
Queued reports the current depth of the handoff queue. Sustained depth near SigQueueLen means the consumer is about to start losing items.
func (*SigFirstSub) UpdateFilter ¶
UpdateFilter updates the active sig-first filter live (opens a fresh control stream) and returns the server's parsed ack, or a *RejectedError if the server refused it. The tier cannot change after the first control message — this always sends full=false and no token, which the server accepts unconditionally on any control message but the first.
type TerminalError ¶
type TerminalError struct {
CloseInfo
// contains filtered or unexported fields
}
TerminalError is returned when a Pulse QUIC connection ends with an application close. It is never collapsed to io.EOF. Use errors.As to access CloseInfo and make a reconnect decision.
func (*TerminalError) Error ¶
func (e *TerminalError) Error() string
func (*TerminalError) Unwrap ¶
func (e *TerminalError) Unwrap() error
type UnknownDatagram ¶
type UnknownDatagram struct{ Type uint8 }
UnknownDatagram carries the type tag of a datagram this decoder does not recognize, so a caller can skip it deliberately rather than erroring.
type UnknownFrame ¶
type UnknownFrame struct{ Type uint8 }
UnknownFrame carries the message type of a frame this decoder does not recognize, so a caller can skip it deliberately rather than erroring — that is what keeps a future wire addition from breaking this client.
type VersionMismatchError ¶
type VersionMismatchError struct{ Negotiated int }
VersionMismatchError is returned when the server's first-control-message ack names a negotiated wire version this SDK does not speak. In practice the server closes the connection outright (code 4) rather than acking success with a version it can't actually serve, so this is a defensive backstop, not the primary version-mismatch signal.
func (*VersionMismatchError) Error ¶
func (e *VersionMismatchError) Error() string
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
fulltx
command
Subscribe to the ordered full-tx tier and print decoded transactions.
|
Subscribe to the ordered full-tx tier and print decoded transactions. |
|
sigfirst
command
Subscribe to the sig-first tier and print (slot, signature) as they arrive.
|
Subscribe to the sig-first tier and print (slot, signature) as they arrive. |