# Tap Race LCMA Sample

Tap Race is the reference free mini game for the controlled Mini App Center
beta. It is intentionally small: one `manifest.json`, one JavaScript entry, one
CSS file, and one SVG asset. It uses only the current `localchat-miniapp-v1`
bridge surface that is implemented in LocalChat.

For the full allowlisted developer beta contract, see
`../../../../../docs/mini-app-center-allowlisted-developer-guide.md`.

## Package

From `apps/gobaby_transfer`:

```sh
dart --disable-dart-dev tool/lcma_packager.dart \
  --source samples/mini_apps/tap_race \
  --output build/mini-app-center/tap-race-0.1.0.lcma \
  --metadata build/mini-app-center/tap-race-0.1.0.submission.json \
  --artifact-url https://localchat.me/v1/mini-app-center/artifacts/<staged-package-storage-key> \
  --key-id localchat-miniapp-beta-<developer> \
  --private-key-seed-base64url <developer-signing-seed>
```

For local unsigned smoke checks, omit `--private-key-seed-base64url` and use the
generated package only in local tests. External beta submissions must be signed
with a registered LCMA beta trust key.

## Manifest Contract

The beta manifest fields used by this sample are:

- `id`: reverse-DNS lowercase package id.
- `name`: display name shown in review/catalog surfaces.
- `version`: semantic version.
- `runtime`: `localchat-miniapp-v1`.
- `type`: `game`.
- `entry`: JavaScript entry file path inside the package.
- `developerId`: allowlisted developer project id.
- `developerName`: developer display name.
- `minLocalChatVersion`: minimum compatible LocalChat version.
- `targetPlatforms`: Android plus at least one Desktop platform.
- `permissions`: current bridge permissions used by the package.
- `network.internet`: must be `false` for the free beta.
- `payment.enabled`: must be `false` for the free beta.
- `ageRating`: `everyone` for this sample.

Native payloads, symlinks, payment, arbitrary internet access, and dynamic
native code are not allowed in beta packages.

## Bridge Surface

Currently implemented in the runtime:

- `localchat.ui.showToast(input)`
- `localchat.ui.setKeepScreenOn(enabled)`
- `localchat.storage.local.get(key)`
- `localchat.storage.local.set(key, value)`
- `localchat.storage.local.remove(key)`
- `localchat.room.create(params)`
- `localchat.room.join(params)`
- `localchat.room.message(params)`
- `localchat.room.poll(params)` through the `room.message` permission
- `localchat.nearby.discoverPeers(params)`
- `localchat.diagnostics.reportError(input)`

Future APIs must not be used by beta packages until the runtime controller and
permission validator implement them.

## Submission Flow

1. Generate or receive a beta signing seed through the approved secret channel.
2. Register the public trust key in the management API trust set.
3. Package Tap Race or your own mini game with `tool/lcma_packager.dart`.
4. Upload the `.lcma` from the developer console.
5. Review the manifest-derived metadata, release notes, reason, artifact hash,
   and supported platforms before submitting.
6. Operators approve test, collect Android/Desktop staged evidence, approve
   release, and verify catalog/artifact public ingress.
7. Operators can suspend the package; clients must disable the installed app on
   catalog sync.

## Smoke Tests

These tests package and validate this committed sample:

```sh
flutter test test/lcma_packager_test.dart test/lcma_packager_tool_test.dart
```
