Skip to content

feat(solana): deposit command #317

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 33 commits into
base: main
Choose a base branch
from
Open

feat(solana): deposit command #317

wants to merge 33 commits into from

Conversation

fadeev
Copy link
Member

@fadeev fadeev commented May 2, 2025

Deposit SOL

✅ Devnet

yarn zetachain solana deposit \
  --amount 0.001 \
  --recipient 0x4955a3F38ff86ae92A914445099caa8eA2B9bA32 \
  --network devnet \
  --private-key $PRIVATE_KEY

https://zetachain-athens.blockpi.network/lcd/v1/public/zeta-chain/crosschain/inboundHashToCctxData/3Tw2S8HPbFAN7xtMase8oLa23d1f9etacTfhuREbGnccuSHTkREbtM9sB3H2H5pYbEhpWMs74wA3QS5wxhSnGsSM

✅ Localnet

yarn zetachain solana deposit \
  --amount 0.001 \
  --recipient 0x4955a3F38ff86ae92A914445099caa8eA2B9bA32 \
  --network localnet  \
  --mnemonic "grape subway rack mean march bubble carry avoid muffin consider thing street"

Deposit SPL

✅ Devnet

yarn zetachain solana deposit \
  --amount 0.001 \
  --recipient 0x4955a3F38ff86ae92A914445099caa8eA2B9bA32 \
  --network devnet \
  --mint Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr \
  --private-key $PRIVATE_KEY

https://zetachain-athens.blockpi.network/lcd/v1/public/zeta-chain/crosschain/inboundHashToCctxData/5LjZVoeCScPqmVBkPGrY4LWX3ukDE2f8z28vjbEbDwJPtmmUPKG1o6D8T3uc61h78NKisxQyABhYMmnVi2secydr

✅ Localnet

SOLANA
┌─────────────────────────┬────────────────────────────────────────────────┐
│ (index)                 │ Values                                         │
├─────────────────────────┼────────────────────────────────────────────────┤
│ SPL-20 USDC             │ 'GeAXJsYXV5nm6SQMyaRmQ6mj4KDWZfTJ55FyLsb6yeAc' │
│ gatewayProgram          │ '94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d' │
│ gatewayTokenAccountUSDC │ '9EFHsQj3Grc29H3xXMbcdZ3P6osBpgUoLvcJFw8cmZV7' │
│ userTokenAccountUSDC    │ 'E2nTupEqLRkr4d4dJUno87wyu7L9ku7LCKJgHKsojw9v' │
│ tokenProgram            │ 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'  │
└─────────────────────────┴────────────────────────────────────────────────┘

Right now it's a bit confusing, because by default localnet airdrops SPL tokens only to the account defined in ~/.config/solana/id.json, and not to the address associated with the default mnemonic below.

yarn zetachain solana deposit \
  --amount 0.001 \
  --recipient 0x4955a3F38ff86ae92A914445099caa8eA2B9bA32 \
  --mnemonic "grape subway rack mean march bubble carry avoid muffin consider thing street" \
  --network localnet \
  --mint GeAXJsYXV5nm6SQMyaRmQ6mj4KDWZfTJ55FyLsb6yeAc

Summary by CodeRabbit

  • New Features

    • Introduced a CLI command to enable Solana token deposits, supporting both native SOL and SPL tokens, with flexible wallet authentication and network selection.
    • Added validation schema for Solana deposit options to improve input reliability.
    • Exported constants for Solana token program ID and supported networks.
  • Chores

    • Updated Node.js version to 21 in build, lint, and test workflows for improved compatibility.
    • Upgraded a Solana protocol dependency to a newer version.
  • Improvements

    • Enhanced account creation to accept both base58 and hex-encoded private keys, returning keys in base58 format.
    • Updated Solana transaction handling to use development versions of gateway interfaces for improved integration.

Copy link
Contributor

coderabbitai bot commented May 2, 2025

📝 Walkthrough

Walkthrough

