feat(gl): expose ledger application and grpc operations
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package ledger
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("ledger record not found")
|
||||
ErrIdempotencyConflict = errors.New("idempotency key belongs to a different payload")
|
||||
ErrIncompleteJournal = errors.New("idempotency key belongs to an unsealed journal")
|
||||
ErrAlreadyReversed = errors.New("journal already has a reversal")
|
||||
)
|
||||
@@ -0,0 +1,74 @@
|
||||
package ledger
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TransactionState string
|
||||
|
||||
const (
|
||||
TransactionStateCreated TransactionState = "CREATED"
|
||||
TransactionStatePendingTransaction TransactionState = "PENDING_TRANSACTION"
|
||||
TransactionStatePendingAdmin TransactionState = "PENDING_ADMIN"
|
||||
TransactionStateSuccessful TransactionState = "SUCCESSFUL"
|
||||
TransactionStateFailed TransactionState = "FAILED"
|
||||
TransactionStateSuspended TransactionState = "SUSPENDED"
|
||||
)
|
||||
|
||||
func (s TransactionState) Valid() bool {
|
||||
switch s {
|
||||
case TransactionStateCreated,
|
||||
TransactionStatePendingTransaction,
|
||||
TransactionStatePendingAdmin,
|
||||
TransactionStateSuccessful,
|
||||
TransactionStateFailed,
|
||||
TransactionStateSuspended:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type TransactionEvent struct {
|
||||
ID string
|
||||
SourceService string
|
||||
IdempotencyKey string
|
||||
SourceTransactionID string
|
||||
TrackingCode string
|
||||
EventVersion uint32
|
||||
State TransactionState
|
||||
ErrorCode string
|
||||
ErrorMessage string
|
||||
OccurredAt time.Time
|
||||
RecordedAt time.Time
|
||||
CorrelationID string
|
||||
ActorID string
|
||||
Blockchain BlockchainReference
|
||||
Metadata map[string]string
|
||||
PayloadHash string
|
||||
}
|
||||
|
||||
func (e TransactionEvent) Validate() error {
|
||||
if e.ID == "" || e.SourceService == "" || e.IdempotencyKey == "" || e.SourceTransactionID == "" {
|
||||
return fmt.Errorf("transaction event identity fields are required")
|
||||
}
|
||||
if e.EventVersion == 0 {
|
||||
return fmt.Errorf("event version must be positive")
|
||||
}
|
||||
if !e.State.Valid() {
|
||||
return fmt.Errorf("invalid transaction state %q", e.State)
|
||||
}
|
||||
if e.OccurredAt.IsZero() {
|
||||
return fmt.Errorf("occurred time is required")
|
||||
}
|
||||
if len(e.PayloadHash) != 64 || e.PayloadHash != strings.ToLower(e.PayloadHash) {
|
||||
return fmt.Errorf("payload hash must be a lowercase SHA-256 hex string")
|
||||
}
|
||||
if _, err := hex.DecodeString(e.PayloadHash); err != nil {
|
||||
return fmt.Errorf("payload hash must be a lowercase SHA-256 hex string")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -80,6 +80,7 @@ type Journal struct {
|
||||
Entries []Entry
|
||||
ReversalOfJournalID string
|
||||
OccurredAt time.Time
|
||||
RecordedAt time.Time
|
||||
CorrelationID string
|
||||
ActorID string
|
||||
Blockchain BlockchainReference
|
||||
@@ -87,6 +88,20 @@ type Journal struct {
|
||||
PayloadHash string
|
||||
}
|
||||
|
||||
type AppendResult struct {
|
||||
JournalID string
|
||||
AlreadyExists bool
|
||||
}
|
||||
|
||||
type JournalFilter struct {
|
||||
Account *AccountReference
|
||||
AssetID *int64
|
||||
RecordedFrom *time.Time
|
||||
RecordedTo *time.Time
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
|
||||
func (j Journal) Validate() error {
|
||||
if j.ID == "" || j.SourceService == "" || j.IdempotencyKey == "" || j.SourceTransactionID == "" || j.EffectKind == "" {
|
||||
return fmt.Errorf("journal identity fields are required")
|
||||
|
||||
Reference in New Issue
Block a user