Skip to content

example: cross-chain-arcade — L1→L2 fan-out to multiple contracts (validates #623) - #624

Merged
kariy merged 1 commit into
mainfrom
example/cross-chain-arcade-l1-fanout
Jul 2, 2026
Merged

example: cross-chain-arcade — L1→L2 fan-out to multiple contracts (validates #623)#624
kariy merged 1 commit into
mainfrom
example/cross-chain-arcade-l1-fanout

Conversation

@kariy

@kariy kariy commented Jul 2, 2026

Copy link
Copy Markdown
Member

What this adds

A new example, examples/cross-chain-arcade/ — a small "arcade" game whose whole
point is that one L1 contract sends L1→L2 messages to many different L2
contracts
.

An arcade dispenser on the settlement layer ("L1") calls play_all, which in
a single L1 transaction sends an L1→L2 message to four distinct machine
contracts
on the appchain ("L2") — SLOTS, PINBALL, CLAW, RACER, each a
separately deployed contract with its own insert_coin #[l1_handler]. The
frontend shows every machine light up; scripts/verify.ts asserts every machine
received its coin.

What it demonstrates

This is a targeted regression demo for the L1-handler nonce fix in #623.

The settlement chain's core contract assigns a single, global, monotonic nonce
to every L1→L2 message, regardless of target. Before #623 the pool gated that as a
per-target account nonce, so the moment a sender messaged a second contract
(global nonce > 0, but that contract's account nonce still 0), the message —
and every later one — was rejected InvalidNonce and never mined. play_all
reproduces exactly this: four messages to four distinct targets with
non-contiguous per-target nonces. With the fix, all four relay; without it, only
SLOTS would.

The existing cross-chain-game example only ever messages a single L2 target, so
it never exercised this path — hence a dedicated, minimal example.

Scope / design

  • Plain Cairo + starknet.js, L1→L2 only (the direction fix(pool): don't gate L1-handler txs on account nonce #623 touches). No
    Dojo, sozo, Torii, TEE registry, or embedded settlement.
  • Uses katana init rollup (validity mode + dummy fact registry) to deploy a real
    piltover core, then boots the appchain from the generated config with
    --messaging.enabled. up.sh/down.sh bring the whole stack up/down.
  • Verified end-to-end against katana at current main: one play_all → all four
    machines credited; the verify.ts gate passes.

Related

🤖 Generated with Claude Code

A minimal example where one L1 contract (an arcade coin dispenser) sends an
L1->L2 message to many distinct L2 contracts (arcade machines) in a single L1
transaction. This exercises the multi-target scenario fixed by #623:
the settlement chain's global, monotonic L1->L2 message nonce used to be gated as
a per-target account nonce, so messages to any target after the first stalled
with InvalidNonce.

Plain Cairo + starknet.js, L1->L2 only (no Dojo/sozo/Torii/TEE/embedded
settlement). Includes arcade + machine contracts, deploy/verify scripts, a React
UI, and up.sh/down.sh. verify.ts is the assertion gate: one play_all must reach
every machine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kariy
kariy merged commit b43c722 into main Jul 2, 2026
1 check passed
@kariy
kariy deleted the example/cross-chain-arcade-l1-fanout branch July 2, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant