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

feat: SPL token balances #204

Merged
merged 6 commits into from
Jan 13, 2025
Merged

feat: SPL token balances #204

merged 6 commits into from
Jan 13, 2025

Conversation

fadeev
Copy link
Member

@fadeev fadeev commented Dec 13, 2024

  • Fixed a bug where Solana SPL tokens where treated as ERC-20
  • Added querying SPL token balances

Summary by CodeRabbit

  • New Features

    • Enhanced support for SPL tokens alongside ERC20 tokens in balance fetching.
    • Introduced a new task for fetching balances with improved parameters for various blockchain addresses.
  • Bug Fixes

    • Improved error handling and output formatting for wallet address issues, providing clearer instructions for users.
  • Documentation

    • Updated error messages to guide users on setting up environment variables for different blockchain private keys.
    • Adjusted output formatting for balance display to enhance clarity.

@fadeev fadeev requested review from andresaiello and a team as code owners December 13, 2024 13:01
Copy link
Contributor

coderabbitai bot commented Dec 13, 2024

📝 Walkthrough

Walkthrough

The changes in this pull request enhance the getBalances function to support both ERC20 and SPL tokens, introducing logic to differentiate between EVM and SVM virtual machines. The function now includes improved error handling for multicall failures and adds a mechanism to fetch SPL token balances from the Solana blockchain. Additionally, modifications in the balances.ts file improve error messaging and output formatting, refining the user experience when querying balances. The package.json file reflects a version update for the @zetachain/networks dependency.

Changes

File Path Change Summary
packages/client/src/getBalances.ts Updated getBalances function to support SPL tokens, improved error handling for multicalls, and expanded balance retrieval logic.
packages/tasks/src/balances.ts Enhanced error handling and output formatting in the main function, added balancesTask for improved user instructions.
package.json Updated @zetachain/networks dependency version from "v10.0.0" to "10.0.0-rc3".

Possibly related issues

Possibly related PRs

  • Support query solana balances #185: This PR introduces modifications to the getBalances function to support querying Solana balances, aligning with the enhancements for handling SPL tokens in this PR.

Suggested reviewers

  • andresaiello

📜 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 917e4cd and 1345269.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (1)
  • package.json (2 hunks)
🔇 Additional comments (1)
package.json (1)

104-104: Verify compatibility with RC version.

Moving from a stable version (v10.0.0) to a release candidate (10.0.0-rc3) of @zetachain/networks could introduce instability. While this might be necessary for the SPL token balance feature, please ensure:

  1. This RC version contains the required SPL token fixes
  2. It's compatible with other RC versions in use ([email protected], [email protected])

Run this script to check the changelog and compatibility:

