Repository navigation
docs(tutorials): add "Connect with Chipi" dApp tutorial (03) - #22
Conversation
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>
Tutorial Completeness Check❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description. Score: 0/2 checks passed. Please fix the issues above. |
|
Warning Review limit reached
Next review available in: 41 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds 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. ChangesTutorial 03 – Connect with Chipi
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
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
tutorials/03-connect-with-chipi/src/App.tsx (1)
32-52: ⚡ Quick winGuard async actions against double-submit
onSign/onExecutecurrently 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
📒 Files selected for processing (10)
README.mdtutorials/03-connect-with-chipi/.gitignoretutorials/03-connect-with-chipi/README.mdtutorials/03-connect-with-chipi/index.htmltutorials/03-connect-with-chipi/package.jsontutorials/03-connect-with-chipi/src/App.tsxtutorials/03-connect-with-chipi/src/main.tsxtutorials/03-connect-with-chipi/src/vite-env.d.tstutorials/03-connect-with-chipi/tsconfig.jsontutorials/03-connect-with-chipi/vite.config.ts
| | [`@chipi-stack/chipi-passkey`](https://www.npmjs.com/package/@chipi-stack/chipi-passkey) |  | WebAuthn passkey auth — biometric login, seedless key management | | ||
| | [`@chipi-stack/types`](https://www.npmjs.com/package/@chipi-stack/types) |  | Shared TypeScript type definitions | | ||
| | [`@chipi-stack/shared`](https://www.npmjs.com/package/@chipi-stack/shared) |  | Shared utilities, constants, and helpers | | ||
| | [`@chipi-stack/starknet-connector`](https://www.npmjs.com/package/@chipi-stack/starknet-connector) |  | "Connect with Chipi" — a starknet-react connector so any Starknet dApp connects to a Chipi wallet (passkey, gasless, no extension) | |
There was a problem hiding this comment.
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) |  | "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", |
There was a problem hiding this comment.
🧩 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:
- 1: https://github.com/chipi-pay/build-with-chipi
- 2: https://registry.npmjs.org/%40chipi-stack%2Fchipi-react
- 3: https://www.npmjs.com/package/@chipi-stack/core
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.
| By default it connects to the production Chipi wallet. To point at a local Chipi | ||
| wallet during development, set `VITE_CHIPI_WALLET_URL`: | ||
|
|
There was a problem hiding this comment.
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.
| 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); |
There was a problem hiding this comment.
🧩 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:
- 1: https://starknetjs.com/docs/next/API/classes/Account
- 2: https://starknetjs.com/docs/8.6.0/API/classes/SignerInterface/
- 3: https://cdn.jsdelivr.net/npm/@starknet-react/core@5.0.3/dist/index-KYmfBIOq.d.ts
- 4: https://github.com/starknet-io/starknet.js/blob/v6.24.1/src/wallet/connect.ts
- 5: https://github.com/PhilippeR26/starknet.js-workshop-typescript/blob/main/src/scripts/signature/4c.signSnip12vActive.ts
- 6: https://start.starknet-react.com/demo/sign-typed-data
🏁 Script executed:
cd tutorials/03-connect-with-chipi && head -40 src/App.tsx | tail -15Repository: 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 -10Repository: chipi-pay/build-with-chipi
Length of output: 526
🏁 Script executed:
cd tutorials/03-connect-with-chipi && cat -n src/App.tsx | head -30Repository: chipi-pay/build-with-chipi
Length of output: 1434
🏁 Script executed:
cd tutorials/03-connect-with-chipi && grep -n "TypedData\|import.*starknet" src/App.tsxRepository: 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
Tutorial Completeness Check❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description. Score: 5/6 checks passed. Please fix the issues above. |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
tutorials/03-connect-with-chipi/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
tutorials/03-connect-with-chipi/README.mdtutorials/03-connect-with-chipi/VALIDATION.mdtutorials/03-connect-with-chipi/package.jsontutorials/03-connect-with-chipi/src/App.tsxtutorials/03-connect-with-chipi/src/main.tsxtutorials/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"; |
There was a problem hiding this comment.
🎯 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 }));
}
JSRepository: 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) |
There was a problem hiding this comment.
📐 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:
- 1: https://vite.dev/config/server-options
- 2: https://github.com/vitejs/vite/blob/main/docs/config/server-options.md
- 3: https://vite.dev/guide/cli
- 4: https://github.com/vitejs/vite/blob/main/packages/vite/src/node/http.ts
- 5: fix: allow binding when strictPort is set but wildcard port is in use vitejs/vite#22150
🏁 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)' || trueRepository: 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
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).
Tutorial Completeness Check❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description. 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.
Tutorial Completeness Check❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description. Score: 5/6 checks passed. Please fix the issues above. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tutorials/03-connect-with-chipi/src/App.tsx (1)
177-212: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConnect 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
⛔ Files ignored due to path filters (1)
tutorials/03-connect-with-chipi/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (4)
tutorials/03-connect-with-chipi/package.jsontutorials/03-connect-with-chipi/src/App.csstutorials/03-connect-with-chipi/src/App.tsxtutorials/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 { |
There was a problem hiding this comment.
📐 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().
Tutorial Completeness Check❌ YouTube video: Missing video link. Paste your YouTube URL in the PR description. 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.
Tutorial Completeness Check✅ VALIDATION.md: tutorials/03-connect-with-chipi/VALIDATION.md Score: 5/5 checks passed. Ready for review. |
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-connectorto 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-starknetwallet_*RPC overpostMessage. 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-reactAccountInterface.🤖 Generated with Claude Code
Summary by CodeRabbit