Help us shape the future of Go! Take the 2026 Go Developer Survey

journal

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package journal persists intent lifecycle and signer-global nonces without secrets.

Index

Constants

View Source
const (
	StatePrepared   = "prepared"
	StateCreating   = "creating"
	StateCreated    = "created"
	StateSubmitting = "submitting"
	StateSigning    = "signing"
	StateSubmitted  = "submitted"
	StateUnknown    = "unknown"
	StateRejected   = "rejected"
	StateAbandoned  = "abandoned"
)
View Source
const (
	SwapOrderActive    = "active"
	SwapOrderTriggered = "triggered"
	SwapOrderExecuting = "executing"
	SwapOrderFilled    = "filled"
	SwapOrderFailed    = "failed"
	SwapOrderCancelled = "cancelled"
)

Swap order states: active -> triggered -> executing -> filled|failed. A triggered order returns to active only when preparing the sell failed before anything was journaled or signed. An executing order returns to active only while its bound sell intent is still prepared (never signed or broadcast); that intent is failed in the same transaction so it can never be submitted later. Otherwise an executing order never sells again. Only an active order can be cancelled.

Variables

View Source
var ErrConflict = errors.New("intent id already used with a different payload")
View Source
var ErrNotFound = errors.New("intent not found")
View Source
var ErrSwapOrderAllConflict = errors.New("another open order already sells all of this token")

ErrSwapOrderAllConflict is returned by CreateSwapOrder when another open order already sells the whole balance of the same agent, chain and token.

View Source
var ErrUnresolved = errors.New("account has unresolved submission")

SwapOrderStates lists every swap order state in lifecycle order.

Functions

This section is empty.

Types

type Batch

type Batch struct {
	Nonce         uint64 `json:"nonce"`
	FromBlock     uint64 `json:"from_block"`
	TransactionID string `json:"transaction_id,omitempty"`
}

Batch records an atomic wallet_sendCalls execution. Nonce is the agent's confirmed and pending nonce observed before submission: the batch is the agent's transaction at exactly that nonce, which lets status and reconcile find it on chain without a Privy transaction lookup.

type Binding

type Binding struct{ Profile, Network, Account, Origin, Signer string }

type Fill

type Fill struct {
	Received   string `json:"received"`
	Gas        string `json:"gas"`
	InValue    string `json:"in_value,omitempty"`
	Source     string `json:"source"`
	RecordedAt string `json:"recorded_at"`
}

Fill is what a confirmed swap actually delivered, read from its receipts. Received is in raw units of the output token; Gas is the native wei paid by every recorded transaction of the intent. InValue is the oracle native wei value of a token -> token swap's input when the fill was recorded, empty when unpriced or not a token -> token swap.

type Journal

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

func Open

func Open(profile string) (*Journal, error)

func OpenBinding

func OpenBinding(b Binding) (*Journal, error)

func (*Journal) AdvanceOnchain

func (j *Journal) AdvanceOnchain(id, from, to, hash string) error

AdvanceOnchain is a durable transition. Hash append commits before receipt polling.

func (*Journal) BeginOnchain

func (j *Journal) BeginOnchain(id, digest, agent string) error

BeginOnchain atomically checks the agent-and-chain unresolved gate and marks the intent sending before any network call. A sending intent must never be replayed.

func (*Journal) BeginSubmission

func (j *Journal) BeginSubmission(r *Record, signer string) (int64, error)

BeginSubmission atomically commits signer-global nonce and submitting state before signing/sending. The caller must sign only after this returns successfully, and must never retry the action.

func (*Journal) BindOnchainExecution

func (j *Journal) BindOnchainExecution(id, digest string, templates []OnchainTemplate) (string, error)

BindOnchainExecution replaces placeholder templates only while prepared and atomically seals the final, verified transactions under a fresh digest.

func (*Journal) Blocking

func (j *Journal) Blocking(network, account string) ([]*Record, error)

Blocking finds possible exposure for the same account across every profile and origin.

