Skip to content
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

Solana deposit and call #203

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

Solana deposit and call #203

wants to merge 4 commits into from

Conversation

fadeev
Copy link
Member

@fadeev fadeev commented Dec 10, 2024

  • Import IDL from npm
  • Separate deposit and depositAndCall functions.

Summary by CodeRabbit

  • New Features

    • Added a new method solanaDepositAndCall for enhanced Solana transaction capabilities.
    • Introduced a new Hardhat task solana-deposit-and-call for executing deposit and call operations from the command line.
    • New dependency added for Solana protocol contracts.
  • Bug Fixes

    • Streamlined the solanaDeposit function by removing unnecessary parameters for a simpler interface.
  • Chores

    • Updated dependency versions in the package configuration.

Copy link
Contributor

coderabbitai bot commented Dec 10, 2024

📝 Walkthrough

Walkthrough

The pull request introduces several changes to the @zetachain/toolkit package, including updates to the package.json file to add a new dependency and update existing ones. A new method, solanaDepositAndCall, is added to the ZetaChainClient class, enhancing Solana transaction capabilities. The solanaDeposit function is modified to simplify its parameters, while a new file for solanaDepositAndCall is created to handle deposits and calls to Solana smart contracts. Additionally, several task files are updated to reflect these changes and streamline functionality.

Changes

File Change Summary
package.json - Added dependency: @zetachain/protocol-contracts-solana: 2.0.0-rc1
- Updated dependency: @zetachain/networks: v10.0.010.0.0-rc1
- Unchanged dependency: @zetachain/protocol-contracts: 11.0.0-rc3
- Added newline at the end of the file.
packages/client/src/client.ts - Method added: solanaDepositAndCall in ZetaChainClient.
packages/client/src/idl/gateway.json - File deleted.
packages/client/src/index.ts - New export added: export * from "./solanaDepositAndCall";.
packages/client/src/solanaDeposit.ts - Method signature updated: Removed params from the function arguments.
packages/client/src/solanaDepositAndCall.ts - Method added: solanaDepositAndCall for depositing and calling a Solana smart contract.
packages/tasks/src/index.ts - Method added: solanaDepositAndCall export.
packages/tasks/src/solanaDeposit.ts - Task signature updated: Removed types and values parameters from the task registration.
packages/tasks/src/solanaDepositAndCall.ts - Functions added: solanaDepositAndCall and getKeypairFromFile.
- Task added: solana-deposit-and-call.

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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. (Experiment)
  • @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.

@fadeev

This comment was marked as outdated.

@fadeev
Copy link
Member Author

fadeev commented Dec 10, 2024

Deposit works:

npx hardhat solana-deposit --amount 0.01 --recipient 0x2DCB13e7Eb5253fD5255Ce3CbCB199B48A0C7dD9
Transaction signature: AXkK7HPVpR8sPxUh7yfV7ad9JijtXwRjrCk828kKpENuZbL6jnCHM3qW8JKNoBnLAwDwYK5jHZFra3ABP3vh8pP

@fadeev
Copy link
Member Author

fadeev commented Dec 10, 2024

Deposit and call:

npx hardhat solana-deposit-and-call --amount 0.01 --recipient 0x0b28dd447932003D40563B0e3707ab3b80a4d956 --types '["address", "address"]' 0x05BA149A7bd6dC1F937fA9046A9e05C05f3b18b0 0xe7508B5026f032b37663718192bA63a40954F2c0

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

It's failing, but that's expected, because currently Solana routes calls to onCrossChainCall, but the contract above uses the new onCall.

@fadeev fadeev marked this pull request as ready for review December 10, 2024 16:29
@fadeev fadeev requested review from andresaiello and a team as code owners December 10, 2024 16:29
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: 8

🧹 Outside diff range and nitpick comments (2)
packages/client/src/solanaDeposit.ts (1)

Line range hint 121-123: Enhance error handling with specific error types

The current error handling catches all errors and logs them generically. Consider:

  1. Adding specific error types for common failures
  2. Including error codes for better debugging
  3. Structuring the error response for better client handling
  } catch (error) {
-   console.error("Transaction failed:", error);
+   const errorMessage = error instanceof Error ? error.message : String(error);
+   console.error("Solana deposit transaction failed:", {
+     error: errorMessage,
+     code: error?.code,
+     type: "SOLANA_DEPOSIT_ERROR"
+   });
+   throw new Error(`Solana deposit failed: ${errorMessage}`);
  }
packages/tasks/src/solanaDepositAndCall.ts (1)

32-35: Remove unused variable 'idPath' from destructuring assignment

The variable idPath is extracted from args but not used in the function, which can lead to confusion.

Update the code to remove idPath:

- const { amount, idPath } = args;
+ const { amount } = args;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5e088f9 and a3f811b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (9)
  • package.json (3 hunks)
  • packages/client/src/client.ts (2 hunks)
  • packages/client/src/idl/gateway.json (0 hunks)
  • packages/client/src/index.ts (1 hunks)
  • packages/client/src/solanaDeposit.ts (2 hunks)
  • packages/client/src/solanaDepositAndCall.ts (1 hunks)
  • packages/tasks/src/index.ts (1 hunks)
  • packages/tasks/src/solanaDeposit.ts (2 hunks)
  • packages/tasks/src/solanaDepositAndCall.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/client/src/idl/gateway.json
🔇 Additional comments (7)
packages/client/src/solanaDeposit.ts (2)

5-5: LGTM! Import IDL from npm package

Importing Gateway_IDL from npm package improves maintainability and ensures consistency across projects.


82-84: Verify recipient format validation

The recipient handling has been simplified to directly use ethers.utils.arrayify. While this is more efficient, ensure that:

  1. The input format is validated before conversion
  2. The recipient buffer length matches the contract's expectations
packages/tasks/src/solanaDeposit.ts (1)

67-71: LGTM! Task registration is well-defined

The task parameters are clearly defined with appropriate descriptions and default values.

packages/client/src/client.ts (2)

26-26: LGTM! Clean import addition.

The new import follows the existing pattern and maintains alphabetical order.


180-180: LGTM! Method assignment follows existing pattern.

The new method assignment is consistent with the class structure and existing patterns.

Let's verify that the imported function exists:

✅ Verification successful

Function exists and is properly implemented

The solanaDepositAndCall function is correctly defined in both packages/client/src/solanaDepositAndCall.ts and packages/tasks/src/solanaDepositAndCall.ts. The assignment in client.ts is valid as it references the function from the client implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the solanaDepositAndCall function exists in the source files

# Search for the solanaDepositAndCall function definition
ast-grep --pattern 'export const solanaDepositAndCall = $_' || \
ast-grep --pattern 'export function solanaDepositAndCall($_)'

Length of output: 11334

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

18-18: Approved: Export of 'solanaDepositAndCall' is correctly added

The new export statement properly includes solanaDepositAndCall in the module exports.

packages/tasks/src/index.ts (1)

15-15: Approved: Export of 'solanaDepositAndCall' is correctly added

The new export statement properly includes solanaDepositAndCall in the module exports.

@@ -56,6 +56,7 @@
"@typescript-eslint/eslint-plugin": "^5.59.9",
"@typescript-eslint/parser": "^5.59.9",
"@uniswap/v2-core": "^1.0.1",
"@zetachain/protocol-contracts-solana": "2.0.0-rc1",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Update dependencies to latest stable versions

Both packages have stable versions available that are newer than the release candidates:

  • @zetachain/protocol-contracts-solana: Use version 2.0.0 instead of 2.0.0-rc1
  • @zetachain/networks: Use version 10.0.0 instead of 10.0.0-rc1
🔗 Analysis chain

Verify stability of release candidate dependencies

The new dependency @zetachain/[email protected] and updated @zetachain/[email protected] are both release candidates. While this aligns with the PR objective of importing IDL from npm, ensure these versions are stable enough for production use.

Also applies to: 104-104

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for newer versions and release notes
echo "Checking @zetachain/protocol-contracts-solana versions:"
npm view @zetachain/protocol-contracts-solana versions --json

echo "Checking @zetachain/networks versions:"
npm view @zetachain/networks versions --json

Length of output: 848

@@ -30,18 +30,9 @@ export const solanaDeposit = async (
recipient = args.recipient;
}
const { amount, idPath } = args;
const params = [JSON.parse(args.types), args.values];
await client.solanaDeposit({ amount, params, recipient });
await client.solanaDeposit({ amount, recipient });
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add amount validation

The amount parameter is passed directly to the client without validation. Consider adding checks for:

  1. Negative values
  2. Maximum deposit limits
  3. Sufficient balance
-  await client.solanaDeposit({ amount, recipient });
+  const parsedAmount = parseFloat(amount);
+  if (isNaN(parsedAmount) || parsedAmount <= 0) {
+    throw new Error("Invalid deposit amount: must be a positive number");
+  }
+  const balance = await provider.connection.getBalance(wallet.publicKey);
+  if (balance < parsedAmount * anchor.web3.LAMPORTS_PER_SOL) {
+    throw new Error("Insufficient balance for deposit");
+  }
+  await client.solanaDeposit({ amount: parsedAmount, recipient });

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +10 to +13
export const solanaDepositAndCall = async (
args: any,
hre: HardhatRuntimeEnvironment
) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Specify a more precise type for 'args' parameter in 'solanaDepositAndCall' function

Using any for args reduces type safety and can lead to runtime errors. Define a specific interface or type for args to improve code reliability and maintainability.

Consider defining an interface for args:

interface SolanaDepositAndCallArgs {
  idPath: string;
  solanaNetwork: string;
  recipient: string;
  types: string;
  values: any[];
  amount: number;
}

Then update the function signature:

export const solanaDepositAndCall = async (
  args: SolanaDepositAndCallArgs,
  hre: HardhatRuntimeEnvironment
) => {
  // function body
};

Comment on lines +21 to +31
let recipient;
try {
if ((bech32 as any).decode(args.recipient)) {
recipient = utils.solidityPack(
["bytes"],
[utils.toUtf8Bytes(args.recipient)]
);
}
} catch (e) {
recipient = args.recipient;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify and clarify recipient address decoding logic

The current logic attempts to decode the recipient address using bech32.decode within a try-catch block, and uses an if statement that is always truthy if no exception is thrown. This can be simplified for clarity.

Refactor the code as follows:

let recipient;
try {
  bech32.decode(args.recipient);
  recipient = utils.solidityPack(
    ["bytes"],
    [utils.toUtf8Bytes(args.recipient)]
  );
} catch (e) {
  recipient = args.recipient;
}

This removes the unnecessary if condition since if bech32.decode doesn't throw an error, the recipient is assumed to be in Bech32 format.

recipient = args.recipient;
}
const { amount, idPath } = args;
const params = [JSON.parse(args.types), args.values];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling for JSON parsing of 'args.types'

Parsing args.types without error handling can result in unhandled exceptions if args.types is not valid JSON.

Add a try-catch block to handle parsing errors:

let paramTypes;
try {
  paramTypes = JSON.parse(args.types);
} catch (error) {
  throw new Error(`Invalid JSON in 'types' parameter: ${error.message}`);
}
const params = [paramTypes, args.values];

Comment on lines +85 to +89
const message = Buffer.from(
ethers.utils.arrayify(
ethers.utils.defaultAbiCoder.encode(args.params[0], args.params[1])
)
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Validate 'args.params' before encoding

To prevent runtime errors, ensure that args.params[0] and args.params[1] are valid before encoding.

Add validation for args.params:

if (!Array.isArray(args.params[0]) || !Array.isArray(args.params[1])) {
  throw new Error("Invalid 'params' format. Expected arrays of types and values.");
}

Comment on lines +132 to +134
} catch (error) {
console.error("Transaction failed:", error);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Re-throw errors after logging in catch block

Currently, errors are logged but not re-thrown, which could lead to silent failures. Re-throw the error after logging to allow upstream handling.

Update the catch block:

} catch (error) {
  console.error("Transaction failed:", error);
  throw error; // Re-throw the error to be handled by the caller
}

Comment on lines +24 to +25
const network = "solana_" + this.network;
const api = getEndpoints("solana" as any, network);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure correct type when calling 'getEndpoints'

Casting "solana" as any reduces type safety. Use the appropriate type or adjust the function definition to accept a string.

Modify the code to avoid casting:

- const api = getEndpoints("solana" as any, network);
+ const api = getEndpoints("solana", network);

If getEndpoints requires a specific type, consider updating its type definitions to accept "solana" as a valid option.

Committable suggestion skipped: line range outside the PR's diff.

@fadeev fadeev changed the title Solana depsit and call Solana deposit and call Dec 11, 2024
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.

1 participant