From e5206a6712832a5f676007fc4c887c651a29c0aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 1 Jun 2026 01:05:17 +0000 Subject: [PATCH 1/3] =?UTF-8?q?chore(defrag):=20phase=201=20=E2=80=94=20fo?= =?UTF-8?q?rmatting?= 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). From aa9cc54382e732b23212b6ef29dd5e3f85d07832 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 1 Jun 2026 01:28:30 +0000 Subject: [PATCH 2/3] =?UTF-8?q?chore(defrag):=20phase=202=20=E2=80=94=20co?= =?UTF-8?q?ntent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Terminology normalization, deduplication, cross-reference suggestions. Changes capped at 10 net removed lines per file. - controller/headless-authentication.md - controller/inventory.md - controller/native/android.md - controller/native/capacitor.md - controller/native/headless.md - controller/native/ios.md - controller/native/overview.md - controller/native/react-native.md - controller/native/session-flow.md - controller/presets.md - controller/sessions.md - controller/signer-management.md - controller/starter-packs.md - controller/toast-notifications.md - controller/usernames.md - services/vrng/how-it-works.md - services/vrng/index.md === Skipped files (large removals — needs manual review) === - controller/configuration.md (124 net lines removed) --- src/pages/arcade/marketplace.md | 16 +++--------- src/pages/arcade/overview.md | 6 ++--- src/pages/arcade/setup.md | 2 +- src/pages/controller/achievements.md | 2 +- src/pages/controller/architecture.md | 3 ++- src/pages/controller/booster-packs.md | 4 +-- src/pages/controller/coinbase-onramp.md | 10 +++++--- src/pages/controller/examples/cli.md | 9 ++++--- src/pages/controller/examples/node.md | 4 +-- src/pages/controller/examples/react.md | 12 +++++---- src/pages/controller/examples/rust.md | 4 +-- src/pages/controller/examples/svelte.md | 8 +++--- src/pages/controller/getting-started.mdx | 6 ++--- .../controller/headless-authentication.md | 20 +++++++-------- src/pages/controller/inventory.md | 2 +- src/pages/controller/native/android.md | 9 ++++++- src/pages/controller/native/capacitor.md | 8 +++++- src/pages/controller/native/headless.md | 2 +- src/pages/controller/native/ios.md | 12 +++++++-- src/pages/controller/native/overview.md | 20 +++++++-------- src/pages/controller/native/react-native.md | 8 +++--- src/pages/controller/native/session-flow.md | 2 +- src/pages/controller/presets.md | 10 ++++---- src/pages/controller/sessions.md | 2 +- src/pages/controller/signer-management.md | 22 ++++++++-------- src/pages/controller/starter-packs.md | 25 +++++++++++-------- src/pages/controller/toast-notifications.md | 2 +- src/pages/controller/usernames.md | 2 +- src/pages/services/vrng/how-it-works.md | 12 ++++----- src/pages/services/vrng/index.md | 12 ++++----- 30 files changed, 138 insertions(+), 118 deletions(-) diff --git a/src/pages/arcade/marketplace.md b/src/pages/arcade/marketplace.md index 7211c9d..d7c399b 100644 --- a/src/pages/arcade/marketplace.md +++ b/src/pages/arcade/marketplace.md @@ -18,22 +18,12 @@ First, configure your game's Torii instances to index the asset, and then config #### Configure your Torii Every digital asset on the Marketplace must be indexed by Torii. -The [Arcade Setup](./setup#torii-configuration) page provides detailed information about configuring Torii for various use cases including marketplace assets. +The [Arcade Setup](./setup) page provides detailed information about configuring Torii for asset indexing. -For basic marketplace asset indexing, add the token address to the configuration file: - -```toml -# torii.toml - -[indexing] -contracts = [ - "erc20:", - "erc721:" -] -``` +For marketplace-specific configuration, ensure your Torii instance includes the token addresses for any assets you want to display. :::info -See the [Torii docs](https://book.dojoengine.org/toolchain/torii/configuration#indexing-configuration) for more information about indexing token contracts. +See the [Arcade Setup](./setup#torii-configuration) page for complete Torii configuration instructions including marketplace assets. ::: #### Add Torii to Controller diff --git a/src/pages/arcade/overview.md b/src/pages/arcade/overview.md index adb1752..1bc5b15 100644 --- a/src/pages/arcade/overview.md +++ b/src/pages/arcade/overview.md @@ -49,7 +49,7 @@ As the game owner, you control which editions are visible or hidden. As the edition owner, you can choose to publish or hide your edition from public view. :::info -No permission is required to register an edition in an existin game, meaning anyone can register a new edition to your game such as registering a Game onto Arcade, however you get the control on their visibility. +No permission is required to register an edition in an existing game, meaning anyone can register a new edition to your game such as registering a Game onto Arcade, however you get the control on their visibility. ::: ![Update Edition](/arcade-update-edition.png) @@ -57,10 +57,10 @@ No permission is required to register an edition in an existin game, meaning any ### 🚀 Publish and whitelist an Edition As the edition owner you have the ability to publish your edition once created. -Once published, the game owner has the ability to whitelist you Edition to make it public. +Once published, the game owner has the ability to whitelist your edition to make it public. :::info -Any update within the Edition will turn off both the publish and the whitelist, the process should be repeat to make it public again +Any update within the edition will turn off both the publish and the whitelist, the process should be repeat to make it public again ::: ![Publish Edition](/arcade-publish-edition.png) diff --git a/src/pages/arcade/setup.md b/src/pages/arcade/setup.md index 906abab..ba31e28 100644 --- a/src/pages/arcade/setup.md +++ b/src/pages/arcade/setup.md @@ -8,7 +8,7 @@ description: Learn how to register, configure, and index your game with Arcade, ## Torii Configuration -To provide a rich user experience in Arcade, we recommend enhancing your Torii configuration to enable live activity feeds, asset indexing, and leaderboards. This configuration also supports marketplace functionality for asset display. +To provide a rich user experience in Arcade, we recommend enhancing your Torii configuration to enable live activity feeds, asset indexing, and leaderboards. This configuration also supports [marketplace functionality](/arcade/marketplace) for asset display. ### ⚡️ Activity Feed diff --git a/src/pages/controller/achievements.md b/src/pages/controller/achievements.md index 6a717ac..a26ebfe 100644 --- a/src/pages/controller/achievements.md +++ b/src/pages/controller/achievements.md @@ -243,7 +243,7 @@ AchievableComponent.progress( ### Controller Configuration -For policy configuration details, see [Sessions](./sessions). +For session policies configuration details, see [Sessions](./sessions). ```typescript new ControllerConnector({ diff --git a/src/pages/controller/architecture.md b/src/pages/controller/architecture.md index c820379..9e3ffc3 100644 --- a/src/pages/controller/architecture.md +++ b/src/pages/controller/architecture.md @@ -7,7 +7,7 @@ description: Technical overview of the Controller smart contract architecture, s # Architecture This page provides a technical overview of the Controller smart contract for developers who need to understand the on-chain mechanisms. -For user-facing documentation, see [Sessions](/controller/sessions) and [Signer Management](/controller/signer-management). +For user-facing documentation, see [Sessions](./sessions) and [Signer Management](./signer-management). ## Account Model @@ -55,6 +55,7 @@ When a signer is added, a `SignerLinked` event is emitted with the GUID and full ## Sessions (On-Chain) Sessions allow dapps to submit transactions on behalf of users without per-transaction approval. +For detailed session configuration examples, see [Sessions](./sessions). ### Session Structure diff --git a/src/pages/controller/booster-packs.md b/src/pages/controller/booster-packs.md index 24fdab9..6d86ac7 100644 --- a/src/pages/controller/booster-packs.md +++ b/src/pages/controller/booster-packs.md @@ -7,7 +7,7 @@ title: Booster Packs # Booster Packs Booster packs are a reward distribution system that allows eligible users to claim various game assets, credits, and exclusive game passes. -Unlike starter packs which are purchased, booster packs are claimed for free by users who meet specific eligibility criteria, often based on holding certain NFTs or participating in events. +Unlike [starter packs](./starter-packs) which are purchased, booster packs are claimed for free by users who meet specific eligibility criteria, often based on holding certain NFTs or participating in events. ## Overview @@ -169,7 +169,7 @@ Asset eligibility is typically determined by: ## Differences from Starter Packs -While both use Merkle Drop technology, booster packs differ from starter packs in key ways: +While both use Merkle Drop technology, booster packs differ from [starter packs](./starter-packs) in key ways: | Feature | Booster Packs | Starter Packs | |---------|---------------|---------------| diff --git a/src/pages/controller/coinbase-onramp.md b/src/pages/controller/coinbase-onramp.md index 65ba35a..f3f4ade 100644 --- a/src/pages/controller/coinbase-onramp.md +++ b/src/pages/controller/coinbase-onramp.md @@ -122,6 +122,8 @@ The integration includes comprehensive error handling for: - **Network Issues**: Retry logic and fallback options for connectivity problems - **Compliance Blocks**: Appropriate messaging when regulatory restrictions apply +For detailed error handling patterns, see [Configuration](./configuration) for comprehensive error management documentation. + ## Development Testing When testing Coinbase onramp integration: @@ -139,7 +141,7 @@ Coinbase onramp integration is automatically included in Controller v0.12.0+ and ## Next Steps -- Learn about [Starter Pack Integration](/controller/starter-packs) for complete purchase flows -- Review [Configuration Options](/controller/configuration) for customization -- Explore [Credit Purchases](/controller/starter-packs#credit-purchases) for account top-ups -- See [Cross-Chain Payments](/controller/starter-packs#cross-chain-bridging-with-layerswap) for alternative payment methods +- Learn about [Starter Pack Integration](./starter-packs) for complete purchase flows +- Review [Configuration Options](./configuration) for customization +- Explore [Credit Purchases](./starter-packs#credit-purchases) for account top-ups +- See [Cross-Chain Payments](./starter-packs#cross-chain-bridging-with-layerswap) for alternative payment methods diff --git a/src/pages/controller/examples/cli.md b/src/pages/controller/examples/cli.md index b982fdc..ddcb9c8 100644 --- a/src/pages/controller/examples/cli.md +++ b/src/pages/controller/examples/cli.md @@ -294,7 +294,7 @@ controller username ### `lookup` -Resolves Cartridge controller usernames to addresses or vice versa. +Resolves Cartridge Controller usernames to addresses or vice versa. ```bash # Look up addresses for usernames @@ -354,7 +354,7 @@ controller starterpack purchase --chain-id SN_MAIN controller starterpack purchase --ui --chain-id SN_MAIN ``` -**Direct mode:** Executes the purchase on-chain using the active session. Requires session policies that include `approve` on the payment token and `issue` on the starter pack contract. +**Direct mode:** Executes the purchase onchain using the active session. Requires session policies that include `approve` on the payment token and `issue` on the starter pack contract. ```bash controller starterpack purchase --direct --chain-id SN_MAIN @@ -491,6 +491,7 @@ Precedence: CLI flags > environment variables > config file. ## Error Handling +For detailed error handling guidance, see [Configuration](/controller/configuration). Common errors and how to fix them: | Error | Meaning | Fix | @@ -498,10 +499,10 @@ Common errors and how to fix them: | `NoSession` | No keypair found | Run `session auth` | | `SessionExpired` | Session has expired | Run `session auth` again | | `InvalidSessionData` | Corrupted session data | Run `session clear` and start over | -| `TransactionFailed` | Execution failed | Check policies and calldata | +| `TransactionFailed` | Execution failed | Check policies and `calldata` | | `CallbackTimeout` | Authorization timed out | Run `session auth` again | | `ManualExecutionRequired` | No authorized session for this transaction | Register session with appropriate policies | -| `InvalidInput` | Invalid input parameters | Check command syntax and calldata | +| `InvalidInput` | Invalid input parameters | Check command syntax and `calldata` | When using `--json`, errors return structured responses with machine-readable codes and recovery hints: diff --git a/src/pages/controller/examples/node.md b/src/pages/controller/examples/node.md index 0e56433..9bb98ad 100644 --- a/src/pages/controller/examples/node.md +++ b/src/pages/controller/examples/node.md @@ -83,7 +83,7 @@ async function main() { main().catch(console.error); ``` -### Using Manual Policies +### Using Manual Session Policies ```typescript import SessionProvider, { @@ -100,7 +100,7 @@ async function main() { process.env.CARTRIDGE_STORAGE_PATH || path.join(process.cwd(), ".cartridge"); - // Create a session provider with manual policies + // Create a session provider with manual session policies const provider = new SessionProvider({ rpc: "https://api.cartridge.gg/x/starknet/sepolia", chainId: constants.StarknetChainId.SN_SEPOLIA, diff --git a/src/pages/controller/examples/react.md b/src/pages/controller/examples/react.md index 68128b9..f64013f 100644 --- a/src/pages/controller/examples/react.md +++ b/src/pages/controller/examples/react.md @@ -42,7 +42,7 @@ First, set up the Starknet provider with the Cartridge Controller connector: You can customize the `ControllerConnector` by providing configuration options during instantiation. The `ControllerConnector` accepts an options object that -allows you to configure various settings such as policies, RPC URLs, theme, and +allows you to configure various settings such as session policies, RPC URLs, theme, and more. > ⚠️ **Important**: The `ControllerConnector` instance must be created outside of any React components. Creating it inside a component will cause the connector to be recreated on every render, which can lead to connection issues. @@ -118,6 +118,8 @@ export function StarknetProvider({ children }: { children: React.ReactNode }) { } ``` +For more detailed configuration options, see the [Controller configuration guide](./configuration). + ### 2. Create a Wallet Connection Component Use the `useConnect`, `useDisconnect`, and `useAccount` hooks to manage wallet @@ -260,7 +262,7 @@ export function MultiAuthConnectWallet() { ### 4. Headless Authentication -For programmatic authentication without opening any UI, you can use headless mode in your React components: +For programmatic authentication without opening any UI, you can use headless mode in your React components. For detailed information on headless authentication, see the [headless authentication guide](./headless-authentication). ```tsx import { useCallback, useState } from 'react' @@ -352,7 +354,7 @@ export function HeadlessLogin() { ``` :::warning -Headless mode requires that the user already has the specified signer (passkey, OAuth account, EVM wallet) associated with their Cartridge username. For new user registration, use the regular `connect()` flow which opens the UI. +Headless mode requires that the user already has the specified authentication method associated with their Cartridge username. For new user registration, use the regular `connect()` flow which opens the UI. ::: ### 5. Performing Transactions @@ -425,7 +427,7 @@ export const TransferEth = () => { } ``` -### 4. Username Lookup +### 6. Username Lookup The Controller provides a `lookupUsername` method that allows you to check if a username exists and see what authentication options are available for existing accounts. This is particularly useful for headless flows where you want to determine login vs signup flows: @@ -549,7 +551,7 @@ Available `AuthOption` values include: - `"rabby"` - Rabby wallet - `"phantom-evm"` - Phantom wallet (EVM) -### 5. Add Components to Your App +### 7. Add Components to Your App ```typescript import { StarknetProvider } from './context/StarknetProvider' diff --git a/src/pages/controller/examples/rust.md b/src/pages/controller/examples/rust.md index 7d4e33c..a5e8436 100644 --- a/src/pages/controller/examples/rust.md +++ b/src/pages/controller/examples/rust.md @@ -57,10 +57,10 @@ async fn main() { chain_id, ); - // Deploy the controller + // Deploy the Controller controller.deploy().await.unwrap(); - // Interact with the controller + // Interact with the Controller // For example, execute a transaction let call = your_function_call(); // Define your function call controller.execute(vec![call], None).await.unwrap(); diff --git a/src/pages/controller/examples/svelte.md b/src/pages/controller/examples/svelte.md index a093792..1d48cb2 100644 --- a/src/pages/controller/examples/svelte.md +++ b/src/pages/controller/examples/svelte.md @@ -10,19 +10,19 @@ description: Learn how to integrate the Cartridge Controller into your Svelte ap :::code-group -```bash \[npm] +```bash [npm] npm install @cartridge/controller starknet ``` -```bash \[pnpm] +```bash [pnpm] pnpm install @cartridge/controller starknet ``` -```bash \[yarn] +```bash [yarn] yarn add @cartridge/controller starknet ``` -```bash \[bun] +```bash [bun] bun add @cartridge/controller starknet ``` diff --git a/src/pages/controller/getting-started.mdx b/src/pages/controller/getting-started.mdx index 83434ae..0e5512b 100644 --- a/src/pages/controller/getting-started.mdx +++ b/src/pages/controller/getting-started.mdx @@ -37,14 +37,14 @@ const phantomAccount = await controller.connect(["phantom-evm"]); ### Headless Authentication -For programmatic authentication without opening any UI, you can use [headless mode](/controller/headless-authentication) by providing a `username` and `signer`: +For programmatic authentication without opening any UI, you can use [headless mode](/controller/headless-authentication): ```typescript import Controller from "@cartridge/controller"; const controller = new Controller({}); -// Headless authentication with WebAuthn/Passkey +// Headless authentication with passkey const account = await controller.connect({ username: "alice", signer: "webauthn", @@ -130,7 +130,7 @@ const controller = new Controller({ policies }); ### With custom configuration -The Controller ships with sensible defaults for chain RPCs, but you can override them if needed. +The Controller ships with sensible defaults for chain RPCs, but you can override them if needed. For more detailed configuration options, see [Configuration](/controller/configuration). ```typescript import { constants } from "starknet"; diff --git a/src/pages/controller/headless-authentication.md b/src/pages/controller/headless-authentication.md index da6417e..91b8d28 100644 --- a/src/pages/controller/headless-authentication.md +++ b/src/pages/controller/headless-authentication.md @@ -58,9 +58,9 @@ try { } ``` -### WebAuthn/Passkey Authentication +### Passkey Authentication -The most secure option for headless authentication uses WebAuthn (passkeys): +The most secure option for headless authentication uses passkeys: ```typescript import Controller from "@cartridge/controller"; @@ -81,7 +81,7 @@ try { ### Password Authentication -For scenarios where WebAuthn isn't available: +For scenarios where passkeys aren't available: ```typescript const account = await controller.connect({ @@ -160,14 +160,14 @@ await controller.connect({ ``` :::note -SMS authentication requires a phone number and uses one-time passcode (OTP) verification. The SMS signer is registered as EIP-191 with provider `"sms"`. +SMS authentication requires a phone number and uses one-time passcode (OTP) verification. The SMS `signer` is registered as EIP-191 with provider `"sms"`. ::: ## Supported Signer Options Headless mode supports all implemented authentication methods: -- `webauthn` - WebAuthn/Passkey (most secure) +- `webauthn` - Passkey (most secure) - `password` - Username/password authentication - `google` - Google OAuth - `discord` - Discord OAuth @@ -177,7 +177,7 @@ Headless mode supports all implemented authentication methods: - `walletconnect` - WalletConnect protocol - `sms` - SMS one-time passcode authentication -For complete details on available authentication methods, see [Signer Management](./signer-management). +For complete details on available authentication methods and UI integration patterns, see [Signer Management](./signer-management). ## Session Approval Flow @@ -207,7 +207,7 @@ await account.execute(/* your transaction */); ## Error Handling -Headless authentication provides specific error handling: +Headless authentication provides specific error handling. For comprehensive error handling patterns, see [Configuration](./configuration). ```typescript import { HeadlessAuthenticationError } from "@cartridge/controller"; @@ -292,7 +292,7 @@ try { ``` :::note -Auto-signup maintains strict signer matching for existing accounts. If an account exists but the specified `signer` is not associated with it, authentication will fail rather than creating a duplicate account. +Auto-signup maintains strict `signer` matching for existing accounts. If an account exists but the specified `signer` is not associated with it, authentication will fail rather than creating a duplicate account. ::: ## Integration Patterns @@ -411,7 +411,7 @@ Server-side headless authentication is currently only available through the brow ### Authentication Method Selection -- **WebAuthn (recommended)**: Most secure, hardware-backed when available +- **Passkey (recommended)**: Most secure, hardware-backed when available - **OAuth**: Good for user convenience, relies on third-party security - **Password**: Least secure, but widely compatible - **EVM Wallets**: Security depends on wallet implementation and user practices @@ -450,7 +450,7 @@ This web-based headless authentication is different from the [native headless Co - *Auto-signup*: Consider enabling auto-signup for new users 2. **"Signer not found"**: The specified `signer` isn't associated with the username - *Solution*: Use `lookupUsername()` to get available signers for the username - - *Fallback*: Implement signer selection UI based on available options + - *Fallback*: Implement `signer` selection UI based on available options 3. **"Not ready to connect"**: Controller initialization is still in progress 4. **Network timeouts**: Check network connectivity and RPC endpoint availability diff --git a/src/pages/controller/inventory.md b/src/pages/controller/inventory.md index 964974b..ce125d1 100644 --- a/src/pages/controller/inventory.md +++ b/src/pages/controller/inventory.md @@ -30,7 +30,7 @@ Self-host Torii against your indexing config. See the [Torii documentation](http ### Configure Controller -Provide your Torii instance URL to `ControllerOptions`. For detailed configuration options, see [configuration](./configuration). +Provide your Torii instance URL to `ControllerOptions`. For detailed Controller configuration options, see [configuration](./configuration). ```typescript const controller = new Controller({ diff --git a/src/pages/controller/native/android.md b/src/pages/controller/native/android.md index dcc4a72..c2180af 100644 --- a/src/pages/controller/native/android.md +++ b/src/pages/controller/native/android.md @@ -132,7 +132,8 @@ controller.disconnect() ## Creating a SessionAccount -Create a session account for executing transactions without repeated signatures: +Create a session account for executing transactions without repeated signatures. +For detailed session policy configuration, see [Sessions](../sessions). ```kotlin val sessionAccount = SessionAccount( @@ -284,3 +285,9 @@ companion object { } } ``` + +## Next Steps + +- For React Native integration: [React Native Guide](./react-native) +- For iOS integration: [iOS Guide](./ios) +- For Capacitor integration: [Capacitor Guide](./capacitor) diff --git a/src/pages/controller/native/capacitor.md b/src/pages/controller/native/capacitor.md index 3c410b5..6f33540 100644 --- a/src/pages/controller/native/capacitor.md +++ b/src/pages/controller/native/capacitor.md @@ -7,7 +7,7 @@ description: Wrap your web app for native iOS and Android distribution using Cap # Capacitor [Capacitor](https://capacitorjs.com/) allows you to wrap an existing web application for native iOS and Android distribution. -This approach uses Controller's SessionProvider for session-based authentication via deep links and custom URL schemes. +This approach uses Controller's `SessionProvider` for session-based authentication via deep links and custom URL schemes. ## When to Use Capacitor @@ -17,6 +17,8 @@ Capacitor is ideal when: - You need access to native features (push notifications, in-app purchases, haptics) - Your team is more comfortable with web technologies than native development +For guidance on choosing between different native approaches, see the [native integration overview](./overview). + ## Prerequisites - Node.js >= 18 @@ -116,6 +118,8 @@ const provider = new SessionProvider({ }); ``` +For detailed policy configuration, see the [sessions guide](../sessions). + ## Browser Interception In native Capacitor apps, you need to intercept window.open calls to ensure the system browser opens for authentication: @@ -319,3 +323,5 @@ The example includes complete setup for both iOS and Android platforms with prop - **Complete Reference**: See the [Capacitor session example](https://github.com/cartridge-gg/controller/tree/main/examples/capacitor) in the repository - **Production Example**: [Jokers of Neon](https://github.com/caravana-studio/jokers-of-neon-app) repository + +For guidance on choosing between Capacitor, React Native, or native implementations, see the [native integration overview](./overview). diff --git a/src/pages/controller/native/headless.md b/src/pages/controller/native/headless.md index eb7f1b9..ee30a11 100644 --- a/src/pages/controller/native/headless.md +++ b/src/pages/controller/native/headless.md @@ -7,7 +7,7 @@ description: Using user-supplied signing keys with Controller for server-side an # Native Headless Controller :::info -This guide covers **native headless mode** using C++ bindings for server-side applications. For **web-based headless authentication** in browser applications, see the [Headless Authentication](../headless-authentication) guide. +This guide covers **native headless mode** using C++ bindings for server-side applications. For **web-based headless authentication** in browser applications, see the [headless authentication](../headless-authentication) guide. ::: ## Setup diff --git a/src/pages/controller/native/ios.md b/src/pages/controller/native/ios.md index 6063058..f14e48b 100644 --- a/src/pages/controller/native/ios.md +++ b/src/pages/controller/native/ios.md @@ -60,7 +60,8 @@ struct Call { ### Session Policies -Define permissions for session accounts: +Define permissions for session accounts. +For detailed policy configuration, see the [Sessions guide](../sessions). ```swift struct SessionPolicy { @@ -110,7 +111,7 @@ SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes) let privateKey = "0x" + bytes.map { String(format: "%02x", $0) }.joined() let publicKey = try getPublicKey(privateKey: privateKey) -// Define policies +// Define session policies let policies = SessionPolicies( policies: [ SessionPolicy( @@ -205,3 +206,10 @@ let hasStorage = try controllerHasStorage(appId: "my_app") Complete working examples are available in the Controller.c repository: - [Swift examples](https://github.com/cartridge-gg/controller.c/tree/main/examples/swift) - [iOS app examples](https://github.com/cartridge-gg/controller.c/tree/main/examples/ios-app) + +## Related Guides + +- [Native Overview](./overview) - Choose the right integration approach +- [React Native](./react-native) - Alternative for cross-platform development +- [Android](./android) - Android-specific integration +- [Capacitor](./capacitor) - Hybrid app development diff --git a/src/pages/controller/native/overview.md b/src/pages/controller/native/overview.md index c919462..0f81282 100644 --- a/src/pages/controller/native/overview.md +++ b/src/pages/controller/native/overview.md @@ -6,7 +6,7 @@ description: Choose the right connection flow for integrating Cartridge Controll # Native Integration -Controller was initially developed as a web wallet for browser-based applications. +Cartridge Controller was initially developed as a web wallet for browser-based applications. As the ecosystem has grown, native integration is now supported across mobile and server-side platforms. The most important decision when integrating Controller natively is **which connection flow** to use. @@ -24,15 +24,15 @@ The session signer can then execute transactions without further user interactio 1. Generate a new keypair locally and store the private key securely 2. Open a browser to the Controller session URL, passing the public key and session policies -3. The user authenticates via WebAuthn in the browser +3. The user authenticates via passkey in the browser 4. The app receives the user's Controller address via callback 5. The app signs transactions using the local private key, validated against the registered session **Best for:** Mobile apps, games, any app where end users authenticate interactively. -**Platform guides:** [React Native](/controller/native/react-native) | [Android](/controller/native/android) | [iOS](/controller/native/ios) | [Capacitor](/controller/native/capacitor) +**Platform guides:** [React Native](./react-native) | [Android](./android) | [iOS](./ios) | [Capacitor](./capacitor) -**Reference:** [Session URL Reference](/controller/native/session-flow) for URL parameters, policy format, and callback metadata. +**Reference:** [Session URL Reference](./session-flow) for URL parameters, policy format, and callback metadata. ### Headless (App-Managed Keys) @@ -46,7 +46,7 @@ No browser authentication is involved --- the app directly controls a Controller - Bots, NPCs, or game systems that interact with the blockchain - Applications with specific key management or compliance requirements -**Implementation:** [Headless Controller](/controller/native/headless) (C++ UniFFI bindings) +**Implementation:** [Headless Controller](./headless) (C++ UniFFI bindings) ### Web Wrapper (Capacitor) @@ -58,16 +58,16 @@ The difference is in the integration approach: you're packaging a web app rather **Best for:** Existing web apps, faster time-to-market, teams stronger in web than native development. -**Platform guide:** [Capacitor](/controller/native/capacitor) +**Platform guide:** [Capacitor](./capacitor) ## Choosing a Flow | Use Case | Flow | Platform Guides | |----------|------|-----------------| -| Mobile game with player login | Browser-based sessions | [React Native](/controller/native/react-native), [Android](/controller/native/android), [iOS](/controller/native/ios) | -| Existing web app → app store | Web wrapper | [Capacitor](/controller/native/capacitor) | -| Game backend / server-side bots | Headless | [Headless Controller](/controller/native/headless) | -| Custom key management | Headless | [Headless Controller](/controller/native/headless) | +| Mobile game with player login | Browser-based sessions | [React Native](./react-native), [Android](./android), [iOS](./ios) | +| Existing web app → app store | Web wrapper | [Capacitor](./capacitor) | +| Game backend / server-side bots | Headless | [Headless Controller](./headless) | +| Custom key management | Headless | [Headless Controller](./headless) | ## Passkey Authentication on Native diff --git a/src/pages/controller/native/react-native.md b/src/pages/controller/native/react-native.md index c57d984..00d2e44 100644 --- a/src/pages/controller/native/react-native.md +++ b/src/pages/controller/native/react-native.md @@ -10,11 +10,11 @@ The Controller SDK can be integrated into React Native applications using TurboM This enables session-based authentication and transaction execution in cross-platform mobile apps. :::info -This guide uses the native Controller.c bindings to implement the [session flow](/controller/native/session-flow) directly. -This is the native equivalent of [SessionProvider](/controller/getting-started#sessionprovider-redirect-based) --- it generates a local session keypair, authenticates via browser, and executes transactions with the session key. -It is **not** the [headless controller](/controller/native/headless) pattern, which uses application-managed owner keys without any browser authentication. +This guide uses the native Controller.c bindings to implement the [session flow](./session-flow) directly. +This is the native equivalent of [SessionProvider](/controller/getting-started#sessionprovider-redirect-based) — it generates a local session keypair, authenticates via browser, and executes transactions with the session key. +It is **not** the [headless controller](./headless) pattern, which uses application-managed owner keys without any browser authentication. -If you are wrapping an existing web app for mobile distribution, consider [Capacitor](/controller/native/capacitor) instead, which uses the JS `SessionProvider` directly. +If you are wrapping an existing web app for mobile distribution, consider [Capacitor](./capacitor) instead, which uses the JS `SessionProvider` directly. ::: ## Prerequisites diff --git a/src/pages/controller/native/session-flow.md b/src/pages/controller/native/session-flow.md index 98cd270..4764685 100644 --- a/src/pages/controller/native/session-flow.md +++ b/src/pages/controller/native/session-flow.md @@ -47,7 +47,7 @@ Each policy object defines which contract methods the session key is authorized The `policies` parameter should be a JSON array of these objects. -For more details on session policies configuration, see [Sessions](/controller/sessions). +For detailed session policies configuration, see [Sessions](/controller/sessions). ## Session Metadata diff --git a/src/pages/controller/presets.md b/src/pages/controller/presets.md index 3a1adb6..ca35b95 100644 --- a/src/pages/controller/presets.md +++ b/src/pages/controller/presets.md @@ -72,12 +72,12 @@ For detailed information about session policies, see [Sessions](./sessions). :::warning **Policy Precedence Rules:** -1. When `shouldOverridePresetPolicies: true` and policies are provided → uses URL policies -2. When preset is configured and has policies for the current chain → uses preset policies (ignores URL policies) -3. When preset is configured but has no policies for the current chain → falls back to URL policies +1. When `shouldOverridePresetPolicies: true` and `policies` are provided → uses URL policies +2. When preset is configured and has `policies` for the current chain → uses preset policies (ignores URL policies) +3. When preset is configured but has no `policies` for the current chain → falls back to URL policies 4. When no preset is configured → uses URL policies -To force manually provided policies over preset policies, set `shouldOverridePresetPolicies: true`. +To force manually provided `policies` over preset policies, set `shouldOverridePresetPolicies: true`. ::: For an example, see [dope-wars](https://github.com/cartridge-gg/presets/blob/main/configs/dope-wars/config.json): @@ -168,7 +168,7 @@ This allows for sophisticated gas sponsorship policies based on game state, user ## Apple App Site Association -The [Apple App Site Association (AASA)](https://developer.apple.com/documentation/xcode/supporting-associated-domains) configuration enables iOS app integration with Cartridge Controller, allowing for usage of Web Credentials (Passkeys) in native applications. +The [Apple App Site Association (AASA)](https://developer.apple.com/documentation/xcode/supporting-associated-domains) configuration enables iOS app integration with Cartridge Controller, allowing for usage of Web Credentials (passkeys) in native applications. ### Configuration diff --git a/src/pages/controller/sessions.md b/src/pages/controller/sessions.md index 4e94f19..b41b706 100644 --- a/src/pages/controller/sessions.md +++ b/src/pages/controller/sessions.md @@ -29,7 +29,7 @@ When no policies are provided: :::warning Running without policies **does not work on local Katana**. The paymaster requires policies to deploy the controller before the first transaction. -See [Using Katana for Local Development](/controller/configuration#using-katana-for-local-development) for setup details. +See [Configuration](/controller/configuration#using-katana-for-local-development) for setup details. ::: ```typescript diff --git a/src/pages/controller/signer-management.md b/src/pages/controller/signer-management.md index 71c134e..58078cd 100644 --- a/src/pages/controller/signer-management.md +++ b/src/pages/controller/signer-management.md @@ -19,7 +19,7 @@ Multi-signer support provides several benefits: Controller supports five categories of signers: -### 1. Passkey (WebAuthn) +### 1. Passkey - **Biometric authentication** using Face ID, Touch ID, or hardware security keys - **Platform-native** security with device-based credential storage @@ -201,7 +201,7 @@ For information about programmatic authentication with external wallets, see [He The Signer(s) section displays all authentication methods associated with your account: - **Signer type** with recognizable icons (fingerprint for passkey, Discord logo, wallet icons) -- **Current status** indicating which signer you're currently using +- **Current status** indicating which `signer` you're currently using - **Identifying information** such as wallet addresses (partially masked for privacy) ### Signer Information Display @@ -216,7 +216,7 @@ Each signer card shows: When connecting to your Controller: - The connection interface will show all available authentication methods - Select any of your registered signers to authenticate -- Your account and assets remain the same regardless of which signer you use +- Your account and assets remain the same regardless of which `signer` you use ### Account Synchronization for Starknet Wallets @@ -318,26 +318,26 @@ interface ExternalWalletResponse { ### Best Practices -- **Multiple Backups**: Add at least 2-3 different signer types to ensure account recovery +- **Multiple Backups**: Add at least 2-3 different `signer` types to ensure account recovery - **Secure Storage**: For passkeys, ensure your device backup (iCloud, Google) is secure - **Regular Access**: Periodically test each authentication method to ensure they work ### Account Recovery If you lose access to your primary authentication method: -1. Use any other registered signer to access your account +1. Use any other registered `signer` to access your account 2. Consider adding additional backup authentication methods -3. Remove compromised signers using the remove signer functionality +3. Remove compromised signers using the remove `signer` functionality ### Removing Signers You can now remove signers from your account for security or convenience: 1. Navigate to the **Signer(s)** section in Controller Settings -2. Find the signer you want to remove -3. Click the **Remove** option for that signer +2. Find the `signer` you want to remove +3. Click the **Remove** option for that `signer` -> **Important**: Ensure you have at least one other working authentication method before removing a signer to avoid losing access to your account. +> **Important**: Ensure you have at least one other working authentication method before removing a `signer` to avoid losing access to your account. ### Deleting Your Account @@ -359,7 +359,7 @@ You can permanently delete your Controller account from the Settings panel: ### Getting Help If you encounter issues with signer management: -- Review the passkey section above for WebAuthn-specific help +- Review the passkey section above for passkey-specific help - Verify your wallet setup in the respective wallet's documentation - Ensure you're using a supported browser and have the latest wallet extensions installed @@ -564,6 +564,6 @@ const DISCONNECT_OAUTH = gql` ## Next Steps -- Learn about [Session Keys](./sessions) for gasless gaming transactions +- Learn about [Sessions](./sessions) for gasless gaming transactions - Explore [Controller Configuration](./configuration) options - Set up [Usernames](./usernames) for your account diff --git a/src/pages/controller/starter-packs.md b/src/pages/controller/starter-packs.md index a3c5535..583bb36 100644 --- a/src/pages/controller/starter-packs.md +++ b/src/pages/controller/starter-packs.md @@ -6,13 +6,14 @@ title: Starter Packs # Starter Packs -Starter packs are pre-configured bundles of game assets, NFTs, and in-game currency that provide a seamless onboarding and monetization experience for your players. Cartridge Controller makes it easy to offer both paid starter packs and free claimable packs with support for multiple payment methods across different blockchain networks. +Starter packs are pre-configured bundles of game assets, NFTs, and in-game currency that provide a seamless onboarding and monetization experience for your players. +Cartridge Controller makes it easy to offer both paid starter packs and free claimable packs with support for multiple payment methods across different blockchain networks. ## Overview Starter packs enable you to: -- **Create Custom Bundles**: Configure packs with fungible tokens, NFTs, and on-chain items with automatic contract execution +- **Create Custom Bundles**: Configure packs with fungible tokens, NFTs, and onchain items with automatic contract execution - **Offer Paid Packs**: Accept payments via cryptocurrency across Ethereum, Base, Arbitrum, and Optimism - **Enable Free Claims**: Distribute free packs using Merkle Drop technology with cross-chain eligibility verification - **Flexible Configuration**: Build packs programmatically or reference pre-configured packs by ID @@ -43,7 +44,8 @@ await controller.openBundle(0, "0x1c53584fdbebd996c163fa2d5d5ad37f4b2f06643ea2bb ### openBundle(bundleId: number, registryAddress: string, options?: BundleOptions) -Opens the bundle interface for a specific starter pack bundle with advanced features including conditional claiming. Bundles support social claim flows where users can claim packs by completing social actions (e.g., following and sharing on X/Twitter). +Opens the bundle interface for a specific starter pack bundle with advanced features including conditional claiming. +Bundles support social claim flows where users can claim packs by completing social actions (e.g., following and sharing on X/Twitter). ```typescript controller.openBundle(bundleId: number, registryAddress: string, options?: BundleOptions); @@ -97,7 +99,8 @@ const handleBundle = async () => { ### openStarterPack(starterpackId: string | number, options?: StarterpackOptions) -Opens the starter pack interface for a specific starter pack bundle. This method works for both paid starter packs (requiring purchase) and claimed starter packs (that can be claimed based on eligibility). +Opens the starter pack interface for a specific starter pack bundle. +This method works for both paid starter packs (requiring purchase) and claimed starter packs (that can be claimed based on eligibility). ```typescript controller.openStarterPack(starterpackId: string | number, options?: StarterpackOptions); @@ -290,7 +293,7 @@ The claiming process follows these steps: ## Gasless Transactions -Starter packs enable gasless gaming experiences through integration with [session policies](/controller/sessions). +Starter packs enable gasless gaming experiences through integration with [session policies](./sessions). When properly configured, users can receive and interact with their starter pack assets without paying gas fees for each transaction. ## Credit Purchases @@ -317,19 +320,19 @@ const handleBuyCredits = () => { }; ``` -Credits purchased through this interface use the same unified payment flow as starter packs, including support for multiple blockchains, automatic token bridging, and available fiat and crypto payment options. See [Coinbase Onramp](/controller/coinbase-onramp) for Apple Pay and regional fiat availability. +Credits purchased through this interface use the same unified payment flow as starter packs, including support for multiple blockchains, automatic token bridging, and available fiat and crypto payment options. See [Coinbase Onramp](./coinbase-onramp) for Apple Pay and regional fiat availability. ## Getting Help If you encounter issues with purchase integration: - Check the browser console for detailed error messages -- Verify your Controller setup matches the [getting started guide](/controller/getting-started) +- Verify your Controller setup matches the [getting started guide](./getting-started) - Ensure you're using the latest version of the Controller SDK -- Review [external wallet setup](/controller/signer-management) for wallet-related issues +- Review [external wallet setup](./signer-management) for wallet-related issues ## Next Steps -- Learn about [Sessions](/controller/sessions) for gasless gaming experiences -- Explore [Controller Configuration](/controller/configuration) options -- Set up [External Wallet Integration](/controller/signer-management) +- Learn about [Sessions](./sessions) for gasless gaming experiences +- Explore [Controller Configuration](./configuration) options +- Set up [External Wallet Integration](./signer-management) - Review [Paymaster Configuration](/services/paymaster) for gasless transactions diff --git a/src/pages/controller/toast-notifications.md b/src/pages/controller/toast-notifications.md index 0c8cada..e84228f 100644 --- a/src/pages/controller/toast-notifications.md +++ b/src/pages/controller/toast-notifications.md @@ -325,7 +325,7 @@ function runToastDemo() { ### Error Notification Integration -The toast API integrates with the Controller's error display system. See [Configuration](/controller/configuration) for details on `errorDisplayMode` settings. +The toast API integrates with the Controller's error display system. See [Configuration](/controller/configuration) for detailed error handling options and `errorDisplayMode` configuration. ```typescript import { Controller } from "@cartridge/controller"; diff --git a/src/pages/controller/usernames.md b/src/pages/controller/usernames.md index e1f431e..553dc5e 100644 --- a/src/pages/controller/usernames.md +++ b/src/pages/controller/usernames.md @@ -82,7 +82,7 @@ interface UsernameLookupResult { ``` **Use Cases:** -- **Headless authentication flows**: Check account existence before attempting to connect +- **Headless authentication flows**: Check account existence before attempting to connect. For comprehensive headless authentication patterns, see [headless authentication](./headless-authentication). - **Form validation**: Validate usernames in real-time - **Authentication method selection**: Show users only the authentication methods they have configured - **Auto-signup flows**: Determine whether to create a new account or authenticate existing one diff --git a/src/pages/services/vrng/how-it-works.md b/src/pages/services/vrng/how-it-works.md index d30d7f5..91ff2b7 100644 --- a/src/pages/services/vrng/how-it-works.md +++ b/src/pages/services/vrng/how-it-works.md @@ -40,7 +40,7 @@ The vRNG is not a separate oracle service; it's a natural extension of the execu 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)`. +A **Verifiable Random Function** adds a secret key to the computation: `VRF(secret_key, seed) → (output, proof)`. Only the key holder can compute the output, but anyone can *verify* it was computed correctly using the public key. | | Hash | VRF | @@ -58,7 +58,7 @@ Cartridge's vRNG uses an **Elliptic Curve VRF (EC-VRF)** built on the Stark curv ### Proof Structure -The VRF provider generates a proof consisting of: +The vRNG provider generates a proof consisting of: - **gamma** --- a point on the Stark curve (the core VRF output) - **c** --- a scalar challenge value @@ -101,7 +101,7 @@ The paymaster intercepts it, generates the VRF proof, and wraps everything into │ │ │ signed by player's passkey) │ │ │ │ │ │ │ │ │ │ │ │ 1. request_random(caller, source) │ │ │ -│ │ │ → signals VRF intent │ │ │ +│ │ │ → signals vRNG intent │ │ │ │ │ │ │ │ │ │ │ │ 2. game_action() on Game Contract │ │ │ │ │ │ → calls consume_random(source) │ │ │ @@ -128,7 +128,7 @@ This is the inner SNIP-9 outside execution. 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 vRNG provider's storage. 6. **Cleanup** --- `assert_consumed` ensures the random value was actually used and clears storage, preventing stale values from persisting. @@ -143,9 +143,9 @@ There is no window where the random value exists but hasn't been used, and no se ## Security Model -### Current (Phase 0) +### Current Deployment -The security assumption is that the **paymaster has not revealed its VRF secret key** and does not collude with players. +The security assumption is that the **paymaster has not revealed its vRNG 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. diff --git a/src/pages/services/vrng/index.md b/src/pages/services/vrng/index.md index 2bd6ba3..185f716 100644 --- a/src/pages/services/vrng/index.md +++ b/src/pages/services/vrng/index.md @@ -35,7 +35,7 @@ The vRNG was previously referred to as the Verifiable Random Function, and most - **Simplicity**: Easy integration with existing Starknet smart contracts and Dojo. - **Performance**: Synchronous randomness generation without waiting for multiple transactions. -- **Cost-effectiveness**: Potential cost savings through Paymaster integration. +- **Cost-effectiveness**: Potential cost savings through paymaster integration. - **Security**: Cryptographically secure randomness that's fully verifiable onchain. ### Deployments @@ -49,7 +49,7 @@ For detailed implementation and usage, refer to the [GitHub repository](https:// ## Using the vRNG Provider -To integrate the Verifiable Random Function (vRNG) into your Starknet contract, follow these steps: +To integrate the vRNG into your Starknet contract, follow these steps: 1. Define the vRNG Provider interface: @@ -130,9 +130,9 @@ const call = await account.execute([ **Ensure that you call `consume_random` with the same `Source` as used in `request_random`.** -### Important: Adding vRNG to Policies +### Important: Adding vRNG to Session Policies -When using the Cartridge Controller with vRNG, make sure to add the vRNG contract address and the `request_random` method to your session policies. This allows the controller to pre-approve vRNG-related transactions, ensuring a seamless experience for your users. +When using Cartridge Controller with vRNG, make sure to add the vRNG contract address and the `request_random` method to your [TODO: link to Controller sessions]. This allows the Controller to pre-approve vRNG-related transactions, ensuring a seamless experience for your users. Add the following policy to your existing session policies: @@ -154,6 +154,6 @@ numbers for your onchain game or application. ## Security Assumptions -During the Phase 0 deployment, the construction assumes the Provider has not revealed the private key and does not collude with players. +During the current deployment, the construction assumes the paymaster has not revealed the private key and does not collude with players. -In the future, we plan to move the Provider to a Trusted Execution Environment (TEE) in order to provide a more robust security model without compromising on performance. +In the future, we plan to move the paymaster to a Trusted Execution Environment (TEE) in order to provide a more robust security model without compromising on performance. From 81d7d285b872985b774dfd4a416116ee0e9b82a2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 1 Jun 2026 01:28:30 +0000 Subject: [PATCH 3/3] =?UTF-8?q?chore(defrag):=20phase=203=20=E2=80=94=20li?= =?UTF-8?q?nk=20repair?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-fixed broken internal links validated against source files. Extension removals, path corrections, broken anchor cleanup. Mode: LIVE Found 37 source files No build output found — validating against source files (anchor checks may be approximate) Found 37 pages from source files controller/examples/react.md:121 — page not found: ./configuration → /controller/configuration controller/examples/react.md:265 — page not found: ./headless-authentication → /controller/headless-authentication services/vrng/index.md:135 — TODO resolved: Controller sessions → /controller/sessions === Summary === Broken links found: 2 Links fixed: 3 TODO markers found: 1 Files modified: 2 --- src/pages/controller/examples/react.md | 4 ++-- src/pages/services/vrng/index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/controller/examples/react.md b/src/pages/controller/examples/react.md index f64013f..487d979 100644 --- a/src/pages/controller/examples/react.md +++ b/src/pages/controller/examples/react.md @@ -118,7 +118,7 @@ export function StarknetProvider({ children }: { children: React.ReactNode }) { } ``` -For more detailed configuration options, see the [Controller configuration guide](./configuration). +For more detailed configuration options, see the [Controller configuration guide](/controller/configuration). ### 2. Create a Wallet Connection Component @@ -262,7 +262,7 @@ export function MultiAuthConnectWallet() { ### 4. Headless Authentication -For programmatic authentication without opening any UI, you can use headless mode in your React components. For detailed information on headless authentication, see the [headless authentication guide](./headless-authentication). +For programmatic authentication without opening any UI, you can use headless mode in your React components. For detailed information on headless authentication, see the [headless authentication guide](/controller/headless-authentication). ```tsx import { useCallback, useState } from 'react' diff --git a/src/pages/services/vrng/index.md b/src/pages/services/vrng/index.md index 185f716..dbf66e8 100644 --- a/src/pages/services/vrng/index.md +++ b/src/pages/services/vrng/index.md @@ -132,7 +132,7 @@ const call = await account.execute([ ### Important: Adding vRNG to Session Policies -When using Cartridge Controller with vRNG, make sure to add the vRNG contract address and the `request_random` method to your [TODO: link to Controller sessions]. This allows the Controller to pre-approve vRNG-related transactions, ensuring a seamless experience for your users. +When using Cartridge Controller with vRNG, make sure to add the vRNG contract address and the `request_random` method to your [Controller sessions](/controller/sessions). This allows the Controller to pre-approve vRNG-related transactions, ensuring a seamless experience for your users. Add the following policy to your existing session policies: