From e0b0be04d14374be005818d1b546a83f087e4ff0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 1 Aug 2026 00:42:44 +0000 Subject: [PATCH] =?UTF-8?q?chore(defrag):=20phase=201=20=E2=80=94=20format?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical fixes: trailing newlines, smart quotes, trailing whitespace, code block language tags. Found 37 doc files === Summary === Files changed: 3 Files unchanged: 34 === Changed files === - arcade/starter-packs.md - services/overview.md - services/vrng/how-it-works.md --- src/pages/arcade/starter-packs.md | 26 ++++++------- src/pages/services/overview.md | 6 +-- src/pages/services/vrng/how-it-works.md | 50 ++++++++++++------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/pages/arcade/starter-packs.md b/src/pages/arcade/starter-packs.md index 0bd86ce..5c007ff 100644 --- a/src/pages/arcade/starter-packs.md +++ b/src/pages/arcade/starter-packs.md @@ -7,15 +7,15 @@ description: Create and register starter packs on the Arcade registry to distrib # Starter Packs Starter packs let you bundle game assets and distribute them to players through a purchase flow integrated with [Cartridge Controller](/controller/starter-packs). -The Arcade starter pack registry is a permissionless onchain system — anyone can register a starter pack by deploying an implementation contract and calling `register`. +The Arcade starter pack registry is a permissionless onchain system --- anyone can register a starter pack by deploying an implementation contract and calling `register`. ## How It Works The registry follows a two-contract pattern: -1. **Implementation contract** — a contract you deploy that implements the `IStarterpackImplementation` interface. +1. **Implementation contract** --- a contract you deploy that implements the `IStarterpackImplementation` interface. When a player purchases your starter pack, the registry calls your contract's `on_issue` function to distribute assets. -2. **Registry contract** — the Arcade registry where you register your implementation, set pricing, and configure options. +2. **Registry contract** --- the Arcade registry where you register your implementation, set pricing, and configure options. ``` Player purchases → Registry collects payment → Registry calls on_issue → Your contract distributes assets @@ -100,8 +100,8 @@ The returned ID is what players use to purchase the starter pack via [`controlle Controls whether the same player can purchase the starter pack more than once. -- `false` — each player can only purchase once, and `quantity` is forced to 1 -- `true` — players can purchase multiple times with any quantity +- `false` --- each player can only purchase once, and `quantity` is forced to 1 +- `true` --- players can purchase multiple times with any quantity ### `referral_percentage` @@ -113,7 +113,7 @@ Self-referrals (referrer == payer) are ignored. Where the base price (minus any referral fee) is sent. If `None`, payment goes to the starter pack owner (the address that called `register`). -If `Some(address)`, payment goes to that address instead — useful for treasury contracts or revenue sharing. +If `Some(address)`, payment goes to that address instead --- useful for treasury contracts or revenue sharing. ### `conditional` @@ -146,17 +146,17 @@ let metadata = MetadataTrait::new( After registration, the owner can manage the starter pack: -- **`update`** — change implementation, pricing, referral percentage, or other parameters -- **`update_metadata`** — update the display metadata -- **`pause`** / **`resume`** — temporarily disable or re-enable purchases +- **`update`** --- change implementation, pricing, referral percentage, or other parameters +- **`update_metadata`** --- update the display metadata +- **`pause`** / **`resume`** --- temporarily disable or re-enable purchases ## Payment Flow When a player purchases a starter pack, the registry handles payment distribution: -1. **Referral fee** — if a referrer is provided, their percentage is deducted from the base price and sent to them -2. **Protocol fee** — a fee is added on top of the base price and sent to the Arcade fee receiver -3. **Owner payment** — the remaining base price (after referral fee) is sent to the `payment_receiver` or owner -4. **Asset distribution** — the registry calls `on_issue` on the implementation contract +1. **Referral fee** --- if a referrer is provided, their percentage is deducted from the base price and sent to them +2. **Protocol fee** --- a fee is added on top of the base price and sent to the Arcade fee receiver +3. **Owner payment** --- the remaining base price (after referral fee) is sent to the `payment_receiver` or owner +4. **Asset distribution** --- the registry calls `on_issue` on the implementation contract If `price` is zero, all payment steps are skipped and `on_issue` is called directly. diff --git a/src/pages/services/overview.md b/src/pages/services/overview.md index c863ea0..2eb8086 100644 --- a/src/pages/services/overview.md +++ b/src/pages/services/overview.md @@ -8,8 +8,8 @@ title: Services Overview Cartridge offers a set of platform services for onchain games and applications: -- **[Paymaster](/services/paymaster)** — sponsor transaction fees so your users don't need to hold STRK for gas. -- **[RPC](/services/rpc)** — Starknet RPC endpoints for mainnet and Sepolia, with API token and CORS-based authentication. -- **[vRNG](/services/vrng)** — atomic, verifiable randomness for fully onchain games via EC-VRF on the Stark curve. +- **[Paymaster](/services/paymaster)** --- sponsor transaction fees so your users don't need to hold STRK for gas. +- **[RPC](/services/rpc)** --- Starknet RPC endpoints for mainnet and Sepolia, with API token and CORS-based authentication. +- **[vRNG](/services/vrng)** --- atomic, verifiable randomness for fully onchain games via EC-VRF on the Stark curve. Each service is self-served via the CLI and can be used independently or together. diff --git a/src/pages/services/vrng/how-it-works.md b/src/pages/services/vrng/how-it-works.md index e18a3d6..d30d7f5 100644 --- a/src/pages/services/vrng/how-it-works.md +++ b/src/pages/services/vrng/how-it-works.md @@ -8,7 +8,7 @@ title: How vRNG Works ## The Onchain Randomness Problem -Blockchains are deterministic by design — every node must compute the same result for every transaction. +Blockchains are deterministic by design --- every node must compute the same result for every transaction. This makes genuine randomness impossible to produce from within a smart contract alone. Common workarounds and their weaknesses: @@ -18,7 +18,7 @@ Common workarounds and their weaknesses: | Block hash / timestamp | Miners/sequencers can influence or predict these values | | Commit-reveal schemes | Require multiple transactions across multiple blocks, adding latency and cost | | Hash of onchain state | Anyone can compute the same hash and predict the outcome before submitting | -| External oracles (e.g. Chainlink VRF) | Randomness arrives in a *separate* transaction, breaking atomicity — your game action resolves in one tx, but the random outcome arrives later | +| External oracles (e.g. Chainlink VRF) | Randomness arrives in a *separate* transaction, breaking atomicity --- your game action resolves in one tx, but the random outcome arrives later | For onchain games, these tradeoffs are unacceptable. A dice roll that takes two transactions and 30 seconds breaks the gameplay loop. @@ -26,18 +26,18 @@ A sequencer that can predict outcomes breaks the game's integrity. ## The Core Idea -The [Cartridge Paymaster](/services/paymaster) already acts as an offchain executor — it wraps player transactions for gas sponsorship and submits them onchain via Starknet's [SNIP-9](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-9.md) `execute_from_outside` protocol. +The [Cartridge Paymaster](/services/paymaster) already acts as an offchain executor --- it wraps player transactions for gas sponsorship and submits them onchain via Starknet's [SNIP-9](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-9.md) `execute_from_outside` protocol. The vRNG extends this existing role. In addition to sponsoring gas, the paymaster holds a **secret key** and uses it to generate a verifiable random number as part of the same execution flow. -The random value and its cryptographic proof are injected into the transaction *before* the player's game action executes, so the game contract can consume verified randomness atomically — no extra transactions, no waiting. +The random value and its cryptographic proof are injected into the transaction *before* the player's game action executes, so the game contract can consume verified randomness atomically --- no extra transactions, no waiting. This works because the paymaster is already in the transaction path. The vRNG is not a separate oracle service; it's a natural extension of the execution infrastructure that's already there. ## Why Not Just Hash? -A hash function like `hash(seed)` is deterministic and publicly computable — anyone with the seed can compute the output. +A hash function like `hash(seed)` is deterministic and publicly computable --- anyone with the seed can compute the output. Since seeds are derived from onchain state, a player could predict the outcome before submitting their transaction. A **Verifiable Random Function (VRF)** adds a secret key to the computation: `VRF(secret_key, seed) → (output, proof)`. @@ -46,24 +46,24 @@ Only the key holder can compute the output, but anyone can *verify* it was compu | | Hash | VRF | | --- | --- | --- | | **Who can compute** | Anyone with the input | Only the secret key holder | -| **Predictable?** | Yes — inputs are public | No — requires the secret key | -| **Verifiable?** | Trivially (recompute it) | Yes — via cryptographic proof | -| **Manipulable?** | No (but predictable = exploitable) | No — deterministic for a given seed and key | +| **Predictable?** | Yes --- inputs are public | No --- requires the secret key | +| **Verifiable?** | Trivially (recompute it) | Yes --- via cryptographic proof | +| **Manipulable?** | No (but predictable = exploitable) | No --- deterministic for a given seed and key | -The "verifiable" part is what distinguishes a VRF from simple encryption — the proof ensures the key holder can't lie about what the output should be for a given input. +The "verifiable" part is what distinguishes a VRF from simple encryption --- the proof ensures the key holder can't lie about what the output should be for a given input. ## Cryptographic Details -Cartridge's vRNG uses an **Elliptic Curve VRF (EC-VRF)** built on the Stark curve — the native curve of Starknet, which enables efficient onchain verification via Poseidon hashing. +Cartridge's vRNG uses an **Elliptic Curve VRF (EC-VRF)** built on the Stark curve --- the native curve of Starknet, which enables efficient onchain verification via Poseidon hashing. ### Proof Structure The VRF provider generates a proof consisting of: -- **gamma** — a point on the Stark curve (the core VRF output) -- **c** — a scalar challenge value -- **s** — a scalar response value -- **sqrt_ratio_hint** — an optimization hint for efficient onchain verification +- **gamma** --- a point on the Stark curve (the core VRF output) +- **c** --- a scalar challenge value +- **s** --- a scalar response value +- **sqrt_ratio_hint** --- an optimization hint for efficient onchain verification The random value is derived from `gamma` via hashing. The `(c, s)` pair constitutes a Schnorr-like proof that `gamma` was correctly computed from the seed and the provider's secret key. @@ -118,27 +118,27 @@ The paymaster intercepts it, generates the VRF proof, and wraps everything into ### Step by Step -1. **Player signs their game action** — the player's wallet signs a multicall containing `request_random` + the game call (e.g. `roll_dice`). +1. **Player signs their game action** --- the player's wallet signs a multicall containing `request_random` + the game call (e.g. `roll_dice`). This is the inner SNIP-9 outside execution. -2. **Paymaster intercepts** — the paymaster sees the `request_random` call, computes the seed from the source parameters, and generates the VRF proof using its secret key. +2. **Paymaster intercepts** --- the paymaster sees the `request_random` call, computes the seed from the source parameters, and generates the VRF proof using its secret key. -3. **Paymaster wraps with proof injection** — the paymaster constructs an outer SNIP-9 execution signed by the VRF Account that prepends `submit_random(seed, proof)` before executing the player's calls. +3. **Paymaster wraps with proof injection** --- the paymaster constructs an outer SNIP-9 execution signed by the VRF Account that prepends `submit_random(seed, proof)` before executing the player's calls. -4. **Onchain verification** — `submit_random` verifies the EC-VRF proof against the VRF Account's stored public key. +4. **Onchain verification** --- `submit_random` verifies the EC-VRF proof against the VRF Account's stored public key. If valid, the derived random value is stored for this transaction. -5. **Game consumes randomness** — when the game contract calls `consume_random(source)`, it reads the verified value from the VRF provider's storage. +5. **Game consumes randomness** --- when the game contract calls `consume_random(source)`, it reads the verified value from the VRF provider's storage. -6. **Cleanup** — `assert_consumed` ensures the random value was actually used and clears storage, preventing stale values from persisting. +6. **Cleanup** --- `assert_consumed` ensures the random value was actually used and clears storage, preventing stale values from persisting. ### Why Nested Execution? The nesting serves two purposes: -- **Proof injection without player awareness** — the player only signs their game action. +- **Proof injection without player awareness** --- the player only signs their game action. The VRF proof is added by the paymaster in the outer layer, invisible to the player. -- **Atomic execution** — proof verification and consumption happen in the same transaction. +- **Atomic execution** --- proof verification and consumption happen in the same transaction. There is no window where the random value exists but hasn't been used, and no second transaction to wait for. ## Security Model @@ -148,9 +148,9 @@ There is no window where the random value exists but hasn't been used, and no se The security assumption is that the **paymaster has not revealed its VRF secret key** and does not collude with players. Given this assumption: -- The provider cannot choose a favorable random value — the VRF is deterministic for a given seed, and the seed is derived from onchain state the provider doesn't control. -- Players cannot predict the random value — they don't have the provider's secret key. -- Anyone can verify after the fact — the proof and public key are onchain. +- The provider cannot choose a favorable random value --- the VRF is deterministic for a given seed, and the seed is derived from onchain state the provider doesn't control. +- Players cannot predict the random value --- they don't have the provider's secret key. +- Anyone can verify after the fact --- the proof and public key are onchain. The main trust assumption is that the provider isn't selectively *withholding* unfavorable results (censorship).