func (*Journal) ClaimForBridge

func (j *Journal) ClaimForBridge(parent string) (*OnchainRecord, error)

ClaimForBridge finds the parent's live claim (any state except failed). A failed claim broadcast nothing that could still land (failed is only set before broadcast or on a reverted receipt), so a new claim may follow it; the unique index allows at most one non-failed claim per parent. The destination chain lock must be held while checking and creating a claim.

func (*Journal) Close

func (j *Journal) Close() error

func (*Journal) Create

func (j *Journal) Create(in trading.Intent) (*Record, bool, error)

func (*Journal) CreateOnchain

func (j *Journal) CreateOnchain(in OnchainIntent) (*OnchainRecord, error)

func (*Journal) CreateSwapOrder

func (j *Journal) CreateSwapOrder(o SwapOrder) (*SwapOrder, error)

CreateSwapOrder stores a new active order. An "all" order is refused with ErrSwapOrderAllConflict while another open "all" order exists for the same agent, chain and token, checked in the same transaction as the insert.

func (*Journal) FinishSigning

func (j *Journal) FinishSigning(r *Record, signed bool) error

FinishSigning atomically advances a verified signature to submitting, or returns an unsent action to created. Nonces remain burned in the nonce table.

func (*Journal) Get

func (j *Journal) Get(id string) (*Record, error)

func (*Journal) GetOnchain

func (j *Journal) GetOnchain(id string) (*OnchainRecord, error)

func (*Journal) GetSwapOrder

func (j *Journal) GetSwapOrder(id string) (*SwapOrder, error)

GetSwapOrder loads one order of this profile.

func (*Journal) List

func (j *Journal) List() ([]*Record, error)

func (*Journal) ListOnchainBridges

func (j *Journal) ListOnchainBridges() ([]*OnchainRecord, error)

ListOnchainBridges returns this profile's bridge records without holding a database cursor while loading individual records.

func (*Journal) ListOnchainSwapChains

func (j *Journal) ListOnchainSwapChains(agent string) ([]uint64, error)

ListOnchainSwapChains returns the chains on which agent has swaps that ListOnchainSwaps would return, in ascending order.

func (*Journal) ListOnchainSwaps

func (j *Journal) ListOnchainSwaps(agent string, chain uint64) ([]*OnchainRecord, error)

ListOnchainSwaps returns an agent's confirmed transaction swaps on one chain. Intent swaps are excluded: 'submitted' is terminal for them even when the backend order later expires or refunds, and no fill is journaled. Prepared, in-flight, unknown and failed swaps are excluded too.

func (*Journal) ListSwapOrders

func (j *Journal) ListSwapOrders(states ...string) ([]*SwapOrder, error)

ListSwapOrders returns this profile's orders, oldest first, optionally restricted to the given states.

func (*Journal) Lock

func (j *Journal) Lock() (func(), error)

Lock remains compatible with existing callers, but should not span network requests.

func (*Journal) LockChain

func (j *Journal) LockChain(agent string, chain uint64) (func(), error)

LockChain serializes transactions for one agent on one EVM chain across processes.

func (*Journal) LockSwapOrderWatch

func (j *Journal) LockSwapOrderWatch() (func(), error)

LockSwapOrderWatch takes the per-profile watcher lock without waiting, so at most one 'swap orders watch' evaluates and sells this profile's orders.

func (*Journal) MarkStepHandoff

func (j *Journal) MarkStepHandoff(id string, step int) error

MarkStepHandoff commits before calling Privy. A crash after this point is ambiguous even when no returned hash was persisted.

func (*Journal) NextNonce

func (j *Journal) NextNonce(signer string) (int64, error)

func (*Journal) Put

func (j *Journal) Put(r *Record, note string) error

func (*Journal) RecordFill

func (j *Journal) RecordFill(id string, f Fill) error

RecordFill stores the receipt-derived fill of a confirmed swap once. A second call for the same intent is a no-op that returns ErrConflict.

func (*Journal) RecordSwapOrderQuote

