Transaction Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://localloop.urbnia.com/projects/loop-protocol/schemas/v0.2.0/transaction.schema.json",
  "title": "Transaction",
  "description": "Transaction schema — LOOP v0.2.0",
  "oneOf": [
    {
      "$ref": "#/definitions/MaterialTransaction"
    },
    {
      "$ref": "#/definitions/Settlement"
    },
    {
      "$ref": "#/definitions/TransactionStatus"
    }
  ],
  "definitions": {
    "MaterialTransaction": {
      "type": "object",
      "required": [
        "@context",
        "@type",
        "id",
        "material",
        "seller",
        "buyer",
        "offer",
        "timestamp"
      ],
      "properties": {
        "@context": {
          "type": "string",
          "enum": [
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.1.1.jsonld",
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.2.0.jsonld"
          ]
        },
        "@type": {
          "type": "string",
          "const": "MaterialTransaction"
        },
        "schema_version": {
          "description": "Optional schema version identifier.",
          "type": "string",
          "pattern": "^0\\.[1-9]\\d*\\.\\d+$",
          "examples": [
            "0.2.0"
          ]
        },
        "id": {
          "description": "Transaction ID",
          "type": "string",
          "pattern": "^TXN-\\d{4}-\\d{2}-\\d{2}-\\d{3,}$",
          "examples": [
            "TXN-2025-05-27-001"
          ]
        },
        "material": {
          "description": "MaterialDNA reference",
          "type": "string",
          "pattern": "^MAT-[A-Z]{2}-[A-Z]{3}-\\d{4}-[A-Z]+-[A-Z0-9]{6,}$"
        },
        "seller": {
          "description": "Selling node",
          "type": "string",
          "pattern": "^[a-z0-9\\-]+\\.loop$"
        },
        "buyer": {
          "description": "Buying node",
          "type": "string",
          "pattern": "^[a-z0-9\\-]+\\.loop$"
        },
        "offer": {
          "type": "object",
          "required": [
            "base_price",
            "loop_cost"
          ],
          "properties": {
            "base_price": {
              "type": "number",
              "minimum": 0
            },
            "loop_cost": {
              "type": "number",
              "minimum": 0
            },
            "breakdown": {
              "type": "object",
              "properties": {
                "export_penalty": {
                  "type": "number",
                  "minimum": 0
                },
                "import_penalty": {
                  "type": "number",
                  "minimum": 0
                },
                "distance_cost": {
                  "type": "number",
                  "minimum": 0
                }
              }
            }
          }
        },
        "timestamp": {
          "type": "string",
          "format": "date-time"
        },
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "confirmed",
            "completed",
            "cancelled",
            "disputed"
          ],
          "default": "pending"
        }
      },
      "additionalProperties": true
    },
    "Settlement": {
      "type": "object",
      "required": [
        "@context",
        "@type",
        "transaction_id",
        "material",
        "seller",
        "buyer",
        "final_cost",
        "distribution",
        "settled_at"
      ],
      "properties": {
        "@context": {
          "type": "string",
          "enum": [
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.1.1.jsonld",
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.2.0.jsonld"
          ]
        },
        "@type": {
          "type": "string",
          "const": "Settlement"
        },
        "schema_version": {
          "description": "Optional schema version identifier.",
          "type": "string",
          "pattern": "^0\\.[1-9]\\d*\\.\\d+$",
          "examples": [
            "0.2.0"
          ]
        },
        "transaction_id": {
          "type": "string",
          "pattern": "^TXN-\\d{4}-\\d{2}-\\d{2}-\\d{3,}$"
        },
        "material": {
          "type": "string",
          "pattern": "^MAT-[A-Z]{2}-[A-Z]{3}-\\d{4}-[A-Z]+-[A-Z0-9]{6,}$"
        },
        "seller": {
          "type": "string",
          "pattern": "^[a-z0-9\\-]+\\.loop$"
        },
        "buyer": {
          "type": "string",
          "pattern": "^[a-z0-9\\-]+\\.loop$"
        },
        "final_cost": {
          "type": "number",
          "minimum": 0
        },
        "distribution": {
          "type": "object",
          "required": [
            "seller_receives"
          ],
          "properties": {
            "seller_receives": {
              "type": "number",
              "minimum": 0
            },
            "seller_community_fund": {
              "type": "number",
              "minimum": 0
            },
            "buyer_community_fund": {
              "type": "number",
              "minimum": 0
            },
            "transport_cost": {
              "type": "number",
              "minimum": 0
            }
          }
        },
        "settled_at": {
          "type": "string",
          "format": "date-time"
        },
        "confirmation": {
          "type": "object",
          "properties": {
            "material_transferred": {
              "type": "boolean"
            },
            "payment_completed": {
              "type": "boolean"
            },
            "signatures": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "additionalProperties": true
    },
    "TransactionStatus": {
      "type": "object",
      "required": [
        "@context",
        "@type",
        "transaction_id",
        "status",
        "updated_at"
      ],
      "properties": {
        "@context": {
          "type": "string",
          "enum": [
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.1.1.jsonld",
            "https://localloop.urbnia.com/projects/loop-protocol/contexts/loop-v0.2.0.jsonld"
          ]
        },
        "@type": {
          "type": "string",
          "const": "TransactionStatus"
        },
        "schema_version": {
          "description": "Optional schema version identifier.",
          "type": "string",
          "pattern": "^0\\.[1-9]\\d*\\.\\d+$",
          "examples": [
            "0.2.0"
          ]
        },
        "transaction_id": {
          "type": "string",
          "pattern": "^TXN-\\d{4}-\\d{2}-\\d{2}-\\d{3,}$"
        },
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "confirmed",
            "in_transit",
            "delivered",
            "completed",
            "cancelled",
            "disputed"
          ]
        },
        "updated_at": {
          "type": "string",
          "format": "date-time"
        },
        "details": {
          "type": "object",
          "properties": {
            "location": {
              "type": "object",
              "properties": {
                "lat": {
                  "type": "number"
                },
                "lon": {
                  "type": "number"
                }
              }
            },
            "estimated_arrival": {
              "type": "string",
              "format": "date-time"
            },
            "notes": {
              "type": "string",
              "maxLength": 500
            }
          }
        },
        "settlement_url": {
          "type": "string"
        }
      },
      "additionalProperties": true
    }
  }
}