Skip to content

Commit ef051b8

Browse files
starknetdevclaude
andcommitted
feat(token_lite): add single-game gas-optimized token component (denshokan lite)
Adds a CoreTokenLiteComponent for single-game deployments (e.g. super-death-mountain) that never used the multi-game registry, objectives, context, skills, per-token renderers, or enumerable, and that keep game-over/objective authority in the game contract: - No mutable token state: no update_game, no metagame callbacks, no game_over latch. is_playable/assert_is_playable check the lifecycle window only — zero storage reads (pure unpack of the packed token id). - New assert_owner_and_playable merges the per-action owner_of + assert_is_playable pair into one external call. - Mint does no SRC5 probe, no registry lookup, no settings/objective validation; keeps the exact IMinigameToken::mint ABI and rejects unsupported params loudly. 251-bit pack_token_id layout is unchanged. - Registers IMINIGAME_TOKEN_LITE_ID plus the legacy IMINIGAME_TOKEN_ID and exposes a zero game_registry_address() so MinigameComponent::initializer accepts a lite token unchanged. Includes IMinigameTokenLite in the interfaces package, a wiring example contract, 30 tests, CI matrix + codecov updates (18 modules), and doc refreshes (root AGENTS.md matrix table was stale). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 17558e9 commit ef051b8

16 files changed

Lines changed: 1295 additions & 5 deletions

File tree

.github/workflows/main-ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ jobs:
178178
module: registry
179179
runner: ubuntu-latest-8
180180
fuzzer_runs: 32
181+
- package: game_components_embeddable_game_standard
182+
module: token_lite
183+
runner: ubuntu-latest-8
184+
fuzzer_runs: 32
181185
# Metagame
182186
- package: game_components_metagame
183187
module: leaderboard

.github/workflows/pr-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ jobs:
235235
add game_components_embeddable_game_standard minigame ubuntu-latest-8 32
236236
add game_components_embeddable_game_standard metagame ubuntu-latest-8 32
237237
add game_components_embeddable_game_standard registry ubuntu-latest-8 32
238+
add game_components_embeddable_game_standard token_lite ubuntu-latest-8 32
238239
fi
239240
if [ "$NEED_METAGAME" = "true" ]; then
240241
add game_components_metagame leaderboard ubuntu-latest-4 256