Consider adding a comment in package.json to document why an RC version is needed:

 {
   "dependencies": {
+    // RC version needed for SPL token balance support
     "@zetachain/networks": "10.0.0-rc3",
✅ Verification successful

RC version is necessary for SPL token support

The code review confirms that @zetachain/[email protected] is required for proper SPL token handling. The implementation relies on specific chain configurations and network information to:

  • Distinguish between EVM and Solana VM chains
  • Handle SPL tokens differently from ERC20 tokens
  • Access correct network endpoints for Solana operations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the changelog for SPL token-related changes and verify version compatibility

# Get the package info and changelog
echo "Checking @zetachain/[email protected]..."
curl -s https://registry.npmjs.org/@zetachain/networks/10.0.0-rc3 | jq -r '.description, .dependencies'

# List all @zetachain dependencies for version compatibility check
echo -e "\nChecking version compatibility..."
rg '"@zetachain/[^"]+": "[^"]+"' package.json

Length of output: 616


Script:

#!/bin/bash
# Check commit history and PR description for context about the RC version change
echo "Checking commit history..."
git log -n 5 --oneline -- package.json

echo -e "\nChecking for related changes..."
# Look for files modified alongside package.json
git show --name-only HEAD

# Search for SPL token related changes
echo -e "\nChecking for SPL token related changes..."
rg -l "SPL" --type ts --type js

Length of output: 525


Script:

#!/bin/bash
# Check the implementation details of SPL token changes
echo "Checking SPL token implementation..."
cat packages/client/src/getBalances.ts

echo -e "\nChecking for network configuration changes..."
# Look for network configuration files that might be affected
fd -e json -e ts -e js . packages/client/src | rg -l "network|config"

Length of output: 12003


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. (Beta)
  • @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 fadeev changed the title fix solana balance query feat: SPL token balances Dec 13, 2024
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

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

360-360: Simplify conditional check using optional chaining

The condition if (r.result && r.result.value && r.result.value.length > 0) can be simplified using optional chaining for better readability.

Suggested code change:

- if (r.result && r.result.value && r.result.value.length > 0) {
+ if (r.result?.value?.length > 0) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 360-360: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

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

📥 Commits

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

📒 Files selected for processing (2)
  • packages/client/src/getBalances.ts (2 hunks)
  • packages/tasks/src/balances.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/client/src/getBalances.ts

[error] 360-360: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (1)
packages/tasks/src/balances.ts (1)

115-115: Output formatting enhancement approved

The formatting changes improve the readability of the address outputs and provide clear separation between different address types.

packages/client/src/getBalances.ts Show resolved Hide resolved
@fadeev
Copy link
Member Author

fadeev commented Dec 19, 2024

@zeta-chain/fullstack please, review.

for (const acc of r.result.value) {
const amount = acc.account.data.parsed.info.tokenAmount.amount;
const decimals = acc.account.data.parsed.info.tokenAmount.decimals;
totalBalance += parseFloat(amount) / Math.pow(10, decimals);
Copy link
Collaborator

Choose a reason for hiding this comment

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

did you consider move this to big int math instead? parseFloat may have errors

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

♻️ Duplicate comments (1)
packages/client/src/getBalances.ts (1)

82-101: ⚠️ Potential issue

Add null check before accessing supportedChain.vm

This is a critical issue that was previously identified but remains unfixed. Accessing supportedChain.vm without checking if supportedChain exists could cause runtime errors.

Apply this fix:

 const supportedChain = supportedChains.find(
   (c: any) => c.chain_id === token.foreign_chain_id
 );
-if (supportedChain.vm === "evm") {
+if (supportedChain?.vm === "evm") {
   tokens.push({
     chain_id: token.foreign_chain_id,
     coin_type: "ERC20",
     contract: token.asset,
     symbol: token.symbol,
     zrc20: token.zrc20_contract_address,
   });
-} else if (supportedChain.vm === "svm") {
+} else if (supportedChain?.vm === "svm") {
   tokens.push({
     chain_id: token.foreign_chain_id,
     coin_type: "SPL",
     contract: token.asset,
     symbol: token.symbol,
     zrc20: token.zrc20_contract_address,
   });
+} else {
+  console.warn(`Unsupported chain or VM type for token ${token.symbol}`);
 }
🧹 Nitpick comments (4)
packages/client/src/getBalances.ts (4)

200-205: LGTM! Good use of BigInt for precise calculations.

The switch to BigInt addresses the previous concern about using parseFloat. This implementation is safer and prevents precision loss.

Consider simplifying the division operation:

-const balance = BigInt(
-  ethers.utils.defaultAbiCoder.decode(["uint256"], data)[0]
-);
-const formattedBalance = (
-  balance / BigInt(10 ** token.decimals)
-).toString();
+const balance = BigInt(ethers.utils.defaultAbiCoder.decode(["uint256"], data)[0]);
+const formattedBalance = (balance / BigInt(10n ** BigInt(token.decimals))).toString();

278-281: Extract magic number to a named constant

The Bitcoin balance calculation is correct but could be more readable by extracting the satoshis-per-BTC conversion factor to a named constant.

+const SATOSHIS_PER_BTC = BigInt(100000000);
+
 const balance = (
-  (BigInt(funded_txo_sum) - BigInt(spent_txo_sum)) /
-  BigInt(100000000)
+  (BigInt(funded_txo_sum) - BigInt(spent_txo_sum)) / SATOSHIS_PER_BTC
 ).toString();

362-372: Use optional chaining and simplify balance calculation

The balance calculation logic could be more concise and safer.

-if (r.result && r.result.value && r.result.value.length > 0) {
+if (r.result?.value?.length > 0) {
   let totalBalance = BigInt(0);
-  for (const acc of r.result.value) {
-    const amount = acc.account.data.parsed.info.tokenAmount.amount;
-    const decimals = acc.account.data.parsed.info.tokenAmount.decimals;
-    totalBalance += BigInt(amount) / BigInt(10 ** decimals);
-  }
+  totalBalance = r.result.value.reduce((sum, acc) => {
+    const { amount, decimals } = acc.account.data.parsed.info.tokenAmount;
+    return sum + BigInt(amount) / BigInt(10n ** BigInt(decimals));
+  }, BigInt(0));
   balances.push({ ...token, balance: totalBalance.toString() });
 } else {
   balances.push({ ...token, balance: "0" });
 }
🧰 Tools
🪛 Biome (1.9.4)

[error] 362-362: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


373-379: Enhance error logging structure

The error handling is good, but the error logging could be more structured for better debugging.

-console.error(
-  `Failed to get SPL balance for ${token.symbol} on ${token.chain_name}:`,
-  err
-);
+console.error({
+  error: err,
+  message: `Failed to get SPL balance`,
+  token: token.symbol,
+  chain: token.chain_name,
+});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 20f1876 and 917e4cd.

📒 Files selected for processing (1)
  • packages/client/src/getBalances.ts (4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/client/src/getBalances.ts

[error] 362-362: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (1)
packages/client/src/getBalances.ts (1)

320-326: LGTM! Good filtering of SPL tokens

The token filtering logic correctly identifies SPL tokens on Solana chains.

@fadeev fadeev requested a review from andresaiello January 9, 2025 06:55
@fadeev
Copy link
Member Author

fadeev commented Jan 13, 2025

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Jan 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@fadeev fadeev merged commit a0892ba into main Jan 13, 2025
8 of 9 checks passed
@fadeev fadeev deleted the fix-solana-balance-query branch January 13, 2025 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants