feat: add ORE mining game connector (experimental, v4) - #578
Conversation
Add connector for ORE v3 mining game on Solana with the following features: Mining Operations: - deploy: Deploy SOL to game board squares - checkpoint: Checkpoint to update rewards - claimSol: Claim SOL rewards - claimOre: Claim ORE token rewards Staking Operations: - stake: Stake ORE tokens - unstake: Unstake ORE tokens - claimStake: Claim staking rewards Info Endpoints: - accountInfo: Get miner and stake account info - boardInfo: Get game board and round state - systemInfo: Get treasury and token supply info 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ctor # Conflicts: # src/app.ts # src/templates/root.yml
The connector was written against an older ORE build and was broken against the currently-deployed program (oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv). Verified every instruction and account layout against live mainnet transactions and the ORE `api` crate (regolith-labs/ore). Instruction fixes (account count / data now match live txs): - deploy: 11 -> 12 accounts (add treasury; authority writable; entropy var = fixed VAR_ADDRESS BWCaDY96..., not the config field) - checkpoint: 6 -> 8 accounts (add authority + automation; board writable) - claimSol: 3 -> 5 accounts (add board, ore program) - claimOre: 9 -> 11 accounts and add required `bps: u64` arg (claim 100% = 10000) State parser fixes (Board/Miner/Round/Treasury) to match the repr(C) structs exactly (correct field order/offsets; Numeric = 16 bytes; Treasury is 48 bytes). Remove staking (stake/unstake/claimStake): those instructions no longer exist in the core ORE program — staking moved to a separate program (regolith-labs/ore-stake). Dropped the routes, schemas, stake-account parsing, and stake fields from account-info/system-info. Also removed treasuryBalanceSol/totalStaked (not in the Treasury struct) and the unused Config parser. Updated discriminators (bury 13->24, newVar 17->19, buyback=13; dropped setFeeCollector/setBuffer), rewrote ORE_INTEGRATION_GUIDE.md to the verified layouts, and removed the stale hand-written idl/ore.json (unused, not built). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N1YS88ZAY2rXVLmgvyN4oY
The deploy route treated any miner whose last round was older than the current round as needing a checkpoint (`miner.roundId < currentRoundId`). A miner that already settled a long-past round (checkpointId == roundId) would then try to re-checkpoint a round whose account no longer exists, and the deploy would fail. Gate the auto-checkpoint on an actually-unsettled past round (`miner.checkpointId < miner.roundId && miner.roundId < currentRoundId`). Verified live on mainnet: deploy + checkpoint both land for a wallet with a stale settled round (tx 2SXHu5… deploy, 4JuykY… checkpoint). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N1YS88ZAY2rXVLmgvyN4oY
The v4 program update went live on mainnet 2026-08-13 (same program ID). Parimutuel SOL payouts were removed: deployed SOL is now returned to each miner minus fees (1% admin on all squares; +10% protocol on losing squares, ~89% returned) instead of moving from losing to winning miners. Wire format (instructions, accounts, discriminators, PDAs) is unchanged; this updates the connector to match the renamed on-chain field and the new payout semantics: - Rename Round.totalWinnings -> totalReturnedSol (renamed on-chain, same offset) - board-info response: totalWinningsSol -> totalReturnedSol - check-round response: wonSol -> returnedSol with accurate description - Document the v4 payout model in the integration guide Verified against live mainnet: round 365351 shows returned/deployed = 0.895, matching the v4 fee model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThis PR adds an experimental Solana connector for ORE v4 mining, including read-only game-state APIs and managed-wallet transaction operations.
Confidence Score: 2/5This PR is not safe to merge until the ORE signing routes are included in Gateway authentication and confirmed transactions are checked for execution failure. The connector currently exposes managed-wallet signing operations outside the sensitive-route boundary and can return successful API responses for transactions that failed on-chain. Files Needing Attention: src/app.ts, src/services/gateway-security.ts, src/connectors/ore/ore.ts, and src/connectors/ore/ore-routes/checkpoint.ts
|
| Filename | Overview |
|---|---|
| src/app.ts | Registers the new route family at a path not covered by Gateway's sensitive-operation authentication matcher. |
| src/connectors/ore/ore.ts | Implements account access and managed-wallet signing, but returns transaction signatures without checking execution errors. |
| src/connectors/ore/ore-routes/deploy.ts | Builds deployments from caller-selected wallets and amounts, making the missing route authentication directly fund-affecting. |
| src/connectors/ore/ore-routes/checkpoint.ts | Settles rounds and derives reward deltas after transaction submission, but can report unchanged state as successful settlement when execution fails. |
| src/connectors/ore/ore.instructions.ts | Adds ORE deploy, checkpoint, and claim instruction serialization and account lists consistent with the supplied protocol layout. |
| src/connectors/ore/ore.parser.ts | Adds fixed-layout parsers and board-square bitmask utilities with no accepted defect identified. |
| src/connectors/ore/schemas.ts | Defines request and response contracts for the new ORE APIs with no accepted defect identified. |
Reviews (1): Last reviewed commit: "Merge branch 'development' into feat/ore..." | Re-trigger Greptile
| app.register(pancakeswapSolRoutes, { prefix: '/connectors/pancakeswap-sol' }); | ||
|
|
||
| // ORE mining game routes (experimental) | ||
| app.register(oreConnectorRoutes.ore, { prefix: '/connectors/ore/ore' }); |
There was a problem hiding this comment.
ORE routes bypass authentication
When Gateway authentication is enabled, /connectors/ore/ore/* does not match the sensitive-path filter, so unauthenticated clients can select a server-managed wallet and trigger signed deployments, checkpoints, or claims. This lets a caller spend another managed wallet's SOL through ORE or mutate its mining state without authorization.
How this was verified: The mounted ORE path does not match the sensitive connector pattern, while the deploy flow loads and signs with the request-selected managed wallet.
| const signature = await this.solana.connection.sendRawTransaction(signedTx.serialize()); | ||
| await this.solana.connection.confirmTransaction(signature, 'confirmed'); | ||
| return signature; |
There was a problem hiding this comment.
Execution failures report success
When an ORE transaction is confirmed but fails during program execution, this helper ignores the confirmation error and returns its signature as success. All transaction endpoints therefore report failed operations as successful, and checkpoint additionally reads unchanged state and returns zero reward deltas as though settlement completed.
Summary
All instruction and account layouts were taken from the ORE
apicrate(regolith-labs/ore) and verified against live mainnet transactions of the deployed
program (
oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWv).ORE v4 update (announcement)
The v4 update removed parimutuel SOL payouts: SOL no longer moves from losing miners
to winning miners. Each miner's deployed SOL is returned minus fees — ~99% on the winning
square (1% admin fee), ~89% on losing squares (1% admin + 10% protocol fee). ORE rewards
remain variable, but mining cost is now deterministic.
Wire format (instructions, account lists, discriminators, PDAs) is unchanged; the connector
updates are semantic:
Round.total_winningswas renamed on-chain tototal_returned_sol(same offset) — theboard-info response field is now
totalReturnedSolwonSol→returnedSol(it is your deployment returnedminus fees, not winnings from other miners)
Verified against live v4 mainnet state: round 365351 shows returned/deployed = 0.895,
matching the new fee model.
Features
Mining Operations
POST /connectors/ore/ore/deploy— Deploy SOL to game board squaresPOST /connectors/ore/ore/check-round— Checkpoint (settle) rewards for a completed roundPOST /connectors/ore/ore/claim-sol— Claim SOL rewardsPOST /connectors/ore/ore/claim-ore— Claim ORE token rewardsInfo Endpoints
GET /connectors/ore/ore/account-info— Miner account state for a walletGET /connectors/ore/ore/board-info— Game board and round stateGET /connectors/ore/ore/system-info— Treasury and ORE token supply infoNot included: staking
Staking (stake / unstake / claim-yield) is not part of the core ORE program — it lives
in a separate program (regolith-labs/ore-stake). The previously-drafted staking endpoints
targeted instructions that no longer exist and have been removed. Staking can be added later
as a separate connector/PR against ore-stake.
Configuration
Program IDs are fixed protocol constants:
oreV3EG1i9BEgiAJ8b177Z2S2rMarzak4NMv1kULvWvoreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcpOptions in
conf/ore.yml:commitment: transaction confirmation level (default:confirmed)priorityFee: priority fee in microlamports (default: 0)Test plan
pnpm start --passphrase=xxx --devGET /connectors/ore/ore/system-inforeturns treasury/supply dataGET /connectors/ore/ore/board-inforeturns current round info (checktotalReturnedSol)GET /connectors/ore/ore/account-info?walletAddress=<wallet>returns miner state🤖 Generated with Claude Code