The updates include raising the Node.js version from 18 to 21 in all GitHub Actions workflows, upgrading the @zetachain/protocol-contracts-solana dependency, and introducing a new Solana deposit CLI command. Supporting changes add network constants, enhance Solana account creation to accept multiple key formats, and introduce schema validation for deposit options.

Changes

Files/Group Change Summary
.github/workflows/build.yaml
.github/workflows/lint.yaml
.github/workflows/test.yaml
Node.js version updated from 18 to 21 in all GitHub Actions workflows.
package.json Upgraded @zetachain/protocol-contracts-solana dependency from 2.0.0-rc1 to 3.0.2-rc2.
packages/client/src/solanaDeposit.ts
packages/client/src/solanaDepositAndCall.ts
Changed Gateway_IDL import path to development version; explicitly imported and used Connection from @solana/web3.js; cast connection argument in transaction sending logic.
packages/commands/src/solana/deposit.ts Added a new Solana deposit CLI command supporting SOL and SPL token deposits, with wallet derivation from mnemonic or base58 private key and network selection. Exports new helper functions and command.
packages/commands/src/solana/index.ts Registered the new depositCommand as a subcommand of solanaCommand.
utils/accounts.ts Enhanced createSolanaAccount to accept private keys in base58 or hex, returning base58-encoded private keys.
types/shared.constants.ts Added exported constants: SOLANA_TOKEN_PROGRAM and SOLANA_NETWORKS.
utils/solana.commands.helpers.ts New module exporting solanaDepositOptionsSchema using zod for deposit command option validation.
packages/tasks/src/solanaDeposit.ts
packages/tasks/src/solanaDepositAndCall.ts
Consolidated imports by replacing direct Keypair import from @solana/web3.js with web3 from @coral-xyz/anchor; updated Keypair usage accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI (depositCommand)
    participant KeypairHelper
    participant SolanaProvider
    participant GatewayProgram

    User->>CLI (depositCommand): Run deposit command with options
    CLI (depositCommand)->>KeypairHelper: Derive Keypair (from mnemonic or private key)
    KeypairHelper-->>CLI (depositCommand): Return Keypair
    CLI (depositCommand)->>SolanaProvider: Connect to selected network
    SolanaProvider-->>CLI (depositCommand): Return provider
    CLI (depositCommand)->>GatewayProgram: Initialize with IDL and provider
    CLI (depositCommand)->>GatewayProgram: Call deposit/depositSplToken with params
    GatewayProgram-->>CLI (depositCommand): Return transaction hash
    CLI (depositCommand)->>User: Output transaction hash
Loading

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • SPL-20: Entity not found: Issue - Could not find referenced Issue.

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 255aec5 and 58b43da.