func (j *Journal) RecordSwapOrderQuote(id, price, value, at string) (string, error)

RecordSwapOrderQuote stores the latest price observation of an active order and ratchets the peak value: it only ever increases. It returns the stored peak. A non-active order is left unchanged (ErrConflict).

func (*Journal) RejectDefinite

func (j *Journal) RejectDefinite(r *Record, reason string) error

RejectDefinite persists a submitting record as rejected on the strength of a definite, non-ambiguous RPC rejection (a Connect error code the API client classifies as returned before the handler acted, e.g. invalid_argument or permission_denied) rather than an observed server state. It only applies to a record currently submitting with the same nonce, and the reason is recorded in last_error and the transition note. Ambiguous outcomes must instead be persisted as unknown.

func (*Journal) RelayOnchain

func (j *Journal) RelayOnchain(id, from, orderID string) error

RelayOnchain stores the backend's offchain order identifier and closes the source submission state. A missing response must instead remain unknown.

func (*Journal) SetExecutionMode

func (j *Journal) SetExecutionMode(id, mode string) error

SetExecutionMode commits the selected mode before any transaction handoff.

func (*Journal) SetOnchainBatch

func (j *Journal) SetOnchainBatch(id, state string, b Batch) error

SetOnchainBatch durably records batch metadata while the intent is in state. The pre-submission record (nonce, block) must commit before wallet_sendCalls.

func (*Journal) SkipApproval

func (j *Journal) SkipApproval(id string) error

SkipApproval advances only when a fresh allowance read proves the exact approval is unnecessary. No transaction hash is appended.

func (*Journal) TransitionSwapOrder

func (j *Journal) TransitionSwapOrder(id, from, to string, p SwapOrderPatch) error

TransitionSwapOrder moves an order from one state to another only if it is still in from (compare-and-set). It returns ErrConflict otherwise, which is how a second watcher or a cancel racing a trigger loses.

func (*Journal) Unresolved

func (j *Journal) Unresolved() ([]*Record, error)

type OnchainIntent

type OnchainIntent struct {
	ID             string            `json:"intent_id"`
	Kind           string            `json:"kind"`
	Intent         bool              `json:"intent_based,omitempty"`
	ChainID        uint64            `json:"chain_id"`
	Sender         string            `json:"sender"`
	Recipient      string            `json:"recipient"`
	Token          string            `json:"token"`
	Amount         string            `json:"amount"`
	ResolvedAmount string            `json:"resolved_amount,omitempty"`
	AmountSource   string            `json:"amount_source,omitempty"`
	Templates      []OnchainTemplate `json:"templates"`
	OrderID        string            `json:"order_id,omitempty"`
	ParentIntent   string            `json:"parent_intent,omitempty"`
	QuoteID        string            `json:"quote_id,omitempty"`
	Generation     int32             `json:"generation,omitempty"`
	Route          string            `json:"route,omitempty"`
	Target         string            `json:"target,omitempty"`
	Spender        string            `json:"spender,omitempty"`
	OutToken       string            `json:"out_token,omitempty"`
	OutChain       uint64            `json:"out_chain,omitempty"`
	MinOut         string            `json:"min_out,omitempty"`
	ExpiresAt      string            `json:"expires_at,omitempty"`
	CreatedAt      string            `json:"created_at"`
}

OnchainIntent binds every economic field and every ordered transaction template.

func (OnchainIntent) Digest

func (in OnchainIntent) Digest() string

type OnchainRecord

type OnchainRecord struct {
	OnchainIntent
	Digest          string   `json:"digest"`
	State           string   `json:"state"`
	Hashes          []string `json:"tx_hashes"`
	Batch           *Batch   `json:"batch,omitempty"`
	NextStep        string   `json:"next_step,omitempty"`
	ExecutionMode   string   `json:"execution_mode,omitempty"`
	StepIndex       int      `json:"step_index,omitempty"`
	StepInFlight    bool     `json:"step_in_flight,omitempty"`
	ApprovalSkipped bool     `json:"approval_skipped,omitempty"`
	BackendOrderID  string   `json:"backend_order_id,omitempty"`
	Fill            *Fill    `json:"fill,omitempty"`
	UpdatedAt       string   `json:"updated_at"`
}

