sealed-precision-oracle 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Sealed Precision Oracle (Track 1: Agentic Infrastructure)
2
+
3
+ [![ClawHub](https://img.shields.io/badge/ClawHub-Published-blue)](https://clawhub.ai)
4
+ [![0G Mainnet](https://img.shields.io/badge/Network-0G_Mainnet-green)](https://chainscan.0g.ai)
5
+
6
+ The **Sealed Precision Oracle** is a cognitive backbone for autonomous intelligence. It resolves complex, data-dependent questions using a verifiable pipeline of **TEE-attested AI**, **0G Storage memory**, and **ERC-7857 agent identity**.
7
+
8
+ ## πŸš€ Quick Install
9
+
10
+ Boost your agent's reasoning with a single command:
11
+
12
+ ```bash
13
+ clawhub install sealed-precision-oracle
14
+ ```
15
+
16
+ ## πŸ—οΈ Architecture: The Cognitive Backbone
17
+
18
+ This project implements a complete cognitive layer for agents, ensuring every decision is logically sound and cryptographically verified.
19
+
20
+ ```
21
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
22
+ β”‚ Atomic Oracle Pipeline β”‚
23
+ β”‚ β”‚
24
+ β”‚ 1. Autonomous Data Fetching (Ground Truth) β”‚
25
+ β”‚ β”‚ β”‚
26
+ β”‚ β–Ό β”‚
27
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” Real-time β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
28
+ β”‚ β”‚ Public RPCs β”‚ ──────────────▢ β”‚ Gas, Prices, Block# β”‚ β”‚
29
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
30
+ β”‚ β”‚ β”‚
31
+ β”‚ 2. Hardware-Secured Reasoning (TEE Compute) β”‚ β”‚
32
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” ECDSA Sig β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
33
+ β”‚ β”‚ 0G Compute β”‚ ──────────────▢ β”‚ AI Reasoning (Qwen) β”‚ β”‚
34
+ β”‚ β”‚ (Direct TEE) β”‚ (Per-Inference) β”‚ Inside Secure Enclaveβ”‚ β”‚
35
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
36
+ β”‚ β”‚ β”‚
37
+ β”‚ 3. Long-Context State Memory (0G Storage) β”‚ β”‚
38
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
39
+ β”‚ β”‚ 0G Storage β”‚ ◀──────────── β”‚ Immutable Receipt JSON β”‚ β”‚
40
+ β”‚ β”‚ (Audit Log) β”‚ Upload β”‚ (Merkle Root Hash) β”‚ β”‚
41
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
42
+ β”‚ β”‚ rootHash β”‚
43
+ β”‚ β–Ό β”‚
44
+ β”‚ 4. On-Chain Settlement (0G Chain) β”‚
45
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” recordResolution() β”‚
46
+ β”‚ β”‚ 0G Mainnet β”‚ ERC-7857 PrecisionOracleID β”‚
47
+ β”‚ β”‚ (Anchor) β”‚ tokenId β†’ storageRoot β”‚
48
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
49
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
50
+ ```
51
+
52
+ ## 0G Stack Integrations (Track 1 Focus)
53
+
54
+ | Component | Integration | Purpose |
55
+ |-----------|-------------|---------|
56
+ | **0G Compute** | Direct TEE Attestation | **Cognitive Layer**: Hardware-verified AI reasoning with per-inference signatures. |
57
+ | **0G Storage** | Turbo Indexer | **Long-Context Memory**: Permanent archival of data snapshots and reasoning logic. |
58
+ | **0G Chain** | ERC-7857 Smart Contracts | **Agent Identity**: On-chain ownership and verifiable anchoring of AI resolutions. |
59
+ | **OpenClaw** | Specialized Skill | **Orchestration**: Seamless integration into autonomous agent frameworks. |
60
+
61
+ ## Feature Status
62
+
63
+ | Feature | Status | Details |
64
+ |---------|--------|---------|
65
+ | Real-time Data | **REAL** | Live fetch from Ethereum RPCs and CoinGecko. |
66
+ | TEE Attestation | **REAL** | **Per-inference ECDSA signatures** verified against on-chain TEE signers. |
67
+ | 0G Storage | **REAL** | Receipts archived on Mainnet Turbo Indexer. |
68
+ | On-chain Settlement| **REAL** | Resolutions recorded on 0G Mainnet via ERC-7857 contracts. |
69
+
70
+ ## πŸ› οΈ Usage
71
+
72
+ ### 1. Zero-Config Demo (Recommended for Judges)
73
+ Experience the full verifiable flow instantly without any setup. Our hosted API bridge handles the 0G gas and storage fees for you.
74
+ ```bash
75
+ # Install globally
76
+ npm install -g sealed-precision-oracle
77
+
78
+ # Run instantly (Managed Mode)
79
+ sealed-precision-oracle "Is the price of Solana above $200?"
80
+ ```
81
+
82
+ ### 2. Autonomous Mode (For Advanced Agents)
83
+ Run the entire pipeline on your own hardware using your own 0G funds.
84
+ ```bash
85
+ # Set your PRIVATE_KEY in your environment
86
+ export PRIVATE_KEY="0x..."
87
+
88
+ # Run locally (Autonomous Mode)
89
+ sealed-precision-oracle "Is the price of Solana above $200?"
90
+ ```
91
+
92
+ ### 3. Smart Contract Integration
93
+ The oracle records proofs to:
94
+ - **Mainnet Address**: `0xf25E765eF573c26d6314Fd83822564E7AF11C9Ac`
95
+ - **Network**: 0G Mainnet (Chain ID: 16661)
96
+
97
+ ## πŸ“‚ Project Structure
98
+
99
+ - `contracts/`: ERC-7857 compliant smart contracts for AI agent identity.
100
+ - `src/`: Core logic for data fetching, TEE inference, and storage.
101
+ - `api/`: Backend bridge for secure TEE execution (Managed Mode).
102
+ - `skills/`: OpenClaw skill manifest for ClawHub publication.
103
+ - `bin/`: CLI entry point for global installation.
104
+
105
+ ## 🏁 Track 1 Alignment
106
+ This project serves as a foundational **Cognitive Backbone** for agentic infrastructure. By combining real-time data ingestion with TEE-secured reasoning and 0G Storage state persistence, it creates an autonomous intelligence layer that is inherently trustworthy and fully auditable on-chain.
107
+
108
+ ## License
109
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ const path = require('path');
3
+ const { spawn } = require('child_process');
4
+
5
+ // The dist directory where the compiled files live
6
+ const oracleScript = path.join(__dirname, '../dist/src/oracle.js');
7
+
8
+ // Pass all CLI arguments to the compiled oracle script
9
+ const args = process.argv.slice(2);
10
+ const child = spawn('node', [oracleScript, ...args], {
11
+ stdio: 'inherit',
12
+ env: process.env
13
+ });
14
+
15
+ child.on('exit', (code) => {
16
+ process.exit(code);
17
+ });
@@ -0,0 +1,86 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.27;
3
+
4
+ /// @title ERC-7857 Types and Interfaces
5
+ /// @notice Faithful implementation of EIP-7857: AI Agents NFT with Private Metadata
6
+ /// @dev See https://eips.ethereum.org/EIPS/eip-7857
7
+
8
+ enum OracleType {
9
+ TEE,
10
+ ZKP
11
+ }
12
+
13
+ struct AccessProof {
14
+ bytes32 oldDataHash;
15
+ bytes32 newDataHash;
16
+ bytes nonce;
17
+ bytes encryptedPubKey;
18
+ bytes proof;
19
+ }
20
+
21
+ struct OwnershipProof {
22
+ OracleType oracleType;
23
+ bytes32 oldDataHash;
24
+ bytes32 newDataHash;
25
+ bytes sealedKey;
26
+ bytes encryptedPubKey;
27
+ bytes nonce;
28
+ bytes proof;
29
+ }
30
+
31
+ struct TransferValidityProof {
32
+ AccessProof accessProof;
33
+ OwnershipProof ownershipProof;
34
+ }
35
+
36
+ struct TransferValidityProofOutput {
37
+ bytes32 oldDataHash;
38
+ bytes32 newDataHash;
39
+ bytes sealedKey;
40
+ bytes encryptedPubKey;
41
+ bytes wantedKey;
42
+ address accessAssistant;
43
+ bytes accessProofNonce;
44
+ bytes ownershipProofNonce;
45
+ }
46
+
47
+ struct IntelligentData {
48
+ string dataDescription;
49
+ bytes32 dataHash;
50
+ }
51
+
52
+ /// @notice Verifier contract for validating transfer proofs (TEE or ZKP)
53
+ interface IERC7857DataVerifier {
54
+ function verifyTransferValidity(
55
+ TransferValidityProof[] calldata _proofs
56
+ ) external returns (TransferValidityProofOutput[] memory);
57
+ }
58
+
59
+ /// @notice Metadata extension for ERC-7857
60
+ interface IERC7857Metadata {
61
+ function name() external view returns (string memory);
62
+ function symbol() external view returns (string memory);
63
+ function intelligentDataOf(uint256 _tokenId) external view returns (IntelligentData[] memory);
64
+ }
65
+
66
+ /// @notice Core ERC-7857 interface β€” agent-specific functions only.
67
+ /// Functions shared with ERC-721 (approve, ownerOf, etc.) are inherited
68
+ /// from OZ's ERC721 implementation. This interface declares only the
69
+ /// agent-identity additions defined by EIP-7857.
70
+ interface IERC7857 {
71
+ event Authorization(address indexed _from, address indexed _to, uint256 indexed _tokenId);
72
+ event AuthorizationRevoked(address indexed _from, address indexed _to, uint256 indexed _tokenId);
73
+ event Transferred(uint256 _tokenId, address indexed _from, address indexed _to);
74
+ event Cloned(uint256 indexed _tokenId, uint256 indexed _newTokenId, address _from, address _to);
75
+ event PublishedSealedKey(address indexed _to, uint256 indexed _tokenId, bytes[] _sealedKeys);
76
+ event DelegateAccess(address indexed _user, address indexed _assistant);
77
+
78
+ function verifier() external view returns (IERC7857DataVerifier);
79
+ function iTransfer(address _to, uint256 _tokenId, TransferValidityProof[] calldata _proofs) external;
80
+ function iClone(address _to, uint256 _tokenId, TransferValidityProof[] calldata _proofs) external returns (uint256 _newTokenId);
81
+ function authorizeUsage(uint256 _tokenId, address _user) external;
82
+ function revokeAuthorization(uint256 _tokenId, address _user) external;
83
+ function delegateAccess(address _assistant) external;
84
+ function authorizedUsersOf(uint256 _tokenId) external view returns (address[] memory);
85
+ function getDelegateAccess(address _user) external view returns (address);
86
+ }
@@ -0,0 +1,72 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.27;
3
+
4
+ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
5
+ import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
6
+ import "./IERC7857.sol";
7
+
8
+ /// @title OracleDataVerifier
9
+ /// @notice ERC-7857 DataVerifier that validates transfer proofs using ECDSA signatures.
10
+ /// The `proof` bytes in each AccessProof/OwnershipProof MUST be a 65-byte ECDSA
11
+ /// signature over keccak256(abi.encodePacked(oldDataHash, newDataHash, nonce)).
12
+ /// The recovered signer is returned in the output for the main contract to check
13
+ /// against the token owner.
14
+ contract OracleDataVerifier is IERC7857DataVerifier {
15
+ using ECDSA for bytes32;
16
+ using MessageHashUtils for bytes32;
17
+
18
+ function verifyTransferValidity(
19
+ TransferValidityProof[] calldata _proofs
20
+ ) external pure override returns (TransferValidityProofOutput[] memory outputs) {
21
+ outputs = new TransferValidityProofOutput[](_proofs.length);
22
+
23
+ for (uint256 i = 0; i < _proofs.length; i++) {
24
+ AccessProof calldata ap = _proofs[i].accessProof;
25
+ OwnershipProof calldata op = _proofs[i].ownershipProof;
26
+
27
+ // Validate non-zero target data hashes
28
+ require(ap.newDataHash != bytes32(0), "Access: empty new hash");
29
+ require(op.newDataHash != bytes32(0), "Ownership: empty new hash");
30
+
31
+ // Access and ownership proofs must agree on the data
32
+ require(ap.newDataHash == op.newDataHash, "Hash mismatch: access vs ownership");
33
+ require(ap.oldDataHash == op.oldDataHash, "Old hash mismatch");
34
+
35
+ // Non-empty nonces (replay protection)
36
+ require(ap.nonce.length > 0, "Access: empty nonce");
37
+ require(op.nonce.length > 0, "Ownership: empty nonce");
38
+
39
+ // Validate ECDSA signature in accessProof.proof
40
+ // The signer must have signed keccak256(oldDataHash, newDataHash, nonce)
41
+ require(ap.proof.length == 65, "Access: proof must be 65-byte ECDSA signature");
42
+ bytes32 accessDigest = keccak256(
43
+ abi.encodePacked(ap.oldDataHash, ap.newDataHash, ap.nonce)
44
+ ).toEthSignedMessageHash();
45
+ address accessSigner = accessDigest.recover(ap.proof);
46
+ require(accessSigner != address(0), "Access: invalid signature");
47
+
48
+ // Validate ECDSA signature in ownershipProof.proof
49
+ require(op.proof.length == 65, "Ownership: proof must be 65-byte ECDSA signature");
50
+ bytes32 ownerDigest = keccak256(
51
+ abi.encodePacked(op.oldDataHash, op.newDataHash, op.nonce)
52
+ ).toEthSignedMessageHash();
53
+ address ownerSigner = ownerDigest.recover(op.proof);
54
+ require(ownerSigner != address(0), "Ownership: invalid signature");
55
+
56
+ // Both proofs must be signed by the same entity (the current owner)
57
+ require(accessSigner == ownerSigner, "Signer mismatch: access vs ownership");
58
+
59
+ outputs[i] = TransferValidityProofOutput({
60
+ oldDataHash: ap.oldDataHash,
61
+ newDataHash: ap.newDataHash,
62
+ sealedKey: op.sealedKey,
63
+ encryptedPubKey: op.encryptedPubKey,
64
+ wantedKey: ap.encryptedPubKey,
65
+ // Return the recovered signer so PrecisionOracleID can verify it's the token owner
66
+ accessAssistant: accessSigner,
67
+ accessProofNonce: ap.nonce,
68
+ ownershipProofNonce: op.nonce
69
+ });
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,328 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.27;
3
+
4
+ import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5
+ import "@openzeppelin/contracts/access/Ownable.sol";
6
+ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
7
+ import "@openzeppelin/contracts/utils/Strings.sol";
8
+ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
9
+ import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
10
+ import "./IERC7857.sol";
11
+
12
+ /// @title PrecisionOracleID
13
+ /// @notice On-chain identity for the Sealed Precision Oracle.
14
+ /// Implements ERC-7857 (AI Agents NFT with Private Metadata) on top of ERC-721.
15
+ /// Maps each agent token to its 0G Storage resolution receipts.
16
+ contract PrecisionOracleID is ERC721, Ownable, IERC7857, IERC7857Metadata {
17
+ using EnumerableSet for EnumerableSet.AddressSet;
18
+ using ECDSA for bytes32;
19
+ using MessageHashUtils for bytes32;
20
+
21
+ // ─── State ──────────────────────────────────────────────────────────
22
+
23
+ uint256 private _nextTokenId;
24
+ IERC7857DataVerifier private _dataVerifier;
25
+
26
+ // TEE signer registry β€” addresses of verified TEE signers
27
+ mapping(address => bool) public registeredTeeSigners;
28
+
29
+ // ERC-7857: authorized users per token (enumerable for authorizedUsersOf)
30
+ mapping(uint256 => EnumerableSet.AddressSet) private _authorizedUsers;
31
+
32
+ // ERC-7857: delegate access (user => assistant)
33
+ mapping(address => address) private _delegates;
34
+
35
+ // ERC-7857: intelligent data per token
36
+ mapping(uint256 => IntelligentData[]) private _intelligentData;
37
+
38
+ // Oracle-specific: latest 0G Storage Merkle root per token
39
+ mapping(uint256 => bytes32) public storageRoots;
40
+
41
+ // Oracle-specific: full resolution history per token
42
+ mapping(uint256 => bytes32[]) public resolutionHistory;
43
+
44
+ // Oracle-specific: nonce per token (anti-replay for resolutions)
45
+ mapping(uint256 => uint256) public resolutionNonces;
46
+
47
+ // Oracle-specific: clone lineage
48
+ mapping(uint256 => uint256) public clonedFrom;
49
+
50
+ // ─── Events ─────────────────────────────────────────────────────────
51
+
52
+ event ResolutionRecorded(
53
+ uint256 indexed tokenId,
54
+ bytes32 indexed storageRoot,
55
+ uint256 nonce,
56
+ address indexed operator,
57
+ address teeSigner,
58
+ uint256 timestamp
59
+ );
60
+
61
+ event TeeSignerRegistered(address indexed signer);
62
+ event TeeSignerRemoved(address indexed signer);
63
+
64
+ // ─── Constructor ────────────────────────────────────────────────────
65
+
66
+ constructor(
67
+ address verifierAddress
68
+ ) ERC721("PrecisionOracleID", "PORID") Ownable(msg.sender) {
69
+ require(verifierAddress != address(0), "Zero verifier address");
70
+ _dataVerifier = IERC7857DataVerifier(verifierAddress);
71
+ _nextTokenId = 1;
72
+ }
73
+
74
+ // ─── Minting (owner-only) ───────────────────────────────────────────
75
+
76
+ function mint(address to) external onlyOwner returns (uint256 tokenId) {
77
+ tokenId = _nextTokenId++;
78
+ _mint(to, tokenId);
79
+ }
80
+
81
+ // ─── TEE Signer Registry ───────────────────────────────────────────
82
+
83
+ /// @notice Register a TEE signer address (from the 0G InferenceServing contract)
84
+ function registerTeeSigner(address signer) external onlyOwner {
85
+ require(signer != address(0), "Zero address");
86
+ registeredTeeSigners[signer] = true;
87
+ emit TeeSignerRegistered(signer);
88
+ }
89
+
90
+ /// @notice Remove a TEE signer
91
+ function removeTeeSigner(address signer) external onlyOwner {
92
+ registeredTeeSigners[signer] = false;
93
+ emit TeeSignerRemoved(signer);
94
+ }
95
+
96
+ // ─── Oracle Resolution Recording ───────────────────────────────────
97
+
98
+ /// @notice Record a resolution receipt with TEE attestation.
99
+ /// Callable by token owner OR authorized users.
100
+ /// @param tokenId The Oracle agent token
101
+ /// @param storageRoot 0G Storage Merkle root hash of the receipt
102
+ /// @param signedText The raw text that the TEE signed
103
+ /// @param teeSignature The TEE's ECDSA signature over the signedText
104
+ /// @param teeSigner The TEE signer address to verify against (zero = skip verification)
105
+ function recordResolution(
106
+ uint256 tokenId,
107
+ bytes32 storageRoot,
108
+ string calldata signedText,
109
+ bytes calldata teeSignature,
110
+ address teeSigner
111
+ ) external {
112
+ require(_ownerOrAuthorized(tokenId, msg.sender), "Not owner or authorized");
113
+ require(storageRoot != bytes32(0), "Empty storage root");
114
+
115
+ // If TEE signature provided, verify it on-chain
116
+ if (teeSignature.length > 0 && teeSigner != address(0)) {
117
+ require(registeredTeeSigners[teeSigner], "TEE signer not registered");
118
+
119
+ // Recover signer from the signature over the raw signed text
120
+ bytes32 ethSignedHash = MessageHashUtils.toEthSignedMessageHash(bytes(signedText));
121
+ address recovered = ethSignedHash.recover(teeSignature);
122
+ require(recovered == teeSigner, "TEE signature verification failed");
123
+ }
124
+
125
+ uint256 nonce = resolutionNonces[tokenId]++;
126
+ storageRoots[tokenId] = storageRoot;
127
+ resolutionHistory[tokenId].push(storageRoot);
128
+
129
+ // Add as intelligent data (ERC-7857 metadata)
130
+ _intelligentData[tokenId].push(IntelligentData({
131
+ dataDescription: string.concat("Oracle Resolution #", Strings.toString(nonce)),
132
+ dataHash: storageRoot
133
+ }));
134
+
135
+ emit ResolutionRecorded(tokenId, storageRoot, nonce, msg.sender, teeSigner, block.timestamp);
136
+ }
137
+
138
+ function resolutionCount(uint256 tokenId) external view returns (uint256) {
139
+ return resolutionHistory[tokenId].length;
140
+ }
141
+
142
+ /// @notice Paginated query for intelligent data. Avoids gas bomb on large histories.
143
+ /// @param tokenId The token to query
144
+ /// @param offset Start index
145
+ /// @param limit Max items to return
146
+ function intelligentDataPaginated(
147
+ uint256 tokenId,
148
+ uint256 offset,
149
+ uint256 limit
150
+ ) external view returns (IntelligentData[] memory result, uint256 total) {
151
+ require(limit > 0 && limit <= 1000, "Limit must be 1-1000");
152
+ IntelligentData[] storage data = _intelligentData[tokenId];
153
+ total = data.length;
154
+ if (offset >= total) {
155
+ return (new IntelligentData[](0), total);
156
+ }
157
+ uint256 end = offset + limit;
158
+ if (end > total) end = total;
159
+ uint256 count = end - offset;
160
+ result = new IntelligentData[](count);
161
+ for (uint256 i = 0; i < count; i++) {
162
+ result[i] = data[offset + i];
163
+ }
164
+ }
165
+
166
+ // ─── ERC-7857: Core Functions ──────────────────────────────────────
167
+
168
+ /// @inheritdoc IERC7857
169
+ function verifier() external view override returns (IERC7857DataVerifier) {
170
+ return _dataVerifier;
171
+ }
172
+
173
+ /// @inheritdoc IERC7857
174
+ function iTransfer(
175
+ address _to,
176
+ uint256 _tokenId,
177
+ TransferValidityProof[] calldata _proofs
178
+ ) external override {
179
+ require(ownerOf(_tokenId) == msg.sender, "Not token owner");
180
+ require(_to != address(0), "Transfer to zero address");
181
+ require(_proofs.length > 0, "No proofs provided");
182
+
183
+ // Verify transfer proofs via the data verifier
184
+ TransferValidityProofOutput[] memory outputs = _dataVerifier.verifyTransferValidity(_proofs);
185
+
186
+ // Verify that the proof signer is the token owner
187
+ // (accessAssistant field carries the recovered ECDSA signer from the verifier)
188
+ for (uint256 j = 0; j < outputs.length; j++) {
189
+ require(outputs[j].accessAssistant == msg.sender, "Proof signer is not token owner");
190
+ }
191
+
192
+ // Execute transfer (ERC-721 internal, no approval check needed)
193
+ address from = msg.sender;
194
+ _transfer(from, _to, _tokenId);
195
+
196
+ // Publish sealed keys so new owner can decrypt agent metadata
197
+ bytes[] memory sealedKeys = new bytes[](outputs.length);
198
+ for (uint256 i = 0; i < outputs.length; i++) {
199
+ sealedKeys[i] = outputs[i].sealedKey;
200
+ }
201
+ emit PublishedSealedKey(_to, _tokenId, sealedKeys);
202
+ emit Transferred(_tokenId, from, _to);
203
+ }
204
+
205
+ /// @inheritdoc IERC7857
206
+ function iClone(
207
+ address _to,
208
+ uint256 _tokenId,
209
+ TransferValidityProof[] calldata _proofs
210
+ ) external override returns (uint256 _newTokenId) {
211
+ require(ownerOf(_tokenId) == msg.sender, "Not token owner");
212
+ require(_to != address(0), "Clone to zero address");
213
+ require(_proofs.length > 0, "No proofs provided");
214
+
215
+ // Verify proofs
216
+ TransferValidityProofOutput[] memory outputs = _dataVerifier.verifyTransferValidity(_proofs);
217
+
218
+ // Verify that the proof signer is the token owner
219
+ for (uint256 j = 0; j < outputs.length; j++) {
220
+ require(outputs[j].accessAssistant == msg.sender, "Proof signer is not token owner");
221
+ }
222
+
223
+ // Mint clone
224
+ _newTokenId = _nextTokenId++;
225
+ _mint(_to, _newTokenId);
226
+ clonedFrom[_newTokenId] = _tokenId;
227
+
228
+ // Inherit intelligent data from parent
229
+ IntelligentData[] storage parentData = _intelligentData[_tokenId];
230
+ for (uint256 i = 0; i < parentData.length; i++) {
231
+ _intelligentData[_newTokenId].push(parentData[i]);
232
+ }
233
+
234
+ // Inherit latest storage root
235
+ storageRoots[_newTokenId] = storageRoots[_tokenId];
236
+
237
+ // Publish sealed keys
238
+ bytes[] memory sealedKeys = new bytes[](outputs.length);
239
+ for (uint256 i = 0; i < outputs.length; i++) {
240
+ sealedKeys[i] = outputs[i].sealedKey;
241
+ }
242
+ emit PublishedSealedKey(_to, _newTokenId, sealedKeys);
243
+ emit Cloned(_tokenId, _newTokenId, msg.sender, _to);
244
+ }
245
+
246
+ /// @inheritdoc IERC7857
247
+ function authorizeUsage(uint256 _tokenId, address _user) external override {
248
+ require(ownerOf(_tokenId) == msg.sender, "Not token owner");
249
+ require(_user != address(0), "Zero address");
250
+ require(_authorizedUsers[_tokenId].add(_user), "Already authorized");
251
+
252
+ emit Authorization(msg.sender, _user, _tokenId);
253
+ }
254
+
255
+ /// @inheritdoc IERC7857
256
+ function revokeAuthorization(uint256 _tokenId, address _user) external override {
257
+ require(ownerOf(_tokenId) == msg.sender, "Not token owner");
258
+ require(_authorizedUsers[_tokenId].remove(_user), "Not authorized");
259
+
260
+ emit AuthorizationRevoked(msg.sender, _user, _tokenId);
261
+ }
262
+
263
+ /// @inheritdoc IERC7857
264
+ function authorizedUsersOf(uint256 _tokenId) external view override returns (address[] memory) {
265
+ return _authorizedUsers[_tokenId].values();
266
+ }
267
+
268
+ /// @inheritdoc IERC7857
269
+ function delegateAccess(address _assistant) external override {
270
+ _delegates[msg.sender] = _assistant;
271
+ emit DelegateAccess(msg.sender, _assistant);
272
+ }
273
+
274
+ /// @inheritdoc IERC7857
275
+ function getDelegateAccess(address _user) external view override returns (address) {
276
+ return _delegates[_user];
277
+ }
278
+
279
+ // ─── ERC-7857 Metadata ─────────────────────────────────────────────
280
+
281
+ /// @inheritdoc IERC7857Metadata
282
+ function intelligentDataOf(
283
+ uint256 _tokenId
284
+ ) external view override returns (IntelligentData[] memory) {
285
+ require(_requireOwned(_tokenId) != address(0), "Token does not exist");
286
+ return _intelligentData[_tokenId];
287
+ }
288
+
289
+ /// @dev Override required because both ERC721 and IERC7857Metadata declare name()
290
+ function name() public view override(ERC721, IERC7857Metadata) returns (string memory) {
291
+ return super.name();
292
+ }
293
+
294
+ /// @dev Override required because both ERC721 and IERC7857Metadata declare symbol()
295
+ function symbol() public view override(ERC721, IERC7857Metadata) returns (string memory) {
296
+ return super.symbol();
297
+ }
298
+
299
+ // ─── Interface Support ──────────────────────────────────────────────
300
+
301
+ function supportsInterface(
302
+ bytes4 interfaceId
303
+ ) public view override returns (bool) {
304
+ return
305
+ interfaceId == type(IERC7857).interfaceId ||
306
+ interfaceId == type(IERC7857Metadata).interfaceId ||
307
+ super.supportsInterface(interfaceId);
308
+ }
309
+
310
+ // ─── ERC-721 Transfer Override ────────────────────────────────────
311
+ // Disable bare ERC-721 transfers β€” all transfers MUST go through
312
+ // iTransfer() with proof verification per ERC-7857.
313
+
314
+ function transferFrom(address, address, uint256) public pure override {
315
+ revert("Use iTransfer() with proofs");
316
+ }
317
+
318
+ function safeTransferFrom(address, address, uint256, bytes memory) public pure override {
319
+ revert("Use iTransfer() with proofs");
320
+ }
321
+
322
+ // ─── Internals ──────────────────────────────────────────────────────
323
+
324
+ function _ownerOrAuthorized(uint256 tokenId, address caller) private view returns (bool) {
325
+ return ownerOf(tokenId) == caller || _authorizedUsers[tokenId].contains(caller);
326
+ }
327
+
328
+ }
@@ -0,0 +1,6 @@
1
+ import { HardhatUserConfig } from "hardhat/config";
2
+ import "@nomicfoundation/hardhat-ethers";
3
+ import "@nomicfoundation/hardhat-chai-matchers";
4
+ import "dotenv/config";
5
+ declare const config: HardhatUserConfig;
6
+ export default config;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("@nomicfoundation/hardhat-ethers");
4
+ require("@nomicfoundation/hardhat-chai-matchers");
5
+ require("dotenv/config");
6
+ const PRIVATE_KEY = process.env.PRIVATE_KEY || "0x" + "0".repeat(64);
7
+ const config = {
8
+ solidity: {
9
+ version: "0.8.27",
10
+ settings: {
11
+ evmVersion: "cancun",
12
+ optimizer: { enabled: true, runs: 200 },
13
+ },
14
+ },
15
+ networks: {
16
+ og_galileo: {
17
+ url: "https://evmrpc-testnet.0g.ai",
18
+ chainId: 16602,
19
+ accounts: [PRIVATE_KEY],
20
+ },
21
+ og_mainnet: {
22
+ url: "https://evmrpc.0g.ai",
23
+ chainId: 16661,
24
+ accounts: [PRIVATE_KEY],
25
+ },
26
+ },
27
+ };
28
+ exports.default = config;
29
+ //# sourceMappingURL=hardhat.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardhat.config.js","sourceRoot":"","sources":["../hardhat.config.ts"],"names":[],"mappings":";;AACA,2CAAyC;AACzC,kDAAgD;AAChD,yBAAuB;AAEvB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAErE,MAAM,MAAM,GAAsB;IAChC,QAAQ,EAAE;QACR,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE;YACR,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;SACxC;KACF;IACD,QAAQ,EAAE;QACR,UAAU,EAAE;YACV,GAAG,EAAE,8BAA8B;YACnC,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,CAAC,WAAW,CAAC;SACxB;QACD,UAAU,EAAE;YACV,GAAG,EAAE,sBAAsB;YAC3B,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,CAAC,WAAW,CAAC;SACxB;KACF;CACF,CAAC;AAEF,kBAAe,MAAM,CAAC"}
@@ -0,0 +1 @@
1
+ export {};