ledger

package
v0.1.1-rc1 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AccountWalletBalance  = "wallet_balance"
	AccountVTXOBalance    = "vtxo_balance"
	AccountFeesPaid       = "fees_paid"
	AccountOnchainFees    = "onchain_fees"
	AccountTransfersIn    = "transfers_in"
	AccountTransfersOut   = "transfers_out"
	AccountOpeningBalance = "opening_balance"
	AccountWalletClearing = "wallet_clearing"
)

Client-side account identifiers matching the seeded accounts in db/sqlc/migrations/000006_accounting.up.sql.

TransfersIn is the counterparty side of received VTXOs (revenue-type), TransfersOut is the counterparty side of sent VTXOs (expense-type). These two accounts keep gross send/receive flows distinct instead of netting them on a single account.

View Source
const (
	EventBoardingFeePaid      = "boarding_fee_paid"
	EventRefreshFeePaid       = "refresh_fee_paid"
	EventOnchainFeePaid       = "onchain_fee_paid"
	EventBoardingSweepFeePaid = "boarding_sweep_fee_paid"
	EventVTXOReceived         = "vtxo_received"
	EventVTXOSent             = "vtxo_sent"
	EventWalletUTXOCreated    = "wallet_utxo_created"
	EventWalletUTXOSpent      = "wallet_utxo_spent"
	EventWalletSweepTransfer  = "wallet_sweep_transfer"
)

Client-side ledger event types matching the seeded event types in the migration.

View Source
const (
	SourceRoundBoarding = "round_boarding"
	SourceRoundRefresh  = "round_refresh"
	SourceRoundTransfer = "round_transfer"
	SourceOOR           = "oor"
)

Canonical VTXOReceivedMsg.Source values. Callers must use one of these strings; any other value causes handleVTXOReceived to return an error rather than silently misclassify the entry.

  • SourceRoundBoarding: VTXO is the result of the client boarding its own on-chain wallet funds into a round. The offsetting leg moves value from wallet_balance into vtxo_balance.
  • SourceRoundRefresh: VTXO materialized as the output side of a round in which the client also forfeited VTXOs of roughly equal value (refresh or directed-send self-change). The offsetting leg credits transfers_out so it cancels with the companion VTXOSentMsg's transfers_out debit; the net effect on vtxo_balance is just the operator fee, booked separately via FeePaidMsg. This avoids spuriously crediting wallet_balance on a flow that never touches the on-chain wallet.
  • SourceRoundTransfer: VTXO was received from another round participant (in-round transfer). The offsetting leg credits transfers_in.
  • SourceOOR: VTXO was received out-of-round (OOR transfer from another participant). The offsetting leg credits transfers_in.
View Source
const (
	FeeTypeBoarding     = "boarding"
	FeeTypeRefresh      = "refresh"
	FeeTypeOnchainSweep = "onchain_sweep"
)

Canonical FeePaidMsg.FeeType values. A misspelled or missing fee type is rejected by handleFeePaid with an explicit error so durable-mailbox replays surface caller bugs loudly instead of silently misclassifying the entry.

FeeTypeBoarding and FeeTypeRefresh book operator (Ark protocol) fees, debiting fees_paid. The credit side names the account the fee was paid from: wallet_balance for boarding (the fee comes out of the wallet funds entering the Ark layer, alongside a same-RoundID VTXOReceivedMsg carrying the SEALED post-fee VTXO value) and vtxo_balance for refresh (the fee is carved out of forfeited VTXO value).

FeeTypeOnchainSweep books wallet-level sweep chain cost (currently emitted by the boarding-sweep flow): debit onchain_fees, credit wallet_clearing. RoundID may be zero — the fee is keyed by sweep txid via IdempotencyKey instead.

View Source
const (
	ClassificationBoardingSweepInput  = "boarding_sweep_input"
	ClassificationBoardingSweepReturn = "boarding_sweep_return"
)

Canonical Classification values seeded by migrations specific to boarding-sweep events. Callers must use these strings rather than literals so the seed table and producer agree.

View Source
const (
	ClassificationDeposit      = "deposit"
	ClassificationSweepReturn  = "sweep_return"
	ClassificationRoundFunding = "round_funding"
	ClassificationChange       = "change"
	ClassificationUnknown      = "unknown"
)

Canonical UTXO audit classification values matching the utxo_classifications seed table in migration 000007. Callers must use one of these strings for UTXOCreatedMsg.Classification and UTXOSpentMsg.Classification.

View Source
const ServiceKeyName = "ledger-accounting"

ServiceKeyName is the actor system service key name for the ledger accounting actor.

View Source
const Subsystem = "LDGR"

Subsystem defines the logging code for the ledger actor.

Variables

View Source
var ErrInvalidMessage = errors.New("ledger: invalid message")

ErrInvalidMessage is the sentinel wrapped by handler errors that stem from caller-side input problems (unknown fee type, unknown source, ambiguous VTXOSentMsg, etc.). Receive logs these at error level because the caller is buggy; persistence failures that don't wrap this sentinel are logged at warn level because they're external triggers (DB locked, I/O, etc.) and should not page on their own.

Functions

func ExitIdempotencyKey

func ExitIdempotencyKey(hash [32]byte, index uint32) []byte

ExitIdempotencyKey exposes the exit-leg dedup key derivation to read-side consumers: the unilateral exit send and fee legs booked by handleExitCost share this outpoint-derived key, so a store can look up the confirmed exit cost for a given VTXO outpoint without text-parsing descriptions.

func NewServiceKey

func NewServiceKey() actor.ServiceKey[LedgerMsg, LedgerResp]

NewServiceKey returns the service key used to register the ledger actor with the actor system.

Types

type ActorConfig

type ActorConfig struct {
	// Log is an optional logger. When None, logging is
	// disabled.
	Log fn.Option[btclog.Logger]

	// DeliveryStore persists actor mailbox state for crash
	// recovery.
	DeliveryStore actor.DeliveryStore

	// LedgerStore provides DB persistence for ledger entries.
	LedgerStore LedgerStore

	// UTXOAuditStore provides DB persistence for UTXO audit
	// log entries. When nil, UTXO audit messages are logged
	// but not persisted.
	UTXOAuditStore UTXOAuditStore

	// ActorID is the mailbox/checkpoint identifier. Defaults
	// to "ledger.accounting" if empty.
	ActorID string

	// Clock is the time source used to stamp ledger entries.
	// When None, the actor uses clock.NewDefaultClock() so
	// production code keeps its behavior; tests inject a
	// deterministic clock (shared with the rest of waved so
	// every persisted row pins to the same test frame).
	Clock fn.Option[clock.Clock]
}

ActorConfig configures the client-side LedgerActor.

type BoardingSweepConfirmedMsg

type BoardingSweepConfirmedMsg struct {
	actor.BaseMessage

	// Txid identifies the sweep transaction.
	Txid [32]byte

	// BlockHeight is the confirmation block height.
	BlockHeight uint32

	// ChainCostSat is the on-chain cost (miner fee + P2A anchor) that
	// leaves the wallet, debited to onchain_fees. Must be positive.
	ChainCostSat int64

	// Inputs are the boarding UTXOs the sweep spent. Must be non-empty
	// and each amount positive.
	Inputs []SweepInput

	// DestinationSat is the sweep destination output value, credited out
	// of wallet_clearing. Must be positive.
	DestinationSat int64

	// DestinationExternal reports whether the destination is a
	// caller-supplied external address (true) rather than a
	// wallet-derived return output (false).
	DestinationExternal bool
}

BoardingSweepConfirmedMsg records a confirmed boarding sweep as a single atomic accounting event. Earlier revisions emitted the fee, per-input, and destination legs as independent Tells; a partial failure could leave the wallet_clearing account stranded non-zero. Folding every leg into one message lets the ledger handler book them inside a single Commit, so the clearing account either nets to zero or nothing is written.

The legs the handler derives, all keyed for idempotent replay:

  • Fee: debit onchain_fees, credit wallet_clearing by ChainCostSat (miner fee + P2A anchor), keyed by the sweep txid.
  • Per input: a wallet_utxo_log "spent" audit row plus debit wallet_clearing, credit wallet_balance, keyed by the input outpoint.
  • Destination: when DestinationExternal, debit transfers_out, credit wallet_clearing (the funds left the wallet); otherwise a "created" audit row for the wallet-return output plus debit wallet_balance, credit wallet_clearing, keyed by the sweep txid's vout 0.

The clearing identity is Σ(inputs) − ChainCostSat − DestinationSat = 0.

func (*BoardingSweepConfirmedMsg) Decode

Decode deserializes a TLV stream into the message.

func (*BoardingSweepConfirmedMsg) Encode

Encode serializes the message as a TLV stream.

func (*BoardingSweepConfirmedMsg) MessageType

func (m *BoardingSweepConfirmedMsg) MessageType() string

MessageType returns the message type name for routing.

func (*BoardingSweepConfirmedMsg) TLVType

func (m *BoardingSweepConfirmedMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type ExitCostMsg

type ExitCostMsg struct {
	actor.BaseMessage

	// OutpointHash is the 32-byte transaction hash of the
	// exited outpoint.
	OutpointHash [32]byte

	// OutpointIndex is the output index within the
	// transaction.
	OutpointIndex uint32

	// AmountSat is the VTXO value that was exited.
	AmountSat int64

	// ExitCostSat is the on-chain fee cost of the exit.
	ExitCostSat int64

	// BlockHeight is the block height at which the exit was
	// confirmed.
	BlockHeight uint32
}

ExitCostMsg is sent when the client pays an on-chain exit cost (e.g. unilateral exit). The ledger actor records the on-chain fee expense.

func (*ExitCostMsg) Decode

func (m *ExitCostMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*ExitCostMsg) Encode

func (m *ExitCostMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*ExitCostMsg) MessageType

func (m *ExitCostMsg) MessageType() string

MessageType returns the message type name for routing.

func (*ExitCostMsg) TLVType

func (m *ExitCostMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type FeePaidMsg

type FeePaidMsg struct {
	actor.BaseMessage

	// RoundID is the 16-byte round UUID that links this fee
	// to a specific boarding or refresh round.
	RoundID [16]byte

	// AmountSat is the fee amount in satoshis. Must be
	// positive. Callers should set the paired VTXOReceivedMsg
	// AmountSat to the gross pre-fee value for the same round
	// so the two entries combine to the correct net balance.
	AmountSat int64

	// FeeType classifies the fee. Must be one of the
	// FeeType* constants (FeeTypeBoarding, FeeTypeRefresh,
	// FeeTypeOnchainSweep); any other value is rejected.
	FeeType string

	// BlockHeight is the confirmation block height.
	BlockHeight uint32

	// IdempotencyKey is an optional natural dedup key used by
	// fee events that do not carry a RoundID — the boarding
	// sweep flow for example uses the sweep txid (32 bytes).
	// Round/refresh fees leave this empty and rely on the
	// (round_id, event_type) partial unique index instead.
	IdempotencyKey []byte
}

FeePaidMsg is sent when the client pays a fee. Two flavors:

  • FeeTypeBoarding / FeeTypeRefresh: an Ark protocol fee paid to the operator during a round. Booked as fees_paid += AmountSat / vtxo_balance -= AmountSat. Keyed by RoundID via the (round_id, event_type) partial unique index.
  • FeeTypeOnchainSweep: L1 chain cost paid by a wallet- internal boarding sweep. Booked as onchain_fees += AmountSat / wallet_clearing -= AmountSat. Has no paired VTXOReceivedMsg; keyed by the sweep txid carried in IdempotencyKey via the idx_client_ledger_idempotent_key partial unique index. RoundID is left zero and stored as NULL.

Caller contract (FeeTypeBoarding / FeeTypeRefresh only): FeePaidMsg accumulates the fee on top of a paired VTXOReceivedMsg. The VTXOReceivedMsg for the same round MUST carry the GROSS (pre-fee) amount -- the FeePaidMsg then nets vtxo_balance down to the delivered post-fee value. Sending a net VTXOReceivedMsg together with a FeePaidMsg will under-count vtxo_balance by the fee. OOR sends and receives are already net-of-fee and do not need a separate FeePaidMsg. FeeTypeOnchainSweep is a standalone entry and never pairs with a VTXOReceivedMsg.

func (*FeePaidMsg) Decode

func (m *FeePaidMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*FeePaidMsg) Encode

func (m *FeePaidMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*FeePaidMsg) MessageType

func (m *FeePaidMsg) MessageType() string

MessageType returns the message type name for routing.

func (*FeePaidMsg) TLVType

func (m *FeePaidMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type LedgerActor

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

LedgerActor is a durable actor that serializes all client-side accounting writes from rounds, OOR transfers, and on-chain exits. It receives fire-and-forget Tell messages and persists double-entry ledger entries to the database.

The actor follows the same durable pattern as the server-side version: each message implements TLVMessage for crash-safe mailbox delivery, and a RestartMessage is prepended on startup for state reconstruction.

func NewLedgerActor

func NewLedgerActor(cfg ActorConfig) *LedgerActor

NewLedgerActor creates a new client-side ledger actor instance. This is a pure constructor that performs no I/O. Call Start to initialize the durable runtime.

func (*LedgerActor) OnStop

func (a *LedgerActor) OnStop(ctx context.Context) error

OnStop implements actor.Stoppable by stopping the durable ledger runtime and waiting for it to exit before the actor system closes shared storage.

func (*LedgerActor) Receive

func (a *LedgerActor) Receive(ctx context.Context, msg LedgerMsg,
	ax actor.Exec[ledgerTx]) fn.Result[LedgerResp]

Receive processes one durable message. This is the TxBehavior implementation called by the durable runtime: each handler that persists state runs inside a single lease-fenced Commit transaction via the Exec handle, so the ledger writes and the mailbox ack land atomically.

func (*LedgerActor) Ref

Ref returns the actor reference for sending messages.

func (*LedgerActor) Start

func (a *LedgerActor) Start(ctx context.Context) error

Start loads durable mailbox state and starts the actor runtime. On restart, unprocessed messages are replayed from the delivery store.

func (*LedgerActor) Stop

func (a *LedgerActor) Stop()

Stop stops the durable ledger actor.

type LedgerEntry

type LedgerEntry struct {
	// DebitAccount is the account name to debit (increase
	// expense or decrease asset).
	DebitAccount string

	// CreditAccount is the account name to credit (increase
	// income or increase asset).
	CreditAccount string

	// AmountSat is the entry amount in satoshis. Must be
	// positive.
	AmountSat int64

	// RoundID links the entry to a specific round (16-byte UUID).
	// Nil for events that have no round association; partial
	// unique index idx_client_ledger_idempotent_round only covers
	// rows where round_id IS NOT NULL.
	RoundID []byte

	// SessionID links the entry to a specific OOR session
	// (32-byte identifier). Nil for events with no session
	// association. Partial unique index
	// idx_client_ledger_idempotent_session covers rows where
	// session_id IS NOT NULL.
	SessionID []byte

	// EventType classifies the ledger event (e.g.
	// "boarding_fee_paid", "vtxo_received").
	EventType string

	// Description is a human-readable summary of the entry.
	Description string

	// CreatedAt is the Unix timestamp when the entry was
	// recorded.
	CreatedAt int64

	// IdempotencyKey is an optional natural dedup key used by
	// handlers whose events carry neither a round_id nor an OOR
	// session_id (e.g. on-chain exit legs keyed by outpoint).
	// Nil for entries that rely on round_id / session_id for
	// uniqueness. Partial unique index
	// idx_client_ledger_idempotent_key covers rows where
	// idempotency_key IS NOT NULL.
	IdempotencyKey []byte

	// ChainTxid optionally links this ledger entry to an on-chain
	// transaction. It is a first-class history field rather than a
	// value callers must recover from Description or IdempotencyKey.
	ChainTxid []byte

	// ChainVout optionally records the output index within ChainTxid.
	// Nil means this ledger entry is not tied to a concrete output.
	ChainVout *int32

	// ConfirmationHeight optionally records the block height that
	// confirmed the on-chain transaction. Nil means the height is
	// unknown or the ledger entry has no chain transaction.
	ConfirmationHeight *int32
}

LedgerEntry is the domain-level representation of a double-entry ledger record for the client. This decouples the ledger actor from sqlc-generated types.

type LedgerMsg

type LedgerMsg interface {
	actor.TLVMessage
}

LedgerMsg is the message constraint for the client-side ledger durable actor mailbox. It embeds actor.TLVMessage so both application messages and the framework RestartMessage satisfy this interface.

type LedgerResp

type LedgerResp interface {
	actor.Message
	// contains filtered or unexported methods
}

LedgerResp is the response type for the ledger actor. The ledger actor is fire-and-forget, so responses are always nil.

type LedgerStore

type LedgerStore interface {
	// InsertLedgerEntry persists a single ledger leg. The call
	// joins any outer actor transaction present in ctx so that
	// multiple invocations within one handler commit atomically
	// with the mailbox ack. Conflicts on the idempotency partial
	// unique indexes (round_id / session_id / idempotency_key)
	// are swallowed via ON CONFLICT DO NOTHING so redelivery of
	// a partially-processed message is a silent no-op.
	InsertLedgerEntry(
		ctx context.Context, entry LedgerEntry,
	) error
}

LedgerStore is the interface for persisting client-side ledger entries. Implementations bridge to the sqlc-generated queries via the db package.

Multi-leg handlers (e.g. ExitCost's send leg + fee leg) still commit atomically even with two separate InsertLedgerEntry calls: the durable actor framework runs the whole Receive body inside a single TxAwareDeliveryStore transaction, and LedgerStoreDB.InsertLedgerEntry joins that outer transaction via db.TransactionExecutor.ExecTx rather than opening a new one. A crash mid-handler therefore rolls back both the writes and the ack together; no partial-write window exists on the durable path.

type Sink

type Sink = actor.TellOnlyRef[LedgerMsg]

Sink is the type producer subsystems hold to forward accounting events to the ledger actor. It is a fire-and-forget reference because LedgerResp is always nil; callers Tell, never Ask.

func NewSink

func NewSink(system *actor.ActorSystem) Sink

NewSink resolves the ledger service key against the supplied actor system and returns a Tell-only reference suitable for embedding in subsystem actor configs. Callers typically wrap the result in fn.Option so test harnesses can pass None when no actor system is available.

The returned reference is a router built from ServiceKey.Ref(system); Tell on a system with no registered ledger actor returns an error which callers should log but not propagate -- accounting is a side observation, never a blocking pre-condition for the operations being recorded.

type SweepInput

type SweepInput struct {
	// Outpoint is the spent boarding UTXO.
	Outpoint wire.OutPoint

	// AmountSat is the boarding UTXO value in satoshis. Must be
	// positive.
	AmountSat int64
}

SweepInput is one boarding UTXO spent by a confirmed sweep, carried inside a BoardingSweepConfirmedMsg. The amount is the value of the boarding outpoint as the wallet persisted it, used both for the audit row and for the wallet_clearing debit leg.

type UTXOAuditEntry

type UTXOAuditEntry struct {
	// OutpointHash is the 32-byte transaction hash.
	OutpointHash []byte

	// OutpointIndex is the output index within the transaction.
	OutpointIndex int32

	// AmountSat is the UTXO value in satoshis.
	AmountSat int64

	// Event is "created" or "spent".
	Event string

	// BlockHeight is the block where this change occurred.
	BlockHeight int32

	// ClassifiedAs categorizes the UTXO event (e.g.
	// "deposit", "round_funding", "sweep_return", "change",
	// "unknown").
	ClassifiedAs string

	// CreatedAt is the Unix timestamp when this entry was
	// recorded.
	CreatedAt int64
}

UTXOAuditEntry is the domain-level representation of a wallet UTXO audit log record. Each row records a single UTXO being created or spent, classified by its likely cause.

type UTXOAuditStore

type UTXOAuditStore interface {
	InsertUTXOAuditEntry(
		ctx context.Context, entry UTXOAuditEntry,
	) error
}

UTXOAuditStore is the interface for persisting wallet UTXO audit log entries. Implementations bridge to the sqlc-generated queries via the db package.

type UTXOCreatedMsg

type UTXOCreatedMsg struct {
	actor.BaseMessage

	// OutpointHash is the 32-byte transaction hash.
	OutpointHash [32]byte

	// OutpointIndex is the output index within the
	// transaction.
	OutpointIndex uint32

	// AmountSat is the UTXO value in satoshis.
	AmountSat int64

	// BlockHeight is the confirmation block height.
	BlockHeight uint32

	// Classification categorizes the UTXO origin (e.g.
	// "deposit", "change", "sweep_return").
	Classification string
}

UTXOCreatedMsg is sent when a new wallet UTXO is confirmed on-chain. The ledger actor writes an audit log entry classified by the UTXO's origin (deposit, change, etc.).

func (*UTXOCreatedMsg) Decode

func (m *UTXOCreatedMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*UTXOCreatedMsg) Encode

func (m *UTXOCreatedMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*UTXOCreatedMsg) MessageType

func (m *UTXOCreatedMsg) MessageType() string

MessageType returns the message type name for routing.

func (*UTXOCreatedMsg) TLVType

func (m *UTXOCreatedMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type UTXOSpentMsg

type UTXOSpentMsg struct {
	actor.BaseMessage

	// OutpointHash is the 32-byte transaction hash of the
	// spent outpoint.
	OutpointHash [32]byte

	// OutpointIndex is the output index within the
	// transaction.
	OutpointIndex uint32

	// AmountSat is the UTXO value in satoshis.
	AmountSat int64

	// BlockHeight is the block height at which the spend was
	// confirmed.
	BlockHeight uint32

	// Classification categorizes the spend purpose (e.g.
	// "round_funding", "unknown").
	Classification string
}

UTXOSpentMsg is sent when a wallet UTXO is spent on-chain. The ledger actor writes an audit log entry classified by the spend's purpose (round_funding, sweep_return, etc.).

func (*UTXOSpentMsg) Decode

func (m *UTXOSpentMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*UTXOSpentMsg) Encode

func (m *UTXOSpentMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*UTXOSpentMsg) MessageType

func (m *UTXOSpentMsg) MessageType() string

MessageType returns the message type name for routing.

func (*UTXOSpentMsg) TLVType

func (m *UTXOSpentMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type VTXOReceivedMsg

type VTXOReceivedMsg struct {
	actor.BaseMessage

	// OutpointHash is the 32-byte transaction hash of the
	// outpoint containing the received VTXO.
	OutpointHash [32]byte

	// OutpointIndex is the output index within the
	// transaction.
	OutpointIndex uint32

	// AmountSat is the VTXO value in satoshis. See the type
	// docstring for the gross-vs-net caller contract.
	AmountSat int64

	// Source classifies how the VTXO was received
	// (e.g. "round", "oor").
	Source string

	// RoundID is the 16-byte round UUID associated with this
	// VTXO.
	RoundID [16]byte
}

VTXOReceivedMsg is sent when the client receives a VTXO from one of three sources (see Source docstring). The ledger actor records the movement from the appropriate counterparty account into vtxo_balance.

Caller contract: for Source == SourceRoundBoarding, AmountSat MUST be the gross (pre-fee) VTXO amount paired with a FeePaidMsg for the same RoundID that debits fees_paid and nets vtxo_balance down. For SourceRoundTransfer and SourceOOR, AmountSat is the net received amount and no FeePaidMsg is expected.

func (*VTXOReceivedMsg) Decode

func (m *VTXOReceivedMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*VTXOReceivedMsg) Encode

func (m *VTXOReceivedMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*VTXOReceivedMsg) MessageType

func (m *VTXOReceivedMsg) MessageType() string

MessageType returns the message type name for routing.

func (*VTXOReceivedMsg) TLVType

func (m *VTXOReceivedMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

type VTXOSentMsg

type VTXOSentMsg struct {
	actor.BaseMessage

	// SessionID is the 32-byte OOR session identifier. Zero
	// when this is an in-round send.
	SessionID [32]byte

	// RoundID is the 16-byte round UUID. Zero when this is an
	// out-of-round send.
	RoundID [16]byte

	// Outpoint identifies the specific VTXO being sent.
	// Optional -- the round-scoped idempotency index treats two
	// sends in the same round without an outpoint as duplicates,
	// so in-round refresh emissions and directed-send forfeits
	// must set this so handleVTXOSent can stamp an outpoint-
	// derived IdempotencyKey on the ledger entry. OOR single-
	// destination sends can leave the outpoint zero-valued and
	// fall back on the session_id partial index.
	Outpoint wire.OutPoint

	// AmountSat is the total value sent in satoshis.
	AmountSat int64

	// IdempotencyKey is an optional caller-supplied key for
	// round-scoped sends that do not have a VTXO outpoint, such
	// as cooperative leave outputs and foreign directed-send
	// recipient outputs. When set, it takes precedence over
	// Outpoint for ledger-entry deduplication.
	IdempotencyKey []byte
}

VTXOSentMsg is sent when the client sends a VTXO to another participant, either out-of-round (SessionID) or inside a round (RoundID). Exactly one of the two identifiers must be non-zero; handleVTXOSent rejects messages that carry both or neither.

func (*VTXOSentMsg) Decode

func (m *VTXOSentMsg) Decode(r io.Reader) error

Decode deserializes a TLV stream into the message.

func (*VTXOSentMsg) Encode

func (m *VTXOSentMsg) Encode(w io.Writer) error

Encode serializes the message as a TLV stream.

func (*VTXOSentMsg) MessageType

func (m *VTXOSentMsg) MessageType() string

MessageType returns the message type name for routing.

func (*VTXOSentMsg) TLVType

func (m *VTXOSentMsg) TLVType() tlv.Type

TLVType returns the TLV type tag for codec registration.

Jump to

Keyboard shortcuts

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