Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
174 commits
Select commit Hold shift + click to select a range
f5d14ff
fix: split shared rpc reads from submit paths
rndrntwrk Mar 30, 2026
440ce2b
docs: align release tracking with active scope
rndrntwrk Mar 31, 2026
bc909e1
Merge branch 'develop' into fix/shared-rpc-proxy-safety
SYMBaiEX Mar 31, 2026
d5f6561
Merge pull request #113 from HyperscapeAI/fix/shared-rpc-proxy-safety
SYMBaiEX Mar 31, 2026
c2b94ec
fix: route CI builds through chain-specific keeper variables
rndrntwrk Apr 1, 2026
6917f6d
fix(bsc): back off rpc reads and hide mobile chart
rndrntwrk Apr 1, 2026
6ec1872
Merge pull request #126 from HyperscapeAI/fix/ci-chain-keeper-variables
SYMBaiEX Apr 1, 2026
0a6865d
Merge branch 'develop' into docs/release-tracking-alignment
SYMBaiEX Apr 1, 2026
60da7a0
Merge pull request #115 from HyperscapeAI/docs/release-tracking-align…
SYMBaiEX Apr 1, 2026
d6dfa99
chore: sync enoomian staging with develop truths
rndrntwrk Apr 2, 2026
6b3a292
fix: harden enoomian staging stream embedding
rndrntwrk Apr 2, 2026
b930c66
fix: defer prediction chart mount until sized
rndrntwrk Apr 2, 2026
ad66afa
fix: delay bsc odds chart until layout settles
rndrntwrk Apr 2, 2026
f1c864b
fix: guard models chart until it is measurable
rndrntwrk Apr 2, 2026
7f3d1a5
fix: stabilize market chart sizing
rndrntwrk Apr 2, 2026
47ced58
feat: overhaul personal staging stream delivery
rndrntwrk Apr 7, 2026
0f4d6b8
fix: stabilize self hls player surfaces
rndrntwrk Apr 7, 2026
5eee555
fix: tolerate transient renderer probe failures
rndrntwrk Apr 7, 2026
ece5321
fix(stream): align personal staging bet delivery and player stack
rndrntwrk Apr 8, 2026
1f27e84
docs(stream): record canonical channel and fallback model
rndrntwrk Apr 9, 2026
06bb9f7
merge: consolidate legacy staging into canonical staging
rndrntwrk Apr 9, 2026
baf8667
[stream][00] Isolate enoomian staging secrets from shared project envs
rndrntwrk Apr 9, 2026
68d479d
[stream][03A] Pass through and consume schema v3 on Solana
rndrntwrk Apr 9, 2026
759302e
[stream][03B] Pass through and consume schema v3 on BSC
rndrntwrk Apr 9, 2026
dee8548
[stream][03C] Use broadcast timeline in bet pages and spectator session
rndrntwrk Apr 9, 2026
360e954
fix(stream): keep sparse timeline overlays non-destructive
rndrntwrk Apr 9, 2026
57d1387
Merge branch 'enoomian/staging-00-personal-secret-boundary' into enoo…
rndrntwrk Apr 9, 2026
0cf2f26
Merge branch 'enoomian/staging-03a-solana-broadcast-timeline' into en…
rndrntwrk Apr 9, 2026
dc95edb
Merge branch 'enoomian/staging-03b-bsc-broadcast-timeline' into enoom…
rndrntwrk Apr 9, 2026
aa7e78b
Merge branch 'enoomian/staging-03c-ui-broadcast-timeline' into enoomi…
rndrntwrk Apr 9, 2026
ce0604d
feat: cut over enoomian staging to unified bets page
rndrntwrk Apr 9, 2026
dc74359
fix: stage unified keeper workspace docker build
rndrntwrk Apr 9, 2026
27c957c
fix: align unified keeper docker context
rndrntwrk Apr 10, 2026
eaaf79e
fix(staging): stabilize unified bets rollout
rndrntwrk Apr 10, 2026
f963bd9
merge: unify staging stabilization
rndrntwrk Apr 10, 2026
e4548bc
fix(keeper): honor unified staging chain freeze
rndrntwrk Apr 10, 2026
52f769c
fix(keeper): avoid startup tdz in solana health merge
rndrntwrk Apr 10, 2026
082de8f
fix(keeper): initialize unified chain gates before overview boot
rndrntwrk Apr 10, 2026
81392b9
fix(keeper): serialize unified status bigint values
rndrntwrk Apr 10, 2026
8b56a1e
fix(proof): run verify-chains under bun cli
rndrntwrk Apr 10, 2026
1aef357
fix(proof): bound chain verification on unified staging
rndrntwrk Apr 10, 2026
63c619c
fix(proof): surface bounded staging verify failures
rndrntwrk Apr 10, 2026
d3c7c15
Implement canonical bettor stream cutover
rndrntwrk Apr 10, 2026
94e2841
Restore unified keeper canonical stream session fields
rndrntwrk Apr 10, 2026
45cb413
Clean up unified Hyperbet staging public lane
rndrntwrk Apr 10, 2026
a00fe7a
Keep canonical playback mounted through soft renderer staleness
rndrntwrk Apr 10, 2026
d370971
Unify staging bettor lifecycle and models parity
rndrntwrk Apr 10, 2026
04ffe1c
Resolve staging bettor lifecycle and chain-scoped perps gaps
rndrntwrk Apr 10, 2026
f536d93
Fix staging perps chain scoping regressions
rndrntwrk Apr 10, 2026
1edda7f
Implement atomic parity staging rollout
rndrntwrk Apr 10, 2026
7d4497d
Harden enoomian staging proof tooling
rndrntwrk Apr 10, 2026
4aecf0b
Silence public lifecycle mismatch diagnostics
rndrntwrk Apr 10, 2026
e394b01
Fix EVM staging config re-export
rndrntwrk Apr 10, 2026
beb4af4
Recover pending unified keeper parity state
rndrntwrk Apr 11, 2026
4a9e75f
Show parity gate in phase badge
rndrntwrk Apr 12, 2026
d4adcc9
Repair Solana staging PM authority lane
rndrntwrk Apr 13, 2026
9a40fb5
Align unified keeper Solana roles
rndrntwrk Apr 13, 2026
57680f1
Compact Solana duel metadata URI
rndrntwrk Apr 13, 2026
2a24430
Use polling Solana confirmations in keepers
rndrntwrk Apr 13, 2026
e634510
Preserve Solana duel manifest on lifecycle updates
rndrntwrk Apr 13, 2026
cab78d7
Freeze mismatched parity bundle events
rndrntwrk Apr 13, 2026
f196a07
Model EVM dispute-window parity resolution
rndrntwrk Apr 13, 2026
20543aa
Handle Solana parity dispute window
rndrntwrk Apr 13, 2026
5cbad91
Ignore post-lock future parity events
rndrntwrk Apr 13, 2026
d9b1e99
Prioritize parity finalization in maintenance
rndrntwrk Apr 13, 2026
dd308b5
Defer perps config until after parity finality
rndrntwrk Apr 13, 2026
7d91f6b
Allow configurable EVM dispute windows
rndrntwrk Apr 13, 2026
11fd929
Finalize parity bundles after proposal windows
rndrntwrk Apr 13, 2026
6902f2d
Prevent perps maintenance from blocking parity
rndrntwrk Apr 13, 2026
985d6e7
Avoid keeper parity starts mid-fight
rndrntwrk Apr 13, 2026
a291b7a
Bound Solana RPC requests in keeper
rndrntwrk Apr 13, 2026
1aad01a
Run embedded keeper bot continuously
rndrntwrk Apr 13, 2026
55f85c6
Harden keeper result persistence
rndrntwrk Apr 13, 2026
7b1ee50
Prevent lock-only parity bundles
rndrntwrk Apr 13, 2026
8688296
Clear resolved-result recovery state
rndrntwrk Apr 13, 2026
fe637e8
Fix staging parity and EVM backoff
rndrntwrk Apr 13, 2026
ccde04d
Fix EVM panel backoff status sync
rndrntwrk Apr 13, 2026
f677b60
Keep post-open parity confirmations public
rndrntwrk Apr 13, 2026
88b95f8
Keep public duel projection parity-scoped
rndrntwrk Apr 13, 2026
8f44a87
Align public markets from parity receipts
rndrntwrk Apr 13, 2026
91d8788
Stabilize self-HLS player startup
rndrntwrk Apr 14, 2026
fe8e1ec
Tune stable self-HLS playback window
rndrntwrk Apr 14, 2026
9f0158b
Align self-HLS drift budget with staging buffer
rndrntwrk Apr 14, 2026
1d9e5c0
Ignore zero presentation delay for HLS sync
rndrntwrk Apr 14, 2026
d5f0042
Clarify local playback lag messaging
rndrntwrk Apr 14, 2026
27362ab
Document enoomian Cloudflare secret keys
rndrntwrk Apr 14, 2026
91d7e04
feat(keeper): alias /api/streaming/session{,/events} to /state{,/events}
rndrntwrk Apr 15, 2026
84394d7
fix(keeper): unmask cycle phase + duel identity during FIGHTING/RESOL…
rndrntwrk Apr 15, 2026
c1327e9
fix(bets-ui): pass openedAtMs to isPublicMarketParityState in phase gate
rndrntwrk Apr 16, 2026
cfe9ccc
fix(ui/marketParity): treat awaiting_confirmations as public-safe whe…
rndrntwrk Apr 16, 2026
3f1a073
fix(spectator): listen for 'state' SSE events in canonical stream ses…
rndrntwrk Apr 16, 2026
334dd4f
fix(keeper): reconcile overdue parity lock transitions on maintenance…
rndrntwrk Apr 16, 2026
bffea0c
fix(keeper): reconcile partial-success locks by checking per-chain re…
rndrntwrk Apr 16, 2026
9baef11
feat(ops): add Cloudflare Stream cleanup script
rndrntwrk Apr 17, 2026
56710b0
feat(ops): add Cloudflare Stream cleanup installer
rndrntwrk Apr 17, 2026
136a680
fix(ops): harden cloudflare-stream-cleanup installer
rndrntwrk Apr 17, 2026
b58a68a
fix(keeper): make reportRoundResult rehydrate and throw specific erro…
rndrntwrk Apr 17, 2026
efbb6ce
feat(keeper): catch up missed duel_ended + relax resolve reconciler g…
rndrntwrk Apr 17, 2026
c705191
feat(keeper): broaden catch-up to drain backlog of stranded locked duels
rndrntwrk Apr 17, 2026
c39dcd8
fix(keeper): stop stale prediction market pinning
rndrntwrk Apr 17, 2026
e12a22b
ci(prediction-market-gates): supply enoomian staging env as inline fa…
rndrntwrk Apr 17, 2026
a6fd97f
fix(ui): align llhls playback budgets to canonical delay
rndrntwrk Apr 17, 2026
bd285a0
fix(ui): add hysteresis before llhls fallback
rndrntwrk Apr 17, 2026
bdbaaf6
fix(ui): stabilize canonical stream playback sync
rndrntwrk Apr 17, 2026
8b41ec0
fix(player): prefer highest viable HLS level
rndrntwrk Apr 17, 2026
ccc072e
fix(ui): stop treating ahead-of-delay playback as drift
rndrntwrk Apr 17, 2026
45dc7e3
fix(keeper): reflect canonical stream health in /api/health
rndrntwrk Apr 17, 2026
43c36d7
chore: prepare code-only enoomian mainline sweep
rndrntwrk Apr 18, 2026
76d7190
fix(ci): resolve unified app lint regressions
rndrntwrk Apr 18, 2026
44d85e3
fix(ci): sync Solana artifacts and app-local Playwright installs
rndrntwrk Apr 18, 2026
87f028f
fix(player): stop 240p pinning and false sync hold
rndrntwrk Apr 19, 2026
58013bd
fix(player): force startup rendition and stop loader re-show
rndrntwrk Apr 19, 2026
1873be2
fix(player): choose startup level before hls bootstrap
rndrntwrk Apr 19, 2026
2c42cf1
fix(player): map startup level to hls sorted indices
rndrntwrk Apr 19, 2026
156b5cc
chore(player): log hls startup diagnostics
rndrntwrk Apr 19, 2026
0230bb3
chore(player): expose hls debug state
rndrntwrk Apr 19, 2026
91b194b
fix(player): force desktop chrome through hls.js
rndrntwrk Apr 19, 2026
94fa9c9
fix(bets): hide masked parity confirmation placeholder
rndrntwrk Apr 19, 2026
644c2a0
fix(player): boot managed desktop playback on stable hls
rndrntwrk Apr 19, 2026
a7573da
sync(pr): forward-port validated staging player and parity fixes
rndrntwrk Apr 19, 2026
202de33
feat(keeper): stamp source/server emission on duel-context + markets …
rndrntwrk Apr 19, 2026
7003826
feat(keeper): stamp source/server emission on duel-context + markets …
rndrntwrk Apr 19, 2026
3cedcfb
feat(ui/viewer-align): add viewer clock core (C3a)
rndrntwrk Apr 19, 2026
e866820
feat(ui/viewer-align): add rail buffers + max-age helpers (C3b)
rndrntwrk Apr 19, 2026
a3110f3
feat(ui/viewer-align): aligned selector + useViewerAlignedState hook …
rndrntwrk Apr 19, 2026
1b388be
feat(ui/viewer-align): compose aligned state in app shells behind dar…
rndrntwrk Apr 19, 2026
6bf3f7b
feat(ui/viewer-align): thread aligned overrides through panel display…
rndrntwrk Apr 19, 2026
a077e9e
fix(viewer-align): carry raw source timeline end to end
rndrntwrk Apr 19, 2026
e427b47
fix(viewer-align): emit shadow divergence logs when flag is dark
rndrntwrk Apr 20, 2026
2c1316c
fix(ui): keep viewer shadow telemetry active
rndrntwrk Apr 20, 2026
d17789b
fix(ui): limit viewer divergence logs to shadow mode
rndrntwrk Apr 20, 2026
12b7306
fix(ui): widen duel-context staleness budget
rndrntwrk Apr 20, 2026
8d47fd8
fix(ui): feed viewer alignment raw session state
rndrntwrk Apr 20, 2026
bc68f8c
fix(ui): keep live phase ahead of parity prep copy
rndrntwrk Apr 20, 2026
ea88b42
fix(keeper): harden sse headers for railway edge
rndrntwrk Apr 20, 2026
9f8c332
feat(keeper): stamp source/server emission on duel-context + markets …
rndrntwrk Apr 19, 2026
f9c6a32
feat(keeper): stamp source/server emission on duel-context + markets …
rndrntwrk Apr 19, 2026
7b70174
feat(ui/viewer-align): add viewer clock core (C3a)
rndrntwrk Apr 19, 2026
477c852
feat(ui/viewer-align): add rail buffers + max-age helpers (C3b)
rndrntwrk Apr 19, 2026
f83f0af
feat(ui/viewer-align): aligned selector + useViewerAlignedState hook …
rndrntwrk Apr 19, 2026
6ca42e9
feat(ui/viewer-align): compose aligned state in app shells behind dar…
rndrntwrk Apr 19, 2026
5bb4a25
feat(ui/viewer-align): thread aligned overrides through panel display…
rndrntwrk Apr 19, 2026
b65e606
fix(viewer-align): carry raw source timeline end to end
rndrntwrk Apr 19, 2026
c28885c
fix(viewer-align): emit shadow divergence logs when flag is dark
rndrntwrk Apr 20, 2026
4aaa637
fix(ui): keep viewer shadow telemetry active
rndrntwrk Apr 20, 2026
2d20488
fix(ui): limit viewer divergence logs to shadow mode
rndrntwrk Apr 20, 2026
527353a
fix(ui): widen duel-context staleness budget
rndrntwrk Apr 20, 2026
b80566c
fix(ui): feed viewer alignment raw session state
rndrntwrk Apr 20, 2026
745b2eb
fix(ui): keep live phase ahead of parity prep copy
rndrntwrk Apr 20, 2026
a086543
fix(keeper): harden sse headers for railway edge
rndrntwrk Apr 20, 2026
a812727
fix(ui): restore stream player status binding on bsc and solana
rndrntwrk Apr 20, 2026
71d228b
fix(build): align acceptance env import with staging
rndrntwrk Apr 20, 2026
1b0f982
fix(ui): honor viewer trade gates and playback progress
rndrntwrk Apr 20, 2026
835a531
fix(keeper): align result catchup auth with provider
rndrntwrk Apr 20, 2026
acd5889
fix(keeper): require dedicated result lookup token
rndrntwrk Apr 20, 2026
a0cee7b
fix(keeper): preserve raw source timeline on sibling rails
rndrntwrk Apr 20, 2026
5c97ebf
sync(pr): forward-port validated staging player and parity fixes
rndrntwrk Apr 19, 2026
e8b5a2b
fix(ui): honor viewer trade gates and playback progress
rndrntwrk Apr 20, 2026
9e9cf7a
fix(keeper): align result catchup auth with provider
rndrntwrk Apr 20, 2026
21590e6
fix(keeper): require dedicated result lookup token
rndrntwrk Apr 20, 2026
d4c051f
fix(keeper): preserve raw source timeline on sibling rails
rndrntwrk Apr 20, 2026
0554b52
Merge branch 'enoomian/staging' into enoomian/unified-bets-parity-kee…
rndrntwrk Apr 21, 2026
24e3526
fix(ui): make duel status transitions deterministic
rndrntwrk Apr 21, 2026
1bfe597
fix(e2e): stabilize unified chain coverage
rndrntwrk Apr 21, 2026
a644db3
fix(ci): wire unified e2e app to keeper port
rndrntwrk Apr 21, 2026
a5d76c0
fix(ci): initialize solady submodule for foundry jobs
rndrntwrk Apr 21, 2026
3df3b5f
fix(ci): prebuild evm artifacts for unified solana gate
rndrntwrk Apr 21, 2026
f4a29d1
fix(keeper): preserve real chain keys in legacy perps fallback
rndrntwrk Apr 22, 2026
42f5183
test(e2e): seed chain-scoped perps data
rndrntwrk Apr 22, 2026
e498a6e
fix(ui): gate canonical preload on lifecycle identity
rndrntwrk Apr 23, 2026
15a3a56
fix(keeper): republish same-duel authority changes
rndrntwrk Apr 23, 2026
657a59b
fix(keeper): ignore volatile stream telemetry churn
rndrntwrk Apr 23, 2026
7df2efd
ci(pr130): clear Unified Bets E2E + hyperbet-evm validate failures
rndrntwrk Apr 24, 2026
c98a005
fix(keeper/betSync.test): widen StreamState casts through unknown
rndrntwrk Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/actions/setup-hyperbet/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ runs:
if: ${{ inputs.install-foundry == 'true' }}
uses: foundry-rs/foundry-toolchain@v1

