-
Notifications
You must be signed in to change notification settings - Fork 619
Dashboard: Fix token not added to UB on launch success #7931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dashboard: Fix token not added to UB on launch success #7931
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
WalkthroughReplaces direct Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as LaunchToken UI
participant Steps as executeSteps
participant Deploy as Contract Deployer
User->>UI: Initiate Launch
UI->>Steps: start()
Steps->>Deploy: deploy ERC20/DropERC20
Deploy-->>Steps: deployed(address)
Steps->>UI: setContractAddress(address)
note right of UI #D3E4CD: Memoized setter updates state and ref
UI->>UI: _setContractAddress(address)
UI->>UI: contractAddressRef.current = address
Steps-->>UI: onLaunchSuccess()
UI->>UI: use contractAddressRef.current for payload
note over UI: Rendering (contract link) continues to read state
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (2)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7931 +/- ##
=======================================
Coverage 56.53% 56.53%
=======================================
Files 904 904
Lines 58592 58592
Branches 4143 4143
=======================================
Hits 33126 33126
Misses 25360 25360
Partials 106 106
🚀 New features to boost your workflow:
|
There was a problem hiding this 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
🧹 Nitpick comments (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx (1)
71-81: Solid stale-closure fix; add a clear helper to reset between runs.Syncing state+ref via a memoized setter correctly avoids stale captures inside
executeSteps. To prevent accidental reuse of a previous address across sessions (e.g., cancel → relaunch), add a tiny clear helper.Apply within this block:
const [contractAddress, _setContractAddress] = useState<string | null>(null); // needed to add a ref to avoid `executeSteps` using the stale value of state `contractAddress` because of closure const contractAddressRef = useRef<string | null>(null); const setContractAddress = useCallback((address: string) => { _setContractAddress(address); contractAddressRef.current = address; }, []); + + const clearContractAddress = useCallback(() => { + _setContractAddress(null); + contractAddressRef.current = null; + }, []);Then, on modal close and at the start of a new launch, call
clearContractAddress():// on modal close handler (current block around lines 454-463) onClick={() => { setIsModalOpen(false); setSteps([]); clearContractAddress(); }} // at the top of handleSubmitClick(), before setting initial steps clearContractAddress();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from@/components/ui/*(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
UseNavLinkfor internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()from@/lib/utilsfor conditional class logic
Use design system tokens (e.g.,bg-card,border-border,text-muted-foreground)
Server Components (Node edge): Start files withimport "server-only";
Client Components (browser): Begin files with'use client';
Always callgetAuthToken()to retrieve JWT from cookies on server side
UseAuthorization: Bearerheader – never embed tokens in URLs
Return typed results (e.g.,Project[],User[]) – avoidany
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stablequeryKeysfor React Query cache hits
ConfigurestaleTime/cacheTimein React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never importposthog-jsin server components
Files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
🧠 Learnings (4)
📚 Learning: 2025-06-10T00:50:20.795Z
Learnt from: MananTank
PR: thirdweb-dev/js#7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx:153-226
Timestamp: 2025-06-10T00:50:20.795Z
Learning: In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx, the updateStatus function correctly expects a complete MultiStepState["status"] object. For pending states, { type: "pending" } is the entire status object. For error states, { type: "error", message: React.ReactNode } is the entire status object. The current code incorrectly spreads the entire step object instead of passing just the status object.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
📚 Learning: 2025-07-07T21:21:47.488Z
Learnt from: saminacodes
PR: thirdweb-dev/js#7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.
Applied to files:
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx
⏰ 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). (3)
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx (2)
8-8: Hook imports look good.
useCallback,useRef, anduseStateare all used below; import change is correct for a client component.
253-257: Correctly read latest address via ref in onLaunchSuccess.Using
contractAddressRef.currentguarantees the freshest value after the async step pipeline and aligns with the PR goal to ensure the token is added on launch success.
size-limit report 📦
|
Merge activity
|
<!--
## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"
If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
## Notes for the reviewer
Anything important to call out? Be sure to also clarify these in your comments.
## How to test
Unit tests, playground, etc.
-->
<!-- start pr-codex -->
---
## PR-Codex overview
This PR focuses on improving the handling of the `contractAddress` state in the `LaunchTokenStatus` component by using a ref to prevent stale closures during function execution.
### Detailed summary
- Added `useCallback` and `useRef` to manage `contractAddress`.
- Renamed the state setter for `contractAddress` to `_setContractAddress`.
- Created a new `setContractAddress` function to update both state and ref.
- Changed the condition to check `contractAddressRef.current` instead of `contractAddress`.
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- Bug Fixes
- Improved reliability of the token launch flow by always using the latest deployed contract address during finalization.
- Prevents rare cases where an outdated address could be referenced after deployment, reducing intermittent errors in success callbacks and post-launch actions.
- Applies to ERC20 and Drop ERC20 deployments.
- No changes to UI or public behavior; users should experience more consistent launches and accurate confirmations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
a4d817f to
7538e8f
Compare
<!--
## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"
If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
## Notes for the reviewer
Anything important to call out? Be sure to also clarify these in your comments.
## How to test
Unit tests, playground, etc.
-->
<!-- start pr-codex -->
---
## PR-Codex overview
This PR focuses on improving the handling of the `contractAddress` state in the `LaunchTokenStatus` component to prevent stale state issues during asynchronous operations.
### Detailed summary
- Added `useCallback` and `useRef` hooks to manage `contractAddress`.
- Renamed the state setter for `contractAddress` to `_setContractAddress`.
- Introduced `contractAddressRef` to store the current value of `contractAddress`.
- Updated logic to use `contractAddressRef.current` instead of `contractAddress` for launching success.
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- Bug Fixes
- Improved reliability of the token launch flow by ensuring the final confirmation always uses the latest deployed contract address.
- Prevents rare cases where an outdated address could be shown or used after deployment, reducing intermittent post-launch errors.
- Applies to ERC20 and Drop ERC20 deployments; no visible UI changes, just more consistent launches and confirmations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
7538e8f to
3226685
Compare
<!--
## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"
If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
## Notes for the reviewer
Anything important to call out? Be sure to also clarify these in your comments.
## How to test
Unit tests, playground, etc.
-->
<!-- start pr-codex -->
---
## PR-Codex overview
This PR focuses on improving the handling of the `contractAddress` state in the `LaunchTokenStatus` component by using a `ref` to avoid stale closures and ensure the latest address is used during execution.
### Detailed summary
- Added `useCallback` and `useRef` imports.
- Replaced the state setter for `contractAddress` with a callback to update a `ref`.
- Updated the condition to check `contractAddressRef.current` instead of `contractAddress` when launching.
> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`
<!-- end pr-codex -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- Bug Fixes
- Improved reliability of the token launch flow so the final confirmation consistently uses the latest deployed contract address.
- Prevents rare cases where an outdated address could be shown or used after deployment, reducing intermittent post-launch errors.
- Fix applies to ERC20 and Drop ERC20 deployments; no visible UI changes, just more consistent launches and confirmations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
3226685 to
3a289e8
Compare

PR-Codex overview
This PR focuses on improving state management for the
contractAddressin theLaunchTokenStatuscomponent by using a ref to avoid stale closures in theexecuteStepsfunction.Detailed summary
useCallbackanduseRefimports.contractAddressRefto hold the current value ofcontractAddress.setContractAddressto update both state and ref.contractAddresstocontractAddressRef.current.Summary by CodeRabbit