AGENTS.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,22 @@ When adding a new module to a group package, update **both** files:
131131
after_n_builds: 15 # ← Must equal total module count in matrix
132132
```
133133

134-
### Current Matrix (16 modules)
134+
### Current Matrix (18 modules)
135135

136136
| Group Package | Module | Runner | Fuzzer Runs |
137137
|---------------|--------|--------|-------------|
138138
| `embeddable_game_standard` | `token` | `ubuntu-latest-32` | 32 |
139-
| `embeddable_game_standard` | `minigame` | `ubuntu-latest-32` | 32 |
140-
| `embeddable_game_standard` | `metagame` | `ubuntu-latest-32` | 256 |
141-
| `embeddable_game_standard` | `registry` | `ubuntu-latest-32` | 256 |
139+
| `embeddable_game_standard` | `minigame` | `ubuntu-latest-8` | 32 |
140+
| `embeddable_game_standard` | `metagame` | `ubuntu-latest-8` | 32 |
141+
| `embeddable_game_standard` | `registry` | `ubuntu-latest-8` | 32 |
142+
| `embeddable_game_standard` | `token_lite` | `ubuntu-latest-8` | 32 |
142143
| `metagame` | `leaderboard` | `ubuntu-latest-4` | 256 |
143144
| `metagame` | `registration` | `ubuntu-latest-4` | 256 |
144145
| `metagame` | `entry_requirement` | `ubuntu-latest-4` | 256 |
145146
| `metagame` | `entry_fee` | `ubuntu-latest-4` | 256 |
146147
| `metagame` | `prize` | `ubuntu-latest-4` | 256 |
147148
| `metagame` | `ticket_booth` | `ubuntu-latest-4` | 256 |
149+
| `metagame` | `merkledrop` | `ubuntu-latest-4` | 256 |
148150
| `economy` | `tokenomics` | `ubuntu-latest-4` | 256 |
149151
| `utilities` | `math` | `ubuntu-latest-4` | 256 |
150152
| `utilities` | `distribution` | `ubuntu-latest-4` | 256 |

codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ codecov:
33
notify:
44
# Must equal package count in .github/workflows/main-ci.yml matrix
55
# See AGENTS.md "CI Configuration" section when adding packages
6-
after_n_builds: 17
6+
after_n_builds: 18
77

88
comment:
99
layout: "diff, files, header, footer"

packages/embeddable_game_standard/src/lib.cairo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pub mod metagame;
22
pub mod minigame;
33
pub mod registry;
44
pub mod token;
5+
pub mod token_lite;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod interface;
2+
3+
#[cfg(test)]
4+
mod tests;
5+
pub mod token_lite_component;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Token Lite Module — CoreTokenLiteComponent (ERC721)
2+
3+
Gas-optimized single-game variant of the `token` module ("denshokan lite").
4+
Built for deployments that embed exactly one game, never used the multi-game
5+
registry/objectives/context/skills/per-token renderer features, and keep
6+
game-over / objective-completion authority in the game contract itself.
7+
8+
## Design Rules
9+
10+
| Rule | Consequence |
11+
| --- | --- |
12+
| One game, configured at init | No registry, no `game_id` resolution, no SRC5 probes on mint |
13+
| No mutable token state | No `update_game`, no metagame callbacks; `is_playable` = lifecycle window only, zero storage reads |
14+
| Token id layout is canonical | Reuses `token::structs::pack_token_id` (251-bit) bit-for-bit; unused fields (`game_id`, `objective_id`, `has_context`, `paymaster`, `metadata`) are written as zero |
15+
| `mint` is ABI-compatible with `IMinigameToken::mint` | Existing call sites and the `minigame::mint` helper work unchanged; unsupported params are rejected loudly, never silently ignored |
16+
| Game contract is the authority | Games gate dead/finished runs themselves and call `refresh_metadata` (ERC-4906) after actions |
17+
18+
## Interface (IMinigameTokenLite)
19+
20+
**Interface ID:** `IMINIGAME_TOKEN_LITE_ID = 0x3ea3d599077fbe09ddbe82ff33c1abc87aef52d8609d8bf3508fdba8dd92056`
21+
22+
Defined in `packages/interfaces/src/token/lite.cairo`. The initializer also
23+
registers `IMINIGAME_TOKEN_ID` so `MinigameComponent::initializer` (which
24+
hard-asserts it and then queries `game_registry_address()`) accepts a lite
25+
token; `game_registry_address()` always returns zero.
26+
27+
| Method | Cost | Notes |
28+
| --- | --- | --- |
29+
| `mint(...)` | 1 minter-map read (warm), optional name write, ERC721 mint | Same 15-arg signature as the full token |
30+
| `assert_owner_and_playable(token_id, expected_owner)` | 1 storage read (owner) | Combined guard — replaces `owner_of` + `assert_is_playable` (two calls) with one |
31+
| `is_playable` / `assert_is_playable` | 0 storage reads | Lifecycle window only — no game_over latch |
32+
| `token_metadata`, `settings_id`, `minted_by`, `is_soulbound` | 0 storage reads | Pure unpack of the token id |
33+
| `player_name`, `minted_by_address` | 1 storage read | |
34+
| `refresh_metadata(_batch)` | event only | Same advisory/no-existence-check semantics as the full token |
35+
| `update_player_name` | owner-gated write | |
36+
37+
Not present (reverts with ENTRYPOINT_NOT_FOUND): `update_game`, all other
38+
`*_batch` views, `mint_batch_recipients`, objectives/settings/context/
39+
renderer/skills/enumerable surfaces.
40+
41+
## Composition
42+
43+
Requires: `ERC721Component`, `SRC5Component`, an `OptionalMinter` impl
44+
(`MinterComponent::MinterOptionalImpl` — minter ids gate reward claims in
45+
consumers), and an `ERC721HooksTrait` (enforce soulbound in `before_update`
46+
via `unpack_soulbound` — pure, no storage).
47+
48+
See `tests/examples/token_lite_contract.cairo` for a full wiring example.
49+
50+
## Testing
51+
52+
```bash
53+
snforge test -p game_components_embeddable_game_standard "::token_lite::"
54+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Re-export from interfaces package (single source of truth)
2+
pub use game_components_interfaces::token::lite::{
3+
IMINIGAME_TOKEN_LITE_ID, IMinigameTokenLite, IMinigameTokenLiteDispatcher,
4+
IMinigameTokenLiteDispatcherTrait,
5+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Token lite package tests
2+
3+
mod examples;
4+
mod test_token_lite;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod token_lite_contract;

0 commit comments

Comments
 (0)