- name: Initialize EVM submodules
if: ${{ inputs.install-foundry == 'true' }}
shell: bash
run: |
set -euo pipefail
if [[ ! -f .gitmodules ]]; then
exit 0
fi
if [[ -f packages/evm-contracts/lib/solady/src/utils/FixedPointMathLib.sol ]]; then
exit 0
fi
git submodule update --init --recursive packages/evm-contracts/lib/solady

- name: Cache Solana CLI
if: ${{ inputs.install-solana == 'true' }}
uses: actions/cache@v5.0.4
Expand Down
24 changes: 18 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,29 +223,41 @@ jobs:
include:
- package: hyperbet-solana
workspace_target: hyperbet-solana
audit_target: pages:solana
audit_target: pages:legacy
build_mode: mainnet-beta
solana_cluster: mainnet-beta
keeper_url_var: HYPERBET_SOLANA_KEEPER_URL
keeper_ws_url_var: HYPERBET_SOLANA_KEEPER_WS_URL
keeper_fallback_url: "https://api.hyperbet.win"
keeper_fallback_ws_url: "wss://api.hyperbet.win/ws"
avax_chain_id: ""
avax_gold_clob_address: ""
- package: hyperbet-bsc
workspace_target: hyperbet-bsc
audit_target: pages:bsc
audit_target: pages:legacy
build_mode: mainnet-beta
solana_cluster: mainnet-beta
keeper_url_var: HYPERBET_BSC_KEEPER_URL
keeper_ws_url_var: HYPERBET_BSC_KEEPER_WS_URL
keeper_fallback_url: "https://bsc-api.hyperbet.win"
keeper_fallback_ws_url: "wss://bsc-api.hyperbet.win/ws"
avax_chain_id: ""
avax_gold_clob_address: ""
- package: hyperbet-avax
workspace_target: hyperbet-avax
audit_target: app:avax
build_mode: testnet
solana_cluster: testnet
keeper_url_var: HYPERBET_AVAX_KEEPER_URL
keeper_ws_url_var: HYPERBET_AVAX_KEEPER_WS_URL
keeper_fallback_url: "https://avax-api.hyperbet.win"
keeper_fallback_ws_url: "wss://avax-api.hyperbet.win/ws"
avax_chain_id: ""
avax_gold_clob_address: ""
env:
CF_PAGES_COMMIT_SHA: ${{ github.sha }}
VITE_GAME_API_URL: https://api.hyperbet.win
VITE_GAME_WS_URL: wss://api.hyperbet.win/ws
VITE_GAME_API_URL: ${{ vars[matrix.keeper_url_var] || matrix.keeper_fallback_url }}
VITE_GAME_WS_URL: ${{ vars[matrix.keeper_ws_url_var] || matrix.keeper_fallback_ws_url }}
VITE_SOLANA_CLUSTER: ${{ matrix.solana_cluster }}
VITE_USE_GAME_RPC_PROXY: "true"
VITE_USE_GAME_EVM_RPC_PROXY: "true"
Expand Down Expand Up @@ -335,8 +347,8 @@ jobs:
needs: shared-validation
env:
CF_PAGES_COMMIT_SHA: ${{ github.sha }}
VITE_GAME_API_URL: https://api.hyperbet.win
VITE_GAME_WS_URL: wss://api.hyperbet.win/ws
VITE_GAME_API_URL: ${{ vars.HYPERBET_BSC_KEEPER_URL || 'https://bsc-api.hyperbet.win' }}
VITE_GAME_WS_URL: ${{ vars.HYPERBET_BSC_KEEPER_WS_URL || 'wss://bsc-api.hyperbet.win/ws' }}
VITE_SOLANA_CLUSTER: mainnet-beta
VITE_USE_GAME_RPC_PROXY: "true"
VITE_USE_GAME_EVM_RPC_PROXY: "true"
Expand Down
13 changes: 1 addition & 12 deletions .github/workflows/deploy-avax-pages.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
name: Deploy Hyperbet AVAX Pages

