# UGLY Lab / current implementation / v0.44.1

Updated 20 September 2026. UGLY is the experimental venue for wallet identity, a testnet entry-token claim and enforced holder access. This document supersedes the earlier proof-only v0.39 description. The creator walkthrough is in [the website docs](../developers.html#ugly-lab).

## Player flow

1. Open [UGLY Lab on testnet](../ugly-lab.html?network=testnet), directly or from the pink mark at the UGLY entrance.
2. Sign in with the Google account used in the game.
3. Choose Verify wallet. The browser requests the account, creates the one-use server challenge automatically, requests a personal identity signature and submits it. The user must approve the signature. No gas or asset-transfer approval is involved in this step.
4. Explicitly accept the tester terms and join the tester list.
5. Existing holders can enter with at least 1 tUGLY. Otherwise choose Claim 1 tUGLY and approve the separate Robinhood Testnet transaction; test ETH is needed for gas.
6. Enter UGLY plaza. The server checks the bound wallet and current balance, not a client success flag.

The signature binds account, canonical origin/URI, chain and a tab-specific challenge secret. Challenges expire after five minutes, allow at most five verification attempts, and are one-use. Creation is limited to one every 15 seconds. Proof lasts 30 days; access still requires current eligibility. EOA message recovery and read-only ERC-1271 proof are implemented; undeployed ERC-6492 wrappers are unsupported.

Manage membership exposes leave-list and unlink actions. Unlink clears the profile address, enrollment and challenge contents and releases the address claim. Closing MetaMask does not unlink a verified address. An address cannot be actively assigned to two tester accounts; merging/recovery is not a shipped self-service feature. No private keys or seed phrases are requested or persisted.

## Testnet scope and claims

Robinhood Testnet chain ID is **46630**. Mainnet chain 4663 records and flags are separate; mainnet verification remains paused. The explicit testnet exception does not authorize production financial operations. The previously reported MetaMask domain warning has not been documented as resolved; do not bypass wallet warnings.

The deployed dispenser issues exactly 1 tUGLY once per address, subject to token supply and faucet/refill limits. This is not one per person or Sybil-resistant reward eligibility. The claim is a zero-value, wallet-approved transaction costing test ETH gas; it has no token approval or server signer. Existing holders do not need to claim. See [UGLY entry claims](UGLY-ENTRY-CLAIMS.md) for deployed addresses, runtime checks, pending-transaction handling and the recorded testnet transaction.

No deposits, custodial trading balance, withdrawals, paid entry, real orders, launch allocation, mainnet claim or fee collection are enabled. The tester registration is not a token-sale whitelist.

## Protected access is now connected to the game

The UGLY published plaza uses the optional whole-plaza gate. Scene admission, multiplayer presence, built-in chat and broadcasts enforce the server's decision. The browser renews roughly every eight seconds; token observations cache for up to ten seconds per warm process. Revocation is not instantaneous. Failed membership/RPC checks close access; seat leases have their own expiry.

Studio owners can also use their own ERC-20/721/1155 on Robinhood Testnet, a private wallet whitelist, or an asset AND whitelist requirement. Custom projects do not have to require tUGLY. All restricted modes currently share the Google/testnet wallet proof and explicit tester registration implemented by this Lab. See [developer whitelists](PLAZA-WHITELISTS.md) and [plaza gates](PLAZA-TOKEN-GATES.md).

Voice and Telegram bridging are disabled in gated worlds until continuous membership enforcement is supported. Telegram-only wallet linking is not implemented. Owner editors can access their private draft without meeting a gate, but do not bypass published player entry. The standalone Lab access panel is a membership demonstration, not a separate connected 3D room.

## Data and operational boundaries

The internal `/api/ugly-lab` endpoint requires the configured exact Origin, JSON and verified account. Testnet is selected explicitly. `GB_UGLY_TESTNET_VERIFICATION` and `GB_UGLY_LAB_VERIFICATION` are independent. Service-account configuration and fixed server RPC/registry validation remain server-side; these endpoints are not a supported public integration API.

Private testnet collections are `uglyTestnetPlayers`, `uglyTestnetChallenges`, `uglyTestnetAddresses`; the separate mainnet namespace uses `uglyLab…`. Firestore client access defaults to deny. Public endpoints do not expose another player's registration or wallet list. No general tester export/deletion administration UI is shipped. Unlink scrubs active identity data; inactive hashed claim bookkeeping may remain. Expiry is enforced in service logic independently of background TTL cleanup.

This page shares the game origin; it is not an independently isolated financial-signing origin. Do not treat identity proof or a testnet dispenser as reviewed infrastructure for custody, valuable rewards or mainnet trading.

## Verification evidence

Recorded service tests cover real generated signatures with mocked identities/storage/RPC, chain/account isolation, replay, expiry, address-claim races, consent and unlink. Claim tests cover exact amount, replay, gas/network/runtime guards, wallet rejection, pending receipts and supply/cooldown behavior. Gate tests cover scene/social admission and revocation. Browser tests cover the actual Lab/Studio/3D UI with controlled account and wallet doubles. A dedicated deployer testnet claim was recorded in the entry-claims document.

These tests do not constitute an independent contract audit, fresh human OAuth or wallet-extension acceptance, or a physical-device concurrency test. No real-money operation is claimed.
