TRACE Example App

Full-stack SAP Fiori app showing how ODATANO drops Cardano into enterprise workflows. Tracks pharmaceutical batches manufacturer → distributor → pharmacy with NFTs as on-chain proof and CIP-30 browser wallet signing.

Highlights

  • Batch NFT minting: Manufacturer mints one NFT per batch with on-chain datum (Plutus V3, Aiken)
  • Chain of custody: Each handoff is a Plutus spend with a continuing-output datum update
  • Document anchoring: SHA-256 hashes of certs / lab reports / cold-chain telemetry via CIP-20 metadata
  • Public verification: Anyone can verify a batch’s full custody chain on-chain
  • Zero key custody: All signing in the user’s browser wallet

Stack

LayerTech
Smart contractAiken (Plutus V3)
NetworkCardano preview
Chain gateway@odatano/core (CAP plugin)
BackendSAP CAP v9, Node.js, TypeScript
DatabaseSQLite (dev) / SAP HANA (prod)
FrontendFreestyle SAPUI5 (sap_horizon)
SigningCIP-30 (Nami, Eternl, Lace)

Signing Flow

1. User clicks "Mint NFT"
2. App → OData action            { unsignedCbor, buildId }
3. App → wallet.signTx(cbor)     wallet popup
4. User confirms                 { signedCbor }
5. App → SubmitSigned            { txHash, status: "SUBMITTED" }
6. Background poll (30 s)        status: "CONFIRMED" | "FAILED"

Smart Contract

Datum:    ChainOfCustody { manufacturer, current_holder, batch_id, step }
Redeemer: Action::Transfer { next_holder }

Mint policy: Only the parameterized manufacturer VKH can mint, exactly 1 token per tx.
Spend validator: Transfer requires the current holder’s signature + a continuing output with updated datum.

Quick Start

git clone https://github.com/ODATANO/TRACE && cd TRACE
npm install
# change dummy blockfrost api key in package.json
npm run deploy                 

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

Data Model

Participants  (Manufacturer | Distributor | Pharmacy | Regulator)
   └──< Batches  (DRAFT → MINTED → IN_TRANSIT → DELIVERED | RECALLED)
          ├──< OnChainAssets    (policyId, assetName, UTxO ref)
          ├──< ProofEvents      (MINT, TRANSFER, VERIFY, DOCUMENT_ANCHOR)
          └──< DocumentAnchors  (doc hash, type, cold-chain temps)

Sourcecode

github.com/ODATANO/TRACE