Paradaux

PAR-240

0

Let Bedrock/Floodgate players link & reach their wallet on the Economy Explorer

Pending ReleaseNormalUnassignedEconomy ExplorerImprovement

Problem

Bedrock players who join via Floodgate hold a Floodgate UUID account (owner_uuid_bin is all-zeros in the high 8 bytes, XUID in the low 8). In-game the economy serves them fine (name resolution shipped in PAR-150), but they effectively can't reach their wallet on the explorer — the web link/auth flow only lands on Java identities.

Evidence (prod, 2026-06-21)

  • 12,616 Floodgate-UUID PERSONAL accounts; ~5,600 active within the last year holding ~$4.3M (3,002 active in 30 days, $2.06M, of which $760k is earned money above the join grant).
  • Only 10 of 437 explorer_identity links point at a Floodgate UUID — i.e. almost no Bedrock player has successfully linked.
  • This is the real "~$1.71M unreachable on the explorer" problem from PAR-147. (PAR-147 was canceled — the dominant Bedrock population is single-identity, not a fragmentation/merge problem; this reachability gap is the genuine remaining work.)

Investigate

The pieces of the current link flow (confirm where a Bedrock player falls off):

  • economy-explorer/lib/auth/viewer.ts — upserts explorer_identity (keycloak_sub → one player_uuid_bin) from the token's minecraft_uuid claim.
  • Tables explorer_link_code (code, keycloak_sub, minecraft_name, expires_at) and explorer_identity — there's already an in-game-code → web-bind mechanism; does it capture/accept a Floodgate UUID + .name, or is it Java-centric?
  • The Paper-side command that issues the link code — does it run for Floodgate players, and does it bind their actual (Floodgate) UUID or a Java-resolved one?
  • How a Bedrock/Xbox player authenticates to keycloak in the first place (Microsoft/Java login assumptions).

Likely shape

The in-game /link-code path should be identity-agnostic (the UUID comes from the in-game session, so a Bedrock player's Floodgate UUID is available there) — most of the work is probably (a) making the code generator run + bind the correct UUID for Floodgate players, and (b) making the explorer accept/normalize a Floodgate-shaped UUID and .name. Confirm during investigation.

Acceptance

  • A Bedrock/Floodgate player can complete the link flow and see/manage their own (Floodgate-UUID) wallet, balance, and transactions on the explorer.
  • Floodgate-shaped UUIDs and .-prefixed names display correctly throughout.
  • No regression for Java linking.

Spun out of PAR-147 (canceled). Not a Treasury/merging concern.

Resources

Comments

tesks · Jun 21, 2026, 8:16 PM

Outcome — already works end-to-end; locked in with regression tests

Investigation conclusion: the explorer + plugin already handle Floodgate identities correctly. The issue's hypothesised work ("make the code generator bind the correct UUID; make the explorer accept a Floodgate UUID + .name") is already done:

  • The in-game link (UiAccessHandler.doLink) binds sender.getUniqueId() — for a Bedrock player that is their Floodgate UUID — straight into explorer_identity.
  • The explorer is UUID-version-agnostic throughout: uuidToBin/binToUuid + every UUID regex accept the all-zero-high-bytes shape; minecraft_name is VARCHAR(32) (V12); no ^\w+$ name rule; wallet lookup matches on owner_uuid_bin.

Live evidence (prod DemocracyCraft): 12,686 Floodgate PERSONAL accounts; of 450 explorer links, 440 Java + 10 Floodgate. All 10 Floodgate links were bound in-game: with correct .-names, and each resolves a working wallet (right name, accounts, transactions). The auto-link (token-claim) path is Java-only (0 Floodgate) because a Keycloak token only carries minecraft_uuid after an in-game link sets it. So the low Bedrock link rate is adoption, not a code defect — and per the ask, the goal was to ensure that if a Bedrock player links, it works (it does).

Delivered (commit faf232a): regression tests so this can't silently regress (e.g. a future v4-UUID assumption or ^\w+$ name rule — the ChestShop PAR-109 class of bug):

  • test/unit/floodgate.test.ts — Floodgate UUID round-trips BINARY(16); looksLikeUuid handles a Floodgate UUID + a dotted name; accountLabel renders the dotted name, never a raw UUID. Verified locally (5/5).
  • test/integration/sql.test.ts + seed — a Bedrock fixture (Floodgate UUID, .BedrockBob, completed explorer_identity link, $0 account so it can't perturb the supply/balance assertions); asserts findIdentityBySub, findAccountsForPlayer, and findPlayerUuidByName all resolve it. Green in CI against MariaDB.

No production code change was needed. (Note for later, out of scope: V17 economy_players isn't applied to prod yet, and the explorer still resolves names via firm_players — fine today since Floodgate players are name-cached there.)

Activity

  • tesks changed status to Status → Pending Release
  • tesks commented
  • ParadauxIO linked a commit — Commit faf232a — Lock in Bedrock/Floodgate wallet linking with regression tests (PAR-240)
  • tesks changed status to Status → In Progress
  • tesks created the issue