{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lopw.com/docs/schemas/receipt-evm.json",
  "title": "Receipt (EVM binding)",
  "description": "The seller's signed statement of what it served on an EVM network (Solidity: Receipt). receiptHash is the EIP-712 digest under the same domain as the offer (chainId and registry replace Stellar's network id and registry address). On the wire it travels as SignedReceipt, ABI-encoded as 0x-hex, in PAYMENT-RESPONSE.extensions.lopw.receipt.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "version",
    "service_id",
    "offer_hash",
    "terms_hash",
    "buyer",
    "payment_reference",
    "request_hash",
    "response_hash",
    "response_bytes",
    "status",
    "served_at",
    "data_as_of",
    "has_oracle",
    "oracle",
    "key_version"
  ],
  "properties": {
    "version": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4294967295,
      "description": "Protocol version, 1",
      "const": 1
    },
    "service_id": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "The registered service"
    },
    "offer_hash": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "The EIP-712 digest of the exact warranty offer this receipt was served under"
    },
    "terms_hash": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "The terms the seller says it served under"
    },
    "buyer": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{40}$",
      "description": "The payer (x402 settlement payer), who receives any claim payout"
    },
    "payment_reference": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "The settlement transaction hash from PAYMENT-RESPONSE.transaction"
    },
    "request_hash": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "SHA-256(METHOD + '\\n' + path?query + '\\n' + lowercase-hex(SHA-256(body))), the same construction as on Stellar"
    },
    "response_hash": {
      "type": "string",
      "pattern": "^0x[0-9a-f]{64}$",
      "description": "SHA-256 of the response body as sent"
    },
    "response_bytes": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4294967295,
      "description": "Size of the response body in bytes"
    },
    "status": {
      "type": "integer",
      "minimum": 0,
      "maximum": 65535,
      "description": "HTTP status served"
    },
    "served_at": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18446744073709551615,
      "description": "Unix seconds when the response was sent"
    },
    "data_as_of": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18446744073709551615,
      "description": "Unix seconds the data was true as of; 0 if not applicable (P3 is then never proven)"
    },
    "has_oracle": {
      "type": "boolean",
      "description": "true when an oracle evidence block is present; oracle is zeroed when false"
    },
    "oracle": {
      "$ref": "#/$defs/OracleEvidence"
    },
    "key_version": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4294967295,
      "description": "Which signing key signed this receipt"
    }
  },
  "$defs": {
    "OracleEvidence": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "feed",
        "asset",
        "round_id",
        "oracle_price",
        "reported_value"
      ],
      "description": "Solidity: OracleEvidence { address feed; bytes32 asset; uint80 roundId; int256 oraclePrice; int256 reportedValue }",
      "properties": {
        "feed": {
          "type": "string",
          "pattern": "^0x[0-9a-fA-F]{40}$",
          "description": "The Chainlink AggregatorV3Interface feed named in the terms"
        },
        "asset": {
          "type": "string",
          "pattern": "^0x[0-9a-f]{64}$",
          "description": "The pair label as bytes32, for example bytes32(\"ETH/USD\"); must equal the terms' asset"
        },
        "round_id": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "description": "uint80: the Chainlink round the seller used. Rounds are immutable once published, so the round id is the citation the validator reads with getRoundData(roundId)"
        },
        "oracle_price": {
          "type": "string",
          "pattern": "^-?[0-9]+$",
          "description": "The feed answer the seller saw; informational, the validator reads the feed itself"
        },
        "reported_value": {
          "type": "string",
          "pattern": "^-?[0-9]+$",
          "description": "The value the seller served, in the feed's decimals (8 on Chainlink USD feeds)"
        }
      }
    },
    "SignedReceipt": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "receipt",
        "signature"
      ],
      "properties": {
        "receipt": {
          "$ref": "#"
        },
        "signature": {
          "type": "string",
          "pattern": "^0x[0-9a-f]{130}$",
          "description": "65-byte secp256k1 signature (r, s, v) as 0x-prefixed hex over the EIP-712 digest"
        }
      },
      "description": "Solidity: SignedReceipt { Receipt receipt; bytes signature }"
    },
    "SignedReceiptWire": {
      "type": "string",
      "pattern": "^0x([0-9a-f]{2})+$",
      "description": "abi.encode(SignedReceipt) as 0x-prefixed hex: the value of PAYMENT-RESPONSE.extensions.lopw.receipt on EVM networks (base64 ScVal XDR on Stellar)",
      "title": "SignedReceipt on the wire"
    },
    "ClaimExtra": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "has_second",
        "second"
      ],
      "description": "Solidity: ClaimExtra { bool hasSecond; SignedReceipt second } (P1 only)",
      "properties": {
        "has_second": {
          "type": "boolean"
        },
        "second": {
          "$ref": "#/$defs/SignedReceipt"
        }
      }
    },
    "EIP712Types": {
      "const": [
        "OracleEvidence(address feed,bytes32 asset,uint80 roundId,int256 oraclePrice,int256 reportedValue)",
        "Receipt(uint32 version,bytes32 serviceId,bytes32 offerHash,bytes32 termsHash,address buyer,bytes32 paymentReference,bytes32 requestHash,bytes32 responseHash,uint32 responseBytes,uint16 status,uint64 servedAt,uint64 dataAsOf,bool hasOracle,OracleEvidence oracle,uint32 keyVersion)"
      ],
      "description": "The exact EIP-712 type strings; the nested OracleEvidence struct is hashed by its own type hash"
    }
  }
}