📒 Files selected for processing (3)
  • packages/commands/src/solana/deposit.ts (1 hunks)
  • packages/tasks/src/solanaDeposit.ts (2 hunks)
  • packages/tasks/src/solanaDepositAndCall.ts (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/tasks/src/solanaDeposit.ts
  • packages/tasks/src/solanaDepositAndCall.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/commands/src/solana/deposit.ts
✨ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.

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.

@github-actions github-actions bot added the feat label May 2, 2025
@fadeev fadeev linked an issue May 2, 2025 that may be closed by this pull request
@fadeev fadeev marked this pull request as ready for review May 5, 2025 17:14
@fadeev fadeev requested review from a team as code owners May 5, 2025 17:14
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: 5

🧹 Nitpick comments (2)
packages/commands/src/solana/deposit.ts (2)

124-124: Purpose of null parameter is unclear.

Both depositSplToken and deposit methods have a null parameter, but there's no comment explaining what this parameter is for.

Add comments to explain the purpose of this parameter:

- null
+ null // Message parameter - null means no additional message data

Also applies to: 141-141


161-163: Consider adding a default network.

The network option doesn't have a default value, which means it must be explicitly provided. Consider setting a default, such as "devnet" for ease of use.

.addOption(
-  new Option("--network <network>", "Solana network").choices(networks)
+  new Option("--network <network>", "Solana network").choices(networks).default("devnet")
)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5aff2a2 and fc1b6e8.

⛔ Files ignored due to path filters (29)
  • typechain-types/@uniswap/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-core/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-core/contracts/interfaces/callback/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-core/contracts/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-core/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-periphery/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-periphery/contracts/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/@uniswap/v3-periphery/index.ts is excluded by !typechain-types/**
  • typechain-types/contracts/SwapHelpers.sol/SwapLibrary.ts is excluded by !typechain-types/**
  • typechain-types/contracts/SwapHelpers.sol/index.ts is excluded by !typechain-types/**
  • typechain-types/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-core/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-core/contracts/interfaces/callback/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-core/contracts/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-core/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-periphery/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-periphery/contracts/interfaces/ISwapRouter__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-periphery/contracts/interfaces/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/@uniswap/v3-periphery/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/SwapHelpers.sol/SwapLibrary__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/SwapHelpers.sol/index.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/index.ts is excluded by !typechain-types/**
  • typechain-types/hardhat.d.ts is excluded by !typechain-types/**
  • typechain-types/index.ts is excluded by !typechain-types/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • .github/workflows/build.yaml (1 hunks)
  • .github/workflows/lint.yaml (1 hunks)
  • .github/workflows/test.yaml (1 hunks)
  • package.json (2 hunks)
  • packages/client/src/solanaDeposit.ts (1 hunks)
  • packages/client/src/solanaDepositAndCall.ts (1 hunks)
  • packages/commands/src/solana/deposit.ts (1 hunks)
  • packages/commands/src/solana/index.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/commands/src/solana/deposit.ts (1)
packages/tasks/src/account.ts (1)
  • main (121-169)
🔇 Additional comments (14)
package.json (1)

121-121: Dependency bump for @zetachain/protocol-contracts-solana
Updated the Solana protocol-contracts dependency from 2.0.0-rc1 to 3.0.2-rc2. Ensure compatibility with the new Gateway IDL and that the yarn.lock has been updated and committed to avoid version mismatches.

.github/workflows/lint.yaml (1)

18-18: Upgrade Node.js runtime to 21
Aligns the lint workflow environment with build and test pipelines. actions/setup-node@v3 supports Node.js 21 out of the box.

.github/workflows/build.yaml (1)

18-18: Upgrade Node.js runtime to 21
Consistent Node.js version across CI ensures uniform behavior. No additional changes needed.

.github/workflows/test.yaml (1)

18-18: Upgrade Node.js runtime to 21
Brings the test workflow in line with build and lint jobs—good for consistency.

packages/client/src/solanaDeposit.ts (1)

8-8:

✅ Verification successful

Switch to development Gateway IDL path
The import was changed to @zetachain/protocol-contracts-solana/dev/idl/gateway.json. Confirm that this path exists in version 3.0.2-rc2 of the package and that any reference in solanaDepositAndCall.ts matches.

To verify, you can run:


🏁 Script executed:

#!/usr/bin/env bash
# Verify that the development IDL exists in the installed package
if [ ! -f "node_modules/@zetachain/protocol-contracts-solana/dev/idl/gateway.json" ]; then
  echo "ERROR: dev/idl/gateway.json not found in protocol-contracts-solana"
  exit 1
else
  echo "OK: Gateway IDL file found"
fi

Length of output: 150


🏁 Script executed:

#!/usr/bin/env bash
# Verify that solanaDepositAndCall.ts uses the same development IDL path
rg -n 'from\s+".*@zetachain/protocol-contracts-solana/dev/idl/gateway.json"' packages/client/src/solanaDepositAndCall.ts || \
echo "WARNING: No matching import of gateway.json found in solanaDepositAndCall.ts"

Length of output: 209


Development Gateway IDL path verified
The import path @zetachain/protocol-contracts-solana/dev/idl/gateway.json exists in version 3.0.2-rc2 and is consistently used in both files; no changes required.

• packages/client/src/solanaDeposit.ts — line 8
• packages/client/src/solanaDepositAndCall.ts — line 8

packages/client/src/solanaDepositAndCall.ts (1)

8-8: Updated Gateway IDL import path to use development version.

The import path for the Gateway IDL has been updated to use the development version from the /dev directory. This change aligns with the dependency upgrade to @zetachain/[email protected] and supports the new deposit functionality.

packages/commands/src/solana/index.ts (1)

3-3: New deposit command successfully integrated.

The deposit command import and registration look good. This properly exposes the new Solana deposit functionality to the CLI.

Also applies to: 11-11

packages/commands/src/solana/deposit.ts (7)

1-15: Import statements look good.

All necessary dependencies are imported for Solana interaction, token handling, and CLI commands. Both development and production Gateway IDLs are properly imported.


18-28: DepositOptions interface is well-defined.

The interface provides all necessary parameters for deposit operations, supporting both native SOL and SPL token deposits.


30-47: Key derivation functions implemented correctly.

The helper functions properly implement keypair derivation from both mnemonics and base58-encoded private keys with appropriate error handling.


54-61: Wallet initialization looks good.

Properly handles keypair initialization from either private key or mnemonic with appropriate error handling.


63-68: API endpoint selection is correct.

The code properly selects the appropriate Solana API endpoint based on the network parameter.


149-164: Command definition looks good.

The CLI command is well-defined with appropriate required and optional parameters. The usage of Option with choices for network is a good practice.


51-52:

❌ Incorrect review comment

Consider environment-specific IDL selection.

The code selects the Gateway IDL based on network, but uses the same IDL for both mainnet and devnet. Ensure this approach is correct as mainnet may require a stable IDL version.


🏁 Script executed:

#!/bin/bash
# Check if there are references to different IDL usage for mainnet vs devnet
rg -A 5 -B 5 "mainnet.*IDL|devnet.*IDL" --type ts

Length of output: 744


🏁 Script executed:

#!/bin/bash
# Locate where GATEWAY_DEV_IDL and GATEWAY_PROD_IDL are defined to verify if a separate devnet IDL exists
rg -n "GATEWAY_DEV_IDL" --type ts
rg -n "GATEWAY_PROD_IDL" --type ts

Length of output: 565


No separate devnet IDL exists
The @zetachain/protocol-contracts-solana package only provides two IDLs—

  • dev/idl/gateway.json (used for localnet)
  • prod/idl/gateway.json (used for everything else, including both devnet and mainnet)

As such, using GATEWAY_PROD_IDL for both devnet and mainnet is intentional and correct. No changes are required unless you plan to introduce a distinct devnet IDL.

• File: packages/commands/src/solana/deposit.ts
Lines: 51–52

Likely an incorrect or invalid review comment.

@fadeev fadeev marked this pull request as draft May 8, 2025 10:33
@fadeev fadeev linked an issue May 8, 2025 that may be closed by this pull request
@fadeev
Copy link
Member Author

fadeev commented May 17, 2025

Modified accounts import --type solana to correctly import base58 private key.

@fadeev fadeev marked this pull request as ready for review May 19, 2025 08:27
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: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc1b6e8 and 01d5f06.

⛔ Files ignored due to path filters (5)
  • typechain-types/factories/contracts/EthZetaMock.sol/ZetaEthMock__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/SwapHelpers.sol/SwapLibrary__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/TestZRC20__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/shared/MockZRC20__factory.ts is excluded by !typechain-types/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • package.json (1 hunks)
  • packages/client/src/solanaDeposit.ts (2 hunks)
  • packages/client/src/solanaDepositAndCall.ts (2 hunks)
  • packages/commands/src/solana/deposit.ts (1 hunks)
  • packages/commands/src/solana/index.ts (1 hunks)
  • packages/tasks/src/solanaDeposit.ts (1 hunks)
  • packages/tasks/src/solanaDepositAndCall.ts (1 hunks)
  • utils/accounts.ts (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/tasks/src/solanaDeposit.ts
  • packages/tasks/src/solanaDepositAndCall.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • package.json
  • packages/client/src/solanaDeposit.ts
  • packages/commands/src/solana/index.ts
  • packages/client/src/solanaDepositAndCall.ts
  • packages/commands/src/solana/deposit.ts
🔇 Additional comments (3)
utils/accounts.ts (3)

5-5: Added bs58 library for base58 encoding/decoding

Good choice to add the bs58 library to handle base58 encoding/decoding for Solana private keys. This is standard practice when working with Solana keypairs.


83-105: Enhanced flexibility for handling Solana private keys

The improved private key handling now supports both base58 and hex formats, which aligns well with the new Solana deposit command requirements. The error handling is comprehensive with helpful error messages.


108-108:

❓ Verification inconclusive

Potential backward compatibility issue

Changing the private key encoding from hex to base58 might break backward compatibility with code that expects the private key to be in hex format. Consider verifying that all consuming code can handle this change.


🏁 Script executed:

#!/bin/bash
# Search for uses of SolanaAccountData that might be affected by the encoding change

echo "Searching for places where SolanaAccountData private keys are used..."
rg -A 5 "SolanaAccountData" --type typescript
echo "Searching for places where Solana private keys might be accessed..."
rg -A 5 "\.privateKey.*solana" --type typescript

Length of output: 460


🏁 Script executed:

#!/bin/bash
# Search for references without relying on --type filter
echo "Searching for uses of SolanaAccountData in .ts files..."
rg -A5 "SolanaAccountData" -g '*.ts'
echo "Searching for privateKey fields in .ts files..."
rg -A5 "\.privateKey" -g '*.ts'

Length of output: 7950


Verify backward compatibility of Solana privateKey encoding

Changing the Solana private key output from hex to base58 will break any code or persisted data that still expects a hex string. Please confirm that all consumers have been updated (or that legacy hex keys are still supported), including:

• utils/accounts.ts – createSolanaAccount now does

privateKey: bs58.encode(keypair.secretKey)

• utils/addressResolver.ts – code loading SolanaAccountData from disk
• packages/commands/src/solana/deposit.ts – keypairFromPrivateKey(...) must decode base58
• Any other CLI commands or helpers that read account.privateKey (e.g. in bitcoin, evm, sui)
• tests or migrations for existing user‐stored keys

If any consumers still expect hex, either restore hex support or add a migration/dual-format parser.

Copy link
Member

@hernan-clich hernan-clich left a comment

Choose a reason for hiding this comment

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

A few comments below, let's also ensure to address coderabbit's suggestions.

@@ -15,7 +15,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
node-version: "21"
Copy link
Member

Choose a reason for hiding this comment

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

Ideally, we should address these types of changes in their own separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, but the test were failing because of the node version. So either we update node in this PR or merge with failing tests.

@@ -1,5 +1,5 @@
import { Wallet } from "@coral-xyz/anchor";
import { Keypair } from "@solana/web3.js";
import { Keypair } from "@coral-xyz/anchor/node_modules/@solana/web3.js";
Copy link
Member

Choose a reason for hiding this comment

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

Why was this needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed b1e9f24

.addOption(
new Option("--network <network>", "Solana network").choices(networks)
)
.action(main);
Copy link
Member

Choose a reason for hiding this comment

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

Let's please use a Zod schema to validate params here.

Copy link
Member Author

Choose a reason for hiding this comment

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

} else if (options.mnemonic) {
keypair = await keypairFromMnemonic(options.mnemonic);
} else {
throw new Error("Either privateKey or mnemonic must be provided");
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be necessary if we validate params with a solid Zod schema.

Copy link
Member Author

Choose a reason for hiding this comment

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

Right now we're duplicating logic: optionality, default values, conflicts are handled both in commander and zod.

Copy link
Member Author

@fadeev fadeev May 21, 2025

Choose a reason for hiding this comment

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

I can see advantages of zod for exported functions, but less so for commands that already use declarative syntax to do validation.

For example,

.refine((data) => !(data.mnemonic && data.privateKey), {
  message: "Only one of mnemonic or privateKey can be provided, not both",
});

And:

.addOption(
  new Option("--name <name>", "Account name")
    .conflicts(["private-key"])
)
.addOption(
  new Option("--private-key <key>", "Private key for signing transactions")
    .conflicts(["name"])
)

We don't need both.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe we do types in zod like .string(), but default values and validation in commander.

Copy link
Member Author

Choose a reason for hiding this comment

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

Default values and enum values should definitely be in commander, because they show up in --help.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added zod validation: a4f049f

const provider = new anchor.AnchorProvider(
connection,
new Wallet(keypair),
{}
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need this? I would imagine this will work the same without this empty object.

Copy link
Member Author

Choose a reason for hiding this comment

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

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

🧹 Nitpick comments (3)
utils/solana.commands.helpers.ts (3)

5-14: Consider adding stricter validation for field formats

The schema efficiently defines the required fields and their types, but could benefit from more specific format validation:

  • amount should validate that it's a valid number string
  • recipient should validate as a valid Solana address (base58 encoded public key)
  • mint should validate as a valid Solana address when provided
  • network should restrict to supported networks (devnet, localnet, mainnet)
 export const solanaDepositOptionsSchema = z
   .object({
-    amount: z.string(),
+    amount: z.string().refine((val) => !isNaN(parseFloat(val)), {
+      message: "Amount must be a valid number",
+    }),
     mint: z.string().optional(),
     mnemonic: z.string().optional(),
-    network: z.string(),
+    network: z.enum(["devnet", "localnet", "mainnet"]),
     privateKey: z.string().optional(),
-    recipient: z.string(),
+    recipient: z.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/, {
+      message: "Recipient must be a valid Solana address",
+    }),
     tokenProgram: z.string().default(SOLANA_TOKEN_PROGRAM),
   })

15-17: Consider enforcing at least one authentication method

The refinement correctly ensures that both authentication methods aren't provided simultaneously, but doesn't enforce that at least one is provided.

   .refine((data) => !(data.mnemonic && data.privateKey), {
     message: "Only one of mnemonic or privateKey can be provided, not both",
   });
+  .refine((data) => !!(data.mnemonic || data.privateKey), {
+    message: "Either mnemonic or privateKey must be provided",
+  });

1-18: Add JSDoc comments for better documentation

Consider adding JSDoc comments to explain the purpose of the schema and document each field's requirements. This would improve developer experience and make the code more maintainable.

+/**
+ * Schema for validating Solana deposit command options.
+ * Used to ensure all required fields are present and correctly formatted.
+ */
 export const solanaDepositOptionsSchema = z
   .object({
+    /**
+     * Amount to deposit, must be a valid number as string
+     */
     amount: z.string(),
+    /**
+     * Optional SPL token mint address for token deposits.
+     * Required when depositing SPL tokens, not used for SOL deposits.
+     */
     mint: z.string().optional(),
+    /**
+     * Optional BIP39 mnemonic phrase for wallet derivation.
+     * Mutually exclusive with privateKey.
+     */
     mnemonic: z.string().optional(),
+    /**
+     * Solana network to use (devnet, localnet, mainnet)
+     */
     network: z.string(),
+    /**
+     * Optional base58-encoded private key for wallet.
+     * Mutually exclusive with mnemonic.
+     */
     privateKey: z.string().optional(),
+    /**
+     * Destination Solana address for the deposit
+     */
     recipient: z.string(),
+    /**
+     * Token program address, defaults to standard Solana token program
+     */
     tokenProgram: z.string().default(SOLANA_TOKEN_PROGRAM),
   })
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6d8cca and 255aec5.

📒 Files selected for processing (2)
  • packages/commands/src/solana/deposit.ts (1 hunks)
  • utils/solana.commands.helpers.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/commands/src/solana/deposit.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
utils/solana.commands.helpers.ts (1)
types/shared.constants.ts (1)
  • SOLANA_TOKEN_PROGRAM (2-3)
🔇 Additional comments (1)
utils/solana.commands.helpers.ts (1)

1-4: Nice clean imports!

The imports are well-organized with clear separation between external libraries (zod) and internal modules.

@fadeev fadeev requested a review from hernan-clich May 21, 2025 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Command: solana deposit
2 participants