Skip to content

docs(tutorials): add "Connect with Chipi" dApp tutorial (03) - #22

Merged
haycarlitos merged 6 commits into
mainfrom
feat/connect-with-chipi-tutorial
Jul 23, 2026
Merged

haycarlitos merged 6 commits into
mainfrom
feat/connect-with-chipi-tutorial

Conversation

@haycarlitos

@haycarlitos haycarlitos commented Jun 18, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds Tutorial 03 — Connect with Chipi: a runnable starknet-react dApp that connects to a Chipi hosted smart-account wallet via @chipi-stack/starknet-connector.

This is the other side of the table from tutorials 01/02 — they build a wallet; this builds a dApp that connects to Chipi wallets. The "Connect with Chipi" model (Argent/Ready Web Wallet + Cartridge Controller), packaged as a one-line connector.

Contents

  • tutorials/03-connect-with-chipi/ — vite + @starknet-react/core@5 + starknet@8, the real ecosystem versions a production Starknet dApp uses. Full round-trip: connect → signTypedData (SNIP-12) → gasless execute.
  • README.md: add @chipi-stack/starknet-connector to the packages table.
  • README.md: add a Tutorials section listing 01 / 02 / 03 (none were linked before).

How it works

The connector opens the hosted Chipi wallet (/connect) in a popup and forwards get-starknet wallet_* RPC over postMessage. It holds no keys; the hosted wallet renders a decoded approval and runs the real passkey + paymaster path. The dApp only sees a standard starknet-react AccountInterface.

Pairs with the connector package + Mintlify guide on the sdks repo (feat/starknet-connector). Connector is not yet published to npm — the tutorial references it by version (^0.1.0).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated the packages list to include the Starknet connection connector.
    • Added Tutorial 03 (“Connect with Chipi”) with a runnable walkthrough covering wallet connection, typed-message signing, and gasless execution.
    • Added supporting tutorial assets, including a tutorial index, example app scaffolding, and a validation report.

A runnable starknet-react dApp that connects to a Chipi hosted
smart-account wallet via @chipi-stack/starknet-connector — the
"Connect with Chipi" connector (passkey, gasless, no extension,
no WalletConnect). Full round-trip: connect → signTypedData →
gasless execute.

- tutorials/03-connect-with-chipi/ (vite + @starknet-react/core@5 + starknet@8)
- README: add starknet-connector to the packages table
- README: add a Tutorials section listing 01/02/03

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description.
❌ VALIDATION.md: No VALIDATION.md found in changed files.

Score: 0/2 checks passed. Please fix the issues above.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@haycarlitos, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d0b9ac2-dd0f-48cd-94d9-c4b2437a4e50

📥 Commits

Reviewing files that changed from the base of the PR and between 0031867 and 4804e83.

📒 Files selected for processing (6)
  • .github/workflows/validate-tutorial-pr.yml
  • tutorials/03-connect-with-chipi/README.md
  • tutorials/03-connect-with-chipi/index.html
  • tutorials/03-connect-with-chipi/src/App.tsx
  • tutorials/03-connect-with-chipi/src/main.tsx
  • tutorials/03-connect-with-chipi/vite.config.ts
📝 Walkthrough

Walkthrough

Adds Tutorial 03, a runnable Vite/React Starknet dApp demonstrating Chipi wallet connection, SNIP-12 signing, gasless approval execution, additional connector choices, project tooling, documentation, styling, and validation records.

Changes

Tutorial 03 – Connect with Chipi

Layer / File(s) Summary
Root README and tutorial documentation
README.md, tutorials/03-connect-with-chipi/README.md
Adds the connector package and Tutorials index to the root README. Tutorial documentation covers setup, connection, signing, execution, popup communication, and local wallet configuration.
Project scaffold and build tooling
tutorials/03-connect-with-chipi/package.json, tutorials/03-connect-with-chipi/tsconfig.json, tutorials/03-connect-with-chipi/vite.config.ts, tutorials/03-connect-with-chipi/.gitignore, tutorials/03-connect-with-chipi/index.html, tutorials/03-connect-with-chipi/src/vite-env.d.ts
Adds package scripts and dependencies, strict TypeScript configuration, Vite React/WASM/top-level-await plugins, the HTML app shell, Vite types, and ignored build artifacts.
Wallet wiring, interaction UI, and styling
tutorials/03-connect-with-chipi/src/main.tsx, tutorials/03-connect-with-chipi/src/App.tsx, tutorials/03-connect-with-chipi/src/App.css
Configures Chipi alongside other Starknet connectors and mounts the app under StarknetConfig. The UI supports connection, disconnect, SNIP-12 signing, gasless approval execution, account actions, responsive presentation, and in-page result logging.
Tutorial validation record
tutorials/03-connect-with-chipi/VALIDATION.md
Records documentation, feature, hook, build, migration-fix, and recording validation results.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant App
  participant StarknetConfig
  participant ChipiConnector
  participant ChipiWallet

  User->>App: Select connector
  App->>StarknetConfig: connect({ connector })
  StarknetConfig->>ChipiConnector: connect()
  ChipiConnector->>ChipiWallet: Open wallet popup
  ChipiWallet-->>ChipiConnector: Return connection response
  ChipiConnector-->>App: Provide account
  User->>App: Sign typed data
  App->>ChipiConnector: account.signMessage(TYPED_DATA)
  ChipiConnector-->>App: Return signature
  User->>App: Execute approval
  App->>ChipiConnector: account.execute(approve calldata)
  ChipiConnector-->>App: Return transaction_hash
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding Tutorial 03, a Connect with Chipi dApp tutorial.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/connect-with-chipi-tutorial

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
tutorials/03-connect-with-chipi/src/App.tsx (1)

