Keeper #551
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Keeper | |
| # Keeps the Turing Arena on-chain rounds alive: every 5 minutes it pushes a real | |
| # price, settles due rounds, reveals committed AI personas, and opens a fresh | |
| # round with commits, so the live site always has something to play. | |
| # | |
| # Setup: add a repository secret KEEPER_PRIVATE_KEY = the 0x... operator key | |
| # (wallet 0xBAE3...3b1E, which is isOperator on ProofOfAlpha + owner/reporter on | |
| # the oracle + owner of the persona agent NFTs). Funded with Mantle Sepolia MNT. | |
| # Until that secret is set, the scheduled run gates out cleanly (green, skipped) | |
| # rather than failing. | |
| on: | |
| schedule: | |
| - cron: "*/5 * * * *" # every 5 minutes (UTC). GitHub may delay under load. | |
| workflow_dispatch: {} # manual "Run workflow" button | |
| # One tick at a time: never let two overlapping runs collide on chain state or on | |
| # the keeper-state commit. Newer runs wait; we don't cancel a tick mid-flight. | |
| concurrency: | |
| group: keeper | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write # to push keeper-state/ back to the repo | |
| # Run the JS-based actions on Node 24, not the deprecated Node 20 runtime. | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| tick: | |
| name: Keeper tick | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Gate the whole tick on the secret being present. When it isn't (e.g. a | |
| # fork, or before the maintainer adds it), every later step skips and the | |
| # job stays green instead of erroring every 5 minutes. | |
| - name: Check operator key is configured | |
| id: gate | |
| env: | |
| KEY: ${{ secrets.KEEPER_PRIVATE_KEY }} | |
| run: | | |
| if [ -n "$KEY" ]; then | |
| echo "ok=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ok=false" >> "$GITHUB_OUTPUT" | |
| echo "KEEPER_PRIVATE_KEY is not set; skipping this tick. Add the repo secret to go live." | |
| fi | |
| - uses: actions/checkout@v5 | |
| if: steps.gate.outputs.ok == 'true' | |
| - uses: pnpm/action-setup@v6 # version comes from package.json "packageManager" | |
| if: steps.gate.outputs.ok == 'true' | |
| - uses: actions/setup-node@v5 | |
| if: steps.gate.outputs.ok == 'true' | |
| with: | |
| node-version: 20 | |
| cache: pnpm | |
| - name: Install | |
| if: steps.gate.outputs.ok == 'true' | |
| run: pnpm install --frozen-lockfile | |
| - name: Run keeper tick | |
| id: tick | |
| if: steps.gate.outputs.ok == 'true' | |
| continue-on-error: true # still commit any state written (e.g. new agent ids) on a partial failure | |
| env: | |
| PRIVATE_KEY: ${{ secrets.KEEPER_PRIVATE_KEY }} | |
| # Public config, safe to hardcode. Mirrors contracts/deployments/5003*.json. | |
| CHAIN_ID: "5003" | |
| # Official RPC for reliable tx submission. The frontend's heavy polling | |
| # was moved to alternative endpoints (see web rpcUrls), so this endpoint | |
| # is no longer saturated and leaves headroom for users' wallet txs. | |
| MANTLE_SEPOLIA_RPC_URL: "https://rpc.sepolia.mantle.xyz" | |
| PROOF_OF_ALPHA_ADDRESS: "0x4f5AFD41BDb602C824e5a86F19E95314180144cf" | |
| IDENTITY_REGISTRY_ADDRESS: "0xbB174b6D9a8ca439d5B3735b6570AAD3FEE8405F" | |
| PRICE_ORACLE_ADDRESS: "0x31510d8a6Bbe5eEF2a315099AD2F94B504a4EEe3" | |
| MANTLE_DEX_ORACLE_ADDRESS: "0x53cf4b4E989dBbDd7009c5108C21AE765f82480b" | |
| # Generous windows: GitHub's */5 cron is best-effort and often runs | |
| # late, so each phase must outlast a delayed or skipped tick. A reveal | |
| # window wider than the cron interval guarantees a tick lands inside it | |
| # to reveal the personas before settlement. | |
| KEEPER_COMMIT_SECONDS: "900" # 15 min commit | |
| KEEPER_REVEAL_SECONDS: "600" # 10 min reveal (>> 5 min cron) | |
| KEEPER_SETTLE_SECONDS: "240" # 4 min before settle | |
| run: pnpm --filter @turing-arena/agent keeper | |
| - name: Commit & push keeper-state | |
| if: steps.gate.outputs.ok == 'true' | |
| env: | |
| GIT_AUTHOR_NAME: turing-arena-keeper | |
| GIT_AUTHOR_EMAIL: keeper@users.noreply.github.com | |
| GIT_COMMITTER_NAME: turing-arena-keeper | |
| GIT_COMMITTER_EMAIL: keeper@users.noreply.github.com | |
| run: | | |
| git add keeper-state | |
| if git diff --cached --quiet; then | |
| echo "No keeper-state changes to commit." | |
| exit 0 | |
| fi | |
| git commit -m "keeper: tick $(date -u +%FT%TZ)" | |
| # Land cleanly even if the branch moved since checkout. | |
| git pull --rebase --autostash origin "${GITHUB_REF_NAME}" || true | |
| git push origin "HEAD:${GITHUB_REF_NAME}" | |
| - name: Surface tick failure | |
| if: steps.gate.outputs.ok == 'true' && steps.tick.outcome == 'failure' | |
| run: | | |
| echo "::error::keeper tick reported a failure (state, if any, was still committed)." | |
| exit 1 |