on:
push:
branches: [main]
paths:
- "packages/hyperbet-avax/app/**"
- "packages/hyperbet-ui/**"
- "scripts/**"
- ".github/actions/setup-hyperbet/**"
- ".github/workflows/deploy-avax-pages.yml"
- "docs/hyperbet-production-deploy.md"
- "package.json"
- "bun.lock"
workflow_dispatch:
inputs:
environment:
Expand Down Expand Up @@ -154,7 +143,7 @@ jobs:
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.environment }}" = "preview" ]; then
BRANCH="preview-${{ github.run_id }}"
elif [ "${DEPLOY_TARGET}" = "staging" ]; then
BRANCH="staging"
BRANCH="enoomian/staging"
else
BRANCH="main"
fi
Expand Down
25 changes: 9 additions & 16 deletions .github/workflows/deploy-bsc-pages.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
name: Deploy Hyperbet BSC Pages
name: Rollback Legacy Hyperbet BSC Pages

on:
push:
branches: [main]
paths:
- "packages/hyperbet-bsc/app/**"
- "packages/hyperbet-ui/**"
- "packages/hyperbet-chain-registry/**"
- "scripts/**"
- ".github/actions/setup-hyperbet/**"
- ".github/workflows/deploy-bsc-pages.yml"
- "docs/hyperbet-production-deploy.md"
- "package.json"
- "bun.lock"
workflow_dispatch:
inputs:
environment:
Expand All @@ -24,6 +12,11 @@ on:
- production
- staging
- preview
rollback_only:
description: "Confirm this legacy workflow is being used for rollback only"
required: true
default: false
type: boolean