type OnchainTemplate

type OnchainTemplate struct {
	ChainID  uint64 `json:"chain_id"`
	To       string `json:"to"`
	Data     string `json:"data"`
	Value    string `json:"value"`
	Token    string `json:"token,omitempty"`
	Amount   string `json:"amount,omitempty"`
	Decimals int    `json:"decimals,omitempty"`
	Spender  string `json:"spender,omitempty"`
}

type Record

type Record struct {
	Intent      trading.Intent `json:"intent"`
	Digest      string         `json:"digest"`
	State       string         `json:"state"`
	ActionID    string         `json:"action_id,omitempty"`
	ActionJSON  string         `json:"action_json,omitempty"`
	Cloid       string         `json:"cloid,omitempty"`
	Nonce       int64          `json:"nonce,omitempty"`
	ServerState string         `json:"server_state,omitempty"`
	OrderID     int64          `json:"order_id,omitempty"`
	LastError   string         `json:"last_error,omitempty"`
	UpdatedAt   string         `json:"updated_at"`
	History     []Transition   `json:"history"`
}

func (*Record) Terminal

func (r *Record) Terminal() bool

func (*Record) Unresolved

func (r *Record) Unresolved() bool

Unresolved reports whether a record still needs reconciliation.

type Store

type Store interface {
	Create(trading.Intent) (*Record, bool, error)
	Get(string) (*Record, error)
	Put(*Record, string) error
	List() ([]*Record, error)
	Unresolved() ([]*Record, error)
	NextNonce(string) (int64, error)
	BeginSubmission(*Record, string) (int64, error)
	Blocking(string, string) ([]*Record, error)
	Close() error
}

Store is the durable journal interface. Operations are short transactions, never network-spanning.

type SwapOrder

type SwapOrder struct {
	ID              string `json:"order_id"`
	Agent           string `json:"agent"`
	ChainID         uint64 `json:"chain_id"`
	Token           string `json:"token"`
	Decimals        int    `json:"decimals"`
	Amount          string `json:"amount"`
	Size            string `json:"size"`
	TakeProfitPct   string `json:"take_profit_pct,omitempty"`
	StopLossPct     string `json:"stop_loss_pct,omitempty"`
	TrailingStopPct string `json:"trailing_stop_pct,omitempty"`
	SlippageBps     int    `json:"slippage_bps"`
	Basis           string `json:"basis,omitempty"`
	BasisSource     string `json:"basis_source"`
	State           string `json:"state"`
	PeakValue       string `json:"peak_value,omitempty"`
	LastPrice       string `json:"last_price,omitempty"`
	LastValue       string `json:"last_value,omitempty"`
	LastQuoteAt     string `json:"last_quote_at,omitempty"`
	Trigger         string `json:"trigger,omitempty"`
	SellIntentID    string `json:"sell_intent_id,omitempty"`
	NeedsReconcile  bool   `json:"needs_reconcile"`
	LastError       string `json:"last_error,omitempty"`
	Attempts        int    `json:"attempts"`
	CreatedAt       string `json:"created_at"`
	UpdatedAt       string `json:"updated_at"`
}

SwapOrder is a client-side exit (token -> native) for an EVM swap position. Values are native-denominated decimals; percentages are decimal strings.

type SwapOrderPatch

type SwapOrderPatch struct {
	Trigger        *string
	SellIntentID   *string
	LastError      *string
	NeedsReconcile *bool
	// CountAttempt increments the failed-sell-attempt counter.
	CountAttempt bool
}

SwapOrderPatch sets optional fields during a state transition.

type Transition

type Transition struct {
	At    string `json:"at"`
	State string `json:"state"`
	Note  string `json:"note,omitempty"`
}

Jump to

Keyboard shortcuts

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