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 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
- func ApplyPrecision(transaction *Transaction) *big.Int
- func ApplyPrecisionWithDBLookup(transaction *Transaction, db *sql.DB) *big.Int
- func CalculateDistributionsPrecise(ctx context.Context, totalPreciseAmount *big.Int, distributions []Distribution, ...) (map[string]*big.Int, error)
- func ComputeChainHash(prevHash string, r ChainRow) string
- func GenerateKey() (string, error)
- func GenerateUUIDWithSuffix(module string) string
- func Int64ToBigInt(value int64) *big.Int
- func PrecisionBankersRound(num float64, precision float64) float64
- func UpdateBalances(transaction *Transaction, source, destination *Balance) error
- type APIKey
- type Account
- type AlertCondition
- type Balance
- func (balance *Balance) CommitInflightCredit(transaction *Transaction) error
- func (balance *Balance) CommitInflightDebit(transaction *Transaction) error
- func (balance *Balance) InitializeBalanceFields()
- func (balance *Balance) RollbackInflightCredit(amount *big.Int) error
- func (balance *Balance) RollbackInflightDebit(amount *big.Int) error
- type BalanceFilter
- type BalanceMonitor
- type BalanceTracker
- type BulkTransactionRequest
- type BulkTransactionResult
- type ChainRow
- type ChainState
- type ChainedTransaction
- type Distribution
- type ExternalTransaction
- type Identity
- type Ledger
- type LedgerFilter
- type LineageMapping
- type LineageOutbox
- type Match
- type MatchingCriteria
- type MatchingRule
- type Reconciliation
- type ReconciliationProgress
- type ReconciliationResults
- type Transaction
Constants ¶
const ( OutboxStatusPending = "pending" OutboxStatusProcessing = "processing" OutboxStatusCompleted = "completed" OutboxStatusFailed = "failed" )
Outbox status constants
const ( LineageTypeCredit = "credit" LineageTypeDebit = "debit" LineageTypeBoth = "both" LineageTypeShadowCommit = "shadow_commit" LineageTypeShadowVoid = "shadow_void" )
Lineage type constants
const ChainGenesisHash = "0000000000000000000000000000000000000000000000000000000000000000"
ChainGenesisHash is the starting head of the transaction hash chain — 64 zeros. blnk.chain_state.head_hash begins here.
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 ApplyPrecisionWithDBLookup ¶
func ApplyPrecisionWithDBLookup(transaction *Transaction, db *sql.DB) *big.Int
ApplyPrecisionWithDBLookup attempts to fetch precision from the database and then applies it to the transaction. Falls back to transaction-defined precision or a default of 1 if DB lookup fails or precision is invalid.
func CalculateDistributionsPrecise ¶
func CalculateDistributionsPrecise(ctx context.Context, totalPreciseAmount *big.Int, distributions []Distribution, precision int64) (map[string]*big.Int, error)
CalculateDistributionsPrecise calculates distributions using big.Int for precision
func ComputeChainHash ¶ added in v0.15.0
ComputeChainHash returns SHA256(prevHash || canonical fields). It is deterministic and the single source of truth for the chain, shared by the background chainer and the verifier. It seals the raw immutable fields directly; the per-row HashTxn() value is deliberately excluded as it is just a function of fields already sealed here.
func GenerateUUIDWithSuffix ¶
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 ¶
Int64ToBigInt converts an int64 value to a *big.Int. This is useful for handling large numbers in computations such as financial transactions.
func PrecisionBankersRound ¶
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.
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"`
}
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"`
}
type AlertCondition ¶
type Balance ¶
type Balance struct {
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"`
}
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 ¶
RollbackInflightCredit rolls back (decreases) the inflight credit 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"`
}
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"`
}
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 BalanceTracker ¶
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 ChainRow ¶ added in v0.15.0
type ChainRow struct {
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 always reproducible. NULL columns are empty strings. Every field here is enforced immutable by the transactions immutability trigger, so a sealed row's hash can never change under a normal write.
type ChainState ¶ added in v0.15.0
type ChainState struct {
ChainKey string
LastSeq int64
HeadHash string
GenesisHash string
GenesisAt time.Time
UpdatedAt time.Time
}
ChainState mirrors the blnk.chain_state bookmark row.
type ChainedTransaction ¶ added in v0.15.0
type ChainedTransaction struct {
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"`
}
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 (*Identity) MarkFieldAsTokenized ¶
type LedgerFilter ¶
type LineageMapping ¶ added in v0.13.0
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"`
}
type LineageOutbox ¶ added in v0.13.0
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 MatchingCriteria ¶
type MatchingRule ¶
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 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 Transaction ¶
type Transaction struct {
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"`
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"`
}
func (*Transaction) GetEffectiveDate ¶
func (t *Transaction) GetEffectiveDate() time.Time
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)