permissions:
contents: read
Expand All @@ -34,7 +27,7 @@ concurrency:

jobs:
deploy:
if: ${{ github.event_name == 'workflow_dispatch' || vars.HYPERBET_BSC_PAGES_DEPLOY_ENABLED == 'true' || (vars.HYPERBET_BSC_PAGES_DEPLOY_ENABLED == '' && vars.HYPERBET_BSC_DEPLOY_ENABLED == 'true') }}
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.rollback_only == 'true' }}
name: Deploy hyperbet-bsc pages
runs-on: ubuntu-latest
environment: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && 'staging' || 'production' }}
Expand Down Expand Up @@ -120,7 +113,7 @@ jobs:
bash scripts/ci-install-verified.sh root hyperbet-bsc-app

- name: Audit deploy env
run: node --import tsx scripts/ci-env-audit.ts --target=pages:bsc --deployment=${DEPLOY_TARGET}
run: node --import tsx scripts/ci-env-audit.ts --target=pages:legacy --deployment=${DEPLOY_TARGET}
env:
VITE_GAME_API_URL: ${{ env.HYPERBET_API_URL }}
VITE_GAME_WS_URL: ${{ env.HYPERBET_WS_URL }}
Expand Down Expand Up @@ -164,7 +157,7 @@ jobs:
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.environment }}" = "preview" ]; then
BRANCH="preview-${{ github.run_id }}"
elif [ "${DEPLOY_TARGET}" = "staging" ]; then
BRANCH="staging"
BRANCH="enoomian/staging"
else
BRANCH="main"
fi
Expand Down
233 changes: 233 additions & 0 deletions .github/workflows/deploy-hyperbet-keeper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
name: Deploy Hyperbet Keeper

