FINCA Example App

Full-stack SAP Fiori app showing how ODATANO anchors financial data on Cardano. FINCA (Financial Data Anchoring) manages organisations, journal transactions, and financial reports, then anchors them on-chain as CIP-10 label-1447 metadata following the Cardano Foundation’s Reeve specification - verifiable accounting without a smart contract.

Highlights

  • Metadata anchoring: Balance Sheets and Income Statements serialized to CIP-10 label-1447 (Reeve format, v1.1)
  • Journal model: Organisations → Accounting Periods → Transactions → debit/credit items with exact Decimal(23,2) ledger math
  • Public verification: VerifyTransaction / VerifyReport re-derive the metadata and confirm on-chain data matches local records
  • Excel integration: ODC file, Power Query M template, and a native OData feed URL for spreadsheet reporting
  • Zero key custody: All signing in the user’s browser wallet via CIP-30

Stack

LayerTech
On-chain formatCIP-10 label-1447 metadata (Reeve spec)
NetworkCardano preview
Chain gateway@odatano/core (CAP plugin)
TX builderBuildooor · Koios backend
BackendSAP CAP v9, Node.js, TypeScript
DatabaseSQLite (dev) / SAP HANA (prod)
FrontendFreestyle SAPUI5 (sap_horizon)
SigningCIP-30 (Nami, Eternl, Lace)

Signing Flow

1. User publishes a transaction or report
2. App → ValidateBatch              double-entry + required-field checks
3. App → PublishTransactions        { buildId, unsignedCbor, txBodyHash, anchorId }
4. App → wallet.signTx(cbor)        wallet popup (CIP-30)
5. App → SubmitSigned               { txHash, status: "SUBMITTED" }
6. CheckPendingAnchors (30 s poll)  status: "CONFIRMED" | "FAILED"

OData Actions

FinanceService at /odata/v4/finance/:

ActionPurpose
ValidateBatchCheck double-entry compliance and required fields
PublishTransactionsBuild unsigned label-1447 metadata TX for journal transactions
PublishReportBuild unsigned label-1447 metadata TX for a financial report
SubmitSignedSubmit the CIP-30-signed CBOR, returns txHash + status
CheckPendingAnchorsPoll submitted anchors for confirmation (runs every 30 s)
RetryFailedRebuild the transaction for failed anchors
VerifyTransaction / VerifyReportConfirm on-chain metadata matches local records

Data Model

Organisations      (bech32 wallet, currency, country, tax id)
   └──< AccountingPeriods  (monthly | quarterly | annual)
          └──< Transactions       (JOURNAL | PAYMENT | INVOICE)
                 │                 DRAFT → VALIDATED → PUBLISHED → CONFIRMED
                 └──< TransactionItems  (debit/credit, Decimal(23,2), account code, VAT)
Organisations
   └──< FinancialReports  (Balance Sheet | Income Statement, subType, interval, version)
          └──< ReportEntries     (category → subcategory → lineItem hierarchy)
OnChainAnchors     (buildId, unsigned/signed CBOR, txHash, slot)
                    PENDING → SUBMITTED → CONFIRMED | FAILED

Quick Start

git clone https://github.com/ODATANO/FINCA && cd FINCA
npm install
# set your Blockfrost/Koios key + network in package.json
npm run deploy                 # SQLite + schema + plugin tables + CSV seeds
npm start                      # cds-serve on :4004
npm test                       # Jest (41 tests)

Open http://localhost:4004/finance/webapp/index.html.

Sourcecode

github.com/ODATANO/FINCA