Overview
Prophet has two autonomous agents running off-chain:- Oracle Agent — resolves markets by calling 0G Compute and posting verdicts on-chain
- Market Maker Agent — seeds new markets with liquidity and returns settled funds to the pool
@0glabs/0g-serving-broker, and @0gfoundation/0g-storage-ts-sdk. They run as a single process (npm run start) or independently.
Repository path: agent/src/
Oracle Agent
File:agent/src/oracle/index.ts
The oracle is Prophet’s core differentiator. It is the only component that can call postResolution() and revealPositions(). Without it, markets cannot resolve. With it, markets resolve deterministically, in under 2 minutes, with a permanent evidence trail on 0G Storage.
Startup: Catch-Up Scan
On startup, before listening for new events, the oracle scans all existing markets to handle any that were missed while the agent was offline:Event Listeners
After the catch-up scan, the oracle attaches listeners to three events:Periodic Scan
In addition to event listeners, the oracle runs a full catch-up scan every 5 minutes. This handles:- Events missed due to RPC instability
- Markets where
triggerResolutionwas called by a third party while the agent was processing another market - Any edge case where the event was not received
Resolution Flow (handleResolutionTriggered)
Position Reveal (NaCl Decryption)
AfterResolutionFinalized, the oracle fetches all encrypted positions from PositionVault, decrypts them using its private key, and calls revealPositions:
Market Maker Agent
File:agent/src/market-maker/index.ts
The market-maker ensures every market has liquidity from minute one. Without it, new markets have zero YES/NO reserves and the AMM cannot process trades.
Startup: Scan Existing Markets
Seeding a New Market
Queued Transaction System
The market-maker can receive manyMarketCreated events in rapid succession (during demos or high activity periods). Submitting multiple transactions simultaneously causes nonce collisions on 0G Chain.
The agent uses a simple FIFO queue:
enqueue(). This serializes transactions and eliminates nonce issues.
Event Listener: New Markets
Recovery Loop: Settled Markets
After a market resolves, the collateral should return to the LiquidityPool. The market-maker runs a recovery loop that checks for resolved markets and returns their allocated liquidity:Shared Utilities
agent/src/shared/compute.ts
Functions:initializeBroker(signer)— creates@0glabs/0g-serving-brokerinstancetopUpLedger(broker, provider, amount)— funds the billing ledger before inferenceverifyProvider(broker, provider)— TEE attestation checkcallOracleInference(question, sources, deadline, signer)— full resolution inferencecallValidationInference(question, signer)— question validation (lighter prompt)callPricingInference(question, signer)— initial price estimateextractJSON(text)— strips markdown fences, parses JSON with error handling
agent/src/shared/storage.ts
Functions:uploadToStorage(data, signer, maxRetries)— upload with retry + read-after-write verificationdownloadFromStorage(rootHash, maxRetries)— download with retrygetIndexer()— returnsIndexerpointed at turbo indexer URL
agent/src/shared/chain.ts
Functions:getFactoryContract(signer)— ProphetFactory with signergetMarketContract(address, signer)— MarketContract at addressgetVaultContract(signer)— PositionVault with signergetLiquidityPoolContract(signer)— LiquidityPool with signerlistenForEvents(contract, eventName, handler)— safe event listener wrapper
agent/src/shared/config.ts
agent/src/shared/logger.ts
Structured JSON logging usingpino (or equivalent). Every log entry includes:
timestamplevel(debug / info / warn / error)component(oracle / mm / storage / compute)- Contextual fields (marketAddress, txHash, etc.)
LOG_LEVEL env var. Default: info.