diff --git a/src/pages/arcade/marketplace.md b/src/pages/arcade/marketplace.md index 7211c9d..a14144a 100644 --- a/src/pages/arcade/marketplace.md +++ b/src/pages/arcade/marketplace.md @@ -7,6 +7,7 @@ description: Learn how to set up your game's Marketplace # Marketplace The Cartridge Marketplace brings onchain assets directly to your players, enabling richer and more complex game experiences. +The marketplace works closely with [starter packs](./starter-packs) to distribute assets to players. ## Adding Assets diff --git a/src/pages/arcade/overview.md b/src/pages/arcade/overview.md index adb1752..494fb4b 100644 --- a/src/pages/arcade/overview.md +++ b/src/pages/arcade/overview.md @@ -31,7 +31,7 @@ When you register a game or an edition, an NFT representing its ownership is min This NFT grants you admin rights over the game or edition. You can update the metadata of your game or any edition at any time --- including name, description, icon, image gallery, video, and more. -For technical setup and configuration details, see [Arcade Setup](./setup). +For technical setup and configuration details, see [Arcade Setup](./setup). For information on marketplace features and asset ownership, see [Arcade Marketplace](./marketplace). ![Register Game](/arcade-register-game.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 you 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..3010162 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](/arcade/marketplace) functionality for asset display. ### ⚡️ Activity Feed 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/controller/achievements.md b/src/pages/controller/achievements.md index 6a717ac..393074e 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 configuration details including `slot` parameter, see [Configuration](./configuration). ```typescript new ControllerConnector({ diff --git a/src/pages/controller/booster-packs.md b/src/pages/controller/booster-packs.md index 24fdab9..e19532a 100644 --- a/src/pages/controller/booster-packs.md +++ b/src/pages/controller/booster-packs.md @@ -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/configuration.md b/src/pages/controller/configuration.md index d24df4b..cd3acb9 100644 --- a/src/pages/controller/configuration.md +++ b/src/pages/controller/configuration.md @@ -155,7 +155,7 @@ Without policies, transactions will fail because Katana does not support the pay ::: Common issues to check: -- **Missing policies**: Controller requires session policies when used with Katana. See [session configuration](/controller/sessions) for details. +- **Missing policies**: Controller requires session policies when used with Katana. See the [Sessions](/controller/sessions) guide for details. - **RPC URL**: Katana defaults to `http://localhost:5050`. If you've configured a different port, update accordingly. - **Native currency address**: The STRK token address must match the token deployed on your Katana instance. @@ -189,7 +189,7 @@ await controller.connect(); // Iframe is created and mounted now ### Propagate Session Errors -The `propagateSessionErrors` option controls how contract execution errors are handled when using session-based transactions. When enabled, errors are returned directly to your application instead of showing the manual approval modal in the keychain. +The `propagateSessionErrors` option controls how contract execution errors are handled when using session-based transactions. When enabled, errors are returned directly to your application instead of showing the manual approval modal in the keychain. For detailed information about session configuration, see the [Sessions](/controller/sessions) guide. **Example:** ```typescript @@ -308,7 +308,7 @@ The configuration options are organized into several categories: ## Error Display Modes -Controller provides configurable error handling through the `errorDisplayMode` option, allowing you to control how transaction and execution errors are presented to users. This gives you fine-grained control over the user experience during error scenarios. +Controller provides configurable error handling through the `errorDisplayMode` option, allowing you to control how transaction and execution errors are presented to users. This gives you fine-grained control over the user experience during error scenarios. For more information about configuring error notifications, see the [Toast Notifications](/controller/toast-notifications) guide. ### Available Modes @@ -456,25 +456,25 @@ try { ## When to Use Policies -**Policies are optional** in Cartridge Controller. Choose based on your application's needs: +**Session policies are optional** in Cartridge Controller. Choose based on your application's needs: -### Use Policies When: +### Use Session Policies When: - Building games that need frequent, seamless transactions - You want gasless transactions via Cartridge Paymaster - Users should not be interrupted with approval prompts during gameplay - You need session-based authorization for better UX -### Skip Policies When: +### Skip Session Policies When: - Building simple applications with occasional transactions - Manual approval for each transaction is acceptable - You don't need gasless transaction capabilities - You want minimal setup complexity ```typescript -// Without policies - simple setup, manual approvals +// Without session policies - simple setup, manual approvals const simpleController = new Controller(); -// With policies - session-based, gasless transactions +// With session policies - session-based, gasless transactions const sessionController = new Controller({ policies: { // ... policy definitions @@ -482,6 +482,8 @@ const sessionController = new Controller({ }); ``` +For detailed information about configuring session policies, see the [Sessions](/controller/sessions) guide. + ## Dynamic Authentication Options Controller supports dynamic authentication configuration on a per-connection basis. This enables multiple branded authentication flows while using a single Controller instance. @@ -590,7 +592,7 @@ controller.openPurchaseCredits(); ### openStarterPack(starterpackId: string) -Opens the starterpack purchase interface for a specific bundle. +Opens the starter pack purchase interface for a specific bundle. ```typescript controller.openStarterPack("starterpack-id-123"); diff --git a/src/pages/controller/examples/cli.md b/src/pages/controller/examples/cli.md index b982fdc..1ca8d0f 100644 --- a/src/pages/controller/examples/cli.md +++ b/src/pages/controller/examples/cli.md @@ -139,7 +139,7 @@ controller marketplace buy --order-id 42 --collection 0x123... --token-id 1 --ch ### Calldata formats -Calldata values support multiple formats: +`calldata` values support multiple formats: | Format | Example | Description | |--------|---------|-------------| @@ -187,14 +187,14 @@ controller session auth --file --chain-id SN_MAIN --expires 1day | `--overwrite` | Overwrite existing session without confirmation | off | | `--expires` | Session expiration duration (e.g., `1min`, `1hr`, `1day`, `7days`, `1week`, `1year`) | `7days` | -**Presets:** Popular games/apps have pre-defined policies: +**Presets:** Popular games/apps have pre-defined session policies: - `loot-survivor` --- Loot Survivor game - `influence` --- Influence space strategy - `realms` --- Realms world - `pistols` --- Pistols at Dawn - `dope-wars` --- Dope Wars -See all presets at [github.com/cartridge-gg/presets](https://github.com/cartridge-gg/presets/tree/main/configs). +See [Sessions](/controller/sessions) for more information on policy structure and the complete list of available presets. ### `session status` @@ -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 @@ -498,10 +498,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..2d3a534 100644 --- a/src/pages/controller/examples/node.md +++ b/src/pages/controller/examples/node.md @@ -85,6 +85,8 @@ main().catch(console.error); ### Using Manual Policies +For detailed information about session policy structure and configuration options, see [Sessions](../sessions). + ```typescript import SessionProvider, { ControllerError, diff --git a/src/pages/controller/examples/react.md b/src/pages/controller/examples/react.md index 7154c84..8b033f3 100644 --- a/src/pages/controller/examples/react.md +++ b/src/pages/controller/examples/react.md @@ -352,9 +352,11 @@ 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 `signer` (passkey, OAuth account, EVM wallet) associated with their Cartridge username. For new user registration, use the regular `connect()` flow which opens the UI. ::: +For more details on session policies and authentication options, see the [Sessions documentation](/controller/sessions). + ### 5. Performing Transactions Execute transactions using the `account` object from `useAccount` hook: @@ -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: @@ -548,7 +550,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..20f12f9 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 ``` @@ -63,6 +63,8 @@ let controller = new Controller({ }); ``` +For detailed information about session policy configuration and syntax, see [Sessions](../sessions). + ### Connecting a Wallet Use the `connect` method to establish a connection: diff --git a/src/pages/controller/getting-started.mdx b/src/pages/controller/getting-started.mdx index f62725c..b4b9049 100644 --- a/src/pages/controller/getting-started.mdx +++ b/src/pages/controller/getting-started.mdx @@ -193,7 +193,7 @@ There are two providers, each with a different security and signing model. > ControllerProvider is the recommended provider for web applications. The default `ControllerProvider` (often exported as `Controller`) embeds the Cartridge keychain in a sandboxed iframe. -Both the owner signer and a **session key** live inside the iframe, employing a trust model similar to any injected wallet (e.g. MetaMask, Argent). +Both the owner `signer` and a **session key** live inside the iframe, employing a trust model similar to any injected wallet (e.g. MetaMask, Argent). When your app calls `execute()`, the request is forwarded to the iframe via `postMessage`. The keychain first tries to sign with the session key. @@ -211,12 +211,12 @@ The `SessionProvider` is designed for environments where an iframe cannot be use Instead of embedding the owner key in an iframe, it: 1. Opens a browser to the Cartridge keychain for one-time user authentication 2. Generates an ephemeral session keypair locally -3. **Registers the session key onchain** with the approved policies compiled into a merkle root +3. **Registers the session key onchain** with the approved `policies` compiled into a merkle root 4. Stores the session private key locally (in `localStorage` or on the filesystem) After registration, transactions are signed with the session key and executed via `executeFromOutside()` --- no further UI is needed. -Because the session key is not the owner key, **policies are enforced onchain** --- every transaction must include a merkle proof showing the call matches the registered policies. -The owner key is never exposed through this provider, so there is no fallback for calls outside the approved policies. +Because the session key is not the owner key, **`policies` are enforced onchain** --- every transaction must include a merkle proof showing the call matches the registered `policies`. +The owner key is never exposed through this provider, so there is no fallback for calls outside the approved `policies`. > For a visual comparison of how each provider authenticates and signs, see the [Architecture](/controller/architecture#auth-flows) page. diff --git a/src/pages/controller/headless-authentication.md b/src/pages/controller/headless-authentication.md index da6417e..faa8bf9 100644 --- a/src/pages/controller/headless-authentication.md +++ b/src/pages/controller/headless-authentication.md @@ -81,7 +81,7 @@ try { ### Password Authentication -For scenarios where WebAuthn isn't available: +For scenarios where WebAuthn is not available: ```typescript const account = await controller.connect({ @@ -181,7 +181,7 @@ For complete details on available authentication methods, see [Signer Management ## Session Approval Flow -If your application uses [session policies](./sessions) that haven't been verified or include spending limits that require approval, the keychain will automatically open the approval UI after successful authentication: +If your application uses [session policies](./sessions) that have not been verified or include spending limits that require approval, the keychain will automatically open the approval UI after successful authentication: ```typescript const controller = new Controller({ @@ -223,7 +223,7 @@ try { console.error("Auth failed:", error.message); // Common reasons: - // - Username doesn't exist + // - Username does not exist // - Signer not associated with username // - Invalid credentials // - Network connectivity issues @@ -258,12 +258,12 @@ interface UsernameLookupResult { This method is particularly useful for: - Validating usernames before attempting authentication - Displaying appropriate login options to users -- Implementing auto-signup flows when accounts don't exist +- Implementing auto-signup flows when accounts do not exist - Preventing unnecessary authentication attempts ### Auto-Signup Support -Version 0.13.7 adds auto-signup functionality for headless flows. When a username doesn't exist, you can automatically create an account: +Version 0.13.7 adds auto-signup functionality for headless flows. When a username does not exist, you can automatically create an account: ```typescript try { @@ -391,7 +391,7 @@ import { SessionProvider } from "@cartridge/connector"; const sessionProvider = new SessionProvider({ rpc: "https://api.cartridge.gg/x/starknet/mainnet", chainId: "SN_MAIN", - // Note: SessionProvider doesn't support headless mode directly + // Note: SessionProvider does not support headless mode directly // Use regular browser-based headless authentication for programmatic flows }); ``` @@ -445,10 +445,10 @@ This web-based headless authentication is different from the [native headless Co ### Common Issues -1. **"User not found"**: Username doesn't exist in the system +1. **"User not found"**: Username does not exist in the system - *Solution*: Use `lookupUsername()` to check existence before attempting to connect - *Auto-signup*: Consider enabling auto-signup for new users -2. **"Signer not found"**: The specified `signer` isn't associated with the username +2. **"Signer not found"**: The specified `signer` is not associated with the username - *Solution*: Use `lookupUsername()` to get available signers for the username - *Fallback*: Implement signer selection UI based on available options 3. **"Not ready to connect"**: Controller initialization is still in progress diff --git a/src/pages/controller/native/android.md b/src/pages/controller/native/android.md index dcc4a72..df50f8e 100644 --- a/src/pages/controller/native/android.md +++ b/src/pages/controller/native/android.md @@ -54,7 +54,8 @@ data class Call( ### Session Policies -Define permissions for session accounts: +Define permissions for session accounts. +For detailed policy configuration, see [Sessions](/controller/sessions): ```kotlin data class SessionPolicy( @@ -132,7 +133,7 @@ controller.disconnect() ## Creating a SessionAccount -Create a session account for executing transactions without repeated signatures: +Create a session account for executing gasless transactions: ```kotlin val sessionAccount = SessionAccount( diff --git a/src/pages/controller/native/capacitor.md b/src/pages/controller/native/capacitor.md index 3c410b5..83f650d 100644 --- a/src/pages/controller/native/capacitor.md +++ b/src/pages/controller/native/capacitor.md @@ -142,6 +142,7 @@ if (Capacitor.isNativePlatform()) { ## Deep Link Handling The authentication flow opens an in-app browser, then redirects back via your custom URL scheme. +For detailed information about session policies and authentication flows, see [sessions](../sessions). ### iOS Configuration diff --git a/src/pages/controller/native/ios.md b/src/pages/controller/native/ios.md index 6063058..bd5849c 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 structure and usage, see [Sessions](../sessions). ```swift struct SessionPolicy { diff --git a/src/pages/controller/native/overview.md b/src/pages/controller/native/overview.md index c919462..fd8a765 100644 --- a/src/pages/controller/native/overview.md +++ b/src/pages/controller/native/overview.md @@ -34,6 +34,8 @@ The session signer can then execute transactions without further user interactio **Reference:** [Session URL Reference](/controller/native/session-flow) for URL parameters, policy format, and callback metadata. +For detailed information about session-based authentication and policy configuration, see [Sessions](/controller/sessions). + ### Headless (App-Managed Keys) Your app supplies its own signing keys rather than using the Cartridge keychain. diff --git a/src/pages/controller/native/react-native.md b/src/pages/controller/native/react-native.md index c57d984..aacc247 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 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](/controller/native/headless) pattern, which uses application-managed owner keys without any browser authentication. +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 @@ -69,6 +69,7 @@ const publicKey = Controller.controller.getPublicKey(privateKey); ## Session Management The `useSessionManager` hook handles the complete session lifecycle: key generation, browser-based authentication, and transaction execution. +For detailed information on session policy structure and usage, see [Sessions](/controller/sessions). ### Key Generation and Storage diff --git a/src/pages/controller/native/session-flow.md b/src/pages/controller/native/session-flow.md index 98cd270..f347dd1 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 information on session policy configuration, see [Sessions](/controller/sessions). ## Session Metadata diff --git a/src/pages/controller/signer-management.md b/src/pages/controller/signer-management.md index 2402e8f..8dba7af 100644 --- a/src/pages/controller/signer-management.md +++ b/src/pages/controller/signer-management.md @@ -78,6 +78,7 @@ All social login providers use an intelligent authentication flow that adapts to Controller offers integration with popular external web3 wallets, including Braavos, MetaMask, Rabby, Base, Phantom, and WalletConnect. +For information about programmatic authentication with external wallets, see [Headless Authentication](./headless-authentication). ## Adding Signers @@ -179,8 +180,6 @@ Controller offers integration with popular external web3 wallets, including Braa > **Mobile Limitation**: Ethereum-based wallets (MetaMask, Phantom, Rabby, Base, WalletConnect) will not appear as options on mobile browsers and are automatically filtered out for better mobile user experience. -For information about programmatic authentication with external wallets, see [Headless Authentication](./headless-authentication). - ## Managing Existing Signers ### Viewing Your Signers @@ -551,6 +550,6 @@ const DISCONNECT_OAUTH = gql` ## Next Steps -- Learn about [Session Keys](./sessions) for gasless gaming transactions +- Learn about [Sessions](./sessions) for session-based authentication and 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 b347c92..ef3d4a7 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); @@ -177,11 +180,13 @@ These typically include premium game assets, larger credit bundles, and exclusiv Cross-chain crypto payments are powered by Layerswap. :::note -Credit card payments via Coinflow are available in sandbox mode. Production credit card payments will be enabled in a future update. +Credit card payments via Coinflow are available in sandbox mode. +Production credit card payments will be enabled in a future update. ::: ### Claimed Starter Packs -Free starter packs that users can claim based on eligibility criteria. These starter packs: +Free starter packs that users can claim based on eligibility criteria. +These starter packs: - **No payment required**: Users can claim them for free - **Eligibility checking**: System verifies if user meets claim requirements - **Collection showcase**: Display supported game collections with platform indicators @@ -191,20 +196,23 @@ Free starter packs that users can claim based on eligibility criteria. These sta The claiming flow automatically determines eligibility and guides users through the appropriate network selection for receiving their assets. ### Social Claim Bundles -Bundles can include conditional claiming flows that require users to complete social actions before claiming. The social claim flow: +Bundles can include conditional claiming flows that require users to complete social actions before claiming. +The social claim flow: - **Social Connection**: Users connect their social media account (e.g., X/Twitter) - **Follow Action**: Users follow a specified account - **Share Action**: Users share a custom message with their network - **Automatic Verification**: System verifies completion of all steps before allowing claim -Use `controller.openBundle()` with `socialClaimOptions` to enable social claim flows. See the API Reference section for usage examples. +Use `controller.openBundle()` with `socialClaimOptions` to enable social claim flows. +See the API Reference section for usage examples. #### Merkle Drop Claims Claimable starter packs use **Merkle Drop** technology to enable secure, verifiable claims across multiple blockchain networks. This system allows users to claim assets that were originally distributed on other networks and receive them in their Cartridge account on Starknet. -**DevConnect Integration**: Cartridge supports DevConnect booster pack claims through the Merkle claim system, allowing users to claim DevConnect rewards using preimage-derived EVM addresses. This enables seamless cross-chain reward distribution for DevConnect participants. +**DevConnect Integration**: Cartridge supports DevConnect booster pack claims through the Merkle claim system, allowing users to claim DevConnect rewards using preimage-derived EVM addresses. +This enables seamless cross-chain reward distribution for DevConnect participants. **How Merkle Drop Claims Work:** @@ -244,7 +252,8 @@ The purchase process follows these steps: ## Cross-Chain Bridging with Layerswap -Cartridge uses Layerswap to enable seamless cross-chain payments. When users pay with cryptocurrency from supported networks (Ethereum, Base, Arbitrum, or Optimism), Layerswap automatically bridges the tokens to your Cartridge account on Starknet. +Cartridge uses Layerswap to enable seamless cross-chain payments. +When users pay with cryptocurrency from supported networks (Ethereum, Base, Arbitrum, or Optimism), Layerswap automatically bridges the tokens to your Cartridge account on Starknet. ### Wallet Chain Switching Behavior diff --git a/src/pages/controller/toast-notifications.md b/src/pages/controller/toast-notifications.md index 0c8cada..9f619bf 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 details on `errorDisplayMode` and `propagateSessionErrors` settings. ```typescript import { Controller } from "@cartridge/controller"; diff --git a/src/pages/controller/usernames.md b/src/pages/controller/usernames.md index e1f431e..eaa8280 100644 --- a/src/pages/controller/usernames.md +++ b/src/pages/controller/usernames.md @@ -54,7 +54,7 @@ Response Format The Controller SDK provides dedicated methods for username lookup with enhanced functionality: -``` +```bash npm install @cartridge/controller ``` 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/paymaster.md b/src/pages/services/paymaster.md index 629a03b..c1845c2 100644 --- a/src/pages/services/paymaster.md +++ b/src/pages/services/paymaster.md @@ -163,7 +163,7 @@ Predicates are optional. Policies without predicates will always sponsor matchin ### vRNG Integration -Paymasters can sponsor vRNG operations, providing gasless random number generation for your games. When configuring policies for vRNG-enabled contracts, the paymaster will automatically handle both the initial request and callback transactions. For detailed vRNG setup and usage, see [vRNG](/services/vrng). +Paymasters can sponsor vRNG operations, providing gasless random number generation for your games. When configuring policies for vRNG-enabled contracts, the paymaster will automatically handle both the initial request and callback transactions. For detailed vRNG setup and usage, see [TODO: link to vRNG overview]. ### Add Policies from Preset (Recommended) diff --git a/src/pages/services/vrng/how-it-works.md b/src/pages/services/vrng/how-it-works.md index e18a3d6..2717d83 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 vRNG) | 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,44 +26,44 @@ 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)`. +A **Verifiable Random Number Generator (vRNG)** adds a secret key to the computation: `vRNG(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 | +| | Hash | vRNG | | --- | --- | --- | | **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 vRNG 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: +The vRNG 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 vRNG 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. @@ -81,15 +81,15 @@ The `Nonce` source auto-increments, guaranteeing a unique seed per request witho ## Transaction Flow The player signs their game action as normal. -The paymaster intercepts it, generates the VRF proof, and wraps everything into a nested SNIP-9 `execute_from_outside_v2` structure: +The paymaster intercepts it, generates the vRNG proof, and wraps everything into a nested SNIP-9 `execute_from_outside_v2` structure: ``` ┌─────────────────────────────────────────────────────────────┐ │ Paymaster │ -│ calls execute_from_outside_v2 on VRF Account │ +│ calls execute_from_outside_v2 on vRNG Account │ │ │ │ ┌────────────────────────────────────────────────────────┐ │ -│ │ VRF Account (outer execution, signed by provider key) │ │ +│ │ vRNG Account (outer execution, signed by provider key)│ │ │ │ │ │ │ │ 1. submit_random(seed, proof) │ │ │ │ → verifies proof against stored public key │ │ @@ -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) │ │ │ @@ -118,39 +118,39 @@ 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 vRNG 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 vRNG 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-vRNG proof against the vRNG 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. +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. -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. +- **Proof injection without player awareness** --- the player only signs their game action. +The vRNG 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. There is no window where the random value exists but hasn't been used, and no second transaction to wait for. ## Security Model ### Current (Phase 0) -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. -- 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 vRNG 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). diff --git a/src/pages/services/vrng/index.md b/src/pages/services/vrng/index.md index 2bd6ba3..306d0f6 100644 --- a/src/pages/services/vrng/index.md +++ b/src/pages/services/vrng/index.md @@ -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 Verifiable Random Number Generator (vRNG) into your Starknet contract, follow these steps: 1. Define the vRNG Provider interface: @@ -142,7 +142,7 @@ const policies: Policy[] = [ { target: VRF_PROVIDER_ADDRESS, method: "request_random", - description: "Allows requesting random numbers from the VRF provider", + description: "Allows requesting random numbers from the vRNG Provider", }, ]; ```