history

package
v1.23.0 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound      = errors.New("no records could be found")
	ErrExists        = errors.New("history record already exists")
	ErrStaleVersion  = errors.New("history record version is stale")
	ErrInvalidCursor = errors.New("cursor is invalid")
)

Functions

func FromCursor

func FromCursor(cursor query.Cursor) (createdAt time.Time, id uint64, ok bool)

FromCursor reverses ToCursor. It reports ok false for anything that is not a cursor this package produced.

func ToCursor

func ToCursor(createdAt time.Time, id uint64) query.Cursor

ToCursor encodes a record's position in a history. A history is ordered by event time, which is not unique, so a position is the time paired with the record ID that breaks ties. Ordering on the time alone would let a page skip or repeat the records sharing a boundary timestamp.

Types

type Fee

type Fee struct {
	Type         FeeType `json:"t"`
	NativeAmount float64 `json:"na"`
}

The tags are what a stored fee is keyed by, so they are the storage schema and the field names are not. Renaming a field without them would leave every stored fee decoding to a zero value rather than failing.

They are abbreviated because a key is repeated in full on every fee of every record, and the field names carry the meaning that the keys give up.

func (*Fee) Validate

func (f *Fee) Validate() error

type FeeType

type FeeType uint8

FeeType is persisted as its ordinal, inside the fees blob rather than in a column of its own, so this block is append-only. Inserting a value anywhere but the end re-labels every fee already stored, and nothing would report it.

const (
	UnknownFeeType FeeType = iota
	ReserveBuyFee
	ReserveSellFee
	WithdrawalAccountCreationFee
	CurrencyLaunchFee
)

func (FeeType) String

func (f FeeType) String() string

type Record

type Record struct {
	Id uint64

	ReferenceId   string
	ReferenceType ReferenceType

	Type Type

	OwnerAccount             string
	CounterpartyOwnerAccount *string

	ExchangeCurrency currency.Code
	NativeAmount     float64

	Fees []Fee

	MintAccount string
	Quantity    uint64

	DestinationMintAccount *string
	DestinationQuantity    *uint64

	GiftCardVault *string
	AppMetadata   []byte

	Version uint64

	State State

	CreatedAt time.Time
	UpdatedAt time.Time
}

func (*Record) Clone

func (r *Record) Clone() Record

func (*Record) CopyTo

func (r *Record) CopyTo(dst *Record)

func (*Record) Validate

func (r *Record) Validate() error

type ReferenceType

type ReferenceType uint8

ReferenceType is the kind of thing a record's reference names. A reference is only unique within its own kind: intent IDs and swap IDs are both client supplied public keys drawn from the same space, and a transaction signature is a third space again. Pairing the two is what keeps one kind's reference from landing on another's.

const (
	UnknownReferenceType ReferenceType = iota
	IntentReference
	SwapReference
	SignatureReference
)

func (ReferenceType) String

func (r ReferenceType) String() string

type State

type State uint8
const (
	StateUnknown State = iota
	StatePending
	StateCompleted
	StateFailed
	StateVoided
	StateReturned
)

func (State) String

func (s State) String() string

type Store

type Store interface {
	// Save creates or updates a record.
	//
	// Returns ErrExists if the owner already has a record for the reference, and
	// ErrStaleVersion if the stored record has moved on.
	Save(ctx context.Context, record *Record) error

	// GetAllByOwner gets a page of an owner's history across all mints, ordered
	// by event time and then by ID, from the position named by cursor. A limit
	// of zero is unbounded.
	//
	// The order is the one a history is read in, so it is the event time rather
	// than the order records happened to be written. The two differ whenever an
	// event is recorded late — a backfill, or a deposit noticed after the fact —
	// and ordering by the write would put those records somewhere their own
	// timestamps do not explain. The cost is that such a record lands behind a
	// cursor a caller has already passed and is seen on a later read from the
	// start, rather than never.
	//
	// Returns ErrInvalidCursor for a cursor this package did not produce, and
	// ErrNotFound if no records are found.
	GetAllByOwner(ctx context.Context, owner string, cursor query.Cursor, limit uint64, direction query.Ordering) ([]*Record, error)

	// GetAllByOwnerMint gets a page of an owner's history for records involving a
	// mint, as either the source or the destination, so that a mint's history
	// holds what was traded into it as well as out of it. It is otherwise
	// GetAllByOwner.
	//
	// Returns ErrNotFound if no records are found.
	GetAllByOwnerMint(ctx context.Context, owner, mint string, cursor query.Cursor, limit uint64, direction query.Ordering) ([]*Record, error)

	// GetAllByIds gets a set of records by ID in one query, ordered by ID. An ID
	// with no record is omitted rather than reported, so a partial result is
	// normal and a caller should not read anything into the count.
	//
	// It is not scoped to an owner, so a caller serving a request on an owner's
	// behalf has to check the records it gets back belong to that owner.
	//
	// Returns ErrNotFound if no records are found.
	GetAllByIds(ctx context.Context, ids []uint64) ([]*Record, error)

	// GetAllByReference gets every owner's records for a reference. It is how an
	// outcome that arrives naming the intent or swap it concerns, rather than any
	// record, finds the records to transition.
	//
	// The reference is qualified by its type, since an ID is only unique within
	// its own kind, so a caller gets back only the records the thing it named
	// produced.
	//
	// Returns ErrNotFound if no records are found.
	GetAllByReference(ctx context.Context, referenceType ReferenceType, referenceId string) ([]*Record, error)

	// GetAllByGiftCardVault gets the records for a gift card: the issuer's
	// IndirectlySent record and, once claimed, the claimant's IndirectlyReceived
	// record. A card being claimed, voided, or returned is reported by vault, so
	// it cannot reach those records by reference.
	//
	// Returns ErrNotFound if no records are found.
	GetAllByGiftCardVault(ctx context.Context, vault string) ([]*Record, error)
}

Store stores a per-owner history of ledger events. A record is one owner's view of one event, so an event involving two owners is two records.

type Type

type Type uint8
const (
	UnknownType Type = iota
	DirectlySent
	DirectlyReceived
	IndirectlySent
	IndirectlyReceived
	Withdrawn
	Deposited
	Swap
)

func (Type) String

func (t Type) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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