Skip to content

Conversation

@laciferin2024
Copy link
Contributor

@laciferin2024 laciferin2024 commented Oct 18, 2025

PR Checklist

Please read and check all that apply.

Changesets

  • This PR includes a Changeset under .changeset/ describing the change (patch/minor/major) with a clear, user-focused summary
  • OR this PR is docs/tests-only and I added the skip-changeset label

Quality

  • UI builds locally: bun run build (Vite)
  • E2E or unit tests added/updated where applicable (playwright, vitest if used)
  • No breaking changes to public interfaces without a major bump

Notes

  • Add a changeset via: bun run changeset
  • Policy and examples: see aidocs/changesets.md

Summary by CodeRabbit

  • New Features

    • Post-airdrop logout: users are automatically logged out and redirected to sign-in after claiming or confirming an airdrop
    • Conditional sign-in routing: users with zero token balance are sent to the airdrop page
    • Onboarding text updated to "Claim Airdrop"
  • Chores / Improvements

    • Improved logout: more thorough client-side data clearing and smoother redirect without forcing a full reload
  • Documentation / Assets

    • Updated default/example URLs and meta tags to use ideomind.org domains

- Implemented automatic logout for users after airdrop completion in both Airdrop and OnboardingFlow components.
- Added error handling for logout process to ensure smooth user experience.
- Integrated navigation to the sign-in page after user logout in both Airdrop and OnboardingFlow components.
- Ensured consistent user experience by implementing the same logout behavior across multiple components.
- Improved logout functionality by clearing all relevant localStorage items for a complete clean slate.
- Updated the SignIn component to redirect users to the airdrop page if their UNREAL balance is zero.
- Added a new somnia testnet configuration to the default chains list.
- Refactored comments for clarity and consistency in the logout process.
@vercel
Copy link

vercel bot commented Oct 18, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
console Ready Ready Preview Comment Nov 5, 2025 4:58pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 18, 2025

Walkthrough

Adds post-airdrop logout+redirect flows, expands logout localStorage cleanup and removes forced reload, conditionally routes zero-balance users to the airdrop page, deduplicates chain entries, and makes registration always attempt permit creation while adding a required token field to RegistrationResult. useApi now exposes logout().

Changes

Cohort / File(s) Summary
Changeset metadata
\.changeset/ninety-rice-send.md
Marks a patch for unreal-console with a note to logout the user after airdrop.
Post-airdrop logout integration
src/components/OnboardingFlow.tsx, src/pages/Airdrop.tsx
Imports useNavigate, reads logout from useApi(), and adds a 2–3s delayed logout() call followed by navigate('/sign-in') after successful/confirmed airdrops with error logging.
API context & storage cleanup
src/lib/ApiContext.tsx, src/store/appStore.ts
logout now clears many unreal_* keys plus onboarding and wallet-related keys, removes WalletConnect-related keys, logs a descriptive message, calls any disconnector, and removes the forced window.location.reload() (navigation handles redirects).
Onboarding / Sign-in routing & UI text
src/pages/SignIn.tsx
Redirect on auth now goes to /airdrop when unrealBalanceWei === 0n (otherwise /dashboard); onboarding completion button text changed to "Claim Airdrop".
Chain configuration
src/lib/onboard.ts
Inserts somniaTestnet as the first DEFAULT_CHAINS entry and removes a duplicate entry.
Registration / permit flow & types
src/lib/registration.ts
Adds helper to resolve payment token, always attempts permit creation when a payment token exists (throws on permit failure), adds logging and allowance checks, and updates RegistrationResult to include required token: string plus optional paymentToken.
Endpoint and metadata updates
index.html, src/config/unreal.ts, src/components/MarketingContent.tsx, src/pages/Index.tsx, .env.example, tests/dash.test.ts
Replaces unreal.art hostnames with ideomind.org variants in meta tags, API examples, defaults, and tests; adds OpenAI client interceptor to inject Authorization header from localStorage when present.

Sequence Diagram

sequenceDiagram
    autonumber
    participant User
    participant UI as Component (Airdrop/Onboarding)
    participant API as ApiContext (useApi)
    participant Store as localStorage
    participant Router as React Router

    User->>UI: Claim airdrop
    UI->>API: confirm/claim airdrop
    activate API
    API-->>UI: success
    deactivate API

    UI->>UI: show success toast
    Note right of UI: wait 2–3s
    UI->>API: logout()
    activate API
    API->>Store: remove unreal_*, onboard, connectedWallets
    API->>Store: remove keys matching wc@ / walletconnect / _walletconnect
    API-->>UI: logout complete
    deactivate API

    UI->>Router: navigate('/sign-in')
    Router->>User: redirect to sign-in
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to focus on during review:

  • src/lib/registration.ts — new token resolution helper, unconditional permit creation, error handling, and the RegistrationResult type change.
  • src/lib/ApiContext.tsx / src/store/appStore.ts — expanded localStorage cleanup and removed reload; ensure no unintended data loss.
  • src/components/OnboardingFlow.tsx and src/pages/Airdrop.tsx — logout timing, error handling, and navigation correctness around airdrop flows.
  • Tests and examples updated for host changes (ideomind.org) — ensure test expectations and doc snippets remain accurate.

Possibly related PRs

Poem

🐰 I hopped to claim a shiny drop,
A toast, a pause — then keys we drop,
Clean slate, new path, the sign‑in door,
I nudge the map and hop once more,
Joy in the airdrop — hop, hop, hooray! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description is an uncompleted checklist template with all items left unchecked and no actual information provided by the author. This is problematic because the raw summary reveals a breaking API change to the RegistrationResult interface (new required token field), which explicitly violates the quality check "No breaking changes to public interfaces without a major bump." The author should have checked the changeset item (a changeset file exists), addressed the breaking change, and completed other applicable checklist items with explanations or verification status. Complete the PR checklist by: (1) checking the first Changesets item since .changeset/ninety-rice-send.md exists; (2) explicitly acknowledging the breaking change to RegistrationResult and confirming it aligns with version bumping strategy; (3) verifying and checking the build/test items or explaining why they don't apply; (4) providing a brief summary of changes beyond the template structure.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Fixup/logout user after airdrop" is specific and directly related to a significant, real component of this changeset. Multiple files (OnboardingFlow.tsx, Airdrop.tsx, ApiContext.tsx, appStore.ts) implement post-airdrop logout flows, and a dedicated changeset file documents this feature. While the PR also includes substantial domain migration changes (unreal.art to ideomind.org) and registration token handling updates, the logout-after-airdrop feature is a substantial and primary concern with dedicated implementation files. The title is clear, specific, and not misleading or vague.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fixup/logout-user-after-airdrop

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
.changeset/ninety-rice-send.md (1)

1-5: Changeset is minimal; clarify user impact and scope.

Add a short, user-focused summary that mentions the new “auto-logout after airdrop” behavior and that local wallet/session data is wiped (users must reconnect). If this is considered a UX behavior change, confirm patch vs minor. Also reference affected routes (SignIn, Airdrop, Onboarding).

Do you want me to expand the changeset text to include these details?

src/pages/Airdrop.tsx (1)

121-130: Timeout-based logout: add cleanup and de-dup helper.

Both blocks schedule setTimeout to logout then navigate. Store the timeout id and clear on unmount; extract a small helper to avoid duplication.

+  const logoutAndRedirect = useCallback((ms = 2000) => {
+    const id = window.setTimeout(async () => {
+      try {
+        await logout()
+        navigate("/sign-in")
+      } catch (e) {
+        console.error("Error during logout after airdrop:", e)
+      }
+    }, ms)
+    return id
+  }, [logout, navigate])
+
+  useEffect(() => {
+    return () => { /* clear any pending timeouts if you store them */ }
+  }, [])

Then:

-          setTimeout(async () => { ... }, 2000)
+          logoutAndRedirect(2000)

Apply similarly to the confirmation block. Also include logout and navigate in handleClaim deps if you in-line them.

Also applies to: 160-169

src/lib/ApiContext.tsx (1)

600-661: Consider resetting Web3-Onboard instance on logout.

You clear storage and disconnect wallet, but Onboard’s in-memory instance persists. Call resetOnboard() so the next getOnboard() starts fresh.

-import { initOnboard, getOnboard, type OnboardChain } from "@/lib/onboard"
+import { initOnboard, getOnboard, resetOnboard, type OnboardChain } from "@/lib/onboard"
...
   const logout = async () => {
     // Reset authentication state
     ...
     // If a thirdweb disconnector is registered, call it
     ...
-    // No window.location.reload() - let the navigation handle the redirect
+    // Drop Onboard instance to avoid any cached state
+    try { resetOnboard() } catch {}
+    // No window.location.reload() - let the navigation handle the redirect
   }
src/components/OnboardingFlow.tsx (1)

337-346: Timeout-based logout repeated; add helper and cleanup.

Mirror the Airdrop suggestion: factor a logoutAndRedirect helper and clear timeouts on unmount to avoid stray navigations if the component unmounts early.

-          setTimeout(async () => {
-            try {
-              await logout()
-              navigate('/sign-in')
-            } catch (error) {
-              console.error("Error during logout after airdrop:", error)
-            }
-          }, 3000)
+          logoutAndRedirect(3000)

Also ensure logout and navigate are stable deps in the helper’s useCallback.

Also applies to: 391-399

src/store/appStore.ts (1)

222-245: Centralize duplicate localStorage cleanup logic to prevent maintenance drift.

The same localStorage purge logic exists in both src/store/appStore.ts (lines 223–244) and src/lib/ApiContext.tsx (lines 612–633)—both removing the identical six keys and scanning for WalletConnect entries. Extract this to a shared utility to avoid future divergence:

+// src/lib/clearClientStorage.ts
+export function clearClientStorage() {
+  try {
+    ["unreal_token", "unreal_wallet_address", "unreal_last_chain", "unreal_onboarding_seen", "onboard", "connectedWallets"]
+      .forEach((k) => localStorage.removeItem(k))
+    const keysToClear: string[] = []
+    for (let i = 0; i < localStorage.length; i++) {
+      const k = localStorage.key(i)
+      if (!k) continue
+      const low = k.toLowerCase()
+      if (low.startsWith("wc@") || low.includes("walletconnect") || low.includes("_walletconnect")) {
+        keysToClear.push(k)
+      }
+    }
+    keysToClear.forEach((k) => localStorage.removeItem(k))
+  } catch { /* noop */ }
+}

Use in both appStore.ts (line 223) and ApiContext.tsx (line 612):

-      // Clear ALL localStorage items for complete clean slate
-      localStorage.removeItem("unreal_token")
-      // ... rest of removals
+      clearClientStorage()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2008ac and 59e708d.

📒 Files selected for processing (7)
  • .changeset/ninety-rice-send.md (1 hunks)
  • src/components/OnboardingFlow.tsx (5 hunks)
  • src/lib/ApiContext.tsx (3 hunks)
  • src/lib/onboard.ts (1 hunks)
  • src/pages/Airdrop.tsx (4 hunks)
  • src/pages/SignIn.tsx (3 hunks)
  • src/store/appStore.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/lib/onboard.ts (2)
src/config/wallet.ts (1)
  • somniaTestnet (166-209)
utils/web3/chains.ts (1)
  • getUnrealTokenAddress (136-148)
src/pages/Airdrop.tsx (1)
src/lib/ApiContext.tsx (1)
  • useApi (712-718)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: E2E Tests
🔇 Additional comments (4)
src/pages/SignIn.tsx (2)

359-362: Onboarding complete route change looks good.


639-645: CTA rename to “Claim Airdrop” aligns with the new flow.

src/pages/Airdrop.tsx (1)

2-3: Import/use of navigate/logout is appropriate for post-claim flows.

Also applies to: 17-19

src/components/OnboardingFlow.tsx (1)

2-3: Navigate/logout wiring added—looks consistent with the new flow.

Also applies to: 43-44, 66-67

Comment on lines +35 to +41
{
id: toHex(somniaTestnet.id), // 8192
token: somniaTestnet.nativeCurrency.symbol,
label: somniaTestnet.name,
rpcUrl: somniaTestnet.rpcUrls.default.http[0],
secondaryTokens: [{ address: getUnrealTokenAddress(somniaTestnet.id) }],
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix incorrect comment for somniaTestnet id.

The inline “// 8192” doesn’t match somniaTestnet.id (50312). Update or remove to avoid confusion.

-  id: toHex(somniaTestnet.id), // 8192
+  id: toHex(somniaTestnet.id), // 50312
📝 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
{
id: toHex(somniaTestnet.id), // 8192
token: somniaTestnet.nativeCurrency.symbol,
label: somniaTestnet.name,
rpcUrl: somniaTestnet.rpcUrls.default.http[0],
secondaryTokens: [{ address: getUnrealTokenAddress(somniaTestnet.id) }],
},
{
id: toHex(somniaTestnet.id), // 50312
token: somniaTestnet.nativeCurrency.symbol,
label: somniaTestnet.name,
rpcUrl: somniaTestnet.rpcUrls.default.http[0],
secondaryTokens: [{ address: getUnrealTokenAddress(somniaTestnet.id) }],
},
🤖 Prompt for AI Agents
In src/lib/onboard.ts around lines 35 to 41, the inline comment "// 8192" next
to the id field is incorrect (somniaTestnet.id is 50312); remove or update that
comment to either the correct id value or eliminate the misleading inline
comment so the code and comment remain consistent.

Comment on lines 220 to +229
useEffect(() => {
if (!apiLoading && isAuthenticated) {
navigate("/dashboard")
// If user has 0 UNREAL balance, redirect to airdrop instead of dashboard
if (unrealBalanceWei === 0n) {
navigate("/airdrop")
} else {
navigate("/dashboard")
}
}
}, [isAuthenticated, apiLoading, navigate])
}, [isAuthenticated, apiLoading, navigate, unrealBalanceWei])
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Redirect can misroute due to default 0n balance and unloaded token.

unrealBalanceWei defaults to 0n and balance isn’t fetched until a token is selected. Authenticated users may be sent to /airdrop incorrectly. Gate on “balance loaded” and a selectedToken (or delay redirect until fetch completes).

Apply this diff (plus a small type change shown below) to avoid premature redirect:

-  // Redirect to dashboard if already authenticated
+  // Redirect if authenticated and balance state is known
   useEffect(() => {
-    if (!apiLoading && isAuthenticated) {
-      // If user has 0 UNREAL balance, redirect to airdrop instead of dashboard
-      if (unrealBalanceWei === 0n) {
-        navigate("/airdrop")
-      } else {
-        navigate("/dashboard")
-      }
-    }
-  }, [isAuthenticated, apiLoading, navigate, unrealBalanceWei])
+    if (apiLoading || !isAuthenticated) return
+    // require selected token and loaded balance
+    if (selectedToken && unrealBalanceWei !== null && !isLoadingBalance) {
+      navigate(unrealBalanceWei === 0n ? "/airdrop" : "/dashboard")
+    }
+  }, [isAuthenticated, apiLoading, navigate, selectedToken, unrealBalanceWei, isLoadingBalance])

And change the balance state to tri-state:

-  const [unrealBalanceWei, setUnrealBalanceWei] = useState<bigint>(0n)
+  const [unrealBalanceWei, setUnrealBalanceWei] = useState<bigint | null>(null)

Also set it back to null when clearing:

-      setUnrealBalanceWei(0n)
+      setUnrealBalanceWei(null)
📝 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
useEffect(() => {
if (!apiLoading && isAuthenticated) {
navigate("/dashboard")
// If user has 0 UNREAL balance, redirect to airdrop instead of dashboard
if (unrealBalanceWei === 0n) {
navigate("/airdrop")
} else {
navigate("/dashboard")
}
}
}, [isAuthenticated, apiLoading, navigate])
}, [isAuthenticated, apiLoading, navigate, unrealBalanceWei])
// Redirect if authenticated and balance state is known
useEffect(() => {
if (apiLoading || !isAuthenticated) return
// require selected token and loaded balance
if (selectedToken && unrealBalanceWei !== null && !isLoadingBalance) {
navigate(unrealBalanceWei === 0n ? "/airdrop" : "/dashboard")
}
}, [isAuthenticated, apiLoading, navigate, selectedToken, unrealBalanceWei, isLoadingBalance])

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/registration.ts (1)

58-61: Add a changeset to document the registration flow and interface changes.

The RegistrationResult interface change (adding paymentToken?: Address field) is committed but no corresponding changeset exists. Create a .changeset/*.md file describing this modification as a "minor" version bump per your repository's changeset policy.

🧹 Nitpick comments (10)
src/lib/registration.ts (10)

16-18: Avoid logging full systemInfo in production.

systemInfo can be large and may expose config details. Remove or gate behind a debug flag.

-    console.log("systemInfo", systemInfo)
+    if (import.meta.env?.MODE === "development") {
+      console.debug("[Registration] systemInfo fetched")
+    }

36-41: paymentTokens key type may differ (string vs number). Verify and normalize.

If keys are numeric, lookup with chainIdStr will miss. Normalize keys or check both.

-      const chainIdStr = chainId.toString()
-      if (systemInfo.paymentTokens[chainIdStr]) {
-        console.debug(`[Registration] Found token ${systemInfo.paymentTokens[chainIdStr]} for chain ${chainIdStr} in paymentTokens map`)
-        return systemInfo.paymentTokens[chainIdStr] as Address
-      }
+      const key = String(chainId)
+      const tokenFromMap = (systemInfo.paymentTokens as Record<string | number, Address>)[key]
+      if (tokenFromMap) {
+        console.debug(`[Registration] Found token ${tokenFromMap} for chain ${key} in paymentTokens map`)
+        return tokenFromMap as Address
+      }

58-61: Public type shape changed → add a Changeset.

RegistrationResult now requires token. Add a Changeset (likely minor) per repo policy.

I can draft the .changeset entry if you confirm the release impact.


80-81: Gate noisy logs.

Replace console.log with debug behind env flag.

-  console.log("Payment Token", paymentToken)
+  if (import.meta.env?.MODE === "development") {
+    console.debug("[Registration] Payment token:", paymentToken)
+  }

112-113: Reuse EXPIRY_SECONDS; avoid magic number duplication.

-      const deadline = Math.floor(Date.now() / 1000) + 3600 // 1 hour
+      const deadline = Math.floor(Date.now() / 1000) + EXPIRY_SECONDS

123-141: Allowance check should be debug‑only to avoid extra RPC in prod.

It’s for logging only; gate behind a debug flag to reduce latency.

-      // Still perform the allowance check for logging purposes
-      try {
+      // Debug-only allowance check
+      if (import.meta.env?.MODE === "development") try {
         const currentAllowance = await walletService.checkAllowance(
           paymentToken,
           walletAddr,
           openaiAddr // paymaster address
         )
@@
-      } catch (allowanceErr) {
+      } catch (allowanceErr) {
         console.warn("Failed to check allowance (non-critical):", allowanceErr)
         // Continue with the permit we already created
       }

143-145: Safer error coercion for unknown errors.

Avoid accessing err.message on non-Error values.

-      throw new Error(`Failed to create permit for token approval: ${err.message || String(err)}`)
+      const msg = err instanceof Error ? err.message : String(err)
+      throw new Error(`Failed to create permit for token approval: ${msg}`)

71-161: Add tests for token resolution and permit flow.

  • getPaymentTokenForCurrentChain: chains match, paymentTokens map, default fallback, and no-token case.
  • performRegistration: calls>0 creates permit; calls=0 skips; error path when permit creation fails; return includes token and optional paymentToken.

I can scaffold vitest specs with walletService/apiClient mocks.


72-75: Consider renaming openaiAddr to paymasterAddr for clarity.

Improves readability across codebase.


150-156: Type the registerResponse for stronger guarantees.

Add a return type/interface for apiClient.register to ensure token is present.

-  const registerResponse = await apiClient.register({
+  const registerResponse: { token: string } = await apiClient.register({
     payload,
     signature,
     address: walletAddr,
     ...(permit && permitSignature ? { permit, permitSignature } : {}),
   })
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59e708d and 85063c0.

📒 Files selected for processing (1)
  • src/lib/registration.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/lib/registration.ts (1)
src/lib/api.ts (2)
  • apiClient (663-663)
  • walletService (664-664)
🔇 Additional comments (2)
src/lib/registration.ts (2)

63-70: Always creating a permit changes UX; confirm double-sign flow.

This likely triggers two wallet prompts (permit + payload). Ensure this is intentional and acceptable.


105-118: Code is correct for its stated design; review comment assumes non-existent infrastructure.

The review comment identifies a technical concern about decimals, but verification shows this is by design:

  1. SystemInfo API responses only provide token addresses without decimals metadata
  2. All UNREAL tokens across configured chains are hardcoded to 18 decimals
  3. The system explicitly uses a "1:1 token pricing model" per design documentation
  4. No getTokenDecimals() or getRequiredAmountForCalls() methods exist—the infrastructure suggested by the review is not available

The code correctly implements the intended 1:1 pricing with 18-decimal tokens. However, this assumption lacks explicit documentation in the code, making it vulnerable if future tokens with different decimals are added. The current implementation is not broken.

Comment on lines +26 to +31
const matchingChain = systemInfo.chains.find(chain => chain.id === chainIdStr)

// If we found a matching chain, use its token address
if (matchingChain && matchingChain.token) {
console.debug(`[Registration] Found token ${matchingChain.token} for chain ${chainIdStr}`)
return matchingChain.token as Address
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Normalize chainId comparison to avoid type mismatches.

If systemInfo.chains[].id is a number, strict equality to a string fails. Coerce both sides.

-      const matchingChain = systemInfo.chains.find(chain => chain.id === chainIdStr)
+      const matchingChain = systemInfo.chains.find(({ id }) => String(id) === chainIdStr)
📝 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
const matchingChain = systemInfo.chains.find(chain => chain.id === chainIdStr)
// If we found a matching chain, use its token address
if (matchingChain && matchingChain.token) {
console.debug(`[Registration] Found token ${matchingChain.token} for chain ${chainIdStr}`)
return matchingChain.token as Address
const matchingChain = systemInfo.chains.find(({ id }) => String(id) === chainIdStr)
// If we found a matching chain, use its token address
if (matchingChain && matchingChain.token) {
console.debug(`[Registration] Found token ${matchingChain.token} for chain ${chainIdStr}`)
return matchingChain.token as Address
🤖 Prompt for AI Agents
In src/lib/registration.ts around lines 26 to 31, the strict equality comparison
between systemInfo.chains[].id and chainIdStr can fail if one is a number and
the other a string; normalize types before comparing by coercing both sides
(e.g., convert chain.id to String() or parseInt(chainIdStr) and use ===) and
ensure you handle null/undefined ids safely so the matchingChain lookup reliably
finds numeric or string ids.

Comment on lines +119 to +123
permit = permitResult.permit
permitSignature = permitResult.signature
console.debug("[Registration] Permit created:", permitResult)

console.debug("[Registration] Allowance check:", {
paymentToken,
owner: walletAddr,
spender: openaiAddr,
requiredAmount: requiredAmount.toString(),
currentAllowance: currentAllowance.toString(),
needsPermit: currentAllowance < requiredAmount,
})

// Only create permit if allowance is insufficient
if (currentAllowance < requiredAmount) {
console.debug(
"[Registration] Insufficient allowance, creating permit signature"
)
const deadline = Math.floor(Date.now() / 1000) + 3600 // 1 hour
const permitResult = await walletService.createPermitSignature(
// Still perform the allowance check for logging purposes
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Don’t log permit payload/signature.

permitResult likely includes signature (r,s,v). Logging it is sensitive and can be abused. Log only non-sensitive metadata.

-      console.debug("[Registration] Permit created:", permitResult)
+      console.debug("[Registration] Permit created", {
+        amount: requiredAmount.toString(),
+        deadline
+      })
🤖 Prompt for AI Agents
In src/lib/registration.ts around lines 119 to 123 the code logs permitResult
which contains sensitive fields (permit payload and signature). Replace that
console.debug call so it does not emit the signature or full permit: either
remove the log or log only non-sensitive metadata (e.g., allowance amount,
expiry, token/owner addresses) or a redacted summary (e.g., { allowed: true,
expiry: permitResult.expiry, token: permitResult.token }). Ensure the signature
and raw permit payload are never included in logs.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/lib/onboard.ts (1)

36-36: Fix incorrect comment for somniaTestnet id.

The inline comment "// 8192" doesn't match somniaTestnet.id (50312). This was already flagged in a previous review.

🧹 Nitpick comments (1)
.env.example (1)

1-2: Optional: Consider alphabetical ordering of environment variables.

The static analysis tool suggests ordering VITE_DOCS_URL before VITE_OPENAI_URL for consistency. While this is a minor style preference, alphabetical ordering can improve maintainability.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 85063c0 and 4d3491a.

📒 Files selected for processing (7)
  • .env.example (2 hunks)
  • index.html (1 hunks)
  • src/components/MarketingContent.tsx (2 hunks)
  • src/config/unreal.ts (1 hunks)
  • src/lib/onboard.ts (2 hunks)
  • src/pages/Index.tsx (3 hunks)
  • tests/dash.test.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • index.html
🧰 Additional context used
🧬 Code graph analysis (1)
src/lib/onboard.ts (2)
src/config/wallet.ts (1)
  • somniaTestnet (166-209)
utils/web3/chains.ts (1)
  • getUnrealTokenAddress (136-148)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 2-2: [UnorderedKey] The VITE_DOCS_URL key should go before the VITE_OPENAI_URL key

(UnorderedKey)

🪛 Gitleaks (8.28.0)
src/pages/Index.tsx

[high] 118-119: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.

(curl-auth-header)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: E2E Tests
🔇 Additional comments (8)
src/lib/onboard.ts (1)

110-111: LGTM: Trezor configuration updated for domain migration.

The appUrl and email updates to ideomind.org align with the broader domain migration effort described in the PR context.

src/components/MarketingContent.tsx (1)

16-16: LGTM: Domain migration applied consistently.

The API endpoint URLs have been correctly updated from unreal.art to ideomind.org across all code examples (cURL, Python, and JavaScript).

Also applies to: 24-24, 37-37

.env.example (2)

1-2: LGTM: Environment defaults updated for domain migration.

The default values correctly reflect the new ideomind.org domain.


23-24: LGTM: Trezor configuration updated consistently.

Both the app URL and support email have been updated to the new domain.

tests/dash.test.ts (1)

37-37: LGTM: Test expectation updated for domain migration.

The test correctly validates the new docs.ideomind.org domain.

src/config/unreal.ts (2)

9-9: LGTM: Configuration defaults updated for domain migration.

The OPENAI_URL and OPENAI_DOCS_URL defaults correctly point to the new ideomind.org domain.

Also applies to: 12-12


23-31: LGTM: Authorization interceptor implemented correctly.

The request interceptor properly injects the Bearer token from localStorage when available. The nullish coalescing operator ensures headers are initialized before setting the Authorization header.

src/pages/Index.tsx (1)

118-118: LGTM: Code examples updated for domain migration.

All code examples (cURL, Python, JavaScript) now reference the correct https://openai.ideomind.org/v1 endpoint.

Note: The Gitleaks warning about line 118-119 is a false positive—the "Authorization: Bearer your-api-key-here" is placeholder text in documentation, not an actual credential.

Also applies to: 129-129, 142-142

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.

2 participants