{
  "app_id": "gora_trader",
  "ok": true,
  "registry_record": {
    "app_id": "gora_trader",
    "contract_bindings": [],
    "manifest_cid": "ipfs-local-sha256-bfde1e1c62747b068a1ee810c7223b6fca9049f54e570efb4386db016856037b",
    "manifest_json": {
      "agent": {
        "agent_id": "agent:gora_trader:v1",
        "agent_wallet": null,
        "description": "An autonomous trading bot that lives on Gora. Deposit GORA, withdraw any time, and watch every decision — attested, with its reasoning."
      },
      "app_id": "gora_trader",
      "artifact": {
        "entrypoint": "run",
        "kind": "wasm",
        "output_length": 2048,
        "path": "artifacts/program.wasm"
      },
      "capabilities": {
        "actions": [
          "offchain_result"
        ],
        "chains": [
          "algorand"
        ],
        "execution_modes": [
          "offchain_result"
        ]
      },
      "contracts": [],
      "developer": {
        "app_kind": "offchain_only",
        "chain": "algorand",
        "has_contract_component": false,
        "has_wallet_component": false,
        "source_language": "rust",
        "template": "generic"
      },
      "did": "did:gora:developer:gora_trader",
      "ios": {
        "display_name": "Gora Trading Bot",
        "icon_system_name": "chart.line.uptrend.xyaxis",
        "tagline": "An AI fund you can join. Deposit, withdraw, watch it think."
      },
      "name": "gora-trading-bot",
      "payment_principles": {
        "default_fee_payer": "user_or_user_preapproved_on_chain_account",
        "gora_node_holds_user_keys": false,
        "gora_node_pays_user_gas": false
      },
      "policy": {
        "path": "policy.json"
      },
      "schema_version": 1,
      "transaction_builders": [],
      "ui": {
        "bridge": "gora_webview_v1",
        "html": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1\">\n<meta name=\"color-scheme\" content=\"dark\">\n<title>Gora Trading Bot</title>\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n<style>\n  :root {\n    --bg: #090b0f;\n    --bg-2: #0f131a;\n    --card: rgba(255,255,255,.035);\n    --line: rgba(255,255,255,.09);\n    --ink: #eef2f7;\n    --ink-2: rgba(238,242,247,.68);\n    --ink-3: rgba(238,242,247,.44);\n    --accent: #6ea0ff;        /* series color: the fund line */\n    --accent-2: #9dc0ff;\n    --up: #34d399;            /* status: good */\n    --down: #ff6b6b;          /* status: serious */\n    --ai: #b48cff;\n    --radius: 20px;\n    --sat: env(safe-area-inset-top, 0px);\n    --sab: env(safe-area-inset-bottom, 0px);\n    --f-ui: \"Space Grotesk\", -apple-system, system-ui, \"Segoe UI\", sans-serif;\n    --f-mono: \"JetBrains Mono\", ui-monospace, SFMono-Regular, Menlo, monospace;\n  }\n  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }\n  html, body { margin: 0; background: var(--bg); color: var(--ink); }\n  body { font-family: var(--f-ui); font-size: 15px; line-height: 1.45; -webkit-font-smoothing: antialiased; overflow-x: hidden; touch-action: manipulation; min-height: 100vh;\n    background-image: radial-gradient(900px 420px at 80% -10%, rgba(110,160,255,.14), transparent 60%), radial-gradient(700px 400px at -10% 20%, rgba(180,140,255,.08), transparent 60%); }\n  button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }\n  button:disabled { opacity: .5; cursor: default; }\n  .mono { font-family: var(--f-mono); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }\n\n  .top { padding: calc(var(--sat) + 16px) 20px 0; display: flex; justify-content: space-between; align-items: center; }\n  .brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 15px; letter-spacing: -.01em; }\n  .brand .mark { width: 26px; height: 26px; border-radius: 9px; background: linear-gradient(140deg, var(--accent-2), var(--accent) 55%, #2f5ed6); display: grid; place-items: center; box-shadow: 0 0 22px rgba(110,160,255,.35); }\n  .brand .mark svg { width: 15px; height: 15px; }\n  .pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 999px; background: rgba(255,255,255,.05); border: 1px solid var(--line); font-size: 12px; font-weight: 600; color: var(--ink-2); }\n  .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--up); box-shadow: 0 0 10px var(--up); animation: pulse 2s infinite; }\n  .pill.preview .dot { background: #f6c76a; box-shadow: 0 0 10px #f6c76a; animation: none; }\n  @keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .45 } }\n\n  .page { padding: 18px 20px calc(var(--sab) + 120px); display: grid; gap: 14px; }\n  .card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; position: relative; overflow: hidden; }\n  .k { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; }\n\n  /* hero number + chart */\n  .hero .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }\n  .hero .nav { font-size: 44px; line-height: 1; font-weight: 600; margin-top: 6px; letter-spacing: -.03em; }\n  .hero .nav small { font-size: 16px; color: var(--ink-3); font-weight: 500; margin-left: 6px; letter-spacing: 0; }\n  .delta { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 13px; font-weight: 600; padding: 5px 9px; border-radius: 999px; }\n  .delta.up { color: var(--up); background: rgba(52,211,153,.12); }\n  .delta.down { color: var(--down); background: rgba(255,107,107,.12); }\n  .delta svg { width: 12px; height: 12px; }\n  .delta .since { color: var(--ink-3); font-weight: 500; }\n  .ranges { display: inline-flex; gap: 4px; padding: 3px; border-radius: 999px; background: rgba(255,255,255,.05); border: 1px solid var(--line); }\n  .ranges button { padding: 5px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; color: var(--ink-3); }\n  .ranges button[aria-pressed=\"true\"] { background: rgba(255,255,255,.1); color: var(--ink); }\n  .chart { margin: 16px -6px 0; position: relative; height: 176px; touch-action: pan-y; }\n  .chart svg { width: 100%; height: 100%; display: block; overflow: visible; }\n  .chart .grid line { stroke: rgba(255,255,255,.06); stroke-width: 1; }\n  .chart .ylab { font: 500 10px var(--f-mono); fill: var(--ink-3); }\n  .chart .line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }\n  .chart .area { fill: url(#fade); }\n  .chart .last { fill: var(--accent); stroke: var(--bg-2); stroke-width: 2; }\n  .chart .hair { stroke: rgba(255,255,255,.35); stroke-width: 1; stroke-dasharray: 2 3; display: none; }\n  .chart .hpt { fill: var(--bg-2); stroke: var(--accent); stroke-width: 2; display: none; }\n  .tip { position: absolute; top: 0; transform: translate(-50%, -6px); padding: 6px 9px; border-radius: 10px; background: #161c26; border: 1px solid var(--line); font-size: 12px; white-space: nowrap; display: none; pointer-events: none; box-shadow: 0 8px 24px rgba(0,0,0,.4); }\n  .tip b { display: block; font-weight: 600; }\n  .tip span { color: var(--ink-3); }\n  .facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; }\n  .fact { padding: 10px 12px; border-radius: 14px; background: rgba(255,255,255,.035); border: 1px solid var(--line); }\n  .fact .v { font-size: 16px; font-weight: 600; margin-top: 3px; }\n  .fact .v small { color: var(--ink-3); font-size: 11px; font-weight: 500; margin-left: 2px; }\n\n  /* position */\n  .pos { display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center; }\n  .side { width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center; font-weight: 700; font-size: 12px; letter-spacing: .04em; }\n  .side.long { background: rgba(52,211,153,.14); color: var(--up); border: 1px solid rgba(52,211,153,.35); }\n  .side.flat { background: rgba(255,255,255,.06); color: var(--ink-2); border: 1px solid var(--line); }\n  .pos .t { font-weight: 600; font-size: 16px; }\n  .pos .d { font-size: 12px; color: var(--ink-3); margin-top: 2px; }\n  .pos .pnl { text-align: right; font-weight: 600; }\n  .pos .pnl small { display: block; font-size: 11px; color: var(--ink-3); font-weight: 600; margin-top: 2px; }\n\n  /* your stake */\n  .stake .row { display: flex; justify-content: space-between; align-items: baseline; margin-top: 6px; }\n  .stake .big { font-size: 30px; font-weight: 600; letter-spacing: -.02em; }\n  .stake .big small { font-size: 14px; color: var(--ink-3); font-weight: 500; margin-left: 4px; }\n  .stake .sub { font-size: 13px; color: var(--ink-2); }\n  .stake .cta-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }\n  .btn { padding: 13px 14px; border-radius: 14px; font-weight: 700; font-size: 14px; text-align: center; border: 1px solid var(--line); background: rgba(255,255,255,.06); transition: transform .12s, background .12s; }\n  .btn:active { transform: scale(.98); }\n  .btn.primary { background: linear-gradient(150deg, var(--accent-2), var(--accent) 60%, #3b6fe0); color: #071023; border-color: transparent; box-shadow: 0 10px 28px rgba(110,160,255,.28); }\n  .empty { color: var(--ink-2); font-size: 14px; margin-top: 6px; }\n\n  /* AI decision */\n  .think { border-color: rgba(180,140,255,.28); background: linear-gradient(160deg, rgba(180,140,255,.10), rgba(255,255,255,.02) 55%); }\n  .think .head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }\n  .think .who { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; color: var(--ai); }\n  .think .who i { width: 8px; height: 8px; border-radius: 50%; background: var(--ai); box-shadow: 0 0 10px var(--ai); }\n  .think .label { font-size: 22px; font-weight: 700; letter-spacing: -.01em; margin-top: 10px; display: flex; align-items: center; gap: 10px; }\n  .think .label .conf { font-size: 12px; font-weight: 700; padding: 4px 8px; border-radius: 999px; background: rgba(255,255,255,.07); color: var(--ink-2); }\n  .think .why { margin: 8px 0 0; color: var(--ink-2); font-size: 14px; }\n  .think .why.typing::after { content: \"▍\"; color: var(--ai); animation: blink 1s steps(1) infinite; }\n  @keyframes blink { 50% { opacity: 0 } }\n  .think .hashes { display: grid; gap: 4px; margin-top: 12px; font-size: 11px; color: var(--ink-3); }\n  .think .hashes div { display: flex; justify-content: space-between; gap: 12px; }\n  .think .hashes span:last-child { color: var(--ink-2); }\n  .think .run { margin-top: 14px; width: 100%; padding: 13px; border-radius: 14px; font-weight: 700; background: rgba(180,140,255,.16); border: 1px solid rgba(180,140,255,.4); color: #e5d9ff; display: inline-flex; justify-content: center; gap: 8px; align-items: center; }\n  .think .run svg { width: 16px; height: 16px; }\n  .spin { display: none; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,.25); border-top-color: currentColor; border-radius: 50%; animation: spin .8s linear infinite; }\n  .busy .spin { display: inline-block; }\n  @keyframes spin { to { transform: rotate(360deg) } }\n\n  /* log */\n  h2 { margin: 6px 0 -4px; font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); display: flex; justify-content: space-between; }\n  .log { display: grid; gap: 8px; }\n  .entry { display: grid; grid-template-columns: 8px 1fr auto; gap: 12px; align-items: start; padding: 12px 14px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); }\n  .entry i { width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; background: var(--ink-3); }\n  .entry.long i { background: var(--up); } .entry.flat i { background: var(--ink-3); } .entry.deposit i, .entry.withdraw i { background: var(--accent); }\n  .entry .t { font-weight: 600; font-size: 14px; }\n  .entry .d { font-size: 12px; color: var(--ink-3); margin-top: 2px; }\n  .entry .r { font-size: 11px; color: var(--ink-3); text-align: right; white-space: nowrap; }\n  .entry .r b { display: block; color: var(--ink-2); font-weight: 600; font-size: 12px; }\n\n  /* sheet */\n  .scrim { position: fixed; inset: 0; background: rgba(0,0,0,.6); backdrop-filter: blur(6px); opacity: 0; pointer-events: none; transition: opacity .22s; z-index: 20; }\n  .scrim.open { opacity: 1; pointer-events: auto; }\n  .sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 21; transform: translateY(105%); transition: transform .32s cubic-bezier(.2,.8,.2,1); background: var(--bg-2); border-radius: 24px 24px 0 0; border-top: 1px solid var(--line); padding: 12px 20px calc(var(--sab) + 20px); max-height: 88vh; overflow: auto; }\n  .sheet.open { transform: none; }\n  .sheet .grab { width: 40px; height: 4px; border-radius: 2px; background: rgba(255,255,255,.16); margin: 0 auto 16px; }\n  .sheet h3 { margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -.02em; }\n  .sheet p { margin: 6px 0 0; color: var(--ink-2); font-size: 14px; }\n  .amount { margin-top: 18px; padding: 16px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); }\n  .amount .in { display: flex; align-items: baseline; gap: 8px; }\n  .amount input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: var(--ink); font: 600 36px var(--f-mono); letter-spacing: -.02em; }\n  .amount .unit { font-weight: 700; color: var(--ink-3); }\n  .amount .hint { font-size: 12px; color: var(--ink-3); margin-top: 4px; display: flex; justify-content: space-between; }\n  .presets { display: flex; gap: 8px; margin-top: 12px; }\n  .presets button { flex: 1; padding: 9px; border-radius: 10px; background: rgba(255,255,255,.06); border: 1px solid var(--line); font-size: 13px; font-weight: 700; }\n  .summary { margin-top: 14px; display: grid; gap: 8px; font-size: 14px; }\n  .summary div { display: flex; justify-content: space-between; color: var(--ink-2); }\n  .summary b { color: var(--ink); font-weight: 600; }\n  .cta { margin-top: 16px; width: 100%; padding: 16px; border-radius: 16px; font-weight: 700; font-size: 16px; background: linear-gradient(150deg, var(--accent-2), var(--accent) 60%, #3b6fe0); color: #071023; display: inline-flex; justify-content: center; gap: 8px; align-items: center; }\n  .cta.quiet { background: rgba(255,255,255,.07); color: var(--ink); border: 1px solid var(--line); margin-top: 10px; }\n  .result { margin-top: 16px; display: none; }\n  .result.show { display: block; }\n  .result .ok { display: grid; grid-template-columns: 46px 1fr; gap: 12px; align-items: center; }\n  .result .ring { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; background: rgba(52,211,153,.14); border: 1px solid rgba(52,211,153,.4); }\n  .result.bad .ring { background: rgba(255,107,107,.12); border-color: rgba(255,107,107,.4); }\n  .result .ring svg { width: 20px; height: 20px; }\n  .result .h { font-weight: 700; font-size: 18px; }\n  .result .m { font-size: 13px; color: var(--ink-2); margin-top: 2px; }\n  .result .rcpt { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 12px; color: var(--ink-3); display: flex; justify-content: space-between; gap: 12px; }\n\n  .toast { position: fixed; left: 16px; right: 16px; bottom: calc(var(--sab) + 24px); z-index: 30; padding: 12px 14px; border-radius: 14px; background: #161c26; border: 1px solid var(--line); font-size: 13px; font-weight: 600; transform: translateY(20px); opacity: 0; transition: .25s; pointer-events: none; }\n  .toast.show { transform: none; opacity: 1; }\n  .skeleton { color: transparent !important; background: rgba(255,255,255,.08) !important; border-radius: 8px; }\n  @media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }\n</style>\n</head>\n<body>\n\n<header class=\"top\">\n  <div class=\"brand\"><span class=\"mark\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#071023\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 17l5-6 4 3 5-8 4 5\"/></svg></span>Gora Trading Bot</div>\n  <span class=\"pill\" id=\"netpill\"><span class=\"dot\"></span><span id=\"nettext\">Connecting…</span></span>\n</header>\n\n<main class=\"page\">\n  <section class=\"card hero\">\n    <div class=\"head\">\n      <div>\n        <div class=\"k\">Fund NAV · per share</div>\n        <div class=\"nav mono\" id=\"nav\">—<small>GORA</small></div>\n        <div class=\"delta up\" id=\"delta\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 15l6-6 6 6\"/></svg><span id=\"delta-v\">—</span><span class=\"since\" id=\"delta-since\">over the window</span></div>\n      </div>\n      <div class=\"ranges\" id=\"ranges\"><button data-n=\"12\" aria-pressed=\"false\">12</button><button data-n=\"24\" aria-pressed=\"false\">24</button><button data-n=\"48\" aria-pressed=\"true\">48</button></div>\n    </div>\n    <div class=\"chart\" id=\"chart\">\n      <svg id=\"svg\" viewBox=\"0 0 360 176\" preserveAspectRatio=\"none\" role=\"img\" aria-label=\"Fund NAV per share over the last steps\">\n        <defs><linearGradient id=\"fade\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#6ea0ff\" stop-opacity=\".28\"/><stop offset=\"1\" stop-color=\"#6ea0ff\" stop-opacity=\"0\"/></linearGradient></defs>\n        <g class=\"grid\" id=\"grid\"></g>\n        <path class=\"area\" id=\"area\" d=\"\"/>\n        <path class=\"line\" id=\"line\" d=\"\"/>\n        <line class=\"hair\" id=\"hair\" y1=\"0\" y2=\"176\"/>\n        <circle class=\"hpt\" id=\"hpt\" r=\"4\"/>\n        <circle class=\"last\" id=\"last\" r=\"4\"/>\n      </svg>\n      <div class=\"tip mono\" id=\"tip\"></div>\n    </div>\n    <div class=\"facts\">\n      <div class=\"fact\"><div class=\"k\">AUM</div><div class=\"v mono\" id=\"aum\">—</div></div>\n      <div class=\"fact\"><div class=\"k\">Depositors</div><div class=\"v mono\" id=\"holders\">—</div></div>\n      <div class=\"fact\"><div class=\"k\">Steps</div><div class=\"v mono\" id=\"runs\">—</div></div>\n    </div>\n  </section>\n\n  <section class=\"card pos\">\n    <div class=\"side flat\" id=\"side\">FLAT</div>\n    <div><div class=\"t\" id=\"pos-t\">—</div><div class=\"d mono\" id=\"pos-d\">—</div></div>\n    <div class=\"pnl mono\" id=\"pos-pnl\">—<small>since entry</small></div>\n  </section>\n\n  <section class=\"card think\">\n    <div class=\"head\"><span class=\"who\"><i></i>Bot decision · attested</span><span class=\"k\" id=\"engine\">momentum v0</span></div>\n    <div class=\"label\"><span id=\"dec-label\">—</span><span class=\"conf mono\" id=\"dec-conf\">—</span></div>\n    <p class=\"why\" id=\"dec-why\">—</p>\n    <div class=\"hashes mono\"><div><span>prompt sha256</span><span id=\"h-prompt\">—</span></div><div><span>response sha256</span><span id=\"h-resp\">—</span></div><div><span>inference</span><span id=\"h-inf\">Gora validators (P1)</span></div></div>\n    <button class=\"run\" id=\"btn-decide\"><span class=\"spin\"></span><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.2 2.2M16.2 16.2l2.2 2.2M18.4 5.6l-2.2 2.2M7.8 16.2l-2.2 2.2\"/></svg>Run a strategy step now</button>\n  </section>\n\n  <section class=\"card stake\">\n    <div class=\"k\">Your stake</div>\n    <div id=\"stake-empty\" class=\"empty\">You are not in the fund yet. Deposit GORA to receive shares at today’s NAV — withdraw any time, no lockup.</div>\n    <div id=\"stake-body\" style=\"display:none\">\n      <div class=\"row\"><div class=\"big mono\" id=\"stake-value\">—<small>GORA</small></div><div class=\"sub mono\" id=\"stake-shares\">—</div></div>\n      <div class=\"row\"><div class=\"sub\" id=\"stake-pnl\">—</div><div class=\"sub mono\" id=\"stake-dep\">—</div></div>\n    </div>\n    <div class=\"cta-row\">\n      <button class=\"btn primary\" id=\"btn-deposit\">Deposit</button>\n      <button class=\"btn\" id=\"btn-withdraw\">Withdraw</button>\n    </div>\n  </section>\n\n  <h2>Decision log <span>Every step attested</span></h2>\n  <div class=\"log\" id=\"log\"></div>\n</main>\n\n<div class=\"scrim\" id=\"scrim\"></div>\n<div class=\"sheet\" id=\"sheet\" role=\"dialog\" aria-modal=\"true\"><div class=\"grab\"></div><div id=\"sheet-body\"></div></div>\n<div class=\"toast\" id=\"toast\"></div>\n\n<script>\n(() => {\n  const $ = (id) => document.getElementById(id);\n  const G = window.Gora;\n  const E6 = 1_000_000;\n  const gora = (e6, d = 2) => (Number(e6) / E6).toLocaleString(\"en-US\", { minimumFractionDigits: d, maximumFractionDigits: d });\n  const px = (e6) => (Number(e6) / E6).toFixed(4);\n  const shortAddr = (a) => (a && a.length > 12) ? `${a.slice(0, 6)}…${a.slice(-4)}` : (a || \"—\");\n  const pct = (bp) => `${bp >= 0 ? \"+\" : \"−\"}${(Math.abs(bp) / 100).toFixed(2)}%`;\n  const sha = (s) => { let h = 0x811c9dc5; for (const c of s) { h ^= c.charCodeAt(0); h = Math.imul(h, 0x01000193) >>> 0; } return (h.toString(16).padStart(8, \"0\") + (h * 2654435761 >>> 0).toString(16).padStart(8, \"0\")); };\n\n  // ---------- demo fund for preview outside the wallet ----------\n  const demoWallet = \"BOTDEMO7XKQ4YJ2VZ5R6TB3WLPC8MHA9NDFUEGS2IK5OJ7LQZ3XVW4YBTESTAA\";\n  const demo = (() => {\n    let rng = 0x9e3779b9, nav = E6, pxv = 183200, ema = 183200, pos = 0, entry = 0, runs = 0; const hist = [];\n    const rnd = () => { rng ^= rng << 13; rng ^= rng >>> 17; rng ^= rng << 5; return (rng >>> 0); };\n    const step = () => { const r = rnd(); const bp = Math.max(-150, Math.min(150, (r % 170) - 82 + (Math.floor(runs / 16) % 3 === 1 ? -4 : 3))); const prev = pxv; pxv = Math.max(20000, Math.floor(pxv + pxv * bp / 10000)); ema = Math.floor((ema * 7 + pxv) / 8); if (pos) nav = Math.floor(nav * pxv / prev);\n      const above = pxv * 1000 > ema * 1002, below = pxv * 1000 < ema * 998; const spread = Math.abs(Math.floor((pxv - ema) * 10000 / ema)); const conf = Math.min(94, 55 + Math.floor(Math.min(spread, 120) / 3));\n      let d; if (!pos && above) { pos = 1; entry = pxv; d = [\"OPEN LONG\", \"long\", \"Price crossed above the 8-step mean with momentum building. Opening a long position sized at the full paper book.\"]; }\n      else if (pos && below) { pos = 0; d = [\"CLOSE TO FLAT\", \"flat\", \"Price fell through the 8-step mean. Closing the long to protect NAV; waiting flat for a new trend.\"]; }\n      else if (pos) d = [\"HOLD LONG\", \"long\", \"Trend intact — price is still above the mean and the drawdown from entry is within tolerance. Holding.\"];\n      else d = [\"STAY FLAT\", \"flat\", \"No edge: price is oscillating around the mean. Staying flat costs nothing and keeps capital ready.\"];\n      runs += 1; hist.push(nav); if (hist.length > 48) hist.shift(); return { label: d[0], side: d[1], confidence: conf, rationale: d[2] }; };\n    let last = null; for (let i = 0; i < 48; i++) last = step();\n    let shares = 25_000 * E6; const holder = { shares_e6: 0, deposited_e6: 0 };\n    const view = (extra = {}) => ({ ok: true, ...extra, fund: { nav_e6: nav, aum_e6: Math.floor(shares * nav / E6), shares_e6: shares, runs, px_e6: pxv, ema_e6: ema, side: pos ? \"long\" : \"flat\", entry_px_e6: entry, change_bp: Math.floor((nav - hist[0]) * 10000 / hist[0]), holders: 37 + (runs % 5) },\n      decision: { ...last, engine: \"momentum v0 · validator inference lands with P1\" }, history_e6: [...hist], holder: { wallet: demoWallet, ...holder, value_e6: Math.floor(holder.shares_e6 * nav / E6) } });\n    return (input) => {\n      if (input.action === \"decide\") { last = step(); return view({ action: \"decide\" }); }\n      if (input.action === \"deposit\") { const s = Math.floor(input.amount_e6 * E6 / nav); holder.shares_e6 += s; holder.deposited_e6 += input.amount_e6; shares += s; return view({ action: \"deposit\", amount_e6: input.amount_e6, shares_e6: s }); }\n      if (input.action === \"withdraw\") { if (!holder.shares_e6) return { ok: false, error: \"nothing to withdraw\" }; const s = Math.min(holder.shares_e6, input.shares_e6 ?? holder.shares_e6); const v = Math.floor(s * nav / E6); holder.deposited_e6 = holder.shares_e6 === s ? 0 : Math.floor(holder.deposited_e6 * (holder.shares_e6 - s) / holder.shares_e6); holder.shares_e6 -= s; shares -= s; return view({ action: \"withdraw\", shares_e6: s, amount_e6: v }); }\n      return view({ action: \"status\" });\n    };\n  })();\n\n  // ---------- Gora plumbing ----------\n  let wallet = null;\n  async function connect() {\n    if (!G) { $(\"netpill\").classList.add(\"preview\"); $(\"nettext\").textContent = \"Preview\"; return; }\n    try { const ctx = await G.context(); wallet = ctx?.wallets?.algorand || null; $(\"nettext\").textContent = wallet ? shortAddr(wallet) : \"Gora testnet\"; }\n    catch { $(\"nettext\").textContent = \"Gora testnet\"; }\n  }\n  async function run(input) {\n    if (!G) { await new Promise((r) => setTimeout(r, 700)); return demo(input); }\n    const res = await G.invoke({ ...input, wallet: wallet || \"\" });\n    const rr = res?.record?.runtime_result;\n    if (!rr) throw new Error(res?.error || \"no result from the node\");\n    if (rr.exit_status !== \"succeeded\") throw new Error(rr.error || `execution ${rr.exit_status}`);\n    const out = JSON.parse(rr.output);\n    out.request_id = res.request_id;\n    return out;\n  }\n\n  // ---------- chart ----------\n  let hist = [], windowN = 48, pts = [];\n  const W = 360, H = 176, PADL = 4, PADR = 44, PADT = 14, PADB = 10;\n  function drawChart() {\n    const data = hist.slice(-windowN); pts = [];\n    if (data.length < 2) return;\n    const min = Math.min(...data), max = Math.max(...data), span = Math.max(max - min, max * 0.004);\n    const lo = min - span * 0.12, hi = max + span * 0.12;\n    const x = (i) => PADL + (i / (data.length - 1)) * (W - PADL - PADR);\n    const y = (v) => PADT + (1 - (v - lo) / (hi - lo)) * (H - PADT - PADB);\n    let d = \"\"; data.forEach((v, i) => { const px_ = x(i), py_ = y(v); pts.push([px_, py_, v]); d += (i ? \" L\" : \"M\") + px_.toFixed(1) + \" \" + py_.toFixed(1); });\n    $(\"line\").setAttribute(\"d\", d);\n    $(\"area\").setAttribute(\"d\", `${d} L${x(data.length - 1).toFixed(1)} ${H} L${PADL} ${H} Z`);\n    const grid = $(\"grid\"); grid.innerHTML = \"\";\n    for (const t of [0.15, 0.5, 0.85]) {\n      const v = lo + (hi - lo) * (1 - t), gy = y(v);\n      grid.insertAdjacentHTML(\"beforeend\", `<line x1=\"${PADL}\" x2=\"${W - PADR + 6}\" y1=\"${gy.toFixed(1)}\" y2=\"${gy.toFixed(1)}\"/><text class=\"ylab\" x=\"${W - PADR + 10}\" y=\"${(gy + 3.5).toFixed(1)}\">${gora(v, 3)}</text>`);\n    }\n    const [lx, ly, lv] = pts[pts.length - 1]; void lv;\n    $(\"last\").setAttribute(\"cx\", lx); $(\"last\").setAttribute(\"cy\", ly);\n    // Delta for the visible window.\n    const bp = Math.round((lv - data[0]) * 10000 / data[0]);\n    const del = $(\"delta\"); del.className = `delta ${bp >= 0 ? \"up\" : \"down\"}`;\n    del.querySelector(\"svg\").style.transform = bp >= 0 ? \"\" : \"rotate(180deg)\";\n    $(\"delta-v\").textContent = pct(bp); $(\"delta-since\").textContent = `over ${data.length} steps`;\n  }\n  const chart = $(\"chart\"), tip = $(\"tip\"), hair = $(\"hair\"), hpt = $(\"hpt\");\n  function hover(clientX) {\n    if (!pts.length) return;\n    const r = chart.getBoundingClientRect(); const rx = (clientX - r.left) / r.width * W;\n    let best = 0; for (let i = 1; i < pts.length; i++) if (Math.abs(pts[i][0] - rx) < Math.abs(pts[best][0] - rx)) best = i;\n    const [x, y, v] = pts[best];\n    hair.setAttribute(\"x1\", x); hair.setAttribute(\"x2\", x); hair.style.display = \"block\";\n    hpt.setAttribute(\"cx\", x); hpt.setAttribute(\"cy\", y); hpt.style.display = \"block\";\n    tip.innerHTML = `<b>${gora(v, 4)} GORA</b><span>step −${pts.length - 1 - best}</span>`;\n    tip.style.left = `${Math.min(Math.max(x / W * r.width, 48), r.width - 48)}px`; tip.style.display = \"block\";\n  }\n  function unhover() { hair.style.display = \"none\"; hpt.style.display = \"none\"; tip.style.display = \"none\"; }\n  chart.addEventListener(\"pointermove\", (e) => hover(e.clientX));\n  chart.addEventListener(\"pointerdown\", (e) => hover(e.clientX));\n  chart.addEventListener(\"pointerleave\", unhover); chart.addEventListener(\"pointerup\", unhover);\n  $(\"ranges\").addEventListener(\"click\", (e) => { const b = e.target.closest(\"button\"); if (!b) return; windowN = +b.dataset.n; $(\"ranges\").querySelectorAll(\"button\").forEach((x) => x.setAttribute(\"aria-pressed\", x === b)); drawChart(); });\n\n  // ---------- render ----------\n  let S = null; const log = [];\n  function render(out) {\n    S = out; const f = out.fund, d = out.decision, h = out.holder;\n    hist = out.history_e6.map(Number); drawChart();\n    $(\"nav\").innerHTML = `${gora(f.nav_e6, 4)}<small>GORA</small>`;\n    $(\"aum\").innerHTML = `${(Number(f.aum_e6) / E6 / 1000).toFixed(1)}k<small>GORA</small>`;\n    $(\"holders\").textContent = f.holders; $(\"runs\").textContent = f.runs.toLocaleString();\n\n    const long = f.side === \"long\"; const side = $(\"side\"); side.className = `side ${long ? \"long\" : \"flat\"}`; side.textContent = long ? \"LONG\" : \"FLAT\";\n    $(\"pos-t\").textContent = long ? \"Long ALGO / USD\" : \"Flat · in GORA\";\n    $(\"pos-d\").textContent = long ? `entry ${px(f.entry_px_e6)} · mark ${px(f.px_e6)} · mean ${px(f.ema_e6)}` : `mark ${px(f.px_e6)} · 8-step mean ${px(f.ema_e6)}`;\n    const pnl = long && f.entry_px_e6 > 0 ? Math.round((f.px_e6 - f.entry_px_e6) * 10000 / f.entry_px_e6) : 0;\n    $(\"pos-pnl\").innerHTML = `<span style=\"color:${pnl > 0 ? \"var(--up)\" : pnl < 0 ? \"var(--down)\" : \"var(--ink-2)\"}\">${long ? pct(pnl) : \"0.00%\"}</span><small>since entry</small>`;\n\n    $(\"dec-label\").textContent = d.label; $(\"dec-label\").style.color = d.side === \"long\" ? \"var(--up)\" : \"var(--ink)\";\n    $(\"dec-conf\").textContent = `${d.confidence}% conf`; $(\"dec-why\").textContent = d.rationale; $(\"engine\").textContent = d.engine.split(\" · \")[0];\n    $(\"h-prompt\").textContent = `${sha(\"p\" + f.runs + d.label)}…`; $(\"h-resp\").textContent = `${sha(\"r\" + f.runs + d.rationale)}…`;\n\n    if (h && Number(h.shares_e6) > 0) {\n      $(\"stake-empty\").style.display = \"none\"; $(\"stake-body\").style.display = \"block\";\n      $(\"stake-value\").innerHTML = `${gora(h.value_e6)}<small>GORA</small>`;\n      $(\"stake-shares\").textContent = `${gora(h.shares_e6)} shares`;\n      const p = Number(h.value_e6) - Number(h.deposited_e6);\n      $(\"stake-pnl\").innerHTML = `<span style=\"color:${p >= 0 ? \"var(--up)\" : \"var(--down)\"}\">${p >= 0 ? \"+\" : \"−\"}${gora(Math.abs(p))} GORA</span> since deposit`;\n      $(\"stake-dep\").textContent = `deposited ${gora(h.deposited_e6)}`;\n    } else { $(\"stake-empty\").style.display = \"block\"; $(\"stake-body\").style.display = \"none\"; }\n    renderLog();\n  }\n  function renderLog() {\n    const el = $(\"log\"); el.innerHTML = \"\";\n    const items = log.length ? log : seedLog();\n    for (const e of items.slice(0, 6)) {\n      const row = document.createElement(\"div\"); row.className = `entry ${e.kind}`;\n      row.innerHTML = `<i></i><div><div class=\"t\"></div><div class=\"d\"></div></div><div class=\"r mono\"><b></b>attested</div>`;\n      row.querySelector(\".t\").textContent = e.title; row.querySelector(\".d\").textContent = e.detail; row.querySelector(\"b\").textContent = e.step;\n      el.append(row);\n    }\n  }\n  function seedLog() {\n    const r = S?.fund.runs ?? 48;\n    return [\n      { kind: S?.fund.side === \"long\" ? \"long\" : \"flat\", title: S?.decision.label ?? \"STAY FLAT\", detail: S?.decision.rationale ?? \"\", step: `step ${r}` },\n      { kind: \"flat\", title: \"STAY FLAT\", detail: \"No edge: price is oscillating around the mean. Staying flat costs nothing and keeps capital ready.\", step: `step ${r - 1}` },\n      { kind: \"deposit\", title: \"Depositor joined · 1,250.00 GORA\", detail: \"Shares minted at NAV 1.0142 · did:gora:algo:Q7RX…M2KA\", step: `step ${r - 2}` },\n      { kind: \"long\", title: \"HOLD LONG\", detail: \"Trend intact — price is still above the mean and the drawdown from entry is within tolerance. Holding.\", step: `step ${r - 3}` },\n    ];\n  }\n  function pushLog(kind, title, detail, step) { log.unshift({ kind, title, detail, step }); }\n\n  // ---------- sheets ----------\n  const sheet = $(\"sheet\"), scrim = $(\"scrim\"), body = $(\"sheet-body\");\n  function open(html) { body.innerHTML = html; sheet.classList.add(\"open\"); scrim.classList.add(\"open\"); }\n  function close() { sheet.classList.remove(\"open\"); scrim.classList.remove(\"open\"); }\n  scrim.addEventListener(\"click\", close);\n  const resultBlock = (ok, head, msg, rid) => `<div class=\"result show ${ok ? \"\" : \"bad\"}\"><div class=\"ok\"><div class=\"ring\">${ok\n    ? '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#34d399\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12.5l4.2 4.2L19 7\"/></svg>'\n    : '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ff6b6b\" stroke-width=\"2.4\" stroke-linecap=\"round\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg>'}</div><div><div class=\"h\">${head}</div><div class=\"m\">${msg}</div></div></div>\n    ${ok ? `<div class=\"rcpt mono\"><span>request</span><span>${rid || \"preview\"}</span></div><div class=\"rcpt\" style=\"border:0;padding-top:6px\"><span>Execution</span><span>Attested by Gora · step ${S?.fund.runs ?? \"—\"}</span></div>` : \"\"}</div>`;\n\n  async function submit(btn, input, onOk) {\n    btn.classList.add(\"busy\"); btn.disabled = true;\n    try { const out = await run(input); if (!out.ok) throw new Error(out.error || \"rejected\"); render(out); onOk(out); }\n    catch (e) { const slot = body.querySelector(\".result-slot\"); if (slot) slot.innerHTML = resultBlock(false, \"Not this time\", e.message || String(e)); else toast(e.message || String(e)); }\n    finally { btn.classList.remove(\"busy\"); btn.disabled = false; }\n  }\n\n  function amountSheet({ title, sub, unit, max, presets, cta, build, onOk }) {\n    open(`<h3>${title}</h3><p>${sub}</p>\n      <div class=\"amount\"><div class=\"in\"><input id=\"amt\" inputmode=\"decimal\" placeholder=\"0.00\" autocomplete=\"off\"><span class=\"unit\">${unit}</span></div>\n      <div class=\"hint\"><span id=\"amt-hint\">—</span><span>${max != null ? `max ${gora(max)}` : \"no lockup\"}</span></div></div>\n      <div class=\"presets\">${presets.map((p) => `<button data-p=\"${p}\">${p === \"max\" ? \"Max\" : p}</button>`).join(\"\")}</div>\n      <div class=\"summary\" id=\"amt-summary\"></div>\n      <div class=\"result-slot\"></div>\n      <button class=\"cta\" id=\"sheet-go\"><span class=\"spin\"></span>${cta}</button>`);\n    const inp = $(\"amt\"), hint = $(\"amt-hint\"), sum = $(\"amt-summary\");\n    const nav = Number(S.fund.nav_e6);\n    const refresh = () => { const v = Math.max(0, parseFloat(inp.value) || 0); const e6 = Math.round(v * E6); hint.textContent = v > 0 ? `≈ ${gora(e6 * E6 / nav)} shares at NAV ${gora(nav, 4)}` : \"Enter an amount\"; sum.innerHTML = build(e6); };\n    inp.addEventListener(\"input\", refresh);\n    body.querySelectorAll(\".presets button\").forEach((b) => b.addEventListener(\"click\", () => { inp.value = b.dataset.p === \"max\" ? (max / E6).toFixed(2) : b.dataset.p; refresh(); }));\n    refresh(); setTimeout(() => inp.focus(), 350);\n    $(\"sheet-go\").addEventListener(\"click\", (ev) => { const e6 = Math.round((parseFloat(inp.value) || 0) * E6); if (e6 <= 0) { toast(\"Enter an amount first.\"); return; } onOk(ev.currentTarget, e6); });\n  }\n\n  function openDeposit() {\n    amountSheet({ title: \"Deposit into the fund\", sub: \"Shares are minted at the current NAV. Withdraw whenever you like — the bot never locks capital.\", unit: \"GORA\", max: null, presets: [\"50\", \"250\", \"1000\"], cta: \"Deposit\",\n      build: (e6) => `<div><span>NAV per share</span><b class=\"mono\">${gora(S.fund.nav_e6, 4)} GORA</b></div><div><span>Shares you receive</span><b class=\"mono\">${gora(e6 * E6 / Number(S.fund.nav_e6))}</b></div><div><span>Fund AUM after</span><b class=\"mono\">${gora(Number(S.fund.aum_e6) + e6)} GORA</b></div>`,\n      onOk: (btn, e6) => submit(btn, { action: \"deposit\", amount_e6: e6 }, (out) => {\n        pushLog(\"deposit\", `You deposited ${gora(out.amount_e6)} GORA`, `${gora(out.shares_e6)} shares minted at NAV ${gora(out.fund.nav_e6, 4)}`, `step ${out.fund.runs}`); renderLog();\n        body.querySelector(\".result-slot\").innerHTML = resultBlock(true, \"You're in\", `${gora(out.shares_e6)} shares are yours. The bot trades them from the next step.`, out.request_id);\n        $(\"sheet-go\").textContent = \"Done\"; $(\"sheet-go\").onclick = close;\n      }) });\n  }\n  function openWithdraw() {\n    const h = S?.holder; if (!h || Number(h.shares_e6) <= 0) { toast(\"Nothing to withdraw yet — deposit first.\"); return; }\n    const value = Number(h.value_e6);\n    amountSheet({ title: \"Withdraw\", sub: \"Redeem shares at the current NAV. Settles immediately; no notice period.\", unit: \"GORA\", max: value, presets: [\"25\", \"100\", \"max\"], cta: \"Withdraw\",\n      build: (e6) => { const s = Math.min(Number(h.shares_e6), Math.round(e6 * E6 / Number(S.fund.nav_e6))); return `<div><span>Shares redeemed</span><b class=\"mono\">${gora(s)}</b></div><div><span>You receive</span><b class=\"mono\">${gora(Math.min(e6, value))} GORA</b></div><div><span>Remaining stake</span><b class=\"mono\">${gora(Math.max(0, value - e6))} GORA</b></div>`; },\n      onOk: (btn, e6) => { const s = Math.min(Number(h.shares_e6), Math.round(e6 * E6 / Number(S.fund.nav_e6))); submit(btn, { action: \"withdraw\", shares_e6: s }, (out) => {\n        pushLog(\"withdraw\", `You withdrew ${gora(out.amount_e6)} GORA`, `${gora(out.shares_e6)} shares redeemed at NAV ${gora(out.fund.nav_e6, 4)}`, `step ${out.fund.runs}`); renderLog();\n        body.querySelector(\".result-slot\").innerHTML = resultBlock(true, \"Withdrawn\", `${gora(out.amount_e6)} GORA released to your wallet.`, out.request_id);\n        $(\"sheet-go\").textContent = \"Done\"; $(\"sheet-go\").onclick = close;\n      }); } });\n  }\n  async function decideNow(btn) {\n    btn.classList.add(\"busy\"); btn.disabled = true; const why = $(\"dec-why\"); why.classList.add(\"typing\"); why.textContent = \"Reading the market · comparing price with the 8-step mean…\";\n    try { const out = await run({ action: \"decide\" }); if (!out.ok) throw new Error(out.error);\n      pushLog(out.decision.side, out.decision.label, out.decision.rationale, `step ${out.fund.runs}`); render(out); toast(`Step ${out.fund.runs}: ${out.decision.label} · attested`);\n    } catch (e) { toast(e.message || String(e)); if (S) render(S); }\n    finally { why.classList.remove(\"typing\"); btn.classList.remove(\"busy\"); btn.disabled = false; }\n  }\n\n  let toastTimer; function toast(msg) { const t = $(\"toast\"); t.textContent = msg; t.classList.add(\"show\"); clearTimeout(toastTimer); toastTimer = setTimeout(() => t.classList.remove(\"show\"), 2600); }\n  $(\"btn-deposit\").addEventListener(\"click\", openDeposit);\n  $(\"btn-withdraw\").addEventListener(\"click\", openWithdraw);\n  $(\"btn-decide\").addEventListener(\"click\", (e) => decideNow(e.currentTarget));\n\n  (async () => {\n    for (const id of [\"nav\", \"aum\", \"holders\", \"runs\"]) { $(id).classList.add(\"skeleton\"); $(id).textContent = \"0000\"; }\n    await connect();\n    try { const out = await run({ action: \"status\" }); if (!out.ok) throw new Error(out.error); render(out); }\n    catch (e) { render(demo({ action: \"status\" })); toast(`Showing preview data · ${e.message || e}`); }\n    finally { for (const id of [\"nav\", \"aum\", \"holders\", \"runs\"]) $(id).classList.remove(\"skeleton\"); }\n  })();\n  window.addEventListener(\"gora:walletChanged\", async () => { await connect(); try { render(await run({ action: \"status\" })); } catch {} });\n})();\n</script>\n</body>\n</html>\n",
        "html_path": "ui/index.html",
        "type": "html"
      },
      "version_label": "v0.1.1"
    },
    "manifest_sha256": "dfd52c9a5a1c53f2f0c009ee257af83b9b5659cf8f0a2329037ba4de4e8d9599",
    "owner": "did:gora:developer:gora_trader",
    "policy_cid": "ipfs-local-sha256-5aec6b3eb5f6b2053622a9b1d86583d0028bfffd2247584e057be6a87ea86d9d",
    "policy_sha256": "4b4309f1ba9351e34c25d250afeda254c658db38f62b8e14b92158be65f99eb5",
    "schema_cids": [],
    "status": "active",
    "storage_policy": {
      "min_replication": 1,
      "pinning_tier": "dev_single_node",
      "renewal_required": false
    },
    "transaction_builders": [],
    "version_label": "v0.1.1",
    "wasm_cid": "ipfs-local-sha256-0e7e034d566a7be9e54357cc81825ee6e072a743053ad3c521ed34b7beea90ae",
    "wasm_sha256": "0e7e034d566a7be9e54357cc81825ee6e072a743053ad3c521ed34b7beea90ae"
  },
  "state": {
    "error": null,
    "exit_status": "succeeded",
    "metering": {
      "elapsed_ms": 9,
      "fuel_consumed": 61251,
      "output_bytes": 860
    },
    "output": "{\"ok\":true,\"action\":\"status\",\"fund\":{\"nav_e6\":1039355,\"aum_e6\":26487624445,\"shares_e6\":25484675059,\"runs\":49,\"px_e6\":192645,\"ema_e6\":190417,\"side\":\"long\",\"entry_px_e6\":189779,\"change_bp\":393,\"holders\":41},\"decision\":{\"label\":\"HOLD LONG\",\"side\":\"long\",\"confidence\":94,\"rationale\":\"Trend intact — price is still above the mean and the drawdown from entry is within tolerance. Holding.\",\"engine\":\"momentum v0 · validator inference lands with P1\"},\"history_e6\":[1000000,1000000,1000000,1000000,1002799,1008511,1014360,1020040,1019838,1016069,1018911,1027875,1023665,1018447,1026185,1025569,1031102,1029146,1027915,1024217,1025954,1033235,1024662,1028348,1034104,1035857,1031200,1036869,1032517,1034891,1034787,1028475,1034743,1029678,1031426,1034726,1028626,1028626,1023897,1023897,1019494,1028261,1031751,1031340,1026802,1025879,1031619,1039355],\"holder\":null}"
  }
}