WATCH
@odatano/watch monitors the Cardano blockchain from a SAP CAP app. It watches addresses, payment credentials and minting policies. Every hit becomes an event with the full UTxO payload (assets, inline datums, reference scripts), persisted for replay. Use it to verify that what your ERP recorded is what the chain settled.
Highlights
- Address watching: New transactions per watched address with
utxosCreated[]/utxosSpent[]deltas - Credential + policy watching: Opt-in via
credentialPolling/policyPolling;assetMinted/assetBurnedevents per policy - Event replay: Persisted
BlockchainEventrows, cursor-paginated viagetEventsSince(scope, key, fromBlock) - Coalescing + filtering:
coalesceMsbatches emits per window with cumulative deltas;includesAssetsJsonallowlists assets - Self-hosted backend:
blockfrostCustomBackendroutes the SDK to a Blockfrost-compatible endpoint (e.g. Dolos MiniBF) to spare the free-tier quota - Phase 2 — Ogmios chainSync: switch from polling to a stream with native
cardano.rollbacksignal; backfill from Blockfrost once per new watch
Stack
| Layer | Tech |
|---|---|
| Network | Cardano (preview / mainnet) |
| Plugin | @odatano/watch (SAP CAP, cds.requires.watch) |
| Backends | Blockfrost (polling), Koios (credentials), Ogmios (chainSync) |
| Events | CAP event bus (cds.on), typed payloads |
| Admin API | OData V4 at /odata/v4/cardano-watcher-admin |
Subscribe to Events
import type { NewTransactionsEvent } from "@odatano/watch";
cds.on("cardano.newTransactions", async (e: NewTransactionsEvent) => {
// e.address, e.tag?, e.transactions[], e.utxosCreated[], e.utxosSpent[]
for (const utxo of e.utxosCreated) {
if (utxo.inlineDatumHex) await applyDatum(utxo.inlineDatumHex);
}
});
Also emitted: cardano.credential.newTransactions, cardano.policy.assetMinted, cardano.policy.assetBurned, and (Ogmios only) cardano.rollback. There is no cross-handler ordering, retry, or backpressure — read the event-delivery contract before building stateful consumers.
Manage Watches
POST /odata/v4/cardano-watcher-admin/addWatchedAddress
{ "address": "addr_test1...", "tag": "my-pool", "coalesceMs": 2000 }
POST /odata/v4/cardano-watcher-admin/getEventsSince
{ "scope": "address", "key": "addr_test1...", "fromBlock": 12345 }
Plus addWatchedCredential, addWatchedPolicy, removeWatched*. The tag is echoed back on each emit for dispatch routing.
Quick Start
npm add @odatano/watch
{
"cds": {
"requires": {
"watch": {
"network": "preview",
"blockfrostApiKey": "preview_YOUR_KEY",
"autoStart": true
}
}
}
}
To keep the key out of package.json, export BLOCKFROST_API_KEY instead — the plugin picks it up as a fallback.