on:
push:
branches: [main]
paths:
- "packages/hyperbet-evm/keeper/**"
- "packages/hyperbet-evm/deployments/**"
- "packages/hyperbet-chain-registry/**"
- "packages/hyperbet-mm-core/**"
- "packages/hyperbet-evm-keeper-core/**"
- "scripts/**"
- ".github/actions/setup-hyperbet/**"
- ".github/workflows/deploy-hyperbet-keeper.yml"
- "docs/hyperbet-production-deploy.md"
- "package.json"
- "bun.lock"
workflow_dispatch:
inputs:
environment:
description: "Deployment target"
required: true
default: production
type: choice
options:
- production
- staging

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
deploy:
name: Deploy hyperbet keeper
runs-on: ubuntu-latest
environment: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && 'enoomian-staging' || 'production' }}
steps:
- name: Checkout code
uses: actions/checkout@v6.0.2
with:
fetch-depth: 0

- name: Resolve deployment target
run: |
deploy_target="production"
pages_url="${{ vars.HYPERBET_PAGES_URL }}"
keeper_url="${{ vars.HYPERBET_KEEPER_URL }}"
keeper_ws_url="${{ vars.HYPERBET_KEEPER_WS_URL }}"
railway_project_id="${{ vars.HYPERBET_RAILWAY_PROJECT_ID }}"
railway_environment_id="${{ vars.HYPERBET_RAILWAY_PRODUCTION_ENVIRONMENT_ID }}"
railway_service_id="${{ vars.HYPERBET_RAILWAY_KEEPER_SERVICE_ID }}"
enabled_evm_chains="bsc,avax"
avax_rpc_url="https://api.avax.network/ext/bc/C/rpc"
avax_gold_clob_address="${{ vars.HYPERBET_AVAX_GOLD_CLOB_ADDRESS }}"
keeper_status_filter='.ok == true and .proxies.solanaRpc == true and .proxies.bscRpc == true and .proxies.avaxRpc == true'

if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.environment }}" = "staging" ]; then
deploy_target="staging"
pages_url="${{ vars.ENOOMIAN_HYPERBET_PAGES_URL }}"
keeper_url="${{ vars.ENOOMIAN_HYPERBET_KEEPER_URL }}"
keeper_ws_url="${{ vars.ENOOMIAN_HYPERBET_KEEPER_WS_URL }}"
railway_project_id="${{ vars.ENOOMIAN_RAILWAY_PROJECT_ID }}"
railway_environment_id="${{ vars.ENOOMIAN_RAILWAY_ENVIRONMENT_ID }}"
railway_service_id="${{ vars.ENOOMIAN_HYPERBET_KEEPER_SERVICE_ID }}"
enabled_evm_chains="bsc"
avax_rpc_url=""
avax_gold_clob_address=""
keeper_status_filter='.ok == true and .proxies.solanaRpc == true and .proxies.bscRpc == true'
fi

if [ -z "${pages_url}" ] || [ -z "${keeper_url}" ] || [ -z "${keeper_ws_url}" ] || [ -z "${railway_project_id}" ] || [ -z "${railway_environment_id}" ] || [ -z "${railway_service_id}" ]; then
echo "Missing Hyperbet keeper configuration for ${deploy_target}" >&2
exit 1
fi

echo "DEPLOY_TARGET=${deploy_target}" >> "${GITHUB_ENV}"
echo "HYPERBET_PAGES_URL=${pages_url}" >> "${GITHUB_ENV}"
echo "HYPERBET_KEEPER_URL=${keeper_url}" >> "${GITHUB_ENV}"
echo "HYPERBET_KEEPER_WS_URL=${keeper_ws_url}" >> "${GITHUB_ENV}"
echo "RAILWAY_PROJECT_ID=${railway_project_id}" >> "${GITHUB_ENV}"
echo "RAILWAY_ENVIRONMENT_ID=${railway_environment_id}" >> "${GITHUB_ENV}"
echo "RAILWAY_KEEPER_SERVICE_ID=${railway_service_id}" >> "${GITHUB_ENV}"
echo "HYPERBET_ENABLED_EVM_CHAINS=${enabled_evm_chains}" >> "${GITHUB_ENV}"
echo "HYPERBET_AVAX_RPC_URL=${avax_rpc_url}" >> "${GITHUB_ENV}"
echo "HYPERBET_AVAX_GOLD_CLOB_ADDRESS=${avax_gold_clob_address}" >> "${GITHUB_ENV}"
echo "KEEPER_STATUS_FILTER=${keeper_status_filter}" >> "${GITHUB_ENV}"

- name: Setup Hyperbet toolchain
uses: ./.github/actions/setup-hyperbet

- name: Detect keeper source changes
id: keeper_changes
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "Manual dispatch requested; forcing keeper deploy."
echo "keeper_source_changed=true" >> "$GITHUB_OUTPUT"
exit 0
fi

base_ref="${{ github.event.before }}"
if [ -z "$base_ref" ] || [ "$base_ref" = "0000000000000000000000000000000000000000" ] || ! git cat-file -e "${base_ref}^{commit}" 2>/dev/null; then
base_ref="$(git rev-parse HEAD^ 2>/dev/null || true)"
fi

if [ -n "$base_ref" ]; then
changed_files="$(git diff --name-only "$base_ref" "${{ github.sha }}")"
else
changed_files="$(git show --pretty='' --name-only "${{ github.sha }}")"
fi
printf '%s\n' "$changed_files"

keeper_change_pattern='^(packages/hyperbet-evm/keeper/|packages/hyperbet-evm/deployments/|packages/hyperbet-chain-registry/|packages/hyperbet-mm-core/|packages/hyperbet-evm-keeper-core/|scripts/|\.github/actions/setup-hyperbet/)'
keeper_source_changed=false
if printf '%s\n' "$changed_files" | grep -Eq "${keeper_change_pattern}"; then
keeper_source_changed=true
fi

echo "keeper_source_changed=${keeper_source_changed}" >> "$GITHUB_OUTPUT"

- name: Install dependencies
run: bash scripts/ci-install-verified.sh root hyperbet-evm-keeper

- name: Audit deploy env
run: node --import tsx scripts/ci-env-audit.ts --target=keeper:unified --deployment=${DEPLOY_TARGET}
env:
ENOOMIAN_HYPERBET_PAGES_URL: ${{ env.HYPERBET_PAGES_URL }}
ENOOMIAN_HYPERBET_KEEPER_URL: ${{ env.HYPERBET_KEEPER_URL }}
ENOOMIAN_HYPERBET_KEEPER_WS_URL: ${{ env.HYPERBET_KEEPER_WS_URL }}
CI_AUDIT_REQUIRE_RUNTIME: "true"
HYPERBET_KEEPER_URL: ${{ env.HYPERBET_KEEPER_URL }}
RAILWAY_PROJECT_ID: ${{ env.RAILWAY_PROJECT_ID }}
RAILWAY_ENVIRONMENT_ID: ${{ env.RAILWAY_ENVIRONMENT_ID }}
RAILWAY_KEEPER_SERVICE_ID: ${{ env.RAILWAY_KEEPER_SERVICE_ID }}
SOLANA_RPC_URL: https://api.mainnet-beta.solana.com
BSC_RPC_URL: https://bsc-dataseed.binance.org
BSC_GOLD_CLOB_ADDRESS: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && (vars.ENOOMIAN_BSC_GOLD_CLOB_ADDRESS != '' && vars.ENOOMIAN_BSC_GOLD_CLOB_ADDRESS || vars.HYPERBET_BSC_STAGING_GOLD_CLOB_ADDRESS) || vars.HYPERBET_BSC_GOLD_CLOB_ADDRESS }}
AVAX_RPC_URL: ${{ env.HYPERBET_AVAX_RPC_URL }}
AVAX_GOLD_CLOB_ADDRESS: ${{ env.HYPERBET_AVAX_GOLD_CLOB_ADDRESS }}
EVM_KEEPER_CHAINS: ${{ env.HYPERBET_ENABLED_EVM_CHAINS }}

- name: Typecheck keeper
run: bunx tsc --noEmit -p packages/hyperbet-evm/keeper/tsconfig.json

- name: Smoke test keeper service
run: |
PORT=18080 \
ENABLE_KEEPER_BOT=false \
EVM_KEEPER_CHAINS="${HYPERBET_ENABLED_EVM_CHAINS}" \
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com \
BSC_RPC_URL=https://bsc-dataseed.binance.org \
AVAX_RPC_URL="${HYPERBET_AVAX_RPC_URL}" \
BSC_GOLD_CLOB_ADDRESS=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && (vars.ENOOMIAN_BSC_GOLD_CLOB_ADDRESS != '' && vars.ENOOMIAN_BSC_GOLD_CLOB_ADDRESS || vars.HYPERBET_BSC_STAGING_GOLD_CLOB_ADDRESS) || vars.HYPERBET_BSC_GOLD_CLOB_ADDRESS }} \
AVAX_GOLD_CLOB_ADDRESS="${HYPERBET_AVAX_GOLD_CLOB_ADDRESS}" \
bun --bun packages/hyperbet-evm/keeper/src/service.ts >/tmp/hyperbet-keeper.log 2>&1 &
KEEPER_PID=$!
trap 'kill "$KEEPER_PID" >/dev/null 2>&1 || true' EXIT

for attempt in $(seq 1 20); do
if curl -fsSL http://127.0.0.1:18080/status | jq -e '.ok == true and .proxies != null' >/dev/null; then
exit 0
fi
sleep 1
done

cat /tmp/hyperbet-keeper.log
exit 1

- name: Install Railway CLI
if: steps.keeper_changes.outputs.keeper_source_changed == 'true'
run: bun add -g @railway/cli

- name: Write Railway keeper context
if: steps.keeper_changes.outputs.keeper_source_changed == 'true'
working-directory: packages/hyperbet-evm/keeper
run: |
keeper_path="$(pwd)"
mkdir -p "${HOME}/.railway"
cat > "${HOME}/.railway/config.json" <<EOF
{
"projects": {
"${keeper_path}": {
"projectPath": "${keeper_path}",
"name": "hyperbet",
"project": "${RAILWAY_PROJECT_ID}",
"environment": "${RAILWAY_ENVIRONMENT_ID}",
"environmentName": "${DEPLOY_TARGET}",
"service": "${RAILWAY_KEEPER_SERVICE_ID}"
}
},
"user": {
"token": "${RAILWAY_TOKEN}"
}
}
EOF
env:
RAILWAY_TOKEN: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && secrets.ENOOMIAN_RAILWAY_TOKEN || secrets.RAILWAY_TOKEN }}

- name: Stage keeper workspace context
if: steps.keeper_changes.outputs.keeper_source_changed == 'true'
run: node --import tsx scripts/stage-deploy-workspace.ts --target=keeper:shared

- name: Deploy keeper
if: steps.keeper_changes.outputs.keeper_source_changed == 'true'
working-directory: packages/hyperbet-evm/keeper
run: |
railway up . \
--path-as-root \
--detach \
--service "${RAILWAY_KEEPER_SERVICE_ID}" \
--environment "${RAILWAY_ENVIRONMENT_ID}"
env:
RAILWAY_TOKEN: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging' && secrets.ENOOMIAN_RAILWAY_TOKEN || secrets.RAILWAY_TOKEN }}
CI: "true"

- name: Verify keeper endpoints
if: steps.keeper_changes.outputs.keeper_source_changed == 'true'
run: |
for attempt in $(seq 1 20); do
status_payload="$(curl -fsSL "${HYPERBET_KEEPER_URL}/status" || true)"
if [ -n "$status_payload" ] && echo "$status_payload" | jq -e "${KEEPER_STATUS_FILTER}" >/dev/null; then
break
fi
sleep 15
done

curl -fsSL "${HYPERBET_KEEPER_URL}/status" | jq -e '.ok == true'
curl -fsSL "${HYPERBET_KEEPER_URL}/api/arena/prediction-markets/active" | jq -e '.duel != null and .markets != null'
curl -fsSL "${HYPERBET_KEEPER_URL}/api/arena/prediction-markets/overview" | jq -e '.duel != null and .markets != null'
curl -fsSL "${HYPERBET_KEEPER_URL}/api/keeper/bot-health" | jq -e '.ok == true and .markets != null'
Loading
Loading