# Hydro dMRV > Carbon-credit MRV for grid-connected hydropower on Hedera, following Verra VMR0017 v1.0 applied with ACM0002 v22.0 > (per plant; the demo plants) or CDM AMS-I.D (≤ 15 MW) and ACM0002, with TOOL07 > (grid emission factor) and TOOL03 (fossil fuel combustion). A deterministic 5-stage engine verifies monitoring data > and quantifies ER = BE − PE − LE. Raw readings and reports are published on the Hedera Consensus Service (HCS), so > any agent can reproduce every figure. The DmrvRegistry contract runs the VCS project cycle: a VVB-validated > registration of the plant's design, meter-signed monitoring records that its VMR0017 module quantifies (recorded, > not issued, in a hash chain), and a VVB's verification of a run of records, which alone issues Hedera Token Service > credits (1 token = 1 t CO2e, 1 base unit = 1 kg). The VVB may only lower the figures. CreditMarket sells them at USD prices settled in HBAR through Chainlink HBAR/USD cross-checked against > a Supra fallback (plus an on-chain SaucerSwap pool check where enabled); retirement burns them and mints an HTS NFT > certificate. Registry methodology is on-chain; demo plants are VMR0017. This is the on-chain half of a Hedera Guardian workflow, not a replacement for it. Guardian runs the roles, documents and methodology policies; a Guardian mint is an amount a policy rule computes and the Guardian service signs. Here the contract holds the supply key, recomputes the tonnes and needs the meter and two VVB signatures (validation, verification), and the credit can be priced, bought and retired on-chain. `trace_guardian_mint` checks a Guardian token before you buy it; `compare_guardian_report` and `verify_guardian_evidence` check a Guardian figure. Everything below is relative to this site's origin. Read-only access needs no credentials. The server never holds a buyer's key: purchases are returned as unsigned transactions. The REST API is described in OpenAPI 3.1 at `/api/openapi.json` (request schemas generated from the validators; operationId = the MCP tool's name). ## MCP (recommended for agents) - Endpoint: `/api/mcp` (streamable HTTP, stateless; MCP 2025-06-18 and 2026-07-28) - Design: `assess_project` (applicability, power density, baseline, TOOL07 CM, TOOL03 COEF → registration integers and designHash), `calculate_grid_emission_factor` (TOOL07 OM / BM sample / CM), `get_project_design` - Methodology engines: `list_methodology_engines`, `get_methodology_engine`, `verify_with_engine` (one engine per methodology; findings cite clauses; the methodology's data and parameters table) - Monitoring: `list_scenarios`, `generate_sample_telemetry`, `verify_telemetry` (decision, 5 stages, EG_PJ, BE, PE, LE, ER with an equation trace, the exact HCS report) - Registry: `get_registry_overview` (totals in kg CO2e, plants with design and ledger, tokens, both oracle sources), `list_attestations` (monitoring records with status monitored / issued / rejected), `list_issuances` (VVB verifications: records, decision, deduction, units issued), `get_plant` (design, validation, ledger, records and verifications of one plant) - Evidence: `audit_attestation` (report vs chain), `reproduce_attestation` (re-run the engine on the data published to HCS, check the registered design and meter, recompute the record's hash-chain link, compare every figure) - Verification: `get_pending_verification { plantId }` (the run a VVB verifies next, each record reproduced from HCS) - Guardian, before buying: `trace_guardian_mint { ref }` (ref = nft::, ft:: or a mint transaction id; follows the mint memo / NFT metadata to the VP on HCS, reads it from IPFS hash-checked against the CID, verifies the signatures, and checks the MintToken VC names this token and amount and the signer's DID was published by the token treasury → verdict backed / not-backed / incomplete). A real Managed Guardian mint that traces as backed: ref `0.0.10238177-1790602426-400520522` (token 0.0.10760359, 12.5 t) - Guardian: `verify_guardian_evidence { ref, topicIds? }` (verify a Guardian VP/VC chain from the mirror node and IPFS: topic, status, every Ed25519 signature; refuses chains with a MintToken VC or a Monitoring Report that does not match) - Checkout (any HTS token, e.g. a Guardian-minted one): `list_checkout_listings` (each listing with its token's Guardian verdict: backed, none, not-backed, incomplete) → `prepare_checkout_purchase { listingId, amount }` (unsigned UsdCheckout.buy; refused when the token cites a Guardian record that is not backed). Associate with the token first. - Market: `get_dex_price`, `list_open_listings`, `prepare_purchase` (unsigned buy / buyAndRetire for your own wallet), `get_credit_pool`, `prepare_dex_retire` (unsigned swap + deposit + retire on the WHBAR/credit pool), `get_retirement_certificate`, `get_portfolio` (retirements by an account or on behalf of a beneficiary) - Guardian figures: `compare_guardian_report` (recompute a Guardian VMR0017 monitoring report's BE, PE, LE and ER: MATCH, MISMATCH or NOT_COMPARABLE) - Write tools, listed only when the request carries `Authorization: Bearer `: `record_monitoring` (verify → HCS → recordMonitoring; issues nothing), `prepare_verification` (publish the VVB's verification report, return the EIP-712 VerificationStatement), `submit_verification` (relay the VVB's signature to verifyPeriod; an approval issues). The VVB signs with its own key; the server never holds one - Resource: `hydro-dmrv://methodology` (equations, QA/QC rules, IPCC bounds, what is not implemented) Buying as an agent: `get_dex_price` → `list_open_listings` → `prepare_purchase { listingId, amountKg, beneficiary }` → sign and send `{ to, data, value }` with your wallet on `chainId` → `get_retirement_certificate`. `prepare_purchase` returns nothing if the SaucerSwap WHBAR/USDC spot is more than 3% from the settlement price. Credits that have left custody: `get_credit_pool` → `prepare_dex_retire { amountKg, buyer, beneficiary }` → sign each `steps[]` in order. `prepare_dex_retire` returns nothing when the settlement oracle is paused, the settlement pair is disabled or not V1, either price check is outside 3%, or the credit pool is more than 3% from the cheapest open listing. The server never holds your key. ## Hedera facts (each proven by a test or workflow in the repo) Full list with proofs: https://github.com/BikramBiswas786/Hedera-hydropower-dMRV-with-5-layer-verification-/blob/main/HEDERA_FACTS.md - `msg.value` inside a contract is tinybar (1e8 per HBAR); a JSON-RPC transaction `value` is weibar (1e18). Scale by 1e10. - HTS calls return a response code (22 = SUCCESS) instead of reverting; check it. 184 = recipient not associated, 194 = already associated, 292 = no allowance. - Associate before receiving a token: call `associate()` on the token address (HIP-719), or use auto-association. - The Hashio relay wants legacy `gasPrice` transactions at `eth_gasPrice`. - The public testnet WHBAR/USDC pair prices HBAR near $2 (testnet USDC is not a dollar); check oracles against a seeded pair or the mainnet pair 0.0.1462797. - Verify a SaucerSwap pool with the factory's `getPair`, not the pool's own `factory()`. - HCS: at most 1,024 bytes per chunk and 20 chunks per message; read messages from the mirror node. - A scheduled transaction executes once its payer's key is satisfied: at `ScheduleCreate` for a single key, on the second `ScheduleSign` for a 2-of-3 `KeyList`. A `KeyList` account calls contracts from its long-zero address. ## Sell any HTS token at a USD price `UsdCheckout` (repo `packages/hardhat/contracts/UsdCheckout.sol`) uses the same settlement as `CreditMarket`: the seller approves the checkout on the token and calls `createListing(token, amount, usdCentsPerWholeToken)`; a buyer associated with the token calls `quote(listingId, amount)` and sends that much with `buy(listingId, amount)`. The HBAR is priced by Chainlink (Supra fallback), checked against a SaucerSwap pair within 3%, and swapped to the pair's USD token for the seller. ## REST - `POST /api/methodology/assess` — body ProjectDesign → assessment, designHash, registration integers - `POST /api/methodology/grid-emission-factor` — body TOOL07 input → OM, BM sample group, weights, CM - `GET /api/methodology/projects` — demo design documents with on-chain designHash check - `GET /api/methodology/projects/{plantId}?raw=1` — the exact bytes whose SHA-256 is the on-chain designHash - `GET /api/mrv/scenarios` — scenarios, demo plant profiles and metering - `GET /api/mrv/scenarios/{name}?hours=24&plant=HYDRO-DEMO-01` — a ready `/api/mrv/verify` body - `GET /api/mrv/engines` — methodology engines (hydro; solar, wind, ocean), each with its documents and on-chain module - `GET /api/mrv/engines/{id}` — one engine and a ready-to-verify example period - `POST /api/mrv/engines/{id}/verify` — the engine's input → decision, findings with clauses, data and parameters table - `POST /api/mrv/verify` — body `{ readings, plant?, metering?, ledger?, signature? }` → report, HCS report message, reportHash, dataHash, dataChunks - `GET /api/registry` — on-chain totals, plants (design + ledger), credit token, oracle status - `GET /api/registry/plants` — registered plants; `GET /api/registry/plants/{plantId}` — design, validation, ledger, totals, records, verifications - `GET /api/registry/attestations?start=0&count=20` — monitoring records: monitored inputs, EG_PJ, BE, PE, LE, ER, chain hash, status - `GET /api/registry/attestations/{id}/audit` — report vs on-chain record - `GET /api/registry/attestations/{id}/reproduce` — full reproduction from HCS data - `GET /api/registry/listings` — open listings with HBAR quotes (tinybar) - `GET /api/market/dex` — the SaucerSwap pair the market swaps through vs the settlement oracle, and the public mainnet WHBAR/USDC pair vs mainnet Chainlink - `POST /api/market/prepare-purchase` — body `{ listingId, amountKg, retire?: true, beneficiary?: "" }` - `GET /api/checkout/listings` — UsdCheckout listings with each token's Guardian verdict - `POST /api/checkout/prepare-purchase` — body `{ listingId, amount }` (base units); 409 if the token's Guardian record is not backed - `GET /api/registry/retirements/{id}` — retirement and NFT certificate - `GET /api/registry/retirements?account=0x…&beneficiary=…&format=json|csv` — portfolio: retirements by the account or on behalf of the beneficiary, totals, certificates; CSV for ESG reporting - `POST /api/mrv/record` — verify → HCS (readings, report) → recordMonitoring (issues nothing); bearer MRV_API_KEY - `GET /api/mrv/verification?plantId=…&lastRecord=…` — records awaiting a VVB, each reproduced from HCS - `POST /api/mrv/verification` — body `{ plantId, decision: approve|reject, deductionG?, findings?, evidenceHash?, lastRecord? }` → publishes the verification report, returns `statement` + EIP-712 `typedData`; bearer MRV_API_KEY - `POST /api/mrv/verification/submit` — body `{ plantId, statement, signature }` → verifyPeriod; bearer MRV_API_KEY - `GET /api/registry/issuances` — every VVB verification and what it issued - `POST /api/methodology/compare` — a Guardian monitoring report's figures → MATCH / MISMATCH / NOT_COMPARABLE - `POST /api/guardian/v1/cross-check?policyId=…` — for a Guardian policy's httpRequestBlock: body = the Monitoring Report VC → a "DMRV Cross-Check Result" VC signed by the bridge did:hedera (Ed25519Signature2018); requires `Authorization: Bearer `; 503 until the bridge key and DID are configured (docs/GUARDIAN.md) - `GET /api/guardian/v1/trace?ref=nft:token:serial|ft:token:account|0.0.x@s.n` — is a Guardian-minted token backed (same as `trace_guardian_mint`) - `GET /api/guardian/v1/evidence/{timestamp|0.0.x@s.n|nft:token:serial}?topicIds=0.0.a,0.0.b` — Guardian evidence check (same as `verify_guardian_evidence`) ## Data shapes - Reading: `{ timestamp (ISO 8601, end of interval), intervalMinutes, generationKwh (gross, TEG), exportKwh, importKwh?, checkExportKwh?, flowRateM3s, headM, fuelKg?, ph?, turbidityNtu?, temperatureC? }` - Metering: `{ mainMeterAccuracyPct, checkMeterAccuracyPct, calibrationValidUntil, flowUncertaintyPct, deviceAddress? }` - Meter signature: a verify request's `signature` is the meter key's EIP-712 signature over `MeterStatement(bytes32 projectId,uint32 sequence,uint64 periodStart,uint64 periodEnd,uint32 intervals,uint32 intervalSeconds,bytes32 meteredHash,bytes32 readingsDigest)` in the domain `{ name: "DmrvRegistry", version: "2", chainId, verifyingContract }`, with `meteredHash` = keccak256(abi.encode(int64 netWh, uint64 grossWh, uint64 fuelG, uint64 leakageG)) of the raw totals and `readingsDigest` = sha256({ schema: "hydro-dmrv/meter-batch@1", plantId, fields, readings }); `domain: { chainId, registry, sequence }` names the registry and the plant's next record number. See `services/mrv/provenance.ts`. Required when `metering.deviceAddress` is set; the contract also requires it, from the plant's registered meter, and rejects figures less conservative than the statement. Sample telemetry is signed by the public demo meter keys. - Decision: REJECTED for a missing or invalid meter signature, replayed or overlapping intervals, > 20% of intervals physically impossible, periods outside the crediting period or across a crediting year, or unregistered fuel; FLAGGED for coverage < 90%, excluded intervals, main/check meter disagreement, efficiency outliers or safeguard exceedances; otherwise APPROVED. - Units: energy in Wh, emissions in g CO2e, grid EF in g CO2/MWh, fuel in g, COEF in g CO2 per tonne of fuel. BE rounds down, PE rounds up; sub-kg remainders and deficits carry to the plant's next period. - VMR0017 (methodology 1 on-chain): hydro ≤ 15 MW (higher of rated and authorized capacity) in UN LDCs at the registration request, checked on-chain, VT0008 additionality evidence (IRR below the benchmark with a sensitivity analysis; common practice when F > 20% and N_all − N_diff > 3), EF_Res 100 kg CO2e/MWh, leakage = embodied emissions 21 g CO2e/kWh of EG_facility (greenfield) or EG_PJ_Add (capacity addition), and the grid factor by VT0011 (BM over all units incl. VCS/CDM ones, hydro weights 0.4/0.6 then 0.25/0.75). The grid-factor tool takes `tool: "TOOL07" | "VT0011"`. - HCS: `hydro-dmrv/readings@6` (readings + meter signature + domain + plant + metering + ledger, up to 20 chunks) then `hydro-dmrv/report@5` (monitored inputs, emissions, `data: { hash, sequence }`); the contract stores sha256(report) and its sequence in the record. A verification publishes `hydro-dmrv/verification@1` (records, chain head, decision, deduction, units to issue, findings), whose sha256 the VVB signs. - Prices: listings in US cents per tonne; quotes in the EVM's native unit (tinybar on Hedera); `prepare_purchase` returns `value` already scaled to 18-decimal weibar with a 1% buffer that the contract refunds. ## Source - Contracts: `packages/hardhat/contracts/DmrvRegistry.sol`, `modules/HydroVmr0017Module.sol`, `modules/RenewableVmr0017Module.sol`, `DmrvAnnotations.sol`, `CreditMarket.sol`, `ResilientHbarUsdFeed.sol` - Methodology: `packages/nextjs/services/mrv/methodology/` (tool07.ts, tool03.ts, project.ts, quantify.ts) - Engine: `packages/nextjs/services/mrv/engine.ts`; reproduction: `services/mrv/audit.ts` - Agent briefing for coding agents: `AGENTS.md`