32-52: ⚡ Quick win

Guard async actions against double-submit

onSign / onExecute currently allow re-entry while a request is in flight, which can trigger duplicate popups/requests.

Minimal in-flight guard
@@
 export function App() {
@@
   const [log, setLog] = useState<string[]>([]);
+  const [busy, setBusy] = useState<null | "sign" | "execute">(null);
@@
   const onSign = async () => {
-    if (!account) return;
+    if (!account || busy) return;
+    setBusy("sign");
     try {
@@
     } catch (e) {
       add(`signTypedData ✗ ${(e as Error).message}`);
+    } finally {
+      setBusy(null);
     }
   };
@@
   const onExecute = async () => {
-    if (!account || !address) return;
+    if (!account || !address || busy) return;
+    setBusy("execute");
     try {
@@
     } catch (e) {
       add(`execute ✗ ${(e as Error).message}`);
+    } finally {
+      setBusy(null);
     }
   };
@@
-            <button onClick={onSign} style={btn}>
+            <button onClick={onSign} style={btn} disabled={busy !== null}>
               signTypedData
             </button>
-            <button onClick={onExecute} style={btn}>
+            <button onClick={onExecute} style={btn} disabled={busy !== null}>
               execute (gasless approve 0)
             </button>

Also applies to: 75-80

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/src/App.tsx` around lines 32 - 52, The
`onSign` and `onExecute` functions are vulnerable to re-entry during async
operations, allowing duplicate requests. Add boolean state variables to track
whether each operation is in-flight (for example, separate loading states for
sign and execute operations). At the beginning of both `onSign` and `onExecute`
functions, check if the corresponding operation is already pending and return
early if it is. Set the loading flag to true before the async operation starts,
and ensure it is reset to false in both the try and catch blocks to prevent the
operation from being blocked indefinitely on error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 20: The README.md table entry for `@chipi-stack/starknet-connector` on
line 20 contains a link to an unpublished npm package, which results in broken
links and badges for users. Remove or replace the npm package link and version
badge with a doc-safe fallback approach that does not point to the unpublished
npm package, such as removing the link entirely or using a placeholder text that
indicates the package is not yet published.

In `@tutorials/03-connect-with-chipi/package.json`:
- Line 12: The package.json file references an unpublished npm dependency
`@chipi-stack/starknet-connector` at version ^0.1.0, which will cause npm install
to fail and break the tutorial. Replace this dependency reference with a
resolvable source such as a workspace reference (using workspace: protocol), a
git repository URL, or a tarball path. Alternatively, ensure the package is
published to npm before merging this tutorial and update the version constraint
to match the published version.

In `@tutorials/03-connect-with-chipi/README.md`:
- Line 68: The fenced code block on line 68 is missing a language hint, which
triggers the MD040 linting rule and reduces readability. Locate the opening
fence (```) for the code block that contains the dApp and Chipi hosted wallet
comparison content, and add the "text" language identifier after the opening
triple backticks to specify the content type and resolve the linting violation.
- Around line 91-93: The documentation in the README at lines 91-93 incorrectly
claims the app defaults to production Chipi wallet, but the actual code in
main.tsx defaults VITE_CHIPI_WALLET_URL to http://localhost:3000. Update the
README text to accurately reflect that the default is a local Chipi wallet
running on localhost:3000, and clarify that users can set VITE_CHIPI_WALLET_URL
to point to production if needed. This correction should align the documentation
with the actual runtime behavior established in the codebase.

In `@tutorials/03-connect-with-chipi/src/App.tsx`:
- Line 35: The signMessage call on line 35 uses an `as never` cast that
suppresses TypeScript type checking for the TYPED_DATA object, preventing the
compiler from catching typed-data shape mismatches at compile time. To fix this,
import the `TypedData` type from starknet and add an explicit type annotation to
the `TYPED_DATA` object declaration to properly type it as `TypedData`, then
remove the `as never` cast from the signMessage call so TypeScript can validate
the data shape at compile time.

---

Nitpick comments:
In `@tutorials/03-connect-with-chipi/src/App.tsx`:
- Around line 32-52: The `onSign` and `onExecute` functions are vulnerable to
re-entry during async operations, allowing duplicate requests. Add boolean state
variables to track whether each operation is in-flight (for example, separate
loading states for sign and execute operations). At the beginning of both
`onSign` and `onExecute` functions, check if the corresponding operation is
already pending and return early if it is. Set the loading flag to true before
the async operation starts, and ensure it is reset to false in both the try and
catch blocks to prevent the operation from being blocked indefinitely on error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b05f7a72-8cb3-4094-a732-b55c785af8af

📥 Commits

Reviewing files that changed from the base of the PR and between 7bd9fa5 and 7cdc282.

📒 Files selected for processing (10)
  • README.md
  • tutorials/03-connect-with-chipi/.gitignore
  • tutorials/03-connect-with-chipi/README.md
  • tutorials/03-connect-with-chipi/index.html
  • tutorials/03-connect-with-chipi/package.json
  • tutorials/03-connect-with-chipi/src/App.tsx
  • tutorials/03-connect-with-chipi/src/main.tsx
  • tutorials/03-connect-with-chipi/src/vite-env.d.ts
  • tutorials/03-connect-with-chipi/tsconfig.json
  • tutorials/03-connect-with-chipi/vite.config.ts

Comment thread README.md
| [`@chipi-stack/chipi-passkey`](https://www.npmjs.com/package/@chipi-stack/chipi-passkey) | ![npm](https://img.shields.io/npm/v/@chipi-stack/chipi-passkey) | WebAuthn passkey auth — biometric login, seedless key management |
| [`@chipi-stack/types`](https://www.npmjs.com/package/@chipi-stack/types) | ![npm](https://img.shields.io/npm/v/@chipi-stack/types) | Shared TypeScript type definitions |
| [`@chipi-stack/shared`](https://www.npmjs.com/package/@chipi-stack/shared) | ![npm](https://img.shields.io/npm/v/@chipi-stack/shared) | Shared utilities, constants, and helpers |
| [`@chipi-stack/starknet-connector`](https://www.npmjs.com/package/@chipi-stack/starknet-connector) | ![npm](https://img.shields.io/npm/v/@chipi-stack/starknet-connector) | "Connect with Chipi" — a starknet-react connector so any Starknet dApp connects to a Chipi wallet (passkey, gasless, no extension) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid linking to an unpublished npm package

Line 20 points to npm for @chipi-stack/starknet-connector; if it is not published yet, both the package link and version badge are broken for users.

Suggested doc-safe fallback until publish
-| [`@chipi-stack/starknet-connector`](https://www.npmjs.com/package/@chipi-stack/starknet-connector) | ![npm](https://img.shields.io/npm/v/@chipi-stack/starknet-connector) | "Connect with Chipi" — a starknet-react connector so any Starknet dApp connects to a Chipi wallet (passkey, gasless, no extension) |
+| [`@chipi-stack/starknet-connector`](./tutorials/03-connect-with-chipi) | coming soon | "Connect with Chipi" — a starknet-react connector so any Starknet dApp connects to a Chipi wallet (passkey, gasless, no extension) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 20, The README.md table entry for
`@chipi-stack/starknet-connector` on line 20 contains a link to an unpublished
npm package, which results in broken links and badges for users. Remove or
replace the npm package link and version badge with a doc-safe fallback approach
that does not point to the unpublished npm package, such as removing the link
entirely or using a placeholder text that indicates the package is not yet
published.

"preview": "vite preview"
},
"dependencies": {
"@chipi-stack/starknet-connector": "^0.1.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Is @chipi-stack/starknet-connector version 0.1.0 (or any 0.1.x satisfying ^0.1.0) currently published on npm?

💡 Result:

No, the package @chipi-stack/starknet-connector is not currently published on npm. An analysis of the @chipi-stack scope and related Chipi Pay repositories indicates that while there are several packages within the @chipi-stack scope (such as @chipi-stack/core, @chipi-stack/chipi-react, and others), a package named @chipi-stack/starknet-connector does not exist in the npm registry [1][2][3].

Citations:


Unpublished dependency will prevent tutorial from running.

Line 12 references @chipi-stack/starknet-connector@^0.1.0, which is not published on npm. This will cause npm install to fail and make the tutorial unrunnable.

Either switch this tutorial to a resolvable source (workspace/git/tarball) or do not merge until the package is published to npm with aligned version documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/package.json` at line 12, The package.json
file references an unpublished npm dependency `@chipi-stack/starknet-connector` at
version ^0.1.0, which will cause npm install to fail and break the tutorial.
Replace this dependency reference with a resolvable source such as a workspace
reference (using workspace: protocol), a git repository URL, or a tarball path.
Alternatively, ensure the package is published to npm before merging this
tutorial and update the version constraint to match the published version.

Comment thread tutorials/03-connect-with-chipi/README.md
Comment on lines +91 to +93
By default it connects to the production Chipi wallet. To point at a local Chipi
wallet during development, set `VITE_CHIPI_WALLET_URL`:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default wallet URL claim conflicts with runtime behavior.

Line 91 says the app defaults to production, but tutorials/03-connect-with-chipi/src/main.tsx defaults VITE_CHIPI_WALLET_URL to http://localhost:3000. This will mislead users and break first-run expectations.

Suggested doc fix
-By default it connects to the production Chipi wallet. To point at a local Chipi
-wallet during development, set `VITE_CHIPI_WALLET_URL`:
+By default it points to a local wallet at `http://localhost:3000`.
+To use a different hosted wallet URL, set `VITE_CHIPI_WALLET_URL`:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
By default it connects to the production Chipi wallet. To point at a local Chipi
wallet during development, set `VITE_CHIPI_WALLET_URL`:
By default it points to a local wallet at `http://localhost:3000`.
To use a different hosted wallet URL, set `VITE_CHIPI_WALLET_URL`:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/README.md` around lines 91 - 93, The
documentation in the README at lines 91-93 incorrectly claims the app defaults
to production Chipi wallet, but the actual code in main.tsx defaults
VITE_CHIPI_WALLET_URL to http://localhost:3000. Update the README text to
accurately reflect that the default is a local Chipi wallet running on
localhost:3000, and clarify that users can set VITE_CHIPI_WALLET_URL to point to
production if needed. This correction should align the documentation with the
actual runtime behavior established in the codebase.

const onSign = async () => {
if (!account) return;
try {
const sig = await account.signMessage(TYPED_DATA as never);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

For starknet@8 and @starknet-react/core@5, what is the canonical TypeScript type for the argument to account.signMessage(SNIP-12 typed data), and shouldas never be avoided?

💡 Result:

For both starknet@8 and @starknet-react/core@5, the canonical TypeScript type for the argument representing SNIP-12 typed data is TypedData [1][2][3]. This type is exported directly by the starknet package [4]. Regarding the use of as never, it should generally be avoided in production TypeScript code [5]. While you may encounter it in older examples or quick-fix workarounds to satisfy strict type-checking, using it bypasses the type system's ability to catch errors in your typed data structure (e.g., mismatched types or missing required fields) [5]. Instead of forcing a cast, you should ensure your object strictly conforms to the TypedData interface [1][6]. If you are encountering type errors with valid data, it is often safer to explicitly type your object using the TypedData interface rather than using as never: const myTypedData: TypedData = {... }; await account.signMessage(myTypedData); This approach leverages Starknet.js's native type definitions to provide compile-time safety and better developer experience [1][2].

Citations:


🏁 Script executed:

cd tutorials/03-connect-with-chipi && head -40 src/App.tsx | tail -15

Repository: chipi-pay/build-with-chipi

Length of output: 544


🏁 Script executed:

cd tutorials/03-connect-with-chipi && cat -n src/App.tsx | grep -A 2 -B 2 "signMessage"

Repository: chipi-pay/build-with-chipi

Length of output: 278


🏁 Script executed:

cd tutorials/03-connect-with-chipi && cat -n src/App.tsx | head -10

Repository: chipi-pay/build-with-chipi

Length of output: 526


🏁 Script executed:

cd tutorials/03-connect-with-chipi && cat -n src/App.tsx | head -30

Repository: chipi-pay/build-with-chipi

Length of output: 1434


🏁 Script executed:

cd tutorials/03-connect-with-chipi && grep -n "TypedData\|import.*starknet" src/App.tsx

Repository: chipi-pay/build-with-chipi

Length of output: 374


Remove as never cast and add explicit TypedData type annotation

Line 35 uses as never to suppress type checking for SNIP-12 data, which bypasses the TypeScript compiler's ability to catch typed-data shape mismatches until runtime. The solution is to import TypedData from starknet and explicitly type the TYPED_DATA object.

Fix
 import { useState } from "react";
 import { useAccount, useConnect, useDisconnect } from "`@starknet-react/core`";
+import type { TypedData } from "starknet";
 
 // A minimal SNIP-12 (revision 1) message to prove signTypedData round-trips.
-const TYPED_DATA = {
+const TYPED_DATA: TypedData = {
   types: {
     StarknetDomain: [
       { name: "name", type: "shortstring" },

Then remove the cast on line 35:

-      const sig = await account.signMessage(TYPED_DATA as never);
+      const sig = await account.signMessage(TYPED_DATA);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/src/App.tsx` at line 35, The signMessage call
on line 35 uses an `as never` cast that suppresses TypeScript type checking for
the TYPED_DATA object, preventing the compiler from catching typed-data shape
mismatches at compile time. To fix this, import the `TypedData` type from
starknet and add an explicit type annotation to the `TYPED_DATA` object
declaration to properly type it as `TypedData`, then remove the `as never` cast
from the signMessage call so TypeScript can validate the data shape at compile
time.

…+ Cartridge), tested against production

Carlos: 'run it here to test that works with chipi, ready and braavos' before
moving the docs link over from the private sdks repo.

## What changed
- connectors array now includes ready() + braavos() (@starknet-react/core's
  built-in factories) and @cartridge/connector's ControllerConnector — proves
  Chipi coexists with real, independent connectors in the same array, zero
  conflicts, zero coordination needed on either side.
- UI now checks connector.available() and greys out/labels wallets that
  aren't installed — an honest picker instead of buttons that would silently
  throw on click.
- Fixed a real bug found during migration: the tutorial's USDC contract
  address was malformed (0x053c9125…, wrong prefix) — now the correct
  0x033068f6… address.
- Fixed the walletUrl default: was http://localhost:3000 (broken out of the
  box for any external developer — this is a PUBLIC tutorial, nobody outside
  Chipi has a local walletv2 to point at). Now defaults to production, same
  as the connector's own built-in default.
- vite.config.ts: added vite-plugin-wasm + vite-plugin-top-level-await —
  required for @cartridge/connector's Rust-compiled WASM bindings, which
  otherwise crash Vite's dev transform ('ESM integration proposal for Wasm
  is not supported').
- README rewritten: drops the Argent/Ready/Cartridge 'same model as X'
  framing per standing instruction, leads with 'no whitelisting'; docs link
  now points at the connector's new dedicated docs section
  (docs.chipipay.com/sdk/connector/overview) instead of the old buried guide.

## Tested (this session, Playwright against PRODUCTION, not a mock)
- Chipi: real popup opens to wallet.chipipay.com/connect, resolves to a real
  'Sign in to Chipi' screen. Full passkey completion needs a real user
  (can't be automated here) — everything up to that point verified working.
- Ready / Braavos: correctly detected as NOT installed (no crash, accurate
  available() reporting) — I don't have those extensions in this
  environment, so a live connection wasn't completable, but the wiring is
  proven correct.
- Cartridge: real connection attempt opened their actual official sign-in
  iframe, no errors, no interference from Chipi being in the same array.

See VALIDATION.md for the full scorecard.

## Known gap: no video
This validation was performed by an agent session with no screen-recording
capability — every claim is backed by Playwright automation against
production instead (documented in VALIDATION.md). The 'validate' CI check
will still fail on the missing YouTube link regardless of VALIDATION.md's
content — that's the one open decision for Carlos: record a short walkthrough,
or treat the automated evidence as sufficient for this tutorial.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019jtHoZvsjoaLRvd58oxNLT
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description.
✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md
✅ SDK version stated: ** @chipi-stack/starknet-connector@0.1.4
✅ All features scored: 7 passed, 0 failed (7 total)
✅ Pass rate: 100% (7/7)
✅ Hooks in code: 3/3 found in source

Score: 5/6 checks passed. Please fix the issues above.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tutorials/03-connect-with-chipi/src/main.tsx`:
- Line 13: Update the walletUrl initialization to trim the VITE_CHIPI_WALLET_URL
value and fall back to the production wallet URL when the result is blank or
otherwise falsy. Ensure the normalized URL is the value passed to
ChipiConnector.

In `@tutorials/03-connect-with-chipi/VALIDATION.md`:
- Line 99: Update the validation guidance around the Vite dev server to make the
port deterministic: either document that Vite may fall back from the configured
5500 port to 5502 when occupied, or add server.strictPort: true in
vite.config.ts and ensure the validation entry reflects the fail-fast behavior.

In `@tutorials/03-connect-with-chipi/vite.config.ts`:
- Around line 6-8: Update the introductory comment in the Vite configuration to
remove the outdated localhost default and state that localhost is used only when
explicitly provided through VITE_CHIPI_WALLET_URL, while preserving the
production default described by src/main.tsx.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 80fb962b-03e9-44df-9ff9-f1241a5a0ea7

📥 Commits

Reviewing files that changed from the base of the PR and between 7cdc282 and 8e7c85f.

⛔ Files ignored due to path filters (1)
  • tutorials/03-connect-with-chipi/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • tutorials/03-connect-with-chipi/README.md
  • tutorials/03-connect-with-chipi/VALIDATION.md
  • tutorials/03-connect-with-chipi/package.json
  • tutorials/03-connect-with-chipi/src/App.tsx
  • tutorials/03-connect-with-chipi/src/main.tsx
  • tutorials/03-connect-with-chipi/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tutorials/03-connect-with-chipi/package.json
  • tutorials/03-connect-with-chipi/src/App.tsx

// external developer running `npm run dev` has no local walletv2 to point at.
// Set VITE_CHIPI_WALLET_URL=http://localhost:3000 only for our own internal
// testing against a locally-running walletv2.
const walletUrl = import.meta.env.VITE_CHIPI_WALLET_URL ?? "https://wallet.chipipay.com";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '1,40p' tutorials/03-connect-with-chipi/src/main.tsx | cat -n

echo
echo "== env-like usages in tutorial =="
rg -n "VITE_CHIPI_WALLET_URL|chipipay|walletUrl|available\\(|connect\\(" tutorials/03-connect-with-chipi -S || true

echo
echo "== package/build hints =="
fd -e json 'package.json|vite.*|chi*' tutorials/03-connect-with-chipi . -x sh -c 'echo "--- $1"; sed -n "1,160p" "$1"' sh {} || true

echo
echo "== deterministic JS behavior for fallbacks =="
node - <<'JS'
const samples = [undefined, "https://wallet.chipipay.com", "", "  ", null];
for (const v of samples) {
  const env = { VITE_CHIPI_WALLET_URL: v };
  const current = env.VITE_CHIPI_WALLET_URL ?? "https://wallet.chipipay.com";
  const configuredWalletUrl = env.VITE_CHIPI_WALLET_URL?.trim();
  const proposed = configuredWalletUrl || "https://wallet.chipipay.com";
  console.log(JSON.stringify({ input: v, current, proposed }));
}
JS

Repository: chipi-pay/build-with-chipi

Length of output: 10441


Treat a blank wallet URL as unset.

Vite expose-values that are strings, so VITE_CHIPI_WALLET_URL= or whitespace-only values bypass the production fallback; trim and use falsy fallback before passing walletUrl to ChipiConnector.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/src/main.tsx` at line 13, Update the
walletUrl initialization to trim the VITE_CHIPI_WALLET_URL value and fall back
to the production wallet URL when the result is blank or otherwise falsy. Ensure
the normalized URL is the value passed to ChipiConnector.

Source: MCP tools


- [x] Clean install works (no manual steps needed)
- [x] Build passes (`npx tsc --noEmit` and `vite build` both clean)
- [x] App runs at localhost (`npm run dev`, verified on port 5502 during testing)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg 'tutorials/03-connect-with-chipi/(VALIDATION\.md|.*config.*|vite\.config|package\.json|README|.*README.*)' || true

echo
echo "validation line context:"
if [ -f tutorials/03-connect-with-chipi/VALIDATION.md ]; then
  nl -ba tutorials/03-connect-with-chipi/VALIDATION.md | sed -n '85,110p'
fi

echo
echo "port/server references:"
rg -n "port\s*[:=]\s*\d+|strictPort|5500|5502|local url|localhost" tutorials/03-connect-with-chipi -S || true

echo
echo "package scripts:"
if [ -f tutorials/03-connect-with-chipi/package.json ]; then
  jq '.scripts // empty' tutorials/03-connect-with-chipi/package.json
fi

echo
echo "vite config candidates:"
fd -i 'vite.*config' tutorials/03-connect-with-chipi -x sh -c 'echo "--- $1"; nl -ba "$1" | sed -n "1,160p"' sh {}

Repository: chipi-pay/build-with-chipi

Length of output: 464


🌐 Web query:

Vite dev port strictPort fallback next available port documentation

💡 Result:

In Vite, the server.strictPort configuration option controls how the dev server handles port conflicts [1][2]. By default, when you specify a port (e.g., via server.port in your configuration or the --port CLI flag), Vite attempts to use that port. If it is already in use, Vite will automatically increment the port number and try the next available one [1][3]. When you set server.strictPort to true (or use the --strictPort CLI flag), you instruct Vite to exit with an error if the specified port is already occupied, rather than attempting to fall back to the next available port [1][2][3]. This setting can be configured in two primary ways: 1. Configuration File (vite.config.js/ts): export default { server: { port: 5173, strictPort: true } } 2. Command Line Interface (CLI): vite --port 5173 --strictPort Technical Note: Recent updates to Vite's internal server logic have improved how this behaves when binding to specific hosts. If server.strictPort is true, Vite will still attempt to bind to the specifically configured host and port even if a pre-check indicates a conflict on a wildcard interface (0.0.0.0 or::), emitting a warning if successful [4][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "validation context:"
awk '{printf "%d\t%s\n", NR, $0}' tutorials/03-connect-with-chipi/VALIDATION.md | sed -n '85,110p'

echo
echo "vite.config.ts:"
awk '{printf "%d\t%s\n", NR, $0}' tutorials/03-connect-with-chipi/vite.config.ts | sed -n '1,180p'

echo
echo "package scripts:"
awk '{printf "%d\t%s\n", NR, $0}' tutorials/03-connect-with-chipi/package.json | sed -n '1,120p'

echo
echo "all port/server references:"
awk '{printf "%d\t%s\n", NR, $0}' tutorials/03-connect-with-chipi/VALIDATION.md tutorials/03-connect-with-chipi/README.md tutorials/03-connect-with-chipi/vite.config.ts tutorials/03-connect-with-chipi/package.json 2>/dev/null | grep -Ei '(port|5500|5502|localhost|npm run dev|vite|strictPort)' || true

Repository: chipi-pay/build-with-chipi

Length of output: 5280


Make the dev-server port deterministic.

vite.config.ts sets server.port to 5500 and npm run dev runs plain vite, but VALIDATION.md says it was verified on 5502. Either document that 5502 is the Vite fallback when 5500 is in use, or add server.strictPort: true so users fail fast instead of landing on an undocumented port.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/VALIDATION.md` at line 99, Update the
validation guidance around the Vite dev server to make the port deterministic:
either document that Vite may fall back from the configured 5500 port to 5502
when occupied, or add server.strictPort: true in vite.config.ts and ensure the
validation entry reflects the fail-fast behavior.

Source: MCP tools

Comment thread tutorials/03-connect-with-chipi/vite.config.ts Outdated
Pill "Connect Wallet" trigger, real wallet-picker modal (backdrop blur,
mobile bottom-sheet), official ready()/braavos()/Cartridge icons pulled
straight from each connector, connected-state address chip with
copy/disconnect. Chipi's icon overridden to the current brand asset since
the published package's default is stale (pending a starknet-connector
0.1.5 release).

Bug fix found while screenshot-testing: disabled wallet rows lost their
name text in dark mode (inherited the browser's default GrayText instead
of the theme color).
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description.
✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md
✅ SDK version stated: ** @chipi-stack/starknet-connector@0.1.4
✅ All features scored: 7 passed, 0 failed (7 total)
✅ Pass rate: 100% (7/7)
✅ Hooks in code: 3/3 found in source

Score: 5/6 checks passed. Please fix the issues above.

@chipi-stack/starknet-connector@0.2.0 is published — chipi() is now
usable, and its default icon is the current brand mark, so the local
override PNG is no longer needed.
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description.
✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md
✅ SDK version stated: ** @chipi-stack/starknet-connector@0.1.4
✅ All features scored: 7 passed, 0 failed (7 total)
✅ Pass rate: 100% (7/7)
✅ Hooks in code: 3/3 found in source

Score: 5/6 checks passed. Please fix the issues above.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tutorials/03-connect-with-chipi/src/App.tsx (1)

177-212: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Connect modal lacks dialog semantics and focus management.

Escape-to-close is handled, but the modal has no role="dialog"/aria-modal="true" and doesn't move focus into itself on open (or trap it), so keyboard/screen-reader users get no indication they're in a modal and can tab behind it.

Suggested addition
-          <div className="modal" onClick={(e) => e.stopPropagation()}>
+          <div className="modal" role="dialog" aria-modal="true" aria-labelledby="connect-modal-title" onClick={(e) => e.stopPropagation()}>
             <div className="modal-head">
-              <h2>Connect a wallet</h2>
+              <h2 id="connect-modal-title">Connect a wallet</h2>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/src/App.tsx` around lines 177 - 212, Update
the modal rendered by the modalOpen branch to expose dialog semantics with
role="dialog" and aria-modal="true", and add focus management that moves focus
into the dialog when it opens and traps keyboard focus within it until close.
Preserve the existing backdrop propagation behavior and close controls, using a
ref and effect in the surrounding App component as needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tutorials/03-connect-with-chipi/src/App.css`:
- Line 149: Rename the keyframes `fadeIn`, `modalIn`, and `sheetIn` in the CSS
to kebab-case names, then update every corresponding `animation` reference,
including the usages near lines 135, 146, and 416, so all animation behavior
remains unchanged.

---

Nitpick comments:
In `@tutorials/03-connect-with-chipi/src/App.tsx`:
- Around line 177-212: Update the modal rendered by the modalOpen branch to
expose dialog semantics with role="dialog" and aria-modal="true", and add focus
management that moves focus into the dialog when it opens and traps keyboard
focus within it until close. Preserve the existing backdrop propagation behavior
and close controls, using a ref and effect in the surrounding App component as
needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f3d22a02-38f0-43bc-bf88-137142706d2d

📥 Commits

Reviewing files that changed from the base of the PR and between 8e7c85f and 0031867.

⛔ Files ignored due to path filters (1)
  • tutorials/03-connect-with-chipi/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • tutorials/03-connect-with-chipi/package.json
  • tutorials/03-connect-with-chipi/src/App.css
  • tutorials/03-connect-with-chipi/src/App.tsx
  • tutorials/03-connect-with-chipi/src/main.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • tutorials/03-connect-with-chipi/package.json
  • tutorials/03-connect-with-chipi/src/main.tsx

animation: modalIn 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes fadeIn {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keyframe names violate kebab-case lint rule.

Stylelint flags fadeIn, modalIn, and sheetIn as non-kebab-case (keyframes-name-pattern). Rename and update the corresponding animation references at lines 135, 146, and 416.

Fix
-@keyframes fadeIn {
+@keyframes fade-in {
...
-@keyframes modalIn {
+@keyframes modal-in {
...
-@keyframes sheetIn {
+@keyframes sheet-in {

And update the usages:

-  animation: fadeIn 0.15s ease;
+  animation: fade-in 0.15s ease;
...
-  animation: modalIn 0.22s cubic-bezier(0.16, 1, 0.3, 1);
+  animation: modal-in 0.22s cubic-bezier(0.16, 1, 0.3, 1);
...
-    animation: sheetIn 0.22s cubic-bezier(0.16, 1, 0.3, 1);
+    animation: sheet-in 0.22s cubic-bezier(0.16, 1, 0.3, 1);

Also applies to: 158-158, 419-419

🧰 Tools
🪛 Stylelint (17.14.0)

[error] 149-149: Expected keyframe name "fadeIn" to be kebab-case (keyframes-name-pattern)

(keyframes-name-pattern)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tutorials/03-connect-with-chipi/src/App.css` at line 149, Rename the
keyframes `fadeIn`, `modalIn`, and `sheetIn` in the CSS to kebab-case names,
then update every corresponding `animation` reference, including the usages near
lines 135, 146, and 416, so all animation behavior remains unchanged.

Source: Linters/SAST tools

Standing house rule: no em dashes in anything published externally.
Also softened two README spots that named other wallets as a brand
comparison (should read as "no whitelisting"), fixed a stale
vite.config.ts comment claiming the default wallet URL is still
localhost, and updated the README's code sample to the new chipi()
factory instead of new ChipiConnector().
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description.
✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md
✅ SDK version stated: ** @chipi-stack/starknet-connector@0.1.4
✅ All features scored: 7 passed, 0 failed (7 total)
✅ Pass rate: 100% (7/7)
✅ Hooks in code: 3/3 found in source

Score: 5/6 checks passed. Please fix the issues above.

The video requirement was tied to Mayra's content-creation role; she's
no longer with the team and there's no one to produce these going
forward. Structural checks (VALIDATION.md presence, SDK version,
feature scoring, hooks-in-code) stay as-is.
@github-actions

Copy link
Copy Markdown

Tutorial Completeness Check

✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md
✅ SDK version stated: ** @chipi-stack/starknet-connector@0.1.4
✅ All features scored: 7 passed, 0 failed (7 total)
✅ Pass rate: 100% (7/7)
✅ Hooks in code: 3/3 found in source

Score: 5/5 checks passed. Ready for review.

@haycarlitos
haycarlitos merged commit 3e5e6df into main Jul 23, 2026
2 checks passed
@haycarlitos
haycarlitos deleted the feat/connect-with-chipi-tutorial branch July 23, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant