Skip to content

Release/1.0 - WIP #242

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

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open

Release/1.0 - WIP #242

wants to merge 31 commits into from

Conversation

robertqin86
Copy link

@robertqin86 robertqin86 commented Apr 10, 2025

This will be the release cut from beta that contains all the latest changes that we want to release to production.

TODO: Add changelog

Summary by CodeRabbit

  • New Features
    • Introduced a secure account deletion flow with confirmation prompts.
    • Added a funding wallet selection interface for smoother transaction management.
    • Enhanced wallet displays with improved feedback and support for optional transaction memos.
    • Upgraded saved prompts with advanced filtering and pagination.
    • Updated the application version to 1.0.0 with new STABLE branding.

robertqin86 and others added 30 commits March 10, 2025 21:49
…error

fix: resolve corepack signature issue (#221)
…e-code-debug

feat: support server side code debugging
…e-code-debug-vscode

feat: add launch.json to enable debug mode on vscode
…-empty-accounts

feat: allow users delete empty accounts
…epage

Feat/add prompt filtering on homepage
…ana and embedded wallets to funding wallets inteface
…nected-wallets

feat: enable privy connected wallets to pay EAP
Copy link

vercel bot commented Apr 10, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
neur-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 10, 2025 4:21pm

Copy link

coderabbitai bot commented Apr 10, 2025

Walkthrough

This pull request introduces multiple configuration updates and new features. It adds entries and files to define the development environment (e.g., .gitignore, .nvmrc, VSCode configurations, Docker settings, and local development instructions). Furthermore, it enhances the application's functionality by implementing new components for account deletion, funding wallet selection, and wallet card displays. Backend changes include the addition of a deleteUser function and improvements in wallet transfer logic. Additional updates include UI tweaks, new hooks for wallet balance management, and expanded constants and environment configurations.

Changes

Files Change Summary
.gitignore, .nvmrc, .vscode/launch.json, .vscode/settings.json, Dockerfile.local, docker-compose.yml, LOCAL_DEV.md, package.json • Configuration updates for development and debugging
• Added .idea ignore, Node version file, VSCode debug configs, disabled format on save, Corepack installation command, updated docker port, local dev instructions, version bump, new scripts and dependencies in package.json
src/app/(user)/account/account-content.tsx, src/app/(user)/account/delete-account-dialog.tsx, src/app/(user)/home/components/select-funding-wallet.tsx, src/app/(user)/home/data/funding-wallets.ts, src/app/(user)/home/home-content.tsx • Enhanced account management and wallet interactions
• Integrated account deletion with new states and a confirmation dialog
• Introduced funding wallet selection component and related data models
• Updated filtering logic and purchase handling in home content
src/app/(user)/saved-prompts/components/filter-dropdown.tsx, src/app/(user)/saved-prompts/page.tsx, src/components/dashboard/app-sidebar.tsx • UI improvements in saved prompts and dashboard
• Added optional displayAtHomePage prop to filter dropdown
• Centralized filter options via import
• Updated sidebar label from "BETA" to "STABLE"
src/components/dashboard/wallet-card-eap.tsx, src/components/dashboard/wallet-card.tsx, src/components/provider-auth.tsx, src/components/transfer-dialog.tsx, src/components/ui/checkbox.tsx • New and modified UI components for wallet display and interactions
• Introduced WalletCardEap for funding wallet info
• Added disableFund property for controlled funding
• Added dynamic provider configuration and a reusable Checkbox component
• Minor formatting changes
src/hooks/use-wallets.ts, src/lib/constants.ts, src/lib/solana/index.ts • Added new helper functions to fetch embedded wallet balances and check for non-empty wallets
• Introduced new constants for filter options, EAP price, Solana cluster configuration, and Phantom wallet select
• Updated Solana lib with enhanced wallet type handling and transfer signature improvements
src/server/actions/ai.ts, src/server/actions/user.ts • Updated SolanaAgentKit configuration with an optional HELIUS_RPC_URL and added support for a memo in transfers
• Added a new asynchronous deleteUser function including necessary validations, transaction management, and error handling

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant AC as AccountContent
    participant DAD as DeleteAccountDialog
    participant S as Server (deleteUser)

    U->>AC: Click "Delete Account"
    AC->>DAD: Show deletion confirmation dialog
    U->>DAD: Confirm deletion action
    DAD->>AC: Trigger delete account process
    AC->>S: Call deleteUser API
    S-->>AC: Return success or error response
    AC->>U: Notify outcome and perform logout on success
Loading

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • slimeonmyhead

Poem

Oh, what a hop in our code today,
Where bugs are chased and glitches stray.
I, a clever rabbit, nibble through each line,
With deletion and wallets now looking so fine.
🐰 Cheers to new features in every array!
Leaping through changes in a joyful display.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/app/(user)/account/account-content.tsx

Oops! Something went wrong! :(

ESLint: 9.18.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

src/app/(user)/account/delete-account-dialog.tsx

Oops! Something went wrong! :(

ESLint: 9.18.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

src/app/(user)/home/home-content.tsx

Oops! Something went wrong! :(

ESLint: 9.18.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.

  • 15 others
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 4

🔭 Outside diff range comments (1)
src/app/(user)/account/account-content.tsx (1)

92-105: 🛠️ Refactor suggestion

Potential one-way logic in balance check.
When hasBalance is false, isEmptyAccount is set to true. However, if the user later acquires a balance, this code does not unset isEmptyAccount. Consider updating to:

- if (!hasBalance) {
-   setIsEmptyAccount(true);
- }
+ setIsEmptyAccount(!hasBalance);

to ensure the flag remains correct as wallet balances change.

🧹 Nitpick comments (11)
src/components/dashboard/app-sidebar.tsx (1)

37-40: Potential Logic Mismatch in Beta Status Display.
The sidebar header now displays "STABLE" when IS_BETA is truthy. Typically, one might expect a beta indicator (e.g., "BETA") when the app is in beta mode. If this change is a deliberate part of the release branding, consider adding an inline comment to clarify the intent and avoid confusion.

docker-compose.yml (1)

63-63: Port mapping change is appropriately documented.

Changing the host port from 5432 to 5433 is a good practice to avoid conflicts with local PostgreSQL instances. The comment clearly explains the rationale.

However, there's a trailing space at the end of the comment line that should be removed:

-      - "5433:5432" # Map container port to a different host port to prevent conflicts with local postgres instance 
+      - "5433:5432" # Map container port to a different host port to prevent conflicts with local postgres instance
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 63-63: trailing spaces

(trailing-spaces)

local_app_dev.sh (1)

1-12: New development script properly configures the PostgreSQL connection.

The script correctly sets up environment variables for the database connection using port 5433, which is consistent with the docker-compose.yml change. The default credentials are provided but can be overridden through the .env file, which is good for developer flexibility.

Consider adding basic error handling and file permission instructions:

 #!/bin/bash

+# Ensure PostgreSQL is running before starting the application
+if ! nc -z localhost 5433 &>/dev/null; then
+  echo "Warning: PostgreSQL doesn't appear to be running on port 5433"
+  echo "Make sure to start Docker containers with: docker-compose up -d"
+fi
+
 # change the default POSTGRES_USER and POSTGRES_PASSWORD 
 # to the actual value defined in your .env
 export POSTGRES_USER=${POSTGRES_USER:-"admin"}
 export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-"admin"}

 DB_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5433/neurdb"
 export DATABASE_URL=$DB_URL
 export DIRECT_URL=$DB_URL

+# Ensure the dev:local script exists
+if ! pnpm run --list | grep -q "dev:local"; then
+  echo "Error: dev:local script not found in package.json"
+  exit 1
+fi
+
 pnpm run dev:local

Don't forget to make the script executable with:

chmod +x local_app_dev.sh
LOCAL_DEV.md (1)

93-110: Add language specifiers to the code blocks.

The markdown fenced code blocks are missing language specifiers, which affects syntax highlighting and is flagged by markdownlint.

-```
+```bash
chmod u+x local_app_dev.sh

- +bash
./local_app_dev.sh

The debugging instructions are otherwise clear and helpful for developers who need to debug server-side code.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

97-97: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)


103-103: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

src/lib/constants.ts (1)

39-39: Consider adding documentation for EAP_PRICE.

While the constant is straightforward, adding a comment explaining what EAP stands for (Early Access Program) and the purpose of this constant would improve code clarity.

-export const EAP_PRICE = 1.0;
+/** Price in SOL for Early Access Program participation */
+export const EAP_PRICE = 1.0;
src/app/(user)/account/delete-account-dialog.tsx (2)

16-21: Fix typo in interface property name.

There's a spelling error in the property name "eligibililty" (extra 'l').

interface DeletePromptDialogProps {
  displayPrompt: boolean;
- eligibililty: boolean;
+ eligibility: boolean;
  onConfirm: () => void;
  onCancel: () => void;
}

23-28: Fix typo in component prop name.

Ensure the prop name is corrected in the component parameter destructuring as well.

export const DeleteAccountDialog = ({
  displayPrompt,
- eligibililty,
+ eligibility,
  onCancel,
  onConfirm,
}: DeletePromptDialogProps) => {
src/hooks/use-wallets.ts (1)

10-27: Consider adding error logging.
Inside the catch block at lines 24-26, you return undefined without logging the error. Logging could help with troubleshooting.

   } catch (error) {
+    console.error("Failed to retrieve embedded wallet balance:", error);
     return undefined;
   }
src/components/dashboard/wallet-card-eap.tsx (1)

1-171: Overall functionality looks solid.
The wallet card’s logic for funding and paying EAP is well structured. Consider removing or clarifying the commented-out code at line 72 if it’s no longer needed.

src/lib/solana/index.ts (1)

132-132: Avoid using this inside static methods.
Using this in a static context can be confusing. Prefer referencing the class name (SolanaUtils) directly for clarity.

- if (this.isConnectedSolanaWallet(wallet)) {
+ if (SolanaUtils.isConnectedSolanaWallet(wallet)) {

- const balance = await this.connection.getBalance(fromPubkey);
+ const balance = await SolanaUtils.connection.getBalance(fromPubkey);

- const { blockhash } = await this.connection.getLatestBlockhash('confirmed');
+ const { blockhash } = await SolanaUtils.connection.getLatestBlockhash('confirmed');

- const signature = await this.connection.sendRawTransaction(signedTransaction.serialize(), ...);
+ const signature = await SolanaUtils.connection.sendRawTransaction(signedTransaction.serialize(), ...);

- const balance = await this.connection.getBalance(fromPubkey);
+ const balance = await SolanaUtils.connection.getBalance(fromPubkey);

Also applies to: 145-145, 177-177, 185-185, 223-223

🧰 Tools
🪛 Biome (1.9.4)

[error] 132-132: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

src/app/(user)/account/account-content.tsx (1)

316-327: Avatar and user info rendering.
Displays user’s Twitter profile picture if available; fallback logic is correct. Optional: include an alt attribute for accessibility on the AvatarImage.

<AvatarImage
  src={userData.twitter?.profilePictureUrl || undefined}
+ alt="User avatar"
  className="rounded-lg object-cover"
/>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b9dfba and 4b95518.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (27)
  • .gitignore (1 hunks)
  • .nvmrc (1 hunks)
  • .vscode/launch.json (1 hunks)
  • .vscode/settings.json (1 hunks)
  • Dockerfile.local (1 hunks)
  • LOCAL_DEV.md (2 hunks)
  • docker-compose.yml (1 hunks)
  • local_app_dev.sh (1 hunks)
  • package.json (3 hunks)
  • src/app/(user)/account/account-content.tsx (11 hunks)
  • src/app/(user)/account/delete-account-dialog.tsx (1 hunks)
  • src/app/(user)/home/components/select-funding-wallet.tsx (1 hunks)
  • src/app/(user)/home/data/funding-wallets.ts (1 hunks)
  • src/app/(user)/home/home-content.tsx (10 hunks)
  • src/app/(user)/saved-prompts/components/filter-dropdown.tsx (3 hunks)
  • src/app/(user)/saved-prompts/page.tsx (2 hunks)
  • src/components/dashboard/app-sidebar.tsx (1 hunks)
  • src/components/dashboard/wallet-card-eap.tsx (1 hunks)
  • src/components/dashboard/wallet-card.tsx (4 hunks)
  • src/components/provider-auth.tsx (2 hunks)
  • src/components/transfer-dialog.tsx (1 hunks)
  • src/components/ui/checkbox.tsx (1 hunks)
  • src/hooks/use-wallets.ts (2 hunks)
  • src/lib/constants.ts (2 hunks)
  • src/lib/solana/index.ts (5 hunks)
  • src/server/actions/ai.ts (3 hunks)
  • src/server/actions/user.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (10)
src/components/dashboard/wallet-card.tsx (2)
src/types/db.ts (1)
  • EmbeddedWallet (12-22)
src/lib/constants.ts (1)
  • solanaCluster (43-45)
src/app/(user)/home/components/select-funding-wallet.tsx (8)
src/types/db.ts (1)
  • EmbeddedWallet (12-22)
src/app/(user)/home/data/funding-wallets.ts (3)
  • FundingWallet (7-12)
  • SolanaConnectedFundingWallet (31-41)
  • EmbeddedFundingWallet (17-29)
src/hooks/use-wallets.ts (1)
  • useEmbeddedWallets (29-39)
src/hooks/use-user.ts (1)
  • useUser (122-230)
src/components/ui/dialog.tsx (5)
  • Dialog (113-113)
  • DialogContent (118-118)
  • DialogHeader (119-119)
  • DialogTitle (121-121)
  • DialogDescription (122-122)
src/lib/utils.ts (1)
  • cn (17-19)
src/components/dashboard/wallet-card-eap.tsx (1)
  • WalletCardEap (29-171)
src/lib/constants.ts (1)
  • solanaCluster (43-45)
src/app/(user)/home/data/funding-wallets.ts (3)
src/types/helius/fungibleToken.ts (1)
  • FungibleToken (8-23)
src/types/helius/nonFungibleToken.ts (1)
  • NonFungibleToken (5-20)
src/types/db.ts (1)
  • EmbeddedWallet (12-22)
src/app/(user)/account/delete-account-dialog.tsx (4)
src/components/ui/dialog.tsx (5)
  • Dialog (113-113)
  • DialogContent (118-118)
  • DialogHeader (119-119)
  • DialogTitle (121-121)
  • DialogFooter (120-120)
src/components/ui/checkbox.tsx (1)
  • Checkbox (39-39)
src/components/ui/label.tsx (1)
  • Label (27-27)
src/components/ui/button.tsx (1)
  • Button (58-58)
src/components/provider-auth.tsx (1)
src/lib/constants.ts (2)
  • solanaCluster (43-45)
  • RPC_URL (9-11)
src/hooks/use-wallets.ts (3)
src/types/db.ts (1)
  • EmbeddedWallet (12-22)
src/lib/solana/helius.ts (1)
  • searchWalletAssets (97-270)
src/types/helius/portfolio.ts (1)
  • SOL_MINT (4-4)
src/components/ui/checkbox.tsx (1)
src/lib/utils.ts (1)
  • cn (17-19)
src/app/(user)/account/account-content.tsx (3)
src/hooks/use-wallets.ts (1)
  • hasWalletWithBalance (41-46)
src/app/(user)/account/delete-account-dialog.tsx (1)
  • DeleteAccountDialog (23-109)
src/server/actions/user.ts (1)
  • deleteUser (319-363)
src/lib/constants.ts (1)
src/app/(user)/saved-prompts/types/prompt.ts (1)
  • FilterOption (1-4)
src/components/dashboard/wallet-card-eap.tsx (7)
src/app/(user)/home/data/funding-wallets.ts (1)
  • FundingWallet (7-12)
src/lib/solana/helius.ts (1)
  • searchWalletAssets (97-270)
src/types/helius/portfolio.ts (1)
  • SOL_MINT (4-4)
src/components/ui/copyable-text.tsx (1)
  • CopyableText (17-68)
src/components/ui/skeleton.tsx (1)
  • Skeleton (15-15)
src/lib/constants.ts (1)
  • EAP_PRICE (39-39)
src/components/ui/button.tsx (1)
  • Button (58-58)
🪛 markdownlint-cli2 (0.17.2)
LOCAL_DEV.md

97-97: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)


103-103: Fenced code blocks should have a language specified
null

(MD040, fenced-code-language)

🪛 Biome (1.9.4)
src/lib/solana/index.ts

[error] 132-132: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 145-145: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 177-177: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 185-185: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 223-223: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

🪛 YAMLlint (1.35.1)
docker-compose.yml

[error] 63-63: trailing spaces

(trailing-spaces)

🔇 Additional comments (68)
.nvmrc (1)

1-1: Node.js Version Specification Looks Good.
The file correctly specifies the Node.js version as v20.18.1, which should help maintain consistent development environments.

.gitignore (1)

45-46: Appropriate Addition of .idea to Ignore List.
Including .idea ensures that JetBrains IDE configuration files are not committed. This is a good practice for keeping the repository clean.

src/components/transfer-dialog.tsx (1)

68-68: Improved Readability with Blank Line Addition.
The insertion of a blank line after the transactionResult state declaration enhances readability without affecting functionality.

.vscode/settings.json (1)

3-3: Review the Editor Formatting Setting Change.
Changing "editor.formatOnSave" from true to false disables automatic formatting on save. Please confirm that this change is intentional and aligns with the team’s coding standards or formatting workflow.

Dockerfile.local (1)

4-7: Good addition to prevent Corepack signature issues.

Adding the latest Corepack installation step ensures the application will use the correct package manager without encountering outdated signature issues. The comment with the reference documentation link provides helpful context for this change.

src/app/(user)/saved-prompts/components/filter-dropdown.tsx (4)

24-30: Well-typed props extension for increased component reusability.

Adding the optional displayAtHomePage property enhances the component's flexibility to be used in different contexts.


32-38: Good default value provided for new optional prop.

Setting a sensible default value for displayAtHomePage ensures the component maintains its original behavior when the prop isn't explicitly provided.


45-54: Responsive styling based on display context.

The conditional Button variant and className changes provide appropriate styling based on the component's context, which improves UX consistency.


59-68: Appropriate icon selection based on component context.

The conditional rendering of different icons (ChevronUp/ChevronDown vs Filter) based on the displayAtHomePage property and open state enhances the UX by providing appropriate visual cues in each context.

src/components/ui/checkbox.tsx (1)

1-39: Well-implemented Checkbox component using Radix UI primitives.

The Checkbox component is well-structured and follows React best practices:

  • Uses forwardRef to properly handle ref forwarding
  • Correctly extends Radix UI's CheckboxPrimitive.Root props
  • Properly handles the checked state and callback
  • Includes displayName for better debugging
  • Uses the cn utility to combine class names

The implementation is clean, accessible, and reusable across the application.

src/components/provider-auth.tsx (2)

4-4: LGTM: Added SolanaCluster type import.

This import is necessary for the type definition used in the solanaCluster constant.


40-40: LGTM: Updated solanaClusters configuration.

Good change to use the environment-specific solanaCluster configuration.

LOCAL_DEV.md (1)

61-61: LGTM: Added clear instructions for Privy configuration.

This comment provides valuable guidance for configuring Privy's server-side access.

src/app/(user)/saved-prompts/page.tsx (2)

12-12: LGTM: Good refactoring to centralize filterOptions.

Moving the filterOptions to a constants file improves maintainability and reusability.


380-380: LGTM: Added truncate class for better UI.

Adding the 'truncate' class ensures that long prompt content is properly truncated with an ellipsis, improving the visual consistency of the UI.

src/server/actions/ai.ts (4)

136-138: Enhancement to utilize custom Helius RPC URL.

Good improvement to conditionally include the HELIUS_RPC_URL in the configuration when available in the environment. This provides more flexibility for different deployment environments.


152-152: Well-structured schema update for memo field.

The addition of the optional memo field to the transferToken schema is properly typed and documented with a clear description.


156-163: Properly updated destructuring for new memo parameter.

The destructuring pattern has been correctly updated to include the new memo property, maintaining alignment with the schema update.


177-177: Appropriate implementation of memo feature.

The memo parameter is now correctly passed to the agent.transfer method, enabling the annotation of token transfers.

.vscode/launch.json (1)

1-34: Well-structured debugging configuration for VS Code.

This configuration provides a comprehensive setup for both server-side and client-side debugging, with a compound configuration for full-stack debugging. The source map path overrides are correctly configured to properly map compiled paths back to the source code.

Key features implemented:

  • Server-side Node.js debugging on port 9230
  • Client-side Chrome debugging pointing to localhost:3001
  • Full-stack debugging setup through the compound configuration
  • Appropriate source map path overrides for turbopack
src/components/dashboard/wallet-card.tsx (4)

27-27: Good practice using centralized constants.

Importing the solanaCluster constant instead of hardcoding cluster values improves maintainability and consistency across the application.


36-36: Enhanced component flexibility with disableFund property.

Adding this property allows better control over the wallet card's funding functionality.


114-114: Improved code maintainability.

Using the solanaCluster constant instead of hardcoding the cluster name makes the code more maintainable and ensures consistency across environments.


200-215: Enhanced user experience with contextual feedback.

Good improvement to add a tooltip explaining why funding might be disabled and updating the Button's disabled state accordingly. This provides users with important context about functionality limitations.

src/server/actions/user.ts (2)

329-345: Good user validation and early access handling.

The implementation correctly checks if the user exists and prevents deletion of accounts with active early access, providing a clear error message directing users to support.


347-353: Proper transaction handling for data integrity.

Using a database transaction to delete both wallets and the user record ensures data consistency is maintained during the deletion process.

src/lib/constants.ts (4)

1-4: Appropriate import additions.

The imports for FilterOption and SolanaCluster are correctly added to support the new constants defined in this file.


17-38: Well-structured filter options.

The filterOptions array is well-typed and properly implements the FilterOption interface from the imported type. The structured approach to defining filter options in constants rather than locally in components improves maintainability.


41-45: Environment-aware Solana cluster configuration.

Good implementation of conditional logic to determine the Solana cluster based on the environment variable. This supports proper development and production environments.


47-47: LGTM: Wallet selection constant.

The constant PHANTOM_WALLET_SELECT is appropriately defined for wallet selection functionality.

package.json (4)

3-3: Major version update indicates significant changes.

Updating to version 1.0.0 signifies a production-ready release, which aligns with the PR objective of preparing for production deployment.


8-8: Enhanced local development setup.

The new dev:local script with debugging options and a different port (3001) allows for better development workflow alongside other services.


31-31: Dependency added for checkbox component.

Addition of @radix-ui/react-checkbox supports the new checkbox functionality used in the account deletion dialog.


79-79:

❓ Verification inconclusive

Verify the impact of changing the solana-agent-kit dependency.

The source for solana-agent-kit has changed from slimeonmyhead/solana-agent-kit to robertqin86/solana-agent-kit with a different commit hash. This change could potentially affect wallet functionality, including the new account deletion feature.


🏁 Script executed:

#!/bin/bash
# Check for breaking changes between the old and new solana-agent-kit versions

# Clone the old repository (if accessible)
echo "Attempting to clone the old repository version..."
git clone https://github.com/slimeonmyhead/solana-agent-kit.git old-solana-agent-kit 2>/dev/null
cd old-solana-agent-kit 2>/dev/null && git checkout c571e8b59ed7d399a705578af2d58c95f7e9e826 2>/dev/null && cd .. || echo "Could not access old repository"

# Clone the new repository
echo "Cloning the new repository version..."
git clone https://github.com/robertqin86/solana-agent-kit.git new-solana-agent-kit
cd new-solana-agent-kit && git checkout f9ba5bfada0ce60527f2641989de553075e24785 && cd ..

# Check for API differences (if both repos are accessible)
echo "Checking for package.json changes between versions:"
if [ -d "old-solana-agent-kit" ] && [ -d "new-solana-agent-kit" ]; then
  diff -u old-solana-agent-kit/package.json new-solana-agent-kit/package.json || echo "Package differences found"
  
  # Check for exported functions relevant to user deletion
  echo "Checking for user-related functionality changes:"
  grep -r "deleteUser\|user" new-solana-agent-kit/src/ --include="*.ts" -A 5 -B 5
else
  echo "Could only access the new repository. Examining relevant functionality:"
  grep -r "deleteUser\|user" new-solana-agent-kit/src/ --include="*.ts" -A 5 -B 5
fi

Length of output: 100535


Dependency update: New solana-agent-kit version appears API-compatible, though further testing is advisable.

  • The diff in package.json only shows an added "packageManager" field.
  • Searching the new repository confirms that user-related functions (e.g., a deleteUserProfile capability) are present.
  • No overt breaking changes in wallet functionality were detected; however, it is recommended to perform end-to-end testing—especially for the account deletion feature—to ensure all wallet flows remain unaffected.
src/app/(user)/home/data/funding-wallets.ts (4)

1-5: Appropriate imports for wallet functionality.

The imports are correctly set up for the wallet interfaces and classes that follow.


7-16: Well-defined interfaces for funding wallets.

The FundingWallet and WalletPortfolio interfaces provide clear contracts for wallet implementations with appropriate properties and types.


17-29: EmbeddedFundingWallet implementation looks good.

The class properly implements the FundingWallet interface with readonly properties for immutability. The constructor correctly initializes properties from the provided EmbeddedWallet.

Consider initializing the optional walletPortfolio property in the constructor for completeness:

constructor(embeddedWallet: EmbeddedWallet) {
  this.id = embeddedWallet.id;
  this.name = embeddedWallet.name;
  this.publicKey = embeddedWallet.publicKey;
+ this.walletPortfolio = undefined; // Explicitly initialize optional property
}

31-41: SolanaConnectedFundingWallet implementation is correct.

The class properly implements the FundingWallet interface and correctly initializes properties from the ConnectedSolanaWallet. Using the wallet address as the ID makes sense for Solana wallets.

Note that the walletPortfolio property is not declared in this class, though it's optional in the interface. For consistency with EmbeddedFundingWallet, consider adding it:

export class SolanaConnectedFundingWallet implements FundingWallet {
  public readonly id: string;
  public readonly name: string;
  public readonly publicKey: string;
+ public walletPortfolio?: WalletPortfolio;

  constructor(solanaConnectedWallet: ConnectedSolanaWallet) {
    this.id = solanaConnectedWallet.address;
    this.name = solanaConnectedWallet.meta.name;
    this.publicKey = solanaConnectedWallet.address;
  }
}
src/app/(user)/account/delete-account-dialog.tsx (2)

36-77: Well-implemented account deletion confirmation flow.

The component correctly implements a confirmation flow with clear warnings about the irreversible nature of account deletion. The checkbox requirement prevents accidental deletion, and the disabled button until confirmation is a good safety measure.


78-104: Clear messaging for ineligible account deletion.

The alternate UI for ineligible users provides clear explanations about why account deletion isn't possible and offers appropriate next steps through Discord support.

src/hooks/use-wallets.ts (2)

5-8: Imports look good.
No issues detected with these newly added import statements.


41-46: Double-check handling of undefined balances.
If getEmbeddedWalletBalance returns undefined (due to an error), hasWalletWithBalance immediately returns true. Verify if considering an error as a valid “has balance” scenario is intentional or if it should be treated as having zero balance.

src/app/(user)/home/components/select-funding-wallet.tsx (1)

1-177: Great addition for wallet selection dialog.
The integration of embedded and external wallets is well implemented, and there are no apparent issues with the approach or the data flow.

src/app/(user)/account/account-content.tsx (11)

3-3: Additions to React imports look good.
They appear to be used appropriately for transitioning and optimistic updates.


18-18: Unused import from 'lodash'.
Currently, set from 'lodash' is not referenced anywhere. The coding guidelines advise ignoring unused imports unless flagged by tools, so no immediate action is required.


40-40: Importing hasWalletWithBalance and useEmbeddedWallets.
These hooks are utilized to fetch and evaluate wallet data. The usage appears logically consistent.


54-58: Imports for new user actions.
Bringing in deleteUser and updateUser from user.ts aligns with the new account deletion functionality.


61-61: New DeleteAccountDialog import.
This integration looks consistent with the code that triggers the dialog.


68-69: New state variables.
isEmptyAccount and displayPrompt are straightforward booleans used to control account deletion checks and dialog visibility. The naming is clear.


71-77: isDeleting and wallet context setup.
The addition of isDeleting cleanly solves the loading state during account deletion. Fetching embedded wallets via useEmbeddedWallets is also appropriate.


89-89: Adding logout to user context.
This is essential for finalizing account deletion and session cleanup.


209-210: Early return with loading or deleting states.
Displaying <LoadingStateSkeleton /> is consistent with typical UI patterns.


289-310: Account deletion flow.
The dialog’s onConfirm implementation handles the loading state, toast messages, and error handling. This is a solid approach that informs the user about the deletion process.


339-347: 'Delete Account' button placement looks fine.
Button styling is consistent with the destructive action. No issues found.

src/app/(user)/home/home-content.tsx (14)

9-10: New imports from @privy-io/react-auth.
Adding ConnectedSolanaWallet and useConnectWallet is coherent with the wallet connection logic introduced below.


14-14: Adding CheckCircle2, Dot, Loader2 from lucide-react.
Useful for icons, pagination indicators, and loading states.


28-29: filterOptions and EAP_PRICE imports.
Consolidating constants in constants.ts is good practice for maintainable configuration.


44-44: EmbeddedWallet type usage.
Indicates new functionalities around local wallet objects. No issues identified.


46-47: Importing filter components and types.
FilterDropdown and FilterValue enable dynamic prompt filtering. Implementation aligns with the newly introduced filtering logic.


49-49: SelectFundingWalletDialog import.
Prepares a wallet selection dialog to handle purchase or funding flows.


51-51: Funding wallet data import.
Allows specifying which wallet covers transaction fees or purchase amounts.


82-82: New pagination index.
Used to support pagination for saved prompts. Straightforward approach to chunking results.


85-85: Adding filter state.
This complements the FilterDropdown and enables various sorting/filtering strategies on prompts.


94-94: displayPrompt state.
Manages the visibility of the wallet funding or purchase dialog. Matches the user flow.


287-288: handlePurchaseOptions function.
Simplifies user experience by setting displayPrompt to true on purchase flow entry.


291-356: Expanded handlePurchase logic.
Accepts both Wallet and FundingWallet for a flexible Solana transfer. Includes memo usage, error handling, and toast notifications. Overall well-structured, though ensure you have test coverage to confirm transaction reliability.


597-605: SelectFundingWalletDialog integration.
Displays the new prompt for EAP purchases, allowing the user to pick the funding source or connect externally. Behavior appears cohesive with the rest of the purchase flow.


665-665: onClick={handlePurchaseOptions} on EAP button.
Triggers the new purchase dialog. Straightforward and consistent naming.

Comment on lines +10 to +14
const isDev = process.env.NEXT_PUBLIC_DEV === 'true';

const solanaCluster: SolanaCluster = isDev
? { name: 'devnet', rpcUrl: process.env.NEXT_PUBLIC_HELIUS_RPC_URL! }
: { name: 'mainnet-beta', rpcUrl: RPC_URL };
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding a fallback for the RPC URL in development mode.

The non-null assertion operator (!) on line 13 assumes that process.env.NEXT_PUBLIC_HELIUS_RPC_URL will always be defined in development mode. This could lead to runtime errors if the environment variable is missing.

const solanaCluster: SolanaCluster = isDev
-  ? { name: 'devnet', rpcUrl: process.env.NEXT_PUBLIC_HELIUS_RPC_URL! }
+  ? { name: 'devnet', rpcUrl: process.env.NEXT_PUBLIC_HELIUS_RPC_URL || 'https://api.devnet.solana.com' }
  : { name: 'mainnet-beta', rpcUrl: RPC_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
const isDev = process.env.NEXT_PUBLIC_DEV === 'true';
const solanaCluster: SolanaCluster = isDev
? { name: 'devnet', rpcUrl: process.env.NEXT_PUBLIC_HELIUS_RPC_URL! }
: { name: 'mainnet-beta', rpcUrl: RPC_URL };
const isDev = process.env.NEXT_PUBLIC_DEV === 'true';
const solanaCluster: SolanaCluster = isDev
? { name: 'devnet', rpcUrl: process.env.NEXT_PUBLIC_HELIUS_RPC_URL || 'https://api.devnet.solana.com' }
: { name: 'mainnet-beta', rpcUrl: RPC_URL };

Comment on lines +319 to +363
export async function deleteUser() {
try {
const authResult = await verifyUser();
const userId = authResult?.data?.data?.id;
const privyId = authResult?.data?.data?.privyId;

if (!userId) {
return { success: false, error: 'UNAUTHORIZED' };
}

// check eap status is active
const user = await prisma.user.findUnique({
where: { id: userId },
});

if (!user) {
return { success: false, error: 'User not found' };
}

const { earlyAccess } = user;
if (earlyAccess) {
return {
success: false,
error:
'Cannot delete user with active early access. Please reach out to support at our official discord channel.',
};
}

const deleteUser = prisma.user.delete({ where: { id: userId } });
const deleteWallets = prisma.wallet.deleteMany({
where: { ownerId: userId },
});

await prisma.$transaction([deleteWallets, deleteUser]);
if (privyId) {
await PRIVY_SERVER_CLIENT.deleteUser(privyId);
}
return {
success: true,
};
} catch (error) {
console.error('Error updating user:', error);
return { success: false, error: 'Failed to delete user' };
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

User deletion functionality properly implemented.

The function provides a comprehensive approach to user deletion, including validation, early access checking, and proper transaction handling for data integrity.

Two improvements to consider:

  1. The error message in the catch block refers to "Error updating user:" but should say "Error deleting user:" to match the actual operation:
-    console.error('Error updating user:', error);
+    console.error('Error deleting user:', error);
  1. Consider enhancing error handling for the Privy client deletion:
     await prisma.$transaction([deleteWallets, deleteUser]);
     if (privyId) {
-      await PRIVY_SERVER_CLIENT.deleteUser(privyId);
+      try {
+        await PRIVY_SERVER_CLIENT.deleteUser(privyId);
+      } catch (privyError) {
+        console.error('Error deleting user from Privy:', privyError);
+        // User is already deleted from our DB, so still return success
+        // but log the error for monitoring
+      }
     }
📝 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
export async function deleteUser() {
try {
const authResult = await verifyUser();
const userId = authResult?.data?.data?.id;
const privyId = authResult?.data?.data?.privyId;
if (!userId) {
return { success: false, error: 'UNAUTHORIZED' };
}
// check eap status is active
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
return { success: false, error: 'User not found' };
}
const { earlyAccess } = user;
if (earlyAccess) {
return {
success: false,
error:
'Cannot delete user with active early access. Please reach out to support at our official discord channel.',
};
}
const deleteUser = prisma.user.delete({ where: { id: userId } });
const deleteWallets = prisma.wallet.deleteMany({
where: { ownerId: userId },
});
await prisma.$transaction([deleteWallets, deleteUser]);
if (privyId) {
await PRIVY_SERVER_CLIENT.deleteUser(privyId);
}
return {
success: true,
};
} catch (error) {
console.error('Error updating user:', error);
return { success: false, error: 'Failed to delete user' };
}
}
export async function deleteUser() {
try {
const authResult = await verifyUser();
const userId = authResult?.data?.data?.id;
const privyId = authResult?.data?.data?.privyId;
if (!userId) {
return { success: false, error: 'UNAUTHORIZED' };
}
// check eap status is active
const user = await prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
return { success: false, error: 'User not found' };
}
const { earlyAccess } = user;
if (earlyAccess) {
return {
success: false,
error:
'Cannot delete user with active early access. Please reach out to support at our official discord channel.',
};
}
const deleteUser = prisma.user.delete({ where: { id: userId } });
const deleteWallets = prisma.wallet.deleteMany({
where: { ownerId: userId },
});
await prisma.$transaction([deleteWallets, deleteUser]);
if (privyId) {
try {
await PRIVY_SERVER_CLIENT.deleteUser(privyId);
} catch (privyError) {
console.error('Error deleting user from Privy:', privyError);
// User is already deleted from our DB, so still return success
// but log the error for monitoring
}
}
return {
success: true,
};
} catch (error) {
console.error('Error deleting user:', error);
return { success: false, error: 'Failed to delete user' };
}
}

Comment on lines +353 to +359
if (privyId) {
await PRIVY_SERVER_CLIENT.deleteUser(privyId);
}
return {
success: true,
};
} catch (error) {
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider resilience for external service failure.

The current implementation doesn't handle the case where the database deletion succeeds but Privy deletion fails. This could lead to inconsistency between your systems.

Run this script to check if there are any additional user-related records that should be included in the deletion transaction:


🏁 Script executed:

#!/bin/bash
# Check for other tables with foreign keys to the user table
grep -r "ownerId\|userId\|user_id\|owner_id" --include="*.prisma" .

Length of output: 1326


Ensure Consistent and Resilient User Deletion

  • The current deletion logic in src/server/actions/user.ts only attempts to delete the user from the external Privy service (via PRIVY_SERVER_CLIENT.deleteUser(privyId)) without a fallback if that call fails.
  • Our Prisma schema reveals several associations referencing the user (via userId, ownerId, etc.), which means that if the external deletion fails while the database deletion succeeds, the system may become inconsistent.
  • Consider refactoring the deletion flow to handle external service failures gracefully. Options might include:
    • Reordering operations (e.g., performing the external deletion first and only committing the internal deletion upon success).
    • Implementing a rollback or compensatory mechanism in the event of an external deletion failure.
    • Adding robust error handling and logging to manage and possibly retry the external deletion.

Comment on lines +54 to +66
<div className="flex items-center gap-2">
<Checkbox
id="ack-checkbox"
onCheckedChange={(checked) => setAckChecked(checked)}
/>
<Label
htmlFor="ack-checkbox"
className="cursor-pointer text-sm leading-snug"
>
I confirm that my wallets are empty and I understand this action
is irreversible.
</Label>
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Reset checkbox state when dialog closes.

Currently, if a user opens the dialog, checks the box, then cancels and reopens the dialog, the checkbox state persists. Consider resetting it when the dialog closes for better security.

export const DeleteAccountDialog = ({
  displayPrompt,
  eligibililty,
  onCancel,
  onConfirm,
}: DeletePromptDialogProps) => {
  const [ackChecked, setAckChecked] = useState(false);
+ 
+ // Reset checkbox when dialog closes
+ const handleOpenChange = (open: boolean) => {
+   if (!open) {
+     setAckChecked(false);
+     onCancel();
+   }
+ };
  
  return (
-   <Dialog onOpenChange={onCancel} open={displayPrompt}>
+   <Dialog onOpenChange={handleOpenChange} open={displayPrompt}>
📝 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
<div className="flex items-center gap-2">
<Checkbox
id="ack-checkbox"
onCheckedChange={(checked) => setAckChecked(checked)}
/>
<Label
htmlFor="ack-checkbox"
className="cursor-pointer text-sm leading-snug"
>
I confirm that my wallets are empty and I understand this action
is irreversible.
</Label>
</div>
export const DeleteAccountDialog = ({
displayPrompt,
eligibililty,
onCancel,
onConfirm,
}: DeletePromptDialogProps) => {
const [ackChecked, setAckChecked] = useState(false);
// Reset checkbox when dialog closes
const handleOpenChange = (open: boolean) => {
if (!open) {
setAckChecked(false);
onCancel();
}
};
return (
<Dialog onOpenChange={handleOpenChange} open={displayPrompt}>
<div className="flex items-center gap-2">
<Checkbox
id="ack-checkbox"
onCheckedChange={(checked) => setAckChecked(checked)}
/>
<Label
htmlFor="ack-checkbox"
className="cursor-pointer text-sm leading-snug"
>
I confirm that my wallets are empty and I understand this action
is irreversible.
</Label>
</div>
</Dialog>
);
};

@briang123
Copy link
Contributor

Until subscriptions are rolled out and we're out of EAP, I think the version should still be < 1.0 (ie. 0.3.5)

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.

3 participants