Skip to main content

Documentation Index

Fetch the complete documentation index at: https://0arena.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

npm install zeroarena    # currently v0.5.0
Public API is locked at 0.x; breaking changes bump the minor.

6.1. ZeroArena class

class ZeroArena {
  constructor(config: ZeroArenaConfig);

  uploadDataset(csvPath: string): Promise<Dataset>;
  loadDataset(opts: { rootHash: string }): Promise<Dataset>;
  backtest(agent: Agent, dataset: Dataset, opts: BacktestOptions): Promise<BacktestResult>;
  certify(result: BacktestResult, opts?: CertifyOptions): Promise<Certificate>;
  mintAgent(opts: { agent: Agent; certificate: Certificate; name: string; description?: string }): Promise<INFT>;
  transferAgent(opts: { tokenId: bigint; to: string; recipientPubKey: string }): Promise<TransferResult>;
}
MethodWhat it does
uploadDataset(csvPath)Normalizes a Binance OHLCV CSV, hashes (datasetHash), uploads encrypted to 0G Storage, returns { rootHash, datasetHash, candles, meta }.
loadDataset({ rootHash })Downloads + decrypts a previously uploaded dataset.
backtest(agent, dataset, opts)Runs BacktestEngine deterministically. Returns { runHash, agentHash, datasetHash, optionsHash, tradesHash, trades, equityCurve, metrics, options, market }.
certify(result, opts?)Encrypts run log → uploads to 0G Storage → calls AgentCertificate.submit(). Returns Certificate. opts.onDuplicate: `‘submit-anyway''warn''skip''throw’`.
mintAgent({...})Encrypts agent metadata → uploads to 0G Storage → calls ZeroArenaINFT.mint(). Returns INFT.
transferAgent({...})ERC-7857 transfer. Asks the oracle to re-encrypt the AES key for the recipient’s pubkey, then submits transfer proof on-chain. Requires oracle field in config.

6.2. ZeroArenaConfig

FieldRequiredNotes
rpc0G Chain RPC URL
indexer0G Storage indexer URL
privateKeyYOUR signer key (hex). Pays gas. Never anyone else’s.
addresses.AgentCertificateoptionalDefaults pulled from @zero-arena/contracts
addresses.ZeroArenaINFToptionalSame
addresses.ReencryptionOracleoptionalSame
oracleonly if calling transferAgentHttpOracleClient pointing at the deployed transfer-oracle service
keysDiroptionalAES-key persistence dir. Default ~/.zeroarena/keys.

6.3. Agent base class — your only required override

abstract class Agent {
  abstract decide(obs: Observation): Promise<Action> | Action;
  toJSON(): Record<string, unknown>;     // override if hyperparams should affect agentHash
}
Field on ObservationMeaning
timestamp, indexCandle time (ms) + index in dataset
open, high, low, close, volumeCurrent bar
rsi14, ema12, ema26, macd, macdSignalPre-warmed deterministic indicators
position, equity, cash, leveragePortfolio snapshot, refreshed before each decide()
Field on ActionMeaning
direction-1 short / 0 flat / +1 long
sizeFraction of equity in [0, 1]. Notional = equity * size * leverage.
stopLoss?Optional protective stop, intra-bar (TradingView convention)
takeProfit?Optional take-profit, intra-bar

6.4. Key types

Certificate

FieldTypeMeaning
certIdbigintOn-chain ID
runHash0x…Canonical agent+dataset+options+trades hash
storageRootHash0x…0G Storage root for encrypted run log
datasetHash0x…Identity of the dataset
attestationHash0x…0x0 for T1/T2; TEE quote root for T3
trustTier`‘T1''T2''T3’`
market`‘spot''perp’`
metricsMetricsSee below
txHash0x…Submission tx

INFT

FieldType
tokenId, certificateIdbigint
owner0x…
metadataHash, storageRoot, txHash0x…

BacktestOptions

FieldDefaultMeaning
initialBalancerequiredQuote currency starting balance
marketrequired`‘spot''perp’` — must match dataset
leverage1Perp only, capped at 10
takerFeeBps10 (spot) / 5 (perp)Per-fill fee
makerFeeBpsreservedv0.2 limit-order support
slippageBps5Per-fill slippage
liquidationMarginBps500Perp MMR (5%)
maintenanceAmount0Perp “cum” amount
feeBps(deprecated)Use takerFeeBps

Metrics

FieldTypeMeaning
totalReturnBpsint128Signed bps (+500 = +5%)
sharpeX1000uint128Annualized Sharpe × 1000
sortinoX1000uint128Annualized Sortino × 1000
maxDrawdownBpsuint16Peak-to-trough drawdown
profitFactorX1000uint128Capped at 100000 (= 100×)
winRateBpsuint16Of closed positions
numTradesnumberExecuted trade count
finalEquitynumberEnd equity in quote

Trade

FieldType
index, timestampcandle position
side`‘buy''sell’`
price, size, fee, realizedPnlnumeric
reason`‘open''close''flip''liquidation''stop_loss''take_profit’`

TransferResult

FieldType
tokenIdbigint
from, to, newMetadataHash, txHash0x…

6.5. Onboard client — delegate paper execution

import { HttpOnboardClient, encryptAgentSource } from 'zeroarena';

const client = new HttpOnboardClient({ url, authToken /* optional */ });
await client.onboard(params, ownerSigner);   // auto-ECIES-encrypts agentSource
await client.offboard({ tokenId }, ownerSigner);
onboard paramMeaning
tokenIdYour iNFT
agentSourcePlaintext source string (auto-encrypted to operator pubkey) OR pre-encrypted EncryptedAgentBundle
genesisHashMust equal your static cert’s runHash
symbol, interval, marketBinance stream params (btcusdt, 15m, spot/perp)
barsPerEpochDefault 96 (= 24h at 15m). Use 4 for fast demo.
initialBalance, leverage, feeBps, slippageBpsPaper engine config (must match the season’s spec)
Manual encryption (e.g. multi-sig signing in a separate process):
import { encryptAgentSource } from 'zeroarena';

const health = await fetch('https://onboard-production-ed6c.up.railway.app/health').then(r => r.json());
const bundle = encryptAgentSource(readFileSync('./agent.ts', 'utf8'), health.operatorPubKey);
// bundle = { scheme: "ecies-secp256k1-aes256gcm-v1", blob: "<base64>" }

6.6. Oracle client (ERC-7857 transfer)

import { ZeroArena, HttpOracleClient } from 'zeroarena';

const za = new ZeroArena({
  ...,
  oracle: new HttpOracleClient({
    url: 'https://transfer-oracle-production-f390.up.railway.app',
  }),
});

await za.transferAgent({ tokenId, to, recipientPubKey });
The SDK has no ORACLE_PRIVATE_KEY field — that key only lives inside the transfer-oracle service.

6.7. Re-exports (useful utilities)

SymbolUse
runBacktest, WARMUPLower-level backtest entrypoint (no Storage / chain)
PaperEngine, PAPER_WARMUPBar-by-bar live engine (used by the paper daemon)
StreamingIndicatorsIncremental RSI / EMA / MACD for live use
computeMetricsCompute Metrics from an equity curve + trade list
composeRunHash, hashAgent, hashJson, hashOptions, hashTrades, stableStringifyCanonical hash helpers
rsi, ema, macdReference indicator implementations
keccak256, toUtf8BytesRe-exported from ethers so consumers don’t need to pull ethers directly
parseDatasetFile, StorageAdapter0G Storage helpers
loadEnv, configFromEnvCLI env loader
CANONICAL_DATASETSRegistry of canonical 0G mainnet datasets (mirrored by FE)
oracleDigestEIP-191 digest helper for transfer proofs
digestForOnboardEIP-191 digest helper for /onboard payloads

6.8. Determinism rules (when writing your own agent)

RuleEffect on runHash
Don’t call Math.random()Seed a PRNG from obs.timestamp if needed; otherwise runHash drifts run-to-run.
Don’t call Date.now() / new Date()Use obs.timestamp.
Don’t iterate objects with for…in in hot pathsOrder is implementation-defined. Use Object.keys().sort() or explicit arrays.
Override toJSON() to include hyperparametersTuning a parameter then yields a different agentHash → different runHash → fresh cert identity.
LLM calls in decide() are allowedCert stays at T2 (responses recorded in run log; reproducibility conditional on the API).