Settlement & Audit
1) why we do that?
Transparency: Freeze all billable usage and prices for a cycle into a snapshot so any party can independently verify.
Verifiability: Every line item (including segmented routes) has a hash; the full set rolls up into a Merkle Root; the snapshot is signed.
Traceability: In case of dispute, you can drill down to the exact request record and its amount.
2) Billing Cycle & Artifacts
Cycle: Weekly.
Artifacts (at minimum):
snapshot.json – contains the Merkle Root of all successful call records in the cycle and the link to the price table for this epoch.
Example keys:
merkleRoot: Merkle root over all successful usage records.
priceUrl: URL to fetch the price table in effect for this cycle.
3) Snapshot Structure
3.1 Snapshot schema (example)
{
"epoch": 1234,
"merkleRoot": "0xabc...",
"priceUrl": "https://proxy.sightai.io/priceUrl/"
}
3.2 Subset export (private to User/Provider)
Exports are provided per account (e.g., my-records.jsonl / CSV). Field names may include requestId, model, tokenIn, tokenOut, proof, etc.
If a proof is present, you can validate each record’s inclusion against the Merkle Root.
Without proof, you can still recompute amounts and reconcile totals, but you cannot independently prove inclusion.
3.3 Merkle construction & proofs
Leaf: Compute keccak256 over the canonical JSON of each normalized record.
Ordering: Sort leaves by their hash (ascending) to form the leaf sequence.
Tree: Binary Merkle; if a level has an odd count, duplicate the last leaf to fill the pair.
Internal node: H = keccak256(left || right).
Root: Write the resulting merkleRoot into snapshot.json.
Proofs (optional): A proofs.jsonl may be provided:
{ "recordId": "...", "leaf": "0x...", "proof": ["0x...", "..."] }
Use it to verify leaf → merkleRoot membership.
4) Price Table & Units
Currency & precision: USD-stable, typically 6 decimal places.
Unit: per_1k_tokens (price per 1,000 tokens).
Structure (example):
"priceTable": [
{
"epoch": 1234,
"model": "gpt-4o",
"priceIn": 0.005, // expense price for input (USD / 1k tokens)
"priceOut": 0.015, // expense price for output (USD / 1k tokens)
"rewardIn": 0.004, // reward price for input (USD / 1k tokens)
"rewardOut": 0.013, // reward price for output (USD / 1k tokens)
"currency": "USD",
"unit": "per_1k_tokens"
}
]
Meaning
price* → Baseline expense prices for user billing.
reward* → Baseline reward prices for provider payouts.
5) Amount Formulas (as implemented)
User expense
userCostUSD = (priceIn * Tin / 1000) + (priceOut * Tout / 1000)
Provider reward
providerRewardUSD = (rewardIn * Tin / 1000) + (rewardOut * Tout / 1000)
Precision & rounding
Use fixed-point decimals (e.g., Decimal with 6 fractional digits) for monetary values.
Token counts are integers; amounts are stored/rounded to USD with 6 decimals.
6) Local Self-Verification (Offline)
6.1 Steps
Fetch the snapshot: Download snapshot.json for the cycle to get epoch, merkleRoot, and priceUrl.
Fetch the price table: Retrieve the priceTable for that epoch via priceUrl.
Export your subset: From the Console, export your relevant records (e.g., my-records.jsonl / CSV).
Verify Merkle inclusion (if proof is present):
Canonicalize each record JSON and hash → leaf.
Verify the path using the provided proof up to the merkleRoot.
(If no proof, skip—membership cannot be independently proven.)
Recompute amounts:
For each record, match on model and time/epoch to select priceIn/priceOut and rewardIn/rewardOut.
Compute userCostUSD and providerRewardUSD per record, then aggregate at your export’s granularity.
Totals should match the Console’s statements (any tiny deltas stem from rounding—align to 6 decimal places).
Handle discrepancies:
If you find mismatches (e.g., price tier selection, token counting method), note the requestId and contact Support with context.
Failed calls are not included in the Merkle tree.
Reference verifier: https://github.com/sight-ai/api-key-merkle-root-verifier
Last updated