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: support FoxWallet #514

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

Conversation

ljunb
Copy link

@ljunb ljunb commented Nov 18, 2024

Hi, We are FoxWallet team, and we want to add supporting FoxWallet in wallet-ts and wallet-evm.
FoxWallet is multi-chain wallet that support Injective protocol. You can find more information about FoxWallet here.

Summary by CodeRabbit

  • New Features

    • Introduced two new wallet strategies: FoxWallet and FoxWalletCosmos.
    • Enhanced wallet interactions for Ethereum and Cosmos transactions with dedicated methods for account management and transaction handling.
    • Added support for detecting the Fox Wallet provider with initialization handling.
  • Bug Fixes

    • Improved error handling for wallet operations and transaction broadcasting.
  • Documentation

    • Updated interfaces to accommodate new wallet types and properties for better integration and detection.
  • Refactor

    • Enhanced existing functions to include support for the new wallet types without altering existing functionalities.

Copy link

coderabbitai bot commented Nov 18, 2024

Walkthrough

The changes introduce two new wallet strategies, FoxWallet and FoxWalletCosmos, into the wallet management system. This includes updates to the createStrategy function to accommodate these new types, along with the implementation of classes and methods for interacting with the Fox Wallet for both Ethereum and Cosmos transactions. New utility functions and modifications to existing interfaces enhance wallet detection and integration capabilities. The overall structure and error handling of the existing code remain consistent, ensuring a seamless extension of functionality.

Changes

File Change Summary
packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts Added cases for Wallet.FoxWallet and Wallet.FoxWalletCosmos in createStrategy. Updated import statements.
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts Introduced FoxWallet class with methods for wallet interactions, including transaction handling and error management.
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/utils.ts Added utility functions for interacting with the Fox Wallet provider, including initialization and provider retrieval.
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/foxwallet/index.ts Introduced FoxWallet class for Cosmos transactions with various wallet operations and error handling.
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/index.ts Added FoxWalletCosmos class extending wallet functionality for Cosmos, with methods for device type, enabling, and transaction handling.
packages/wallet-ts/src/strategies/wallet-strategy/types.ts Updated interfaces to include new properties for Fox Wallet integration.
packages/wallet-ts/src/strategies/wallet-strategy/utils.ts Added Wallet.FoxWallet to isEthWallet function for wallet recognition.
packages/wallet-ts/src/types/enums.ts Updated Wallet enum to include FoxWallet and FoxWalletCosmos.
packages/wallets/wallet-base/src/types/enums.ts Updated Wallet enum to include FoxWallet and FoxWalletCosmos.
packages/wallets/wallet-base/src/types/provider.ts Updated interfaces to include new properties for Fox Wallet detection.
packages/wallets/wallet-base/src/utils/wallet.ts Added Wallet.FoxWallet to the isEthWallet function.
packages/wallets/wallet-evm/src/strategy/strategy.ts Added Wallet.FoxWallet to evmWallets and updated getEthereum method to support it.
packages/wallets/wallet-evm/src/strategy/utils/foxwallet.ts Introduced functions for interacting with the Fox Wallet provider in an Ethereum environment.
packages/wallets/wallet-evm/src/strategy/utils/index.ts Exported getFoxWalletProvider from foxwallet.js.
packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts Added case for Wallet.FoxWallet in createStrategy function.

Poem

🐰 In the land of wallets, new friends arise,
FoxWallet and Cosmos, a sweet surprise!
With strategies crafted, our paths intertwine,
Transactions and tokens, all in good time.
Hopping through code, with joy we embrace,
A world of new wallets, a magical space! ✨

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.

packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts

Oops! Something went wrong! :(

ESLint: 7.32.0

Error: Error while loading rule 'jest/unbound-method': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.
Occurred while linting /packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts
at throwError (/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js:39:11)
at getParserServices (/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js:31:9)
at create (/node_modules/@typescript-eslint/eslint-plugin/dist/rules/unbound-method.js:116:55)
at Object.create (/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js:38:20)
at create (/node_modules/eslint-plugin-jest/lib/rules/unbound-method.js:47:88)
at Object.create (/node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js:41:20)
at createRuleListeners (/node_modules/eslint/lib/linter/linter.js:765:21)
at /node_modules/eslint/lib/linter/linter.js:937:31
at Array.forEach ()
at runRules (/node_modules/eslint/lib/linter/linter.js:882:34)


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 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.

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.

# Conflicts:
#	packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts
#	packages/wallets/wallet-evm/src/strategy/strategy.ts
#	packages/wallets/wallet-evm/src/strategy/utils/index.ts
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: 11

🧹 Outside diff range and nitpick comments (21)
packages/wallet-ts/src/types/enums.ts (1)

22-23: Consider maintaining alphabetical ordering of enum entries.

The new entries are added at the end, which breaks the alphabetical ordering of the enum. Consider reordering them to maintain consistency.

export enum Wallet {
  BitGet = 'BitGet',
  Cosmostation = 'cosmostation',
  CosmostationEth = 'cosmostation-eth',
+ FoxWallet = 'fox-wallet',
+ FoxWalletCosmos = 'fox-wallet-cosmos',
  Keplr = 'keplr',
  Leap = 'leap',
  Ledger = 'ledger',
  LedgerCosmos = 'ledger-cosmos',
  LedgerLegacy = 'ledger-legacy',
  Magic = 'magic',
  Metamask = 'metamask',
  Ninji = 'ninji',
  OkxWallet = 'okx-wallet',
  Phantom = 'phantom',
  PrivateKey = 'private-key',
  Torus = 'torus',
  Trezor = 'trezor',
  TrustWallet = 'trust-wallet',
  WalletConnect = 'wallet-connect',
- FoxWallet = 'fox-wallet',
- FoxWalletCosmos = 'fox-wallet-cosmos',
}
packages/wallets/wallet-evm/src/strategy/utils/foxwallet.ts (2)

11-21: Add JSDoc documentation for better code maintainability

Consider adding JSDoc documentation to explain the function's purpose, parameters, and return type.

+/**
+ * Retrieves the Fox Wallet provider, waiting for initialization if necessary.
+ * @param {Object} options - The options object
+ * @param {number} [options.timeout=3000] - Maximum time in milliseconds to wait for provider initialization
+ * @returns {Promise<BrowserEip1993Provider>} The Fox Wallet provider
+ */
 export async function getFoxWalletProvider({ timeout } = { timeout: 3000 }) {

23-38: Consider adding cleanup mechanism for premature unmounts

While the timeout cleanup is handled, there's a potential memory leak if the component unmounts before the timeout occurs. Consider adding a way to cancel the listener externally.

-async function listenForFoxWalletInitialized({ timeout } = { timeout: 3000 }) {
+async function listenForFoxWalletInitialized({ timeout } = { timeout: 3000 }, abortSignal?: AbortSignal) {
   return new Promise((resolve) => {
+    if (abortSignal?.aborted) {
+      resolve(null);
+      return;
+    }
+
     const handleInitialization = () => {
       resolve(getFoxWalletFromWindow())
     }
 
+    const cleanup = () => {
+      $window.removeEventListener('foxwallet#initialized', handleInitialization)
+      resolve(null)
+    }
+
+    abortSignal?.addEventListener('abort', cleanup)
     $window.addEventListener('foxwallet#initialized', handleInitialization, {
       once: true,
     })
 
-    setTimeout(() => {
-      $window.removeEventListener('foxwallet#initialized', handleInitialization)
-      resolve(null)
-    }, timeout)
+    setTimeout(cleanup, timeout)
   })
 }
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/utils.ts (3)

1-6: Consider adding runtime type checking for window access

While the type casting provides compile-time safety, consider adding runtime checks to ensure type safety when accessing window properties.

-const $window = (isServerSide()
-  ? {}
-  : window) as unknown as WindowWithEip1193Provider
+const $window = (() => {
+  if (isServerSide()) {
+    return {} as WindowWithEip1193Provider;
+  }
+  if (typeof window === 'undefined') {
+    return {} as WindowWithEip1193Provider;
+  }
+  return window as unknown as WindowWithEip1193Provider;
+})();

8-18: Add JSDoc documentation and explicit return type

The function would benefit from documentation explaining the timeout parameter and its behavior.

+/**
+ * Attempts to get the FoxWallet provider, waiting for initialization if necessary.
+ * @param {Object} options - Configuration options
+ * @param {number} [options.timeout=3000] - Maximum time in milliseconds to wait for provider initialization
+ * @returns {Promise<BrowserEip1993Provider>} The FoxWallet provider or null if not available
+ */
-export async function getFoxWalletProvider({ timeout } = { timeout: 3000 }) {
+export async function getFoxWalletProvider({ timeout } = { timeout: 3000 }): Promise<BrowserEip1993Provider | null> {

1-66: Consider adding retry mechanism and logging for better debugging

The current implementation could benefit from:

  1. A retry mechanism for temporary provider unavailability
  2. Debug logging to help troubleshoot wallet detection issues
  3. Metrics collection for timeout frequency and initialization success rate

This would improve the reliability and maintainability of the wallet integration.

Would you like me to provide an example implementation with these improvements?

packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts (1)

93-97: Consider documenting wallet integration patterns

The FoxWallet implementation correctly follows the established patterns. To maintain this consistency for future wallet integrations, consider documenting:

  1. The required steps for adding new EVM wallets
  2. The standard argument structure
  3. The error handling patterns
packages/wallets/wallet-evm/src/strategy/strategy.ts (2)

364-365: Consider refactoring provider selection for better maintainability

The growing chain of ternary operators makes the code harder to maintain. Consider refactoring to a more maintainable pattern, such as a map of wallet types to provider functions.

Here's a suggested refactor:

-  private async getEthereum(): Promise<BrowserEip1993Provider> {
-    const provider =
-      this.wallet === Wallet.Metamask
-        ? await getMetamaskProvider()
-        : this.wallet === Wallet.Phantom
-        ? await getPhantomProvider()
-        : this.wallet === Wallet.BitGet
-        ? await getBitGetProvider()
-        : this.wallet === Wallet.OkxWallet
-        ? await getOkxWalletProvider()
-        : this.wallet === Wallet.TrustWallet
-        ? await getTrustWalletProvider()
-        : this.wallet === Wallet.FoxWallet
-        ? await getFoxWalletProvider()
-        : undefined
+  private readonly walletProviders = {
+    [Wallet.Metamask]: getMetamaskProvider,
+    [Wallet.Phantom]: getPhantomProvider,
+    [Wallet.BitGet]: getBitGetProvider,
+    [Wallet.OkxWallet]: getOkxWalletProvider,
+    [Wallet.TrustWallet]: getTrustWalletProvider,
+    [Wallet.FoxWallet]: getFoxWalletProvider,
+  }
+
+  private async getEthereum(): Promise<BrowserEip1993Provider> {
+    const getProvider = this.walletProviders[this.wallet]
+    const provider = getProvider ? await getProvider() : undefined

     if (!provider) {
       throw this.EvmWalletException(
         new Error(`Please install the ${this.wallet} wallet extension.`),
         {
           code: UnspecifiedErrorCode,
           type: ErrorType.WalletNotInstalledError,
           contextModule: WalletAction.GetAccounts,
         },
       )
     }

     return provider
   }

Line range hint 74-98: Add FoxWallet case in EvmWalletException method

The EvmWalletException method needs to handle Wallet.FoxWallet specifically, similar to how other wallets are handled.

Add the following case:

   public EvmWalletException(
     error: Error,
     context?: ErrorContext,
   ): ThrownException {
     if (this.wallet === Wallet.Metamask) {
       return new MetamaskException(error, context)
     }

     if (this.wallet === Wallet.BitGet) {
       return new BitGetException(error, context)
     }

     if (this.wallet === Wallet.OkxWallet) {
       return new OkxWalletException(error, context)
     }

     if (this.wallet === Wallet.Phantom) {
       return new MetamaskException(error, context)
     }

     if (this.wallet === Wallet.TrustWallet) {
       return new TrustWalletException(error, context)
     }

+    if (this.wallet === Wallet.FoxWallet) {
+      return new FoxWalletException(error, context)
+    }

     return new WalletException(error, context)
   }
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/foxwallet/index.ts (5)

43-43: Improve error handling by avoiding casting errors to any

In several catch blocks, errors are cast to any to access the message property:

throw new CosmosWalletException(new Error((e as any).message))

Casting to any undermines type safety. Instead, you can check if e is an instance of Error and handle it accordingly. If e is not an Error, you can convert it to a string to capture the error message.

Apply the following changes to improve error handling:

- throw new CosmosWalletException(new Error((e as any).message))
+ throw new CosmosWalletException(e instanceof Error ? e : new Error(String(e)))

This approach maintains type safety and ensures that meaningful error messages are propagated.

Also applies to: 54-54, 72-72, 87-87, 125-125, 163-163


95-95: Fix grammatical errors in comments

There are minor grammatical errors in the code comments:

  • Line 95: "after its broadcasted" should be "after it's broadcasted" or "after it has been broadcasted."
  • Line 134: "Since it uses the 'Block' mode, and it will wait..." The word "and" is unnecessary and can be removed for clarity.

Apply this diff to correct the typos:

- * so we have to make sure the transaction is included in a block after its broadcasted
+ * so we have to make sure the transaction is included in a block after it's broadcasted

- * Since it uses the `Block` mode, and it will wait for the transaction to be included in a block,
+ * Since it uses the `Block` mode, it will wait for the transaction to be included in a block,

Also applies to: 134-134


101-130: Refactor duplicate code in broadcastTx methods

The broadcastTx and broadcastTxBlock methods share similar logic, differing only in the BroadcastMode used (Sync vs. Block). Refactoring them into a single method will reduce code duplication and enhance maintainability.

You can create a private method to handle transaction broadcasting:

private async broadcastTransaction(
  txRaw: CosmosTxV1Beta1Tx.TxRaw,
  mode: BroadcastMode
): Promise<string> {
  const { chainId } = this
  const foxwallet = await this.getFoxWallet()

  try {
    const result = await foxwallet.sendTx(
      chainId,
      CosmosTxV1Beta1Tx.TxRaw.encode(txRaw).finish(),
      mode,
    )

    if (!result || result.length === 0) {
      throw new TransactionException(
        new Error('Transaction failed to be broadcasted'),
        { contextModule: 'FoxWallet' },
      )
    }

    return Buffer.from(result).toString('hex')
  } catch (e) {
    if (e instanceof TransactionException) {
      throw e
    }

    throw new CosmosWalletException(
      e instanceof Error ? e : new Error(String(e)),
      {
        context: 'broadcast-tx',
        contextModule: 'FoxWallet',
      },
    )
  }
}

async broadcastTx(txRaw: CosmosTxV1Beta1Tx.TxRaw): Promise<string> {
  return this.broadcastTransaction(txRaw, BroadcastMode.Sync)
}

async broadcastTxBlock(txRaw: CosmosTxV1Beta1Tx.TxRaw): Promise<string> {
  return this.broadcastTransaction(txRaw, BroadcastMode.Block)
}

This refactoring consolidates the common code and makes it easier to manage any future changes.

Also applies to: 139-168


85-85: Simplify unnecessary double type assertion

In getOfflineSigner(), there is an unnecessary double type assertion:

) as unknown as OfflineDirectSigner

Since getOfflineSigner(chainId) likely returns a compatible type, you can simplify the assertion:

- ) as unknown as OfflineDirectSigner
+ ) as OfflineDirectSigner

Ensure that the getOfflineSigner method returns the correct type or adjust the types appropriately.


186-195: Review the check for $window being falsy

The check for $window being falsy may not be necessary:

if (!$window) {
  throw new CosmosWalletException(
    new Error('Please install FoxWallet extension'),
    {
      code: UnspecifiedErrorCode,
      type: ErrorType.WalletNotInstalledError,
      contextModule: 'FoxWallet',
    },
  )
}

Since $window is initially assigned as an object ({}) when window is undefined, this condition will never be true.

Consider removing the check or modifying it to accurately reflect the intended condition:

- if (!$window) {
+ if (typeof window === 'undefined') {

Alternatively, since you handle the absence of foxwallet?.cosmos in the next check, this initial check might be redundant and can be safely removed.

packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/index.ts (2)

45-45: Simplify the return statement in getWalletDeviceType

Since the method is async, you can directly return the value without wrapping it in Promise.resolve().

Apply this diff to simplify the return statement:

- return Promise.resolve(WalletDeviceType.Browser)
+ return WalletDeviceType.Browser

74-78: Simplify the return statement in getSessionOrConfirm

Since the method is async, you can directly return the value without using Promise.resolve().

Apply this diff to simplify the return statement:

- return Promise.resolve(
-   `0x${Buffer.from(
-     `Confirmation for ${address} at time: ${Date.now()}`,
-   ).toString('hex')}`,
- )
+ return `0x${Buffer.from(
+     `Confirmation for ${address} at time: ${Date.now()}`,
+   ).toString('hex')}`
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts (5)

30-32: Remove unnecessary constructor

The constructor does not add any additional logic beyond calling the superclass's constructor and can be safely removed to simplify the code.

Apply this diff to remove the unnecessary constructor:

-  constructor(args: EthereumWalletStrategyArgs) {
-    super(args)
-  }
🧰 Tools
🪛 Biome

[error] 30-32: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


34-36: Simplify return statement by removing Promise.resolve

Since the method is declared as async, you can return the value directly without wrapping it in Promise.resolve.

Apply this diff to simplify the return statement:

-    return Promise.resolve(WalletDeviceType.Browser)
+    return WalletDeviceType.Browser

38-40: Simplify return statement by removing Promise.resolve

As this method is async, you can return the boolean value directly without Promise.resolve.

Apply this diff to simplify the return statement:

-    return Promise.resolve(true)
+    return true

72-78: Simplify return statement by removing Promise.resolve

Since the method is declared as async, you can return the value directly without wrapping it in Promise.resolve.

Apply this diff to simplify the return statement:

-    return Promise.resolve(
-      `0x${Buffer.from(
-        `Confirmation for ${address} at time: ${Date.now()}`,
-      ).toString('hex')}`,
-    )
+    return `0x${Buffer.from(
+      `Confirmation for ${address} at time: ${Date.now()}`,
+    ).toString('hex')}`

255-259: Provide more context in the error message

When throwing an exception in getPubKey, consider providing additional context or guidance on how to obtain the public key if needed.

Optionally, you can include suggestions in the error message:

    throw new WalletException(
-     new Error('You can only fetch PubKey from Cosmos native wallets'),
+     new Error('Public keys are only available from Cosmos native wallets. Please use a compatible wallet to access the public key.'),
    )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7bc68a8 and 383db91.

📒 Files selected for processing (15)
  • packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts (2 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts (1 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/utils.ts (1 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/foxwallet/index.ts (1 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/index.ts (1 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/types.ts (2 hunks)
  • packages/wallet-ts/src/strategies/wallet-strategy/utils.ts (1 hunks)
  • packages/wallet-ts/src/types/enums.ts (1 hunks)
  • packages/wallets/wallet-base/src/types/enums.ts (1 hunks)
  • packages/wallets/wallet-base/src/types/provider.ts (2 hunks)
  • packages/wallets/wallet-base/src/utils/wallet.ts (1 hunks)
  • packages/wallets/wallet-evm/src/strategy/strategy.ts (3 hunks)
  • packages/wallets/wallet-evm/src/strategy/utils/foxwallet.ts (1 hunks)
  • packages/wallets/wallet-evm/src/strategy/utils/index.ts (1 hunks)
  • packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts (1 hunks)
🧰 Additional context used
🪛 Biome
packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts

[error] 30-32: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (20)
packages/wallets/wallet-base/src/types/provider.ts (2)

10-10: LGTM! Property addition follows established patterns.

The isFoxWallet boolean flag is consistent with other wallet identification properties in the interface.


20-20: LGTM! Verify property name matches FoxWallet's documentation.

The foxwallet provider injection follows the same pattern as other supported wallets.

Let's verify the property name matches FoxWallet's official documentation:

✅ Verification successful

The initial search shows extensive usage of foxwallet property in the codebase, but let's verify the documentation and actual implementation to confirm the property name matches FoxWallet's conventions.


The previous searches didn't yield documentation, so let's examine the actual implementation to verify how the provider is detected and accessed in the code.


Property name foxwallet.ethereum is correctly implemented and matches FoxWallet's injection pattern

The implementation shows consistent usage of foxwallet.ethereum across the codebase:

  • The provider detection code in getFoxWalletFromWindow() specifically checks for $window.foxwallet?.ethereum
  • The property is used consistently in both wallet-evm and wallet-ts packages
  • The code handles both direct injection (foxwallet.ethereum) and legacy injection (via ethereum.isFoxWallet) patterns
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for FoxWallet provider documentation references
# Expected: Find references confirming the correct property name

# Search for FoxWallet documentation or examples in the codebase
rg -i "foxwallet" -g "*.md" -g "*.txt" -g "*.js" -g "*.ts"

# Search for any test files that might verify the provider detection
rg -i "foxwallet.*provider" -g "*test*.ts" -g "*spec*.ts"

Length of output: 13702


Script:

#!/bin/bash
# Let's search for FoxWallet's documentation or examples in the repository
rg -i "foxwallet" -g "*.md" -g "README*" -g "CHANGELOG*" -g "docs/*"

# Let's also check the implementation to see how the provider is accessed
ast-grep --pattern 'foxwallet?.ethereum'

Length of output: 111


Script:

#!/bin/bash
# Let's check the actual implementation of FoxWallet provider detection
rg -A 5 "getFoxWalletFromWindow" 

# Let's also check for any window property access patterns
ast-grep --pattern '$window.foxwallet'

Length of output: 4448

packages/wallet-ts/src/strategies/wallet-strategy/utils.ts (2)

18-18: Verify EIP-712 compatibility for FoxWallet

FoxWallet is added as an Ethereum wallet but not included in isEip712V2OnlyWallet. Please verify if FoxWallet supports other EIP-712 versions or if it should be restricted to v2 only.


18-18: Clarify multi-chain support architecture

The PR objectives mention FoxWallet as a multi-chain wallet, and the AI summary indicates a separate FoxWalletCosmos class exists. However, adding FoxWallet to isEthWallet means isCosmosWallet(Wallet.FoxWallet) will return false. Please clarify if this is the intended architecture for handling multi-chain support.

packages/wallets/wallet-base/src/utils/wallet.ts (3)

18-18: LGTM! Addition of FoxWallet to Ethereum wallets list.

The change correctly identifies FoxWallet as an Ethereum-compatible wallet.


18-18: Verify EIP-712 v2 support for FoxWallet.

Since some wallets only support EIP-712 v2, we should verify if FoxWallet needs to be added to the isEip712V2OnlyWallet list.


18-18: Consider multi-chain support implications.

Since FoxWallet is described as a multi-chain wallet compatible with Injective protocol, should it also be added to the COSMOS_WALLETS array? This would ensure proper handling of both Ethereum and Cosmos transactions.

Also applies to: 34-41

packages/wallet-ts/src/types/enums.ts (1)

22-23: LGTM! The new wallet entries follow the established naming conventions.

The new entries FoxWallet and FoxWalletCosmos are well-integrated and follow the project's conventions:

  • Uses hyphenated values consistent with other entries
  • Follows the established pattern for Cosmos variants
packages/wallets/wallet-base/src/types/enums.ts (1)

23-24: LGTM! Verify string literal usage.

The new enum entries follow the established naming patterns and correctly represent both EVM and Cosmos variants of FoxWallet.

Let's verify the consistent usage of these string literals across the codebase:

✅ Verification successful

String literals are used consistently across the codebase

The verification shows that:

  • The enum values 'fox-wallet' and 'fox-wallet-cosmos' are only used in the enum definition
  • All references to FoxWallet in the codebase use the proper enum values through Wallet.FoxWallet and Wallet.FoxWalletCosmos
  • The implementation includes proper strategy handling for both variants in switch statements
  • No hardcoded string literals are used where the enum should be used
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the wallet string literals are used consistently

# Check for any hardcoded string literals that should use the enum
rg -i "fox.?wallet" --type ts

# Check for proper enum usage in strategy creation
ast-grep --pattern 'case Wallet.FoxWallet: $$$'
ast-grep --pattern 'case Wallet.FoxWalletCosmos: $$$'

Length of output: 13721

packages/wallet-ts/src/strategies/wallet-strategy/types.ts (2)

12-12: LGTM! Property follows established pattern

The isFoxWallet boolean property follows the same pattern as other wallet detection flags in the interface.


22-22: LGTM! Window extension properly typed

The foxwallet property is correctly structured with optional chaining and proper typing, consistent with other wallet provider implementations.

packages/wallets/wallet-evm/src/strategy/utils/foxwallet.ts (2)

1-10: LGTM: Proper setup for cross-environment compatibility

The imports and window setup are well-structured with appropriate type safety and server-side rendering consideration.


51-57: Verify Fox Wallet provider authenticity

The current implementation trusts the isFoxWallet flag without additional verification. Consider adding checks to verify the authenticity of the provider to prevent potential security risks from malicious providers.

packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts (1)

93-97: LGTM! FoxWallet implementation follows established patterns

The implementation correctly uses EvmWalletStrategy and follows the same pattern as other EVM wallets, ensuring consistency in the codebase.

packages/wallets/wallet-evm/src/strategy/strategy.ts (2)

43-43: LGTM: Import follows established patterns

The addition of getFoxWalletProvider follows the existing import pattern and naming convention.


52-52: ⚠️ Potential issue

Add FoxWalletException class for consistent error handling

While Wallet.FoxWallet is added to supported wallets, there's no corresponding FoxWalletException class in the error handling section (like other wallets have MetamaskException, BitGetException, etc.). This should be added to maintain consistent error handling across all wallet types.

Let's verify the error handling for other wallets:

packages/wallet-ts/src/strategies/wallet-strategy/WalletStrategy.ts (2)

106-109: Implementation follows established patterns correctly

The integration of FoxWallet and FoxWalletCosmos follows the existing patterns:

  • FoxWallet uses ethWalletArgs like other EVM wallets
  • FoxWalletCosmos uses full args like other Cosmos wallets

Let's verify the wallet type definitions and utility functions:

#!/bin/bash
# Description: Verify wallet enum types and utility functions
# Expected: FoxWallet and FoxWalletCosmos should be defined in enums.js
# and properly categorized in utils.js

# Check wallet enum definitions
rg -A 2 "export enum Wallet" "packages/wallet-ts/src/types/enums.js"

# Check wallet type categorization
rg "FoxWallet" "packages/wallet-ts/src/strategies/wallet-strategy/utils.js"

22-23: Verify the existence of FoxWallet strategy files

The imports look consistent with the project's structure. Let's verify that the referenced strategy files exist.

✅ Verification successful

Import paths for FoxWallet strategy files are correct and files exist

The verification confirms that both strategy files exist in the correct locations:

  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts
  • packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/index.ts

The import paths in the code match the actual file structure, following the same pattern as other wallet implementations in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the FoxWallet strategy files exist
# Expected: Both files should exist in the strategies directory

fd -t f "FoxWallet/index.js" "packages/wallet-ts/src/strategies"
fd -t f "FoxWalletCosmos/index.js" "packages/wallet-ts/src/strategies"

Length of output: 319


Script:

#!/bin/bash
# Let's try searching with .ts extension and broader path patterns
fd -t f "FoxWallet/index.ts" "packages/wallet-ts"
fd -t f "FoxWalletCosmos/index.ts" "packages/wallet-ts"

# Let's also check if these files exist in the wallet-strategy directory
ls -la packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/
ls -la packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/

# Let's verify the import paths by checking the directory structure
tree packages/wallet-ts/src/strategies/wallet-strategy/

Length of output: 2005

packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWalletCosmos/foxwallet/index.ts (1)

2-2: Verify compatibility between Keplr types and FoxWallet implementation

The import statement aliases Keplr as Fox:

import type { Keplr as Fox } from '@keplr-wallet/types'

This assumes that FoxWallet's API is fully compatible with Keplr's types. If FoxWallet does not implement all methods and properties defined in the Keplr interface, this could lead to runtime errors or type mismatches. Ensure that FoxWallet's cosmos API conforms to the Keplr type definitions or consider defining specific types for FoxWallet to accurately represent its API.

packages/wallet-ts/src/strategies/wallet-strategy/strategies/FoxWallet/index.ts (1)

106-112: Ensure endpoints.grpc is defined before using it

While you check if endpoints is defined, endpoints.grpc might still be undefined, which could lead to runtime errors.

Please verify that endpoints.grpc is always defined when endpoints is provided. Consider adding a check for endpoints.grpc:

    if (!endpoints || !endpoints.grpc) {
      throw new WalletException(
        new Error(
          'You have to pass endpoints with a valid grpc endpoint within the options for using Ethereum native wallets',
        ),
      )
    }

@@ -3,3 +3,4 @@ export { getBitGetProvider } from './bitget.js'
export { getPhantomProvider } from './phantom.js'
export { getMetamaskProvider } from './metamask.js'
export { getTrustWalletProvider } from './trustWallet.js'
export { getFoxWalletProvider } from './foxwallet.js'
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

The export statement needs to be updated to .ts extension

The file being imported exists as foxwallet.ts, but the import statement incorrectly uses .js extension. The export statement should be:

export { getFoxWalletProvider } from './foxwallet.ts'
  • packages/wallets/wallet-evm/src/strategy/utils/foxwallet.ts exists and contains the getFoxWalletProvider function
  • Current import uses .js extension: from './foxwallet.js'
  • All other files in the directory are .ts files
🔗 Analysis chain

LGTM! Verify foxwallet.js exists

The export statement follows the established pattern for wallet providers and is appropriately placed.

Let's verify the existence and content of the referenced file:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and basic structure of foxwallet.js

# Check if the file exists in the same directory
fd -p "wallet-evm/src/strategy/utils/foxwallet.js$"

# Verify the exported function exists
rg -A 5 "export function getFoxWalletProvider"

Length of output: 102


Script:

#!/bin/bash
# Let's try a broader search to understand the structure
# 1. Find any file with "fox" in the name
fd -t f "fox" packages/wallets/wallet-evm

# 2. Check the directory structure of the wallet-evm package
fd . packages/wallets/wallet-evm/src/strategy/utils

# 3. Look for any references to FoxWallet in the codebase
rg -i "foxwallet" packages/wallets/wallet-evm

Length of output: 2530

Comment on lines +40 to +64
function getFoxWalletFromWindow() {
const injectedProviderExist =
typeof window !== 'undefined' &&
(typeof $window.ethereum !== 'undefined' ||
typeof $window.foxwallet !== 'undefined')

// No injected providers exist.
if (!injectedProviderExist) {
return
}

if ($window.foxwallet?.ethereum) {
return $window.foxwallet?.ethereum
}

if ($window.ethereum.isFoxWallet) {
return $window.ethereum
}

if ($window.providers) {
return $window.providers.find((p) => p.isFoxWallet)
}

return
}
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Type safety suggestion can be improved

The review suggestion is good but needs refinement. All wallet utilities in the codebase already import and use the BrowserEip1993Provider type, and the pattern of checking $window.providers.find() is consistently used across all wallet implementations. However, the array check is still a valid concern.

 if ($window.providers) {
-    return $window.providers.find((p) => p.isFoxWallet)
+    return Array.isArray($window.providers)
+      ? $window.providers.find((p) => p.isFoxWallet)
+      : undefined
 }
🔗 Analysis chain

Enhance type safety and array verification

While the provider detection logic is thorough, consider these improvements:

  1. Add type safety for the providers array
  2. Verify array access before using find
 if ($window.providers) {
-    return $window.providers.find((p) => p.isFoxWallet)
+    return Array.isArray($window.providers)
+      ? $window.providers.find((p: BrowserEip1993Provider) => p.isFoxWallet)
+      : undefined
 }

Let me check the implementation patterns in other wallet utilities to make a more informed decision.


Let me check if there are any type definitions or interfaces used in these wallet utilities.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify if there are any other wallet implementations that might have similar provider detection patterns
rg -l "providers?.find\(" --type ts

Length of output: 723


Script:

#!/bin/bash
# Check implementation patterns in other wallet utilities
rg "providers?.find\(" -A 5 --type ts

Length of output: 4214


Script:

#!/bin/bash
# Check for type definitions and interfaces
rg "type|interface.*Provider" --type ts packages/wallets/wallet-evm/src/
rg "BrowserEip1993Provider" --type ts

Length of output: 11490

Comment on lines +42 to +66
function getFoxWalletFromWindow() {
const injectedProviderExist =
typeof window !== 'undefined' &&
(typeof $window.ethereum !== 'undefined' ||
typeof $window.foxwallet !== 'undefined')

// No injected providers exist.
if (!injectedProviderExist) {
return
}

if ($window.foxwallet?.ethereum) {
return $window.foxwallet.ethereum
}

if ($window.ethereum.isFoxWallet) {
return $window.ethereum
}

if ($window.providers) {
return $window.providers.find((p) => p.isFoxWallet)
}

return
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance type safety and return consistency

The function could benefit from improved type safety and consistent return types.

-function getFoxWalletFromWindow() {
+function getFoxWalletFromWindow(): BrowserEip1993Provider | undefined {
   const injectedProviderExist =
-    typeof window !== 'undefined' &&
-    (typeof $window.ethereum !== 'undefined' ||
+    (typeof $window.ethereum !== 'undefined' ||
       typeof $window.foxwallet !== 'undefined')

   // No injected providers exist.
   if (!injectedProviderExist) {
     return
   }

   if ($window.foxwallet?.ethereum) {
     return $window.foxwallet.ethereum
   }

   if ($window.ethereum?.isFoxWallet) {
     return $window.ethereum
   }

-  if ($window.providers) {
+  if (Array.isArray($window.providers)) {
     return $window.providers.find((p) => p.isFoxWallet)
   }

   return
 }
📝 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
function getFoxWalletFromWindow() {
const injectedProviderExist =
typeof window !== 'undefined' &&
(typeof $window.ethereum !== 'undefined' ||
typeof $window.foxwallet !== 'undefined')
// No injected providers exist.
if (!injectedProviderExist) {
return
}
if ($window.foxwallet?.ethereum) {
return $window.foxwallet.ethereum
}
if ($window.ethereum.isFoxWallet) {
return $window.ethereum
}
if ($window.providers) {
return $window.providers.find((p) => p.isFoxWallet)
}
return
}
function getFoxWalletFromWindow(): BrowserEip1993Provider | undefined {
const injectedProviderExist =
(typeof $window.ethereum !== 'undefined' ||
typeof $window.foxwallet !== 'undefined')
// No injected providers exist.
if (!injectedProviderExist) {
return
}
if ($window.foxwallet?.ethereum) {
return $window.foxwallet.ethereum
}
if ($window.ethereum?.isFoxWallet) {
return $window.ethereum
}
if (Array.isArray($window.providers)) {
return $window.providers.find((p) => p.isFoxWallet)
}
return
}

Comment on lines +20 to +40
async function listenForFoxWalletInitialized(
{ timeout } = { timeout: 3000 },
) {
return new Promise((resolve) => {
const handleInitialization = () => {
resolve(getFoxWalletFromWindow())
}

$window.addEventListener('foxwallet#initialized', handleInitialization, {
once: true,
})

setTimeout(() => {
$window.removeEventListener(
'foxwallet#initialized',
handleInitialization,
)
resolve(null)
}, timeout)
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve error handling and prevent potential memory leaks

The current implementation has several potential issues:

  1. No error handling for invalid event data
  2. Possible memory leak if timeout occurs after event resolution
  3. No Promise rejection for error cases
 async function listenForFoxWalletInitialized(
   { timeout } = { timeout: 3000 },
 ) {
-  return new Promise((resolve) => {
+  return new Promise((resolve, reject) => {
+    let isResolved = false;
     const handleInitialization = () => {
-      resolve(getFoxWalletFromWindow())
+      if (isResolved) return;
+      isResolved = true;
+      try {
+        const provider = getFoxWalletFromWindow();
+        resolve(provider);
+      } catch (error) {
+        reject(error);
+      }
     }

     $window.addEventListener('foxwallet#initialized', handleInitialization, {
       once: true,
     })

-    setTimeout(() => {
+    const timeoutId = setTimeout(() => {
+      if (isResolved) return;
+      isResolved = true;
       $window.removeEventListener(
         'foxwallet#initialized',
         handleInitialization,
       )
       resolve(null)
     }, timeout)
   })
 }
📝 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
async function listenForFoxWalletInitialized(
{ timeout } = { timeout: 3000 },
) {
return new Promise((resolve) => {
const handleInitialization = () => {
resolve(getFoxWalletFromWindow())
}
$window.addEventListener('foxwallet#initialized', handleInitialization, {
once: true,
})
setTimeout(() => {
$window.removeEventListener(
'foxwallet#initialized',
handleInitialization,
)
resolve(null)
}, timeout)
})
}
async function listenForFoxWalletInitialized(
{ timeout } = { timeout: 3000 },
) {
return new Promise((resolve, reject) => {
let isResolved = false;
const handleInitialization = () => {
if (isResolved) return;
isResolved = true;
try {
const provider = getFoxWalletFromWindow();
resolve(provider);
} catch (error) {
reject(error);
}
}
$window.addEventListener('foxwallet#initialized', handleInitialization, {
once: true,
})
const timeoutId = setTimeout(() => {
if (isResolved) return;
isResolved = true;
$window.removeEventListener(
'foxwallet#initialized',
handleInitialization,
)
resolve(null)
}, timeout)
})
}

Comment on lines +93 to +97
case Wallet.FoxWallet:
return new EvmWalletStrategy({
...ethWalletArgs,
wallet: Wallet.FoxWallet,
})
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

FoxWallet is not registered in wallet-base package

FoxWallet needs to be added to both:

  • Wallet enum in packages/wallets/wallet-base/src/types/enums.ts
  • isEthWallet function in packages/wallets/wallet-base/src/utils/wallet.ts
🔗 Analysis chain

Verify FoxWallet registration in wallet-base package

Ensure that FoxWallet is properly registered in the wallet-base package's isEthWallet function to maintain consistent wallet type checking.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify FoxWallet registration in wallet-base package

# Check if FoxWallet is properly registered in isEthWallet function
rg -A 5 "isEthWallet.*=.*" packages/wallets/wallet-base/src

# Check if FoxWallet is defined in Wallet enum
rg -A 10 "export enum Wallet" packages/wallets/wallet-base/src

Length of output: 2223

try {
return await ethereum.request({
method: 'eth_signTypedData_v4',
params: [eip712json, address],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct parameter order for eth_signTypedData_v4

The parameters for eth_signTypedData_v4 should be [address, typedData], but they are currently [typedData, address], which will cause incorrect behavior.

Apply this diff to fix the parameter order:

         method: 'eth_signTypedData_v4',
-        params: [eip712json, address],
+        params: [address, eip712json],
📝 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
params: [eip712json, address],
params: [address, eip712json],

try {
const signature = await ethereum.request({
method: 'personal_sign',
params: [toUtf8(data), signer],
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Convert data to a hex string for personal_sign

The personal_sign method expects the message parameter to be a hex-encoded string. Currently, toUtf8(data) returns a Uint8Array. You should convert it to a hex string prefixed with 0x.

Apply this diff to convert the data to a hex string:

-        params: [toUtf8(data), signer],
+        params: [`0x${Buffer.from(data).toString('hex')}`, signer],

Ensure that data is properly converted to a hex string.

📝 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
params: [toUtf8(data), signer],
params: [`0x${Buffer.from(data).toString('hex')}`, signer],

Comment on lines +229 to +241
const transactionReceiptRetry = async () => {
const receipt = await ethereum.request({
method: 'eth_getTransactionReceipt',
params: [txHash],
})

if (!receipt) {
await sleep(interval)
await transactionReceiptRetry()
}

return receipt
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid potential stack overflow due to recursive retry logic

The transactionReceiptRetry function recursively calls itself when receipt is not found, which could lead to a stack overflow after many retries.

Refactor the function to use a loop instead of recursion:

    const transactionReceiptRetry = async () => {
-     const receipt = await ethereum.request({
-       method: 'eth_getTransactionReceipt',
-       params: [txHash],
-     })
-
-     if (!receipt) {
-       await sleep(interval)
-       await transactionReceiptRetry()
-     }
-
-     return receipt
+     let receipt = null
+     while (!receipt) {
+       receipt = await ethereum.request({
+         method: 'eth_getTransactionReceipt',
+         params: [txHash],
+       })
+       if (!receipt) {
+         await sleep(interval)
+       }
+     }
+     return receipt
    }
📝 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 transactionReceiptRetry = async () => {
const receipt = await ethereum.request({
method: 'eth_getTransactionReceipt',
params: [txHash],
})
if (!receipt) {
await sleep(interval)
await transactionReceiptRetry()
}
return receipt
}
const transactionReceiptRetry = async () => {
let receipt = null
while (!receipt) {
receipt = await ethereum.request({
method: 'eth_getTransactionReceipt',
params: [txHash],
})
if (!receipt) {
await sleep(interval)
}
}
return receipt
}

Comment on lines +80 to +98
async sendEthereumTransaction(
transaction: unknown,
_options: { address: AccountAddress; ethereumChainId: EthereumChainId },
): Promise<string> {
const ethereum = await this.getEthereum()

try {
return await ethereum.request({
method: 'eth_sendTransaction',
params: [transaction],
})
} catch (e: unknown) {
throw new CosmosWalletException(new Error((e as any).message), {
code: UnspecifiedErrorCode,
type: ErrorType.WalletError,
contextModule: WalletAction.SendEthereumTransaction,
})
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Specify the type of the transaction parameter

The transaction parameter is currently typed as unknown. Providing a specific type will improve type safety and code readability.

Please specify the appropriate type for transaction. For example:

-  async sendEthereumTransaction(
-    transaction: unknown,
+  async sendEthereumTransaction(
+    transaction: EthereumTransactionRequest,

Replace EthereumTransactionRequest with the actual type that matches the expected transaction object.

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

Comment on lines +217 to +222
throw new CosmosWalletException(new Error((e as any).message), {
code: UnspecifiedErrorCode,
type: ErrorType.WalletError,
contextModule: WalletAction.GetChainId,
})
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use appropriate exception type for Ethereum-related errors

In Ethereum-related methods, wrapping errors in CosmosWalletException might be misleading. Consider using a more appropriate exception type like WalletException to accurately reflect the context.

Update the exception to use WalletException:

-      throw new CosmosWalletException(new Error((e as any).message), {
+      throw new WalletException(new Error((e as any).message), {

Apply similar changes in other Ethereum-related methods where CosmosWalletException is used.

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

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