diff --git a/ledger/v1/msg.proto b/ledger/v1/msg.proto new file mode 100644 index 0000000..b027852 --- /dev/null +++ b/ledger/v1/msg.proto @@ -0,0 +1,168 @@ +syntax = "proto3"; + +package ledger.v1; + +import "google/protobuf/timestamp.proto"; + +enum AccountClass { + ACCOUNT_CLASS_UNSPECIFIED = 0; + ACCOUNT_CLASS_USER_AVAILABLE = 1; + ACCOUNT_CLASS_USER_FROZEN = 2; + ACCOUNT_CLASS_EXTERNAL_BLOCKCHAIN = 3; + ACCOUNT_CLASS_TREASURY = 4; + ACCOUNT_CLASS_MARKET_CLEARING = 5; + ACCOUNT_CLASS_IPG_CLEARING = 6; + ACCOUNT_CLASS_COMMISSION_REVENUE = 7; +} + +enum TransactionState { + TRANSACTION_STATE_UNSPECIFIED = 0; + TRANSACTION_STATE_CREATED = 1; + TRANSACTION_STATE_PENDING_TRANSACTION = 2; + TRANSACTION_STATE_PENDING_ADMIN = 3; + TRANSACTION_STATE_SUCCESSFUL = 4; + TRANSACTION_STATE_FAILED = 5; + TRANSACTION_STATE_SUSPENDED = 6; +} + +message AccountReference { + AccountClass account_class = 1; + string owner_type = 2; + string owner_id = 3; + int64 asset_id = 4; +} + +message JournalEntry { + uint32 line_number = 1; + AccountReference account = 2; + // Canonical base-10 decimal. Positive is credit and negative is debit. + string amount = 3; + string description = 4; +} + +message BlockchainReference { + string network = 1; + string transaction_hash = 2; + string ledger_sequence = 3; +} + +message Journal { + string journal_id = 1; + string source_service = 2; + string idempotency_key = 3; + string source_transaction_id = 4; + string tracking_code = 5; + string effect_kind = 6; + uint32 event_version = 7; + repeated JournalEntry entries = 8; + optional string reversal_of_journal_id = 9; + google.protobuf.Timestamp occurred_at = 10; + google.protobuf.Timestamp recorded_at = 11; + string correlation_id = 12; + string actor_id = 13; + BlockchainReference blockchain = 14; + map metadata = 15; + string payload_hash = 16; +} + +message AppendJournalRequest { + string source_service = 1; + string idempotency_key = 2; + string source_transaction_id = 3; + string tracking_code = 4; + string effect_kind = 5; + uint32 event_version = 6; + repeated JournalEntry entries = 7; + optional string reversal_of_journal_id = 8; + google.protobuf.Timestamp occurred_at = 9; + string correlation_id = 10; + string actor_id = 11; + BlockchainReference blockchain = 12; + map metadata = 13; +} + +message AppendJournalResponse { + Journal journal = 1; + bool already_existed = 2; +} + +message AppendTransactionEventRequest { + string source_service = 1; + string idempotency_key = 2; + string source_transaction_id = 3; + string tracking_code = 4; + uint32 event_version = 5; + TransactionState state = 6; + string error_code = 7; + string error_message = 8; + google.protobuf.Timestamp occurred_at = 9; + string correlation_id = 10; + string actor_id = 11; + BlockchainReference blockchain = 12; + map metadata = 13; +} + +message TransactionEvent { + string event_id = 1; + AppendTransactionEventRequest event = 2; + google.protobuf.Timestamp recorded_at = 3; + string payload_hash = 4; +} + +message AppendTransactionEventResponse { + TransactionEvent event = 1; + bool already_existed = 2; +} + +message GetJournalRequest { + oneof lookup { + string journal_id = 1; + string idempotency_key = 2; + } +} + +message ListEntriesRequest { + optional AccountReference account = 1; + optional int64 asset_id = 2; + google.protobuf.Timestamp recorded_from = 3; + google.protobuf.Timestamp recorded_to = 4; + uint32 page_size = 5; + string page_token = 6; +} + +message ListEntriesResponse { + repeated Journal journals = 1; + string next_page_token = 2; +} + +message GetBalanceRequest { + AccountReference account = 1; + google.protobuf.Timestamp as_of = 2; +} + +message GetBalanceResponse { + AccountReference account = 1; + // Canonical base-10 decimal reconstructed from immutable entries. + string balance = 2; + google.protobuf.Timestamp as_of = 3; +} + +message ReplayJournalsRequest { + // Each item is independently atomic and uses normal append idempotency. + repeated AppendJournalRequest journals = 1; +} + +message ReplayJournalResult { + string idempotency_key = 1; + Journal journal = 2; + bool already_existed = 3; +} + +message ReplayJournalsResponse { + repeated ReplayJournalResult results = 1; +} + +message HealthResponse { + bool serving = 1; + bool database_ready = 2; +} diff --git a/ledger/v1/srv.proto b/ledger/v1/srv.proto new file mode 100644 index 0000000..439d5ca --- /dev/null +++ b/ledger/v1/srv.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package ledger.v1; + +import "base/v1/msg.proto"; +import "ledger/v1/msg.proto"; + +service GeneralLedgerService { + rpc Health(base.v1.Empty) returns (HealthResponse); + rpc AppendJournal(AppendJournalRequest) returns (AppendJournalResponse); + rpc AppendTransactionEvent(AppendTransactionEventRequest) returns (AppendTransactionEventResponse); + rpc GetJournal(GetJournalRequest) returns (Journal); + rpc ListEntries(ListEntriesRequest) returns (ListEntriesResponse); + rpc GetBalance(GetBalanceRequest) returns (GetBalanceResponse); + rpc ReplayJournals(ReplayJournalsRequest) returns (ReplayJournalsResponse); +}