Skip to content

feat: improve Ledger hardware wallet support for Solana DEX connectors #571

@fengtality

Description

@fengtality

Summary

Audit and improve Ledger hardware wallet support across all Solana DEX connectors. Currently, hardware wallet support is inconsistent - some connectors (Raydium, Jupiter) have it implemented while others (Meteora, Orca, PancakeSwap-Sol) are missing it entirely.

Current Status

✅ Connectors WITH Ledger Support

Connector Type Endpoints with Ledger Support
Raydium AMM executeSwap, addLiquidity, removeLiquidity
Raydium CLMM executeSwap, openPosition, closePosition, addLiquidity, removeLiquidity, collectFees
Jupiter Router executeQuote
PancakeSwap-Sol CLMM Has prepareWallet() and signAndSendTransaction() helper methods in connector class

❌ Connectors MISSING Ledger Support

Connector Type POST Endpoints Needing Ledger Support
Meteora CLMM executeSwap, openPosition, closePosition, addLiquidity, removeLiquidity, collectFees
Orca CLMM executeSwap, openPosition, closePosition, addLiquidity, removeLiquidity, collectFees

Requirements

1. Meteora CLMM - Add Ledger Support

Add hardware wallet support to all POST endpoints:

// In meteora.ts - Add prepareWallet method similar to Raydium
import { SolanaLedger } from '../../chains/solana/solana-ledger';

public async prepareWallet(walletAddress: string): Promise<{
  wallet: Keypair | PublicKey;
  isHardwareWallet: boolean;
}> {
  const isHardwareWallet = await this.solana.isHardwareWallet(walletAddress);
  const wallet = isHardwareWallet
    ? new PublicKey(walletAddress)
    : await this.solana.getWallet(walletAddress);
  return { wallet, isHardwareWallet };
}

public async signAndSendTransaction(
  transaction: VersionedTransaction | Transaction,
  walletAddress: string,
  isHardwareWallet: boolean,
): Promise<string> {
  if (isHardwareWallet) {
    logger.info(`Hardware wallet detected. Signing transaction with Ledger.`);
    const ledger = new SolanaLedger();
    await ledger.init();
    const signedTx = await ledger.signTransaction(transaction);
    return await this.solana.connection.sendRawTransaction(signedTx.serialize());
  } else {
    // Regular wallet signing
    const wallet = await this.solana.getWallet(walletAddress);
    // ... existing signing logic
  }
}

Files to update:

  • src/connectors/meteora/meteora.ts - Add helper methods
  • src/connectors/meteora/clmm-routes/executeSwap.ts
  • src/connectors/meteora/clmm-routes/openPosition.ts
  • src/connectors/meteora/clmm-routes/closePosition.ts
  • src/connectors/meteora/clmm-routes/addLiquidity.ts
  • src/connectors/meteora/clmm-routes/removeLiquidity.ts
  • src/connectors/meteora/clmm-routes/collectFees.ts

2. Orca CLMM - Add Ledger Support

Same pattern as Meteora - add prepareWallet() and signAndSendTransaction() methods.

Files to update:

  • src/connectors/orca/orca.ts - Add helper methods
  • src/connectors/orca/clmm-routes/executeSwap.ts
  • src/connectors/orca/clmm-routes/openPosition.ts
  • src/connectors/orca/clmm-routes/closePosition.ts
  • src/connectors/orca/clmm-routes/addLiquidity.ts
  • src/connectors/orca/clmm-routes/removeLiquidity.ts
  • src/connectors/orca/clmm-routes/collectFees.ts

3. PancakeSwap-Sol CLMM - Verify Usage

PancakeSwap-Sol has the helper methods but need to verify they are used in all route handlers:

  • src/connectors/pancakeswap-sol/clmm-routes/executeSwap.ts
  • src/connectors/pancakeswap-sol/clmm-routes/openPosition.ts
  • src/connectors/pancakeswap-sol/clmm-routes/closePosition.ts
  • src/connectors/pancakeswap-sol/clmm-routes/addLiquidity.ts
  • src/connectors/pancakeswap-sol/clmm-routes/removeLiquidity.ts
  • src/connectors/pancakeswap-sol/clmm-routes/collectFees.ts

Implementation Reference

Use Raydium as the reference implementation:

  • src/connectors/raydium/raydium.ts - prepareWallet() and signAndSendTransaction() methods
  • src/connectors/raydium/clmm-routes/executeSwap.ts - Example usage in route handler

Testing

Manual Testing with Ledger

  1. Connect Ledger device with Solana app open
  2. Add Ledger wallet to Gateway: POST /wallet/add with hardware wallet derivation path
  3. Test each POST endpoint with the Ledger wallet address
  4. Verify transaction appears on Ledger for signing
  5. Confirm transaction completes successfully after approval

Test Cases

For each connector (Meteora, Orca, PancakeSwap-Sol):

  • executeSwap with Ledger wallet
  • openPosition with Ledger wallet
  • closePosition with Ledger wallet
  • addLiquidity with Ledger wallet
  • removeLiquidity with Ledger wallet
  • collectFees with Ledger wallet

Acceptance Criteria

  • Meteora CLMM: All 6 POST endpoints support Ledger signing
  • Orca CLMM: All 6 POST endpoints support Ledger signing
  • PancakeSwap-Sol CLMM: Verify all 6 POST endpoints use Ledger signing
  • No regressions for software wallet signing
  • Proper error handling for Ledger-specific errors (device locked, user rejected, etc.)
  • Logging indicates when hardware wallet is detected

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions