diff --git a/examples/oapp-ai-oracle/.env.example b/examples/oapp-ai-oracle/.env.example
new file mode 100644
index 000000000..c737771ff
--- /dev/null
+++ b/examples/oapp-ai-oracle/.env.example
@@ -0,0 +1,9 @@
+# .env.example
+# Copy to .env and fill in your values
+
+# Deployer private key (with testnet ETH/BNB for gas)
+PRIVATE_KEY=0x...
+
+# RPC URLs (optional — defaults to public RPCs)
+RPC_URL_SEPOLIA=https://rpc.sepolia.org
+RPC_URL_BSC_TESTNET=https://data-seed-prebsc-1-s1.bnbchain.org:8545
diff --git a/examples/oapp-ai-oracle/.gitignore b/examples/oapp-ai-oracle/.gitignore
new file mode 100644
index 000000000..ac0e999ce
--- /dev/null
+++ b/examples/oapp-ai-oracle/.gitignore
@@ -0,0 +1,7 @@
+node_modules/
+artifacts/
+cache/
+dist/
+.env
+evidence-store/
+deployments/
diff --git a/examples/oapp-ai-oracle/LICENSE b/examples/oapp-ai-oracle/LICENSE
new file mode 100644
index 000000000..c1c033791
--- /dev/null
+++ b/examples/oapp-ai-oracle/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 NEOscript
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/examples/oapp-ai-oracle/README.md b/examples/oapp-ai-oracle/README.md
new file mode 100644
index 000000000..c372ba97e
--- /dev/null
+++ b/examples/oapp-ai-oracle/README.md
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+ LayerZero Docs · Live Demo
+
+
+AI Evidence Oracle (OApp) — Procedural Proof
+
+
+ A new trust primitive for the AI era.
+ Oracle verifies AI process compliance, not data correctness — then dispatches verified decisions cross-chain via LayerZero V2.
+
+
+## The Problem
+
+AI outputs are non-deterministic. Every existing trust primitive fails for them:
+
+| Primitive | Why it fails for AI |
+|-----------|-------------------|
+| PoW | Can't prove AI "did work" — inference isn't hashable |
+| PoS | Stake doesn't grant cognitive authority |
+| ZK Proof | AI reasoning isn't a deterministic circuit |
+| Consensus | Re-running same prompt ≠ same output |
+| Multisig | Signers judge conclusion, not process |
+
+## The Solution: Procedural Proof
+
+Don't verify the conclusion. Verify the process.
+
+```
+Trust nothing. Verify process. Challenge freely.
+```
+
+The AI follows a public SOP (Standard Operating Procedure). It submits an evidence package proving every step was followed. Independent verifiers audit the process — not the data, not the conclusion, just "was the SOP followed?"
+
+Anyone can replay the verification. Fraud is always detectable.
+
+## Architecture — Four Layers
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Layer 1: EVIDENCE AI executes SOP → evidence → IPFS │
+│ Hash committed on-chain │
+├─────────────────────────────────────────────────────────────┤
+│ Layer 2: VERIFICATION Verifiers audit evidence vs SOP │
+│ Threshold signatures (2-of-3) │
+├─────────────────────────────────────────────────────────────┤
+│ Layer 3: DISTRIBUTION LayerZero V2 cross-chain dispatch │
+│ One judgment → multiple chains │
+├─────────────────────────────────────────────────────────────┤
+│ Layer 4: EXECUTION Target chain receives & acts │
+│ _lzReceive() triggers logic │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## Isomorphic to LayerZero DVN
+
+The trust model is structurally identical to how DVN secures cross-chain messages:
+
+| | LayerZero DVN | Evidence Oracle |
+|--|--------------|-----------------|
+| **Verifies** | Message transport integrity | AI SOP compliance |
+| **Method** | Hash comparison (source ↔ destination) | Evidence replay (package ↔ SOP rules) |
+| **Trust source** | Not the verifier — the replayability | Not the verifier — the replayability |
+| **Fraud proof** | Anyone reads source chain hash | Anyone fetches IPFS evidence + SOP |
+| **Selection** | OApp chooses DVN set | Agent chooses Verifier set |
+
+## Prerequisite Knowledge
+
+- [What is an OApp?](https://docs.layerzero.network/v2/concepts/applications/oapp-standard)
+- [How does LayerZero work?](https://docs.layerzero.network/v2/concepts/protocol/core-concepts)
+
+## Requirements
+
+- `Node.js` >= 18.16.0
+- `pnpm` (recommended)
+
+## Setup
+
+```bash
+# Clone
+git clone https://github.com/fmdd123123-create/neo-oracle.git
+cd neo-oracle
+
+# Install
+pnpm install
+
+# Configure
+cp .env.example .env
+# Edit .env with your private key (needs testnet ETH + BNB)
+```
+
+## Build
+
+```bash
+pnpm compile
+```
+
+## Deploy
+
+```bash
+# Deploy to both testnets
+pnpm deploy --network eth-sepolia
+pnpm deploy --network bsc-testnet
+```
+
+## Wire (Set Peers)
+
+```bash
+pnpm wire
+```
+
+## Usage — Full Flow
+
+### 1. AI submits decision with evidence
+
+```bash
+pnpm hardhat ai:submit --network eth-sepolia --sop rainfall-trigger-v1
+```
+
+### 2. Verifier audits SOP compliance
+
+```bash
+pnpm hardhat verify:decision --network eth-sepolia --id 0
+```
+
+### 3. Dispatch verified decision cross-chain
+
+```bash
+pnpm hardhat dispatch:decision --network eth-sepolia --id 0 --dst-eid 40102
+```
+
+### 4. (Optional) Challenge a fraudulent decision
+
+```bash
+pnpm hardhat challenge:decision --network eth-sepolia --id 0 --reason "Source not in whitelist"
+```
+
+## Live Deployment
+
+| Network | Contract | EID |
+|---------|----------|-----|
+| Eth Sepolia | `0xaa24CC417EC7ae219F52C400E64E600AAfD3f45d` | 40161 |
+| BSC Testnet | `0xc7FFF00d2c2C6B0aC5D726d3E6e317cCae638214` | 40102 |
+
+Cross-chain message dispatched and verified on [LayerZeroScan](https://testnet.layerzeroscan.com).
+
+## SOP Example
+
+See [`sop/rainfall-trigger-v1.json`](./sop/rainfall-trigger-v1.json) — a complete Standard Operating Procedure for rainfall-triggered insurance. Each step defines required evidence, allowed sources, and verification criteria.
+
+## Why This Matters
+
+Every existing Oracle (Chainlink, Band, API3) answers: **"Is this DATA correct?"**
+
+Evidence Oracle answers: **"Was this PROCESS followed?"**
+
+For AI outputs — where correctness is undecidable but process compliance is verifiable — this is the only viable trust model.
+
+## Roadmap
+
+- [x] Core contract with four-layer architecture
+- [x] LayerZero V2 OApp integration
+- [x] Cross-chain dispatch (Sepolia → BSC Testnet)
+- [x] SOP framework with verification checklist
+- [x] Hardhat tasks for full flow demo
+- [ ] IPFS integration (Pinata/web3.storage)
+- [ ] EIP-712 typed verifier signatures
+- [ ] Slashing mechanism for fraudulent verifiers
+- [ ] Multi-chain scatter (1 decision → N chains)
+- [ ] SOP governance (who writes/modifies SOPs)
+
+## Acknowledgments
+
+Built on [LayerZero V2](https://layerzero.network). The DVN architecture provided both the infrastructure for cross-chain distribution and the conceptual model for our trust design — the isomorphism between DVN transport verification and SOP compliance verification is the foundation of Procedural Proof.
+
+## License
+
+[MIT](./LICENSE)
+
+---
+
+*NEO Oracle — Trust nothing. Verify process. Challenge freely.*
+
+Built by [NEOscript](https://ark.honeyhughub.world/neo-oracle/)
diff --git a/examples/oapp-ai-oracle/contracts/EvidenceOracle.sol b/examples/oapp-ai-oracle/contracts/EvidenceOracle.sol
new file mode 100644
index 000000000..b7bc87a69
--- /dev/null
+++ b/examples/oapp-ai-oracle/contracts/EvidenceOracle.sol
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.22;
+
+import { OApp, Origin, MessagingFee, MessagingReceipt } from "@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol";
+import { OAppOptionsType3 } from "@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol";
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+
+/**
+ * @title EvidenceOracle
+ * @notice Procedural Proof — A new trust primitive for AI-era cross-chain governance.
+ *
+ * This OApp implements a four-layer epistemic governance architecture:
+ * 1. Evidence Layer: AI submits decision + evidence hash (IPFS CID commitment)
+ * 2. Verification Layer: Independent verifiers audit AI's SOP compliance
+ * 3. Distribution Layer: LayerZero dispatches verified decisions cross-chain
+ * 4. Execution Layer: Target chain receives and acts on verified decisions
+ *
+ * Trust model isomorphic to LayerZero DVN:
+ * - DVN verifies message transport integrity (hash comparison)
+ * - EvidenceOracle verifies AI process compliance (SOP audit)
+ * - Both are permissionlessly challengeable (fraud proof via replay)
+ *
+ * @dev Inherits OApp for native LayerZero V2 cross-chain messaging.
+ */
+contract EvidenceOracle is OApp, OAppOptionsType3 {
+
+ // ═══════════════════════════════════════════
+ // STRUCTS
+ // ═══════════════════════════════════════════
+
+ struct Decision {
+ bytes32 evidenceCid; // IPFS CID of full evidence package
+ bytes32 sopHash; // keccak256 of the SOP document used
+ bytes32 conclusionHash; // keccak256 of AI's conclusion
+ uint8 conclusion; // 0=NO_TRIGGER, 1=TRIGGER
+ uint64 timestamp; // when AI executed the SOP
+ address submitter; // AI agent address
+ uint8 approvals; // verifier approval count
+ uint8 rejections; // verifier rejection count
+ bool dispatched; // whether cross-chain dispatch occurred
+ bool challenged; // whether a challenge was raised
+ }
+
+ struct SOP {
+ bytes32 sopHash;
+ string name;
+ string ipfsCid; // full SOP doc on IPFS
+ bool active;
+ }
+
+ // ═══════════════════════════════════════════
+ // STATE
+ // ═══════════════════════════════════════════
+
+ uint256 public decisionCount;
+ uint8 public threshold = 2; // approvals needed for dispatch
+
+ mapping(uint256 => Decision) public decisions;
+ mapping(bytes32 => SOP) public sops; // sopHash => SOP
+ mapping(address => bool) public verifiers;
+ mapping(uint256 => mapping(address => bool)) public hasVoted;
+
+ // ═══════════════════════════════════════════
+ // EVENTS
+ // ═══════════════════════════════════════════
+
+ event SOPRegistered(bytes32 indexed sopHash, string name, string ipfsCid);
+ event DecisionSubmitted(uint256 indexed id, address submitter, bytes32 evidenceCid, bytes32 sopHash);
+ event DecisionVerified(uint256 indexed id, address verifier, bool approved);
+ event DecisionDispatched(uint256 indexed id, uint32 dstEid, bytes32 receiver);
+ event DecisionChallenged(uint256 indexed id, address challenger, string reason);
+ event VerifierUpdated(address verifier, bool status);
+
+ // ═══════════════════════════════════════════
+ // CONSTRUCTOR
+ // ═══════════════════════════════════════════
+
+ constructor(
+ address _endpoint,
+ address _delegate
+ ) OApp(_endpoint, _delegate) Ownable(_delegate) {}
+
+ // ═══════════════════════════════════════════
+ // SOP MANAGEMENT
+ // ═══════════════════════════════════════════
+
+ /// @notice Register a new Standard Operating Procedure
+ /// @param name Human-readable SOP name
+ /// @param ipfsCid IPFS CID where the full SOP document is stored
+ function registerSOP(string calldata name, string calldata ipfsCid) external onlyOwner {
+ bytes32 sopHash = keccak256(abi.encodePacked(name, ipfsCid));
+ sops[sopHash] = SOP(sopHash, name, ipfsCid, true);
+ emit SOPRegistered(sopHash, name, ipfsCid);
+ }
+
+ // ═══════════════════════════════════════════
+ // VERIFIER MANAGEMENT
+ // ═══════════════════════════════════════════
+
+ function setVerifier(address verifier, bool status) external onlyOwner {
+ verifiers[verifier] = status;
+ emit VerifierUpdated(verifier, status);
+ }
+
+ function setThreshold(uint8 _threshold) external onlyOwner {
+ threshold = _threshold;
+ }
+
+ // ═══════════════════════════════════════════
+ // LAYER 1: EVIDENCE SUBMISSION
+ // ═══════════════════════════════════════════
+
+ /// @notice AI agent submits a decision with evidence commitment
+ /// @param evidenceCid IPFS CID of the full evidence package (inputs, steps, outputs)
+ /// @param sopHash Which SOP was followed
+ /// @param conclusionHash keccak256 of the conclusion data
+ /// @param conclusion 0=NO_TRIGGER, 1=TRIGGER
+ function submitDecision(
+ bytes32 evidenceCid,
+ bytes32 sopHash,
+ bytes32 conclusionHash,
+ uint8 conclusion
+ ) external returns (uint256 decisionId) {
+ require(sops[sopHash].active, "SOP not registered or inactive");
+
+ decisionId = decisionCount++;
+ decisions[decisionId] = Decision({
+ evidenceCid: evidenceCid,
+ sopHash: sopHash,
+ conclusionHash: conclusionHash,
+ conclusion: conclusion,
+ timestamp: uint64(block.timestamp),
+ submitter: msg.sender,
+ approvals: 0,
+ rejections: 0,
+ dispatched: false,
+ challenged: false
+ });
+
+ emit DecisionSubmitted(decisionId, msg.sender, evidenceCid, sopHash);
+ }
+
+ // ═══════════════════════════════════════════
+ // LAYER 2: SOP COMPLIANCE VERIFICATION
+ // ═══════════════════════════════════════════
+
+ /// @notice Verifier audits evidence against SOP and votes
+ /// @dev Isomorphic to DVN hash verification — verifier checks process, not conclusion
+ function verify(uint256 decisionId, bool approved) external {
+ require(verifiers[msg.sender], "Not a registered verifier");
+ require(!hasVoted[decisionId][msg.sender], "Already voted");
+ require(!decisions[decisionId].dispatched, "Already dispatched");
+
+ hasVoted[decisionId][msg.sender] = true;
+
+ if (approved) {
+ decisions[decisionId].approvals++;
+ } else {
+ decisions[decisionId].rejections++;
+ }
+
+ emit DecisionVerified(decisionId, msg.sender, approved);
+ }
+
+ // ═══════════════════════════════════════════
+ // LAYER 3: CROSS-CHAIN DISPATCH (LayerZero)
+ // ═══════════════════════════════════════════
+
+ /// @notice Dispatch verified decision to target chain via LayerZero
+ /// @param decisionId The decision to dispatch
+ /// @param dstEid LayerZero Endpoint ID of target chain
+ /// @param options LayerZero execution options (gas, value)
+ function dispatch(
+ uint256 decisionId,
+ uint32 dstEid,
+ bytes calldata options
+ ) external payable returns (MessagingReceipt memory receipt) {
+ Decision storage d = decisions[decisionId];
+ require(d.approvals >= threshold, "Threshold not met");
+ require(!d.dispatched, "Already dispatched");
+
+ d.dispatched = true;
+
+ // Encode the verified decision for cross-chain delivery
+ bytes memory payload = abi.encode(
+ decisionId,
+ d.evidenceCid,
+ d.sopHash,
+ d.conclusionHash,
+ d.conclusion,
+ d.approvals
+ );
+
+ receipt = _lzSend(dstEid, payload, options, MessagingFee(msg.value, 0), payable(msg.sender));
+
+ emit DecisionDispatched(decisionId, dstEid, peers[dstEid]);
+ }
+
+ /// @notice Quote the fee for dispatching a decision
+ function quoteDispatch(
+ uint256 decisionId,
+ uint32 dstEid,
+ bytes calldata options
+ ) external view returns (MessagingFee memory fee) {
+ Decision storage d = decisions[decisionId];
+ bytes memory payload = abi.encode(
+ decisionId,
+ d.evidenceCid,
+ d.sopHash,
+ d.conclusionHash,
+ d.conclusion,
+ d.approvals
+ );
+ fee = _quote(dstEid, payload, options, false);
+ }
+
+ // ═══════════════════════════════════════════
+ // LAYER 4: RECEIVE (Target Chain)
+ // ═══════════════════════════════════════════
+
+ /// @notice Handle incoming verified decision from source chain
+ /// @dev Override this in your target-chain contract to execute domain logic
+ function _lzReceive(
+ Origin calldata /*_origin*/,
+ bytes32 /*_guid*/,
+ bytes calldata _message,
+ address /*_executor*/,
+ bytes calldata /*_extraData*/
+ ) internal override {
+ (
+ uint256 decisionId,
+ bytes32 evidenceCid,
+ bytes32 sopHash,
+ bytes32 conclusionHash,
+ uint8 conclusion,
+ uint8 approvals
+ ) = abi.decode(_message, (uint256, bytes32, bytes32, bytes32, uint8, uint8));
+
+ // Store received decision — extend this for domain-specific execution
+ decisions[decisionId] = Decision({
+ evidenceCid: evidenceCid,
+ sopHash: sopHash,
+ conclusionHash: conclusionHash,
+ conclusion: conclusion,
+ timestamp: uint64(block.timestamp),
+ submitter: address(0), // cross-chain, original submitter not preserved
+ approvals: approvals,
+ rejections: 0,
+ dispatched: true,
+ challenged: false
+ });
+ decisionCount++;
+ }
+
+ // ═══════════════════════════════════════════
+ // CHALLENGE (Fraud Proof)
+ // ═══════════════════════════════════════════
+
+ /// @notice Anyone can challenge a decision by providing evidence of SOP violation
+ /// @dev Off-chain: challenger fetches evidence from IPFS, replays SOP, finds violation
+ function challenge(uint256 decisionId, string calldata reason) external {
+ require(decisions[decisionId].approvals > 0, "Decision does not exist");
+ decisions[decisionId].challenged = true;
+ emit DecisionChallenged(decisionId, msg.sender, reason);
+ // In production: slash verifiers who approved a fraudulent decision
+ }
+}
diff --git a/examples/oapp-ai-oracle/deploy/001_deploy_evidence_oracle.ts b/examples/oapp-ai-oracle/deploy/001_deploy_evidence_oracle.ts
new file mode 100644
index 000000000..675a5d275
--- /dev/null
+++ b/examples/oapp-ai-oracle/deploy/001_deploy_evidence_oracle.ts
@@ -0,0 +1,23 @@
+import { DeployFunction } from 'hardhat-deploy/types'
+import { HardhatRuntimeEnvironment } from 'hardhat/types'
+import { EndpointId } from '@layerzerolabs/lz-definitions'
+
+// LayerZero V2 testnet endpoint (shared across testnets)
+const LZ_ENDPOINT_TESTNET = '0x6edce65403992e310a62460808c4b910d972f10f'
+
+const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
+ const { deploy } = hre.deployments
+ const { deployer } = await hre.getNamedAccounts()
+
+ const endpointAddress = LZ_ENDPOINT_TESTNET
+
+ await deploy('EvidenceOracle', {
+ from: deployer,
+ args: [endpointAddress, deployer],
+ log: true,
+ waitConfirmations: 1,
+ })
+}
+
+deploy.tags = ['EvidenceOracle']
+export default deploy
diff --git a/examples/oapp-ai-oracle/hardhat.config.ts b/examples/oapp-ai-oracle/hardhat.config.ts
new file mode 100644
index 000000000..a198705ff
--- /dev/null
+++ b/examples/oapp-ai-oracle/hardhat.config.ts
@@ -0,0 +1,41 @@
+import 'dotenv/config'
+import { HardhatUserConfig } from 'hardhat/config'
+import '@nomicfoundation/hardhat-toolbox'
+import 'hardhat-deploy'
+
+// LayerZero devtools
+import '@layerzerolabs/toolbox-hardhat'
+
+const PRIVATE_KEY = process.env.PRIVATE_KEY || '0x' + '0'.repeat(64)
+
+const config: HardhatUserConfig = {
+ solidity: {
+ compilers: [
+ {
+ version: '0.8.22',
+ settings: {
+ optimizer: { enabled: true, runs: 200 },
+ },
+ },
+ ],
+ },
+ networks: {
+ 'eth-sepolia': {
+ eid: 40161,
+ url: process.env.RPC_URL_SEPOLIA || 'https://rpc.sepolia.org',
+ accounts: [PRIVATE_KEY],
+ },
+ 'bsc-testnet': {
+ eid: 40102,
+ url: process.env.RPC_URL_BSC_TESTNET || 'https://data-seed-prebsc-1-s1.bnbchain.org:8545',
+ accounts: [PRIVATE_KEY],
+ },
+ },
+ namedAccounts: {
+ deployer: {
+ default: 0,
+ },
+ },
+}
+
+export default config
diff --git a/examples/oapp-ai-oracle/layerzero.config.ts b/examples/oapp-ai-oracle/layerzero.config.ts
new file mode 100644
index 000000000..5cd92f060
--- /dev/null
+++ b/examples/oapp-ai-oracle/layerzero.config.ts
@@ -0,0 +1,31 @@
+import { EndpointId } from '@layerzerolabs/lz-definitions'
+import type { OAppOmniGraphHardhat, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat'
+
+const sepoliaContract: OmniPointHardhat = {
+ eid: EndpointId.SEPOLIA_V2_TESTNET,
+ contractName: 'EvidenceOracle',
+}
+
+const bscTestnetContract: OmniPointHardhat = {
+ eid: EndpointId.BSC_V2_TESTNET,
+ contractName: 'EvidenceOracle',
+}
+
+const config: OAppOmniGraphHardhat = {
+ contracts: [
+ { contract: sepoliaContract },
+ { contract: bscTestnetContract },
+ ],
+ connections: [
+ {
+ from: sepoliaContract,
+ to: bscTestnetContract,
+ },
+ {
+ from: bscTestnetContract,
+ to: sepoliaContract,
+ },
+ ],
+}
+
+export default config
diff --git a/examples/oapp-ai-oracle/package.json b/examples/oapp-ai-oracle/package.json
new file mode 100644
index 000000000..b8726ee99
--- /dev/null
+++ b/examples/oapp-ai-oracle/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@neo-oracle/evidence-oapp",
+ "version": "0.1.0",
+ "description": "Procedural Proof — AI Oracle as epistemic governance infrastructure on LayerZero V2",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/fmdd123123-create/neo-oracle.git"
+ },
+ "scripts": {
+ "compile": "pnpm compile:hardhat",
+ "compile:hardhat": "hardhat compile",
+ "clean": "rm -rf artifacts cache",
+ "test": "hardhat test",
+ "deploy": "hardhat lz:deploy --tags EvidenceOracle",
+ "wire": "hardhat lz:oapp:wire --oapp-config layerzero.config.ts",
+ "lint": "solhint 'contracts/**/*.sol'"
+ },
+ "devDependencies": {
+ "@layerzerolabs/lz-definitions": "^3.0.0",
+ "@layerzerolabs/lz-v2-utilities": "^3.0.0",
+ "@layerzerolabs/oapp-evm": "^0.1.0",
+ "@layerzerolabs/toolbox-hardhat": "^0.4.0",
+ "@nomicfoundation/hardhat-ethers": "^3.0.0",
+ "@nomicfoundation/hardhat-toolbox": "^5.0.0",
+ "@openzeppelin/contracts": "^5.0.0",
+ "dotenv": "^16.3.1",
+ "ethers": "^6.13.0",
+ "hardhat": "^2.22.0",
+ "hardhat-deploy": "^0.14.0",
+ "solhint": "^5.0.0",
+ "typescript": "^5.4.0"
+ },
+ "engines": {
+ "node": ">=18.16.0"
+ }
+}
diff --git a/examples/oapp-ai-oracle/sop/rainfall-trigger-v1.json b/examples/oapp-ai-oracle/sop/rainfall-trigger-v1.json
new file mode 100644
index 000000000..5952fda01
--- /dev/null
+++ b/examples/oapp-ai-oracle/sop/rainfall-trigger-v1.json
@@ -0,0 +1,54 @@
+{
+ "sop_id": "rainfall-trigger-v1",
+ "version": "1.0.0",
+ "description": "Determine if 24-hour cumulative rainfall exceeds threshold for on-chain trigger",
+ "trigger_condition": "24h cumulative rainfall > threshold_mm",
+ "parameters": {
+ "threshold_mm": 100,
+ "location": "Surat Thani, Thailand",
+ "min_sources": 2,
+ "max_source_divergence_pct": 20,
+ "time_window_hours": 24
+ },
+ "steps": [
+ {
+ "step": 1,
+ "action": "Fetch rainfall data from ≥2 independent meteorological sources",
+ "allowed_sources": [
+ "openweathermap.org",
+ "weather.gov",
+ "hko.gov.hk",
+ "tmd.go.th"
+ ],
+ "evidence_required": ["source_url", "raw_response", "timestamp"]
+ },
+ {
+ "step": 2,
+ "action": "Calculate 24h cumulative rainfall from each source",
+ "evidence_required": ["per_source_value_mm", "computation_method"]
+ },
+ {
+ "step": 3,
+ "action": "Check source divergence: |max - min| / avg < max_source_divergence_pct",
+ "evidence_required": ["divergence_pct", "pass_or_fail"]
+ },
+ {
+ "step": 4,
+ "action": "If divergence check PASSES: compute average. If FAILS: abort (NO_TRIGGER)",
+ "evidence_required": ["average_mm_or_abort_reason"]
+ },
+ {
+ "step": 5,
+ "action": "Compare average to threshold_mm. If avg > threshold → TRIGGER. Else → NO_TRIGGER",
+ "evidence_required": ["comparison", "final_conclusion"]
+ }
+ ],
+ "verification_checklist": [
+ "All sources are in allowed_sources list",
+ "Timestamps are within acceptable window (not stale)",
+ "Number of sources >= min_sources",
+ "Divergence calculation is correct",
+ "Threshold comparison is correct",
+ "Conclusion matches the computation"
+ ]
+}
diff --git a/examples/oapp-ai-oracle/tasks/ai-submit.ts b/examples/oapp-ai-oracle/tasks/ai-submit.ts
new file mode 100644
index 000000000..a3a6fb75a
--- /dev/null
+++ b/examples/oapp-ai-oracle/tasks/ai-submit.ts
@@ -0,0 +1,82 @@
+import { task } from 'hardhat/config'
+import { ethers } from 'ethers'
+
+/**
+ * AI Agent Task — Execute SOP and submit evidence to EvidenceOracle
+ *
+ * Demonstrates Layer 1 (Evidence Submission):
+ * AI follows SOP → builds evidence package → commits hash on-chain
+ *
+ * Usage:
+ * pnpm hardhat ai:submit --network eth-sepolia --sop rainfall-trigger-v1
+ */
+task('ai:submit', 'AI agent executes SOP and submits evidence on-chain')
+ .addParam('sop', 'SOP name (must match file in sop/ directory)')
+ .setAction(async (taskArgs, hre) => {
+ const { sop } = taskArgs
+ const sopDoc = require(`../sop/${sop}.json`)
+ const [signer] = await hre.ethers.getSigners()
+
+ console.log(`\n🤖 AI Agent executing SOP: ${sop}`)
+ console.log(` Location: ${sopDoc.parameters.location}`)
+ console.log(` Threshold: ${sopDoc.parameters.threshold_mm}mm\n`)
+
+ // Step 1: Fetch weather data (simulated for demo)
+ const sources = [
+ { name: 'openweathermap.org', rainfall_mm: 6.9, timestamp: Date.now() },
+ { name: 'tmd.go.th', rainfall_mm: 7.2, timestamp: Date.now() },
+ ]
+ console.log(` 📡 Source 1 (${sources[0].name}): ${sources[0].rainfall_mm}mm`)
+ console.log(` 📡 Source 2 (${sources[1].name}): ${sources[1].rainfall_mm}mm`)
+
+ // Step 2-5: Execute SOP steps
+ const avg = sources.reduce((s, x) => s + x.rainfall_mm, 0) / sources.length
+ const divergence = Math.abs(sources[0].rainfall_mm - sources[1].rainfall_mm) / avg * 100
+ const conclusion = avg > sopDoc.parameters.threshold_mm ? 1 : 0
+
+ console.log(` 📊 Average: ${avg.toFixed(1)}mm | Divergence: ${divergence.toFixed(1)}%`)
+ console.log(` 📋 Conclusion: ${conclusion === 1 ? 'TRIGGER' : 'NO_TRIGGER'}\n`)
+
+ // Build evidence package
+ const evidencePackage = {
+ sop_version: sop,
+ executed_at: new Date().toISOString(),
+ steps: sources.map((s, i) => ({
+ step: i + 1,
+ source: s.name,
+ value_mm: s.rainfall_mm,
+ timestamp: s.timestamp,
+ })),
+ computation: { average_mm: avg, divergence_pct: divergence },
+ conclusion: conclusion === 1 ? 'TRIGGER' : 'NO_TRIGGER',
+ }
+
+ // In production: pin to IPFS. Here we use deterministic hash.
+ const evidenceJson = JSON.stringify(evidencePackage)
+ const evidenceCid = ethers.keccak256(ethers.toUtf8Bytes(evidenceJson))
+ const sopHash = ethers.keccak256(ethers.toUtf8Bytes(JSON.stringify(sopDoc)))
+ const conclusionHash = ethers.keccak256(ethers.toUtf8Bytes(evidencePackage.conclusion))
+
+ console.log(` 🔒 Evidence CID: ${evidenceCid.slice(0, 18)}...`)
+ console.log(` 🔒 SOP Hash: ${sopHash.slice(0, 18)}...`)
+
+ // Submit on-chain
+ const deployment = await hre.deployments.get('EvidenceOracle')
+ const oracle = await hre.ethers.getContractAt('EvidenceOracle', deployment.address)
+
+ // Register SOP if not already registered
+ const sopData = await oracle.sops(sopHash)
+ if (!sopData.active) {
+ console.log(`\n 📝 Registering SOP on-chain...`)
+ const tx = await oracle.registerSOP(sop, evidenceCid)
+ await tx.wait()
+ console.log(` ✅ SOP registered`)
+ }
+
+ // Submit decision
+ console.log(` 📤 Submitting decision...`)
+ const tx = await oracle.submitDecision(evidenceCid, sopHash, conclusionHash, conclusion)
+ const receipt = await tx.wait()
+ console.log(` ✅ Decision submitted. Tx: ${receipt.hash}`)
+ console.log(`\n Waiting for verifier approval...`)
+ })
diff --git a/examples/oapp-ai-oracle/tasks/challenge-decision.ts b/examples/oapp-ai-oracle/tasks/challenge-decision.ts
new file mode 100644
index 000000000..2e1995e7f
--- /dev/null
+++ b/examples/oapp-ai-oracle/tasks/challenge-decision.ts
@@ -0,0 +1,38 @@
+import { task } from 'hardhat/config'
+
+/**
+ * Challenge Task — Permissionless fraud proof
+ *
+ * ANYONE can run this. No stake, no permission required.
+ * Demonstrates the trust model: fraud is detectable because evidence is immutable.
+ *
+ * Usage:
+ * pnpm hardhat challenge:decision --network eth-sepolia --id 0 --reason "Source not in whitelist"
+ */
+task('challenge:decision', 'Challenge a decision with fraud proof')
+ .addParam('id', 'Decision ID to challenge')
+ .addParam('reason', 'Reason for the challenge (what SOP violation was found)')
+ .setAction(async (taskArgs, hre) => {
+ const decisionId = parseInt(taskArgs.id)
+ const reason = taskArgs.reason
+ const [, , challenger] = await hre.ethers.getSigners() // third account = challenger
+
+ const deployment = await hre.deployments.get('EvidenceOracle')
+ const oracle = await hre.ethers.getContractAt('EvidenceOracle', deployment.address)
+
+ const decision = await oracle.decisions(decisionId)
+ console.log(`\n⚠️ Challenging Decision #${decisionId}`)
+ console.log(` Evidence CID: ${decision.evidenceCid.slice(0, 18)}...`)
+ console.log(` Reason: ${reason}`)
+
+ console.log(`\n 📋 Challenger's audit trail:`)
+ console.log(` 1. Fetched evidence from IPFS (CID: ${decision.evidenceCid.slice(0, 18)}...)`)
+ console.log(` 2. Verified hash matches on-chain commitment ✓`)
+ console.log(` 3. Replayed SOP steps against evidence`)
+ console.log(` 4. Found violation: ${reason}`)
+
+ const tx = await oracle.connect(challenger).challenge(decisionId, reason)
+ const receipt = await tx.wait()
+ console.log(`\n 🚨 Challenge submitted. Tx: ${receipt.hash}`)
+ console.log(` In production: verifiers who approved this decision would be slashed.`)
+ })
diff --git a/examples/oapp-ai-oracle/tasks/dispatch-decision.ts b/examples/oapp-ai-oracle/tasks/dispatch-decision.ts
new file mode 100644
index 000000000..a471a05fc
--- /dev/null
+++ b/examples/oapp-ai-oracle/tasks/dispatch-decision.ts
@@ -0,0 +1,48 @@
+import { task } from 'hardhat/config'
+import { Options } from '@layerzerolabs/lz-v2-utilities'
+
+/**
+ * Dispatch Task — Send verified decision cross-chain via LayerZero
+ *
+ * Demonstrates Layer 3 (Distribution):
+ * Threshold met → LayerZero dispatch → target chain receives
+ *
+ * Usage:
+ * pnpm hardhat dispatch:decision --network eth-sepolia --id 0 --dst-eid 40102
+ */
+task('dispatch:decision', 'Dispatch verified decision to target chain')
+ .addParam('id', 'Decision ID to dispatch')
+ .addParam('dstEid', 'LayerZero Endpoint ID of destination chain')
+ .setAction(async (taskArgs, hre) => {
+ const decisionId = parseInt(taskArgs.id)
+ const dstEid = parseInt(taskArgs.dstEid)
+ const [signer] = await hre.ethers.getSigners()
+
+ const deployment = await hre.deployments.get('EvidenceOracle')
+ const oracle = await hre.ethers.getContractAt('EvidenceOracle', deployment.address)
+
+ const decision = await oracle.decisions(decisionId)
+ const threshold = await oracle.threshold()
+ console.log(`\n🚀 Dispatching Decision #${decisionId}`)
+ console.log(` Approvals: ${decision.approvals}/${threshold}`)
+ console.log(` Destination EID: ${dstEid}`)
+
+ if (decision.approvals < threshold) {
+ console.log(` ❌ Threshold not met. Need ${threshold} approvals.`)
+ return
+ }
+
+ // Build LayerZero options (200k gas for execution on destination)
+ const options = Options.newOptions().addExecutorLzReceiveOption(200000, 0).toHex()
+
+ // Quote fee
+ const fee = await oracle.quoteDispatch(decisionId, dstEid, options)
+ console.log(` 💰 Fee: ${hre.ethers.formatEther(fee.nativeFee)} ETH`)
+
+ // Dispatch
+ console.log(` 📡 Sending via LayerZero...`)
+ const tx = await oracle.dispatch(decisionId, dstEid, options, { value: fee.nativeFee })
+ const receipt = await tx.wait()
+ console.log(` ✅ Dispatched! Tx: ${receipt.hash}`)
+ console.log(`\n Track on LayerZeroScan: https://testnet.layerzeroscan.com/tx/${receipt.hash}`)
+ })
diff --git a/examples/oapp-ai-oracle/tasks/verify-decision.ts b/examples/oapp-ai-oracle/tasks/verify-decision.ts
new file mode 100644
index 000000000..a0b463580
--- /dev/null
+++ b/examples/oapp-ai-oracle/tasks/verify-decision.ts
@@ -0,0 +1,44 @@
+import { task } from 'hardhat/config'
+
+/**
+ * Verifier Task — Audit AI's evidence against SOP
+ *
+ * Demonstrates Layer 2 (Verification):
+ * Verifier fetches evidence → replays SOP checklist → approves or rejects
+ *
+ * Usage:
+ * pnpm hardhat verify:decision --network eth-sepolia --id 0
+ */
+task('verify:decision', 'Verifier audits a decision against SOP')
+ .addParam('id', 'Decision ID to verify')
+ .setAction(async (taskArgs, hre) => {
+ const decisionId = parseInt(taskArgs.id)
+ const [, verifier] = await hre.ethers.getSigners() // second account = verifier
+
+ const deployment = await hre.deployments.get('EvidenceOracle')
+ const oracle = await hre.ethers.getContractAt('EvidenceOracle', deployment.address)
+
+ const decision = await oracle.decisions(decisionId)
+ console.log(`\n🔍 Verifier auditing Decision #${decisionId}`)
+ console.log(` Evidence CID: ${decision.evidenceCid.slice(0, 18)}...`)
+ console.log(` SOP Hash: ${decision.sopHash.slice(0, 18)}...`)
+ console.log(` Conclusion: ${decision.conclusion === 1 ? 'TRIGGER' : 'NO_TRIGGER'}`)
+
+ // In production: fetch evidence from IPFS, replay SOP checklist
+ // For demo: auto-approve
+ console.log(`\n 📋 Running SOP compliance checklist...`)
+ console.log(` ✓ Sources in whitelist`)
+ console.log(` ✓ Timestamps within window`)
+ console.log(` ✓ Source count >= minimum`)
+ console.log(` ✓ Divergence calculation correct`)
+ console.log(` ✓ Threshold comparison correct`)
+ console.log(` ✓ Conclusion matches computation`)
+
+ console.log(`\n ✅ All checks passed. Approving...`)
+ const tx = await oracle.connect(verifier).verify(decisionId, true)
+ const receipt = await tx.wait()
+ console.log(` ✅ Approved. Tx: ${receipt.hash}`)
+
+ const updated = await oracle.decisions(decisionId)
+ console.log(` Approvals: ${updated.approvals}/${await oracle.threshold()}`)
+ })
diff --git a/examples/oapp-ai-oracle/tsconfig.json b/examples/oapp-ai-oracle/tsconfig.json
new file mode 100644
index 000000000..ec0b5adce
--- /dev/null
+++ b/examples/oapp-ai-oracle/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "commonjs",
+ "strict": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "outDir": "./dist",
+ "declaration": true
+ },
+ "include": ["hardhat.config.ts", "deploy/**/*.ts", "tasks/**/*.ts", "test/**/*.ts", "layerzero.config.ts"]
+}