model

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2026 LedgerForge Contributors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024 Blnk Finance Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

View Source
const (
	OutboxStatusPending    = "pending"
	OutboxStatusProcessing = "processing"
	OutboxStatusCompleted  = "completed"
	OutboxStatusFailed     = "failed"
)

Outbox status constants

View Source
const (
	LineageTypeCredit       = "credit"
	LineageTypeDebit        = "debit"
	LineageTypeBoth         = "both"
	LineageTypeShadowCommit = "shadow_commit"
	LineageTypeShadowVoid   = "shadow_void"
)

Lineage type constants

View Source
const (
	PreviewRoleSource      = "source"
	PreviewRoleDestination = "destination"
)

Balance roles reported by a projection.

View Source
const ChainGenesisHash = "0000000000000000000000000000000000000000000000000000000000000000"

ChainGenesisHash is the starting head of the transaction hash chain — 64 zeros. ledgerforge.chain_state.head_hash begins here.

View Source
const RefundReferenceSuffix = "_refund"

RefundReferenceSuffix is appended to the original transaction id to form the refund transaction's reference (see ledgerforge.io/docs/reference/refund-transaction).

Variables

This section is empty.

Functions

func ApplyPrecision

func ApplyPrecision(transaction *Transaction) *big.Int

ApplyPrecision handles both operations involving precision: 1. If PreciseAmount exists: converts it to a decimal Amount 2. If Amount exists: converts it to a PreciseAmount This function is now a wrapper that sets default precision if needed and calls applyPrecisionLogic.

func ApplyPrecisionChecked

func ApplyPrecisionChecked(transaction *Transaction) (*big.Int, error)

ApplyPrecisionChecked validates monetary inputs before changing them.

func ApplyPrecisionWithDBLookup

func ApplyPrecisionWithDBLookup(transaction *Transaction, db *sql.DB) *big.Int

ApplyPrecisionWithDBLookup is retained for compatibility. Lookup failures return nil; callers needing the cause should use the checked variant.

func ApplyPrecisionWithDBLookupChecked

func ApplyPrecisionWithDBLookupChecked(transaction *Transaction, db *sql.DB) (*big.Int, error)

ApplyPrecisionWithDBLookupChecked resolves precision authoritatively without process-global state. API callers use their injected datasource instead.

func ApplyRate

func ApplyRate(preciseAmount *big.Int, rate float64) *big.Int

ApplyRate applies the exchange rate to the precise amount and returns a *big.Int. The rate is applied after precision to maintain accuracy.

func CalculateDistributionsPrecise

func CalculateDistributionsPrecise(ctx context.Context, totalPreciseAmount *big.Int, distributions []Distribution, precision int64) (map[string]*big.Int, error)

CalculateDistributionsPrecise parses components exactly, truncates fractional minor units, then assigns the remainder to the largest allocation. Equal allocations are ordered lexicographically by identifier. This preserves the existing allocation policy while making every split conserve its total.

func CanonicalChainV2

func CanonicalChainV2(prevHash string, r ChainRow) []byte

CanonicalChainV2 is a domain-separated, length-delimited encoding. Each length is an unsigned big-endian uint64 byte count. Numeric text retains its exact stored representation; timestamps denote UTC instants. Mutable metadata is intentionally excluded from the financial commitment.

func CanonicalChainV3

func CanonicalChainV3(prevHash string, r ChainRow) []byte

CanonicalChainV3 retains the exact v2 payload and adds immutable execution evidence under a new domain version. V1 and v2 remain byte-for-byte stable.

func ComputeChainHash

func ComputeChainHash(prevHash string, r ChainRow) string

ComputeChainHash is the v1 encoding, retained for older-format verification. New seals use ComputeChainHashVersion with canonical version 3.

func ComputeChainHashVersion

func ComputeChainHashVersion(version int, prevHash string, r ChainRow) (string, error)

ComputeChainHashVersion verifies explicitly supplied v1/v2 records and v3 seals.

func DecodeTransactionMetadata

func DecodeTransactionMetadata(data []byte, t *Transaction) error

DecodeTransactionMetadata consumes the private SQL projection of immutable controls. The marker is removed before metadata leaves the database layer.

func GenerateKey

func GenerateKey() (string, error)

GenerateKey creates a new secure API key

func GenerateUUIDWithSuffix

func GenerateUUIDWithSuffix(module string) string

GenerateUUIDWithSuffix generates a UUID with a given module name as a suffix. This is useful for creating unique identifiers with context-specific prefixes.

func Int64ToBigInt

func Int64ToBigInt(value int64) *big.Int

Int64ToBigInt converts an int64 value to a *big.Int. This is useful for handling large numbers in computations such as financial transactions.

func ParseAmount

func ParseAmount(amount string, precision float64) (*big.Int, error)

ParseAmount parses a major-unit decimal exactly and rounds to the nearest minor unit, with halves away from zero. Positive amounts rounding to zero are rejected. Use precise_amount for integer amounts beyond float64 accuracy.

func PrecisionBankersRound

func PrecisionBankersRound(num float64, precision float64) float64

PrecisionBankersRound applies banker's rounding (round half to even) at the given precision scale factor.

func RefundReference

func RefundReference(originalTransactionID string) string

RefundReference returns the canonical reference for a refund of originalTransactionID.

func UpdateBalances

func UpdateBalances(transaction *Transaction, source, destination *Balance) error

UpdateBalances updates the balances for both the source and destination based on the transaction details. It ensures precision is applied and checks for overdraft before updating.

func ValidateCustomerTransactionMetadata

func ValidateCustomerTransactionMetadata(metadata map[string]interface{}) error

ValidateCustomerTransactionMetadata protects execution, lineage and internal recovery/policy bookkeeping while leaving arbitrary customer keys mutable.

func ValidatePrecision

func ValidatePrecision(precision float64) error

ValidatePrecision accepts a finite positive integer scale. Zero means the existing default scale of one; stored precisions must be positive.

Types

type APIKey

type APIKey struct {
	APIKeyID   string     `json:"api_key_id" db:"api_key_id"`
	Key        string     `json:"key" db:"key"`
	Name       string     `json:"name" db:"name"`
	OwnerID    string     `json:"owner_id" db:"owner_id"`
	Scopes     []string   `json:"scopes" db:"scopes"`
	ExpiresAt  time.Time  `json:"expires_at" db:"expires_at"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
	LastUsedAt time.Time  `json:"last_used_at" db:"last_used_at"`
	IsRevoked  bool       `json:"is_revoked" db:"is_revoked"`
	RevokedAt  *time.Time `json:"revoked_at,omitempty" db:"revoked_at"`

	ParentAPIKeyID string `json:"parent_api_key_id,omitempty" db:"parent_api_key_id"`
}

func NewAPIKey

func NewAPIKey(name, ownerID string, scopes []string, expiresAt time.Time) (*APIKey, error)

NewAPIKey creates a new API key instance

func (*APIKey) HasScope

func (k *APIKey) HasScope(scope string) bool

HasScope checks if the API key has the required scope

func (*APIKey) IsValid

func (k *APIKey) IsValid() bool

IsValid checks if the API key is valid

type Account

type Account struct {
	AccountID  string                 `json:"account_id"`
	Name       string                 `json:"name" form:"name"`
	Number     string                 `json:"number" form:"number"`
	BankName   string                 `json:"bank_name"`
	Currency   string                 `json:"currency"`
	BalanceID  string                 `json:"balance_id" `
	IdentityID string                 `json:"identity_id" form:"identity_id"`
	LedgerID   string                 `json:"ledger_id"`
	Ledger     *Ledger                `json:"ledger"`
	Balance    *Balance               `json:"balance"`
	Identity   *Identity              `json:"identity"`
	CreatedAt  time.Time              `json:"created_at"`
	MetaData   map[string]interface{} `json:"meta_data"`
}

Account represents a financial account linked to a balance, identity, and ledger.

type AlertCondition

type AlertCondition struct {
	Value        float64  `json:"value"`
	Precision    float64  `json:"precision"`
	PreciseValue *big.Int `json:"precise_value"`
	Field        string   `json:"field"`
	Operator     string   `json:"operator"`
}

AlertCondition specifies the field, operator, value, and precision for a balance monitor alert threshold.

type Balance

type Balance struct {
	// CurrencyMultiplier is retained for client compatibility; ledger arithmetic does not use it.
	CurrencyMultiplier    float64                `json:"currency_multiplier"`
	ID                    int64                  `json:"-"`
	Balance               *big.Int               `json:"balance"`
	Version               int64                  `json:"version"`
	InflightBalance       *big.Int               `json:"inflight_balance"`
	CreditBalance         *big.Int               `json:"credit_balance"`
	InflightCreditBalance *big.Int               `json:"inflight_credit_balance"`
	DebitBalance          *big.Int               `json:"debit_balance"`
	InflightDebitBalance  *big.Int               `json:"inflight_debit_balance"`
	QueuedDebitBalance    *big.Int               `json:"queued_debit_balance,omitempty"`
	QueuedCreditBalance   *big.Int               `json:"queued_credit_balance,omitempty"`
	LedgerID              string                 `json:"ledger_id"`
	IdentityID            string                 `json:"identity_id"`
	BalanceID             string                 `json:"balance_id"`
	Indicator             string                 `json:"indicator,omitempty"`
	Currency              string                 `json:"currency"`
	Identity              *Identity              `json:"identity,omitempty"`
	Ledger                *Ledger                `json:"ledger,omitempty"`
	CreatedAt             time.Time              `json:"created_at"`
	InflightExpiresAt     time.Time              `json:"inflight_expires_at"`
	MetaData              map[string]interface{} `json:"meta_data"`
	TrackFundLineage      bool                   `json:"track_fund_lineage"`
	AllocationStrategy    string                 `json:"allocation_strategy,omitempty"`
}

Balance represents a financial balance with credit, debit, inflight, and queued sub-balances.

func (*Balance) Clone

func (balance *Balance) Clone() *Balance

Clone returns a deep copy of the balance that a transaction can be applied to without affecting the original.

Every *big.Int field is copied by value. This is what makes the copy meaningful: big.Int's Add and Sub mutate their receiver, so a plain struct copy would share the underlying integers with the original, and applying a transaction to the copy would silently rewrite the original's balances too.

Used by the dry-run projection to hold a "before" snapshot alongside the balances the transaction is applied to.

func (*Balance) CommitInflightCredit

func (balance *Balance) CommitInflightCredit(transaction *Transaction) error

CommitInflightCredit commits a credit from the inflight balance and adds it to the credit balance.

func (*Balance) CommitInflightDebit

func (balance *Balance) CommitInflightDebit(transaction *Transaction) error

CommitInflightDebit commits a debit from the inflight balance and adds it to the debit balance, returning an error if the inflight hold cannot cover the amount.

func (*Balance) InitializeBalanceFields

func (balance *Balance) InitializeBalanceFields()

InitializeBalanceFields initializes all the fields of the Balance struct that might be nil. This ensures that all balance-related fields have valid *big.Int values for further operations.

func (*Balance) RollbackInflightCredit

func (balance *Balance) RollbackInflightCredit(amount *big.Int) error

RollbackInflightCredit rolls back (decreases) the inflight credit balance by the specified amount.

func (*Balance) RollbackInflightDebit

func (balance *Balance) RollbackInflightDebit(amount *big.Int) error

RollbackInflightDebit rolls back (decreases) the inflight debit balance by the specified amount.

type BalanceFilter

type BalanceFilter struct {
	ID                 int64     `json:"id"`
	BalanceRange       string    `json:"balance_range"`
	CreditBalanceRange string    `json:"credit_balance_range"`
	DebitBalanceRange  string    `json:"debit_balance_range"`
	Currency           string    `json:"currency"`
	LedgerID           string    `json:"ledger_id"`
	From               time.Time `json:"from"`
	To                 time.Time `json:"to"`
}

BalanceFilter defines filter criteria for querying balances by range, currency, ledger, and time period.

type BalanceMonitor

type BalanceMonitor struct {
	MonitorID   string         `json:"monitor_id"`
	BalanceID   string         `json:"balance_id"`
	Description string         `json:"description,omitempty"`
	CallBackURL string         `json:"-"`
	CreatedAt   time.Time      `json:"created_at"`
	Condition   AlertCondition `json:"condition"`
}

BalanceMonitor defines a condition-based alert that triggers a callback when a balance meets the specified criteria.

func (*BalanceMonitor) CheckCondition

func (bm *BalanceMonitor) CheckCondition(b *Balance) bool

CheckCondition checks if a balance meets the condition specified by a BalanceMonitor. It compares various balance fields (e.g., debit balance, credit balance) against the precise value.

type BalanceProjection

type BalanceProjection struct {
	BalanceID string `json:"balance_id"`
	Role      string `json:"role"`
	Currency  string `json:"currency"`

	// Virtual marks a balance that does not exist yet — an @indicator that a
	// real post would create on demand. It is projected against zero and is
	// not created by the preview.
	Virtual bool `json:"virtual,omitempty"`

	CurrentBalance               string `json:"current_balance"`
	CurrentAvailable             string `json:"current_available"`
	CurrentCreditBalance         string `json:"current_credit_balance"`
	CurrentDebitBalance          string `json:"current_debit_balance"`
	CurrentInflightDebitBalance  string `json:"current_inflight_debit_balance"`
	CurrentInflightCreditBalance string `json:"current_inflight_credit_balance"`

	ResultingBalance               string `json:"resulting_balance"`
	ResultingAvailable             string `json:"resulting_available"`
	ResultingCreditBalance         string `json:"resulting_credit_balance"`
	ResultingDebitBalance          string `json:"resulting_debit_balance"`
	ResultingInflightDebitBalance  string `json:"resulting_inflight_debit_balance"`
	ResultingInflightCreditBalance string `json:"resulting_inflight_credit_balance"`
}

BalanceProjection is one balance's state before and after the projected transaction. Current* is the snapshot the projection started from; Resulting* is that snapshot with the transaction applied in memory.

type BalanceTracker

type BalanceTracker struct {
	Balances    map[string]*Balance
	Frequencies map[string]int
	Mutex       sync.Mutex
}

BalanceTracker tracks in-memory balance state and access frequency for hot-path optimization.

type BulkTransactionPreview

type BulkTransactionPreview struct {
	DryRun bool `json:"dry_run"`

	// WouldApply is false when any item in the batch would be rejected.
	WouldApply bool `json:"would_apply"`

	// Cumulative reports whether items were projected against each other's
	// effects. That mirrors how the batch would really run: items are applied
	// one after another only when skip_queue is set, and are otherwise
	// dispatched concurrently with no guaranteed order.
	Cumulative bool `json:"cumulative"`
	Atomic     bool `json:"atomic"`

	Results []TransactionPreview `json:"results"`

	// Balances is the batch's combined effect per balance, and is reported only
	// in cumulative mode — without a guaranteed order there is no single
	// combined outcome to state.
	Balances []BalanceProjection `json:"balances,omitempty"`

	Notes []string `json:"notes,omitempty"`
}

BulkTransactionPreview is the projected effect of a batch that was evaluated but never applied.

func (*BulkTransactionPreview) AddNote

func (preview *BulkTransactionPreview) AddNote(note string)

AddNote appends an advisory note to the batch projection.

func (*BulkTransactionPreview) Finalize

func (preview *BulkTransactionPreview) Finalize()

Finalize applies the same reconciliation to a batch and to each of its items, so a rejected item does not report a status either.

type BulkTransactionRequest

type BulkTransactionRequest struct {
	Transactions []*Transaction `json:"transactions"`
	Inflight     bool           `json:"inflight"`
	Atomic       bool           `json:"atomic"`
	RunAsync     bool           `json:"run_async"`
	SkipQueue    bool           `json:"skip_queue"`
}

BulkTransactionRequest encapsulates the data needed for a bulk transaction request.

type BulkTransactionResult

type BulkTransactionResult struct {
	BatchID          string `json:"batch_id"`
	Status           string `json:"status"` // e.g., "processing", "applied", "inflight", "failed"
	TransactionCount int    `json:"transaction_count,omitempty"`
	Error            string `json:"error,omitempty"`
}

BulkTransactionResult represents the outcome of a bulk transaction operation.

type ChainCheckpoint

type ChainCheckpoint struct {
	Sequence  int64     `json:"sequence"`
	Count     int64     `json:"count"`
	HeadHash  string    `json:"head_hash"`
	CreatedAt time.Time `json:"created_at"`
}

ChainCheckpoint is an exportable root. External signatures or anchors can attest to it independently of the database that holds the chain.

type ChainIssue

type ChainIssue struct {
	Sequence      int64  `json:"sequence,omitempty"`
	TransactionID string `json:"transaction_id,omitempty"`
	Reason        string `json:"reason"`
}

type ChainRow

type ChainRow struct {
	HistoricalRate    string
	OverdraftLimit    string
	QueueAction       string
	ExecutionControls string
	ScheduledFor      *time.Time

	ID                string
	Precision         string
	Rate              string
	ParentTransaction string
	EffectiveDate     *time.Time
	TransactionID     string
	Source            string
	Destination       string
	Amount            string // NUMERIC rendered as text
	PreciseAmount     string // NUMERIC rendered as text (the authoritative ledger amount)
	Currency          string
	Status            string
	Reference         string
	CreatedAt         time.Time
}

ChainRow carries the canonical, immutable fields of a transaction that the hash chain seals. The chainer and the verifier both build it from the same DB columns so a recomputed hash is reproducible. Numeric values are read as exact PostgreSQL text, never converted through floating point.

type ChainState

type ChainState struct {
	ChainKey    string
	LastSeq     int64
	HeadHash    string
	GenesisHash string
	GenesisAt   time.Time
	UpdatedAt   time.Time
}

ChainState mirrors the ledgerforge.chain_state bookmark row.

type ChainVerifyResult

type ChainVerifyResult struct {
	Verified    bool         `json:"verified"`
	LastSeq     int64        `json:"last_sequence"`
	HeadHash    string       `json:"head_hash"`
	BrokenSeq   int64        `json:"broken_sequence,omitempty"`
	BrokenTxnID string       `json:"broken_transaction_id,omitempty"`
	Reason      string       `json:"reason,omitempty"`
	Pending     int64        `json:"pending"`
	Tampering   []ChainIssue `json:"tampering"`
}

ChainVerifyResult distinguishes broken commitments from asynchronous coverage.

type ChainedTransaction

type ChainedTransaction struct {
	CanonicalVersion int
	Row              ChainRow
	ChainSeq         int64
	ChainPrevHash    string
	ChainHash        string
}

ChainedTransaction is a transaction read back in chain order for verification: its canonical fields plus the stored chain linkage.

type Distribution

type Distribution struct {
	Identifier          string `json:"identifier"`
	Distribution        string `json:"distribution"`                   // Can be a percentage (e.g., "10%"), a fixed amount (e.g., "100"), or "left"
	PreciseDistribution string `json:"precise_distribution,omitempty"` // Fixed amount in minor units (e.g., "1006" for 1006 cents)
	TransactionID       string `json:"transaction_id"`
}

Distribution defines how a transaction amount is allocated to a specific source or destination.

type ExecutionControls

type ExecutionControls struct {
	ReservedMetadata   map[string]interface{} `json:"reserved_metadata"`
	EconomicVersion    int                    `json:"economic_version"`
	AllowOverdraft     bool                   `json:"allow_overdraft"`
	Inflight           bool                   `json:"inflight"`
	Atomic             bool                   `json:"atomic"`
	SkipQueue          bool                   `json:"skip_queue"`
	SkipBalanceUpdate  bool                   `json:"skip_balance_update"`
	ParentKind         string                 `json:"parent_kind"`
	QueuedParent       string                 `json:"queued_parent"`
	QueueLane          string                 `json:"queue_lane"`
	ShadowFor          string                 `json:"shadow_for"`
	GroupIDs           []string               `json:"group_ids"`
	Sources            []Distribution         `json:"sources"`
	Destinations       []Distribution         `json:"destinations"`
	InflightExpiryDate time.Time              `json:"inflight_expiry_date"`
	InflightCommitDate time.Time              `json:"inflight_commit_date"`
}

ExecutionControls is stored in an immutable JSONB column. It is independent of customer metadata, including for recovery and queued execution.

func DecodeExecutionControls

func DecodeExecutionControls(data []byte) (ExecutionControls, error)

DecodeExecutionControls applies the historical type checks only to schema 0. It never normalizes the original evidence used by the hash chain.

func (ExecutionControls) Apply

func (c ExecutionControls) Apply(t *Transaction)

type ExternalTransaction

type ExternalTransaction struct {
	ID          string    `json:"id"`
	Amount      float64   `json:"amount"`
	Reference   string    `json:"reference"`
	Currency    string    `json:"currency"`
	Description string    `json:"description"`
	Date        time.Time `json:"date"`
	Source      string    `json:"source"`
}

func (*ExternalTransaction) ToInternalTransaction

func (et *ExternalTransaction) ToInternalTransaction() *Transaction

ToInternalTransaction converts an ExternalTransaction to an InternalTransaction. This is useful when reconciling external transactions with internal records.

type Identity

type Identity struct {
	IdentityID       string                 `json:"identity_id" form:"identity_id"`
	IdentityType     string                 `json:"identity_type" form:"identity_type"`
	OrganizationName string                 `json:"organization_name" form:"organization_name"`
	Category         string                 `json:"category" form:"category"`
	FirstName        string                 `json:"first_name" form:"first_name"`
	LastName         string                 `json:"last_name" form:"last_name"`
	OtherNames       string                 `json:"other_names" form:"other_names"`
	Gender           string                 `json:"gender" form:"gender"`
	EmailAddress     string                 `json:"email_address" form:"email_address"`
	PhoneNumber      string                 `json:"phone_number" form:"phone_number"`
	Nationality      string                 `json:"nationality" form:"nationality"`
	Street           string                 `json:"street" form:"street"`
	Country          string                 `json:"country" form:"country"`
	State            string                 `json:"state" form:"state"`
	PostCode         string                 `json:"post_code" form:"postCode"`
	City             string                 `json:"city" form:"city"`
	DOB              time.Time              `json:"dob" form:"dob"`
	CreatedAt        time.Time              `json:"created_at" form:"createdAt"`
	MetaData         map[string]interface{} `json:"meta_data" form:"metaData"`
}

func (*Identity) IsFieldTokenized

func (i *Identity) IsFieldTokenized(fieldName string) bool

func (*Identity) MarkFieldAsTokenized

func (i *Identity) MarkFieldAsTokenized(fieldName string)

type KeyPolicy

type KeyPolicy struct {
	DenyAll       bool           `json:"deny_all,omitempty"`
	InheritedFrom []string       `json:"inherited_from,omitempty"`
	APIKeyID      string         `json:"api_key_id"`
	Version       int64          `json:"version"`
	Rules         []SpendingRule `json:"rules"`
	LedgerIDs     []string       `json:"ledger_ids,omitempty"`
	BalanceIDs    []string       `json:"balance_ids,omitempty"`
}

type Ledger

type Ledger struct {
	ID        int64                  `json:"-"`
	LedgerID  string                 `json:"ledger_id"`
	Name      string                 `json:"name"`
	CreatedAt time.Time              `json:"created_at"`
	MetaData  map[string]interface{} `json:"meta_data"`
}

type LedgerFilter

type LedgerFilter struct {
	ID   int64     `json:"id"`
	From time.Time `json:"from"`
	To   time.Time `json:"to"`
}

type LegProjection

type LegProjection struct {
	Identifier    string  `json:"identifier"`
	Role          string  `json:"role"`
	PreciseAmount string  `json:"precise_amount"`
	Amount        float64 `json:"amount"`
}

LegProjection is one split of a multi-source/destination transaction.

type LineageMapping

type LineageMapping struct {
	ID                 int64     `json:"id"`
	BalanceID          string    `json:"balance_id"`
	Provider           string    `json:"provider"`
	ShadowBalanceID    string    `json:"shadow_balance_id"`
	AggregateBalanceID string    `json:"aggregate_balance_id"`
	IdentityID         string    `json:"identity_id"`
	CreatedAt          time.Time `json:"created_at"`
}

LineageMapping tracks the relationship between a balance, its fund provider, and associated shadow/aggregate balances.

type LineageOutbox

type LineageOutbox struct {
	ID                   int64           `json:"id"`
	TransactionID        string          `json:"transaction_id"`
	SourceBalanceID      string          `json:"source_balance_id,omitempty"`
	DestinationBalanceID string          `json:"destination_balance_id,omitempty"`
	Provider             string          `json:"provider,omitempty"`
	LineageType          string          `json:"lineage_type"` // "credit", "debit", "both"
	Payload              json.RawMessage `json:"payload"`
	Status               string          `json:"status"`
	Attempts             int             `json:"attempts"`
	MaxAttempts          int             `json:"max_attempts"`
	LastError            string          `json:"last_error,omitempty"`
	CreatedAt            time.Time       `json:"created_at"`
	ProcessedAt          *time.Time      `json:"processed_at,omitempty"`
	LockedUntil          *time.Time      `json:"locked_until,omitempty"`
	Inflight             bool            `json:"inflight"`
}

LineageOutbox represents a pending lineage processing task. It is inserted atomically with the main transaction to ensure no lineage work is lost.

type Match

type Match struct {
	ExternalTransactionID string
	InternalTransactionID string
	ReconciliationID      string
	Amount                float64
	Date                  time.Time
}

type MatchingCriteria

type MatchingCriteria struct {
	Field          string  `json:"field"`
	Operator       string  `json:"operator"`
	Value          string  `json:"value"`
	Pattern        string  `json:"pattern"`
	AllowableDrift float64 `json:"allowable_drift"`
}

type MatchingRule

type MatchingRule struct {
	ID          int64              `json:"-"`
	RuleID      string             `json:"rule_id"`
	CreatedAt   time.Time          `json:"created_at"`
	UpdatedAt   time.Time          `json:"updated_at"`
	Name        string             `json:"name"`
	Description string             `json:"description"`
	Criteria    []MatchingCriteria `json:"criteria"`
}

type PolicyAdmission

type PolicyAdmission struct {
	ID        string      `json:"admission_id"`
	APIKeyID  string      `json:"api_key_id"`
	Identity  string      `json:"identity"`
	Version   int64       `json:"policy_version"`
	Day       time.Time   `json:"day"`
	Decision  string      `json:"decision"`
	DecidedBy string      `json:"decided_by,omitempty"`
	Legs      []PolicyLeg `json:"legs"`
}

type PolicyBudgetCapacity

type PolicyBudgetCapacity struct {
	APIKeyID string `json:"api_key_id"`
	Used     string `json:"used_minor"`
	Limit    string `json:"daily_limit,omitempty"`
}

type PolicyCapacity

type PolicyCapacity struct {
	Budgets   []PolicyBudgetCapacity `json:"budgets,omitempty"`
	Currency  string                 `json:"currency"`
	Precision float64                `json:"precision"`
	Day       time.Time              `json:"day"`
	Used      string                 `json:"used_minor"`
	Remaining *string                `json:"remaining_minor,omitempty"`
}

Used reports the narrowest declared daily budget. Remaining is the minimum available capacity across all charged budgets, whose usage is shown in Budgets.

type PolicyLeg

type PolicyLeg struct {
	TransactionID     string  `json:"transaction_id"`
	Reference         string  `json:"reference"`
	Source            string  `json:"source"`
	Destination       string  `json:"destination"`
	SourceLedger      string  `json:"source_ledger"`
	DestinationLedger string  `json:"destination_ledger"`
	Currency          string  `json:"currency"`
	Precision         float64 `json:"precision"`
	Amount            string  `json:"amount"`
}

type PreviewRejection

type PreviewRejection struct {
	Code    string `json:"code"`
	Reason  string `json:"reason"`
	Message string `json:"message"`
}

PreviewRejection describes why a projected transaction would not apply.

Code is the same error code a real post would return, so existing client-side handling for e.g. TXN_INSUFFICIENT_FUNDS works against a preview unchanged.

type Reconciliation

type Reconciliation struct {
	ID                    int64      `json:"-"`
	ReconciliationID      string     `json:"reconciliation_id"`
	UploadID              string     `json:"upload_id"`
	Status                string     `json:"status"`
	MatchedTransactions   int        `json:"matched_transactions"`
	UnmatchedTransactions int        `json:"unmatched_transactions"`
	IsDryRun              bool       `json:"is_dry_run"`
	StartedAt             time.Time  `json:"started_at"`
	CompletedAt           *time.Time `json:"completed_at"`
}

type ReconciliationProgress

type ReconciliationProgress struct {
	LastProcessedExternalTxnID string `json:"last_processed_external_txn_id"`
	ProcessedCount             int    `json:"processed_count"`
}

type ReconciliationResults

type ReconciliationResults struct {
	ReconciliationID      string     `json:"reconciliation_id"`
	Status                string     `json:"status"`
	StartedAt             time.Time  `json:"started_at"`
	CompletedAt           *time.Time `json:"completed_at,omitempty"`
	MatchedTransactions   []Match    `json:"matched_transactions"`
	UnmatchedTransactions []string   `json:"unmatched_transactions"`
}

type SpendingRule

type SpendingRule struct {
	Currency       string  `json:"currency"`
	Precision      float64 `json:"precision"`
	MaxTransaction string  `json:"max_transaction,omitempty"`
	DailyLimit     string  `json:"daily_limit,omitempty"`
	ApprovalAbove  string  `json:"approval_above,omitempty"`
}

Policy amounts are exact integer minor units encoded as decimal strings. A currency is authorised only at the specified minor-unit multiplier.

type Transaction

type Transaction struct {
	ParentKind       string                 `json:"-"`
	QueuedParent     string                 `json:"queued_parent,omitempty"`
	QueueLane        string                 `json:"queue_lane,omitempty"`
	ShadowFor        string                 `json:"-"`
	ReservedMetadata map[string]interface{} `json:"-"`

	// Rate is retained for client compatibility; ledger arithmetic does not use it.
	Rate               float64                `json:"rate"`
	ID                 int64                  `json:"-"`
	PreciseAmount      *big.Int               `json:"precise_amount,omitempty"`
	Amount             float64                `json:"amount"`
	AmountString       string                 `json:"amount_string,omitempty"`
	Precision          float64                `json:"precision"`
	OverdraftLimit     float64                `json:"overdraft_limit"`
	TransactionID      string                 `json:"transaction_id"`
	ParentTransaction  string                 `json:"parent_transaction"`
	Source             string                 `json:"source,omitempty"`
	Destination        string                 `json:"destination,omitempty"`
	Reference          string                 `json:"reference"`
	Currency           string                 `json:"currency"`
	Description        string                 `json:"description,omitempty"`
	Status             string                 `json:"status"`
	QueueAction        string                 `json:"queue_action,omitempty"`
	Hash               string                 `json:"hash"`
	AllowOverdraft     bool                   `json:"allow_overdraft"`
	Inflight           bool                   `json:"inflight"`
	SkipBalanceUpdate  bool                   `json:"-"`
	SkipQueue          bool                   `json:"skip_queue"`
	Atomic             bool                   `json:"atomic"`
	GroupIds           []string               `json:"-"`
	Sources            []Distribution         `json:"sources,omitempty"`
	Destinations       []Distribution         `json:"destinations,omitempty"`
	CreatedAt          time.Time              `json:"created_at"`
	EffectiveDate      *time.Time             `json:"effective_date,omitempty"`
	ScheduledFor       time.Time              `json:"scheduled_for,omitempty"`
	InflightExpiryDate time.Time              `json:"inflight_expiry_date,omitempty"`
	InflightCommitDate time.Time              `json:"inflight_commit_date,omitempty"`
	MetaData           map[string]interface{} `json:"meta_data,omitempty"`
}

Transaction represents a financial transaction between source and destination balances.

func (*Transaction) Clone

func (transaction *Transaction) Clone() *Transaction

Clone returns a deep copy of the transaction, safe to mutate without affecting the original.

The balance-applying path mutates the transaction it is given — UpdateBalances sets PreciseAmount, and the inflight helpers rewrite Amount — so a caller that wants to keep its own transaction intact (notably the dry-run projection, which must not disturb a transaction it was only asked to evaluate) applies the arithmetic to a clone.

func (*Transaction) ExecutionControls

func (t *Transaction) ExecutionControls() ExecutionControls

func (*Transaction) ExecutionMetadata

func (t *Transaction) ExecutionMetadata() map[string]interface{}

ExecutionMetadata returns immutable internal lineage decisions after a DB read, and creation-time metadata for a transaction that has not been accepted.

func (*Transaction) GetEffectiveDate

func (t *Transaction) GetEffectiveDate() time.Time

GetEffectiveDate returns the transaction's effective date, falling back to CreatedAt if not explicitly set.

func (*Transaction) HashTxn

func (transaction *Transaction) HashTxn() string

HashTxn generates a SHA-256 hash of a transaction's relevant fields. This ensures the integrity of the transaction by creating a unique hash from its details.

func (*Transaction) SplitTransactionPrecise

func (transaction *Transaction) SplitTransactionPrecise(ctx context.Context) ([]*Transaction, error)

Function to integrate the new CalculateDistributionsPrecise into SplitTransaction

func (*Transaction) ToJSON

func (transaction *Transaction) ToJSON() ([]byte, error)

ToJSON serializes the transaction to JSON bytes.

func (*Transaction) ValidateAmount

func (transaction *Transaction) ValidateAmount() error

ValidateAmount is the exported ingest check used by QueueTransaction so zero/empty amounts never land on the queue.

type TransactionPreview

type TransactionPreview struct {
	DryRun bool `json:"dry_run"`

	// WouldApply reports whether a real post of this transaction would be
	// accepted against the balances as they currently stand. When false,
	// Rejection carries the reason.
	WouldApply bool              `json:"would_apply"`
	Rejection  *PreviewRejection `json:"rejection,omitempty"`

	// Operation names the settlement being projected on the inflight endpoint:
	// "commit" or "void". Empty for ordinary transaction projections.
	Operation string `json:"operation,omitempty"`

	// Status is the status the transaction would carry once applied. It is
	// omitted when WouldApply is false: a rejected projection has no resulting
	// status, because the real endpoint returns an error and writes no
	// transaction at all. See Finalize.
	Status        string              `json:"status,omitempty"`
	Reference     string              `json:"reference,omitempty"`
	Currency      string              `json:"currency"`
	Amount        float64             `json:"amount"`
	PreciseAmount string              `json:"precise_amount"`
	Precision     float64             `json:"precision"`
	Balances      []BalanceProjection `json:"balances"`

	// Legs is populated for multi-source/destination transactions: one entry
	// per split, using the same distribution math a real post would use.
	Legs []LegProjection `json:"legs,omitempty"`

	// Notes carry advisory information that is not a rejection — an ignored
	// field, or a condition worth surfacing before the caller posts for real.
	Notes []string `json:"notes,omitempty"`
}

TransactionPreview is the projected effect of a transaction that was evaluated but never applied.

Monetary values are strings in minor units, matching precise_amount, so no precision is lost in transit.

func (*TransactionPreview) AddNote

func (preview *TransactionPreview) AddNote(note string)

AddNote appends an advisory note to the projection.

func (*TransactionPreview) Finalize

func (preview *TransactionPreview) Finalize()

Finalize reconciles fields that only describe a transaction that would actually apply.

Status is set early, from the status the transaction would carry once applied, and the projection only later discovers it would be rejected -- an insufficient balance, a failing leg, a validation failure downstream. Left alone, the response then asserts two things that cannot both be true:

"would_apply": false,
"rejection":   { "code": "TXN_INSUFFICIENT_FUNDS", ... },
"status":      "APPLIED"

A rejected projection has no resulting status. The real endpoint returns an error and writes no transaction, so there is no status to report; clearing it lets the omitempty tag drop the field rather than name an outcome that cannot happen. Callers read would_apply and rejection for that answer.

Jump to

Keyboard shortcuts

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