> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baanx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Complete Solana Wallet Delegation

> Finalize delegation of spending authority from Solana wallets (Step 3 of 3)

## Overview

This endpoint finalizes the delegation of spending authority from a user's Solana wallet. After the user has completed wallet connection and token account delegation transaction in your frontend, call this endpoint to register the wallet with the platform.

<Note>
  **When to Use**: Call this endpoint after the user has successfully completed the token account delegation transaction on Solana in your frontend application (Step 2). This is the final step in the delegation workflow for Solana wallets.
</Note>

## Solana-Specific Validation

This endpoint performs strict validation for Solana blockchain:

* **Address Format**: Must be a valid Solana public key (base58-encoded, 32-44 characters)
* **Transaction Signature**: Must be a valid Solana transaction signature (base58-encoded, 87-88 characters)
* **Message Signature**: Must be a valid Solana signature (base58-encoded, 87-88 characters)
* **Network**: Must be `solana`

## Authentication

<ParamField header="x-client-key" type="string" required>
  Your public client key for API authentication
</ParamField>

<ParamField header="Authorization" type="string" required>
  Bearer token format: `Bearer {access_token}`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

## Query Parameters

<ParamField query="region" type="string">
  Region identifier for environment routing. Use `us` for US-specific routing.

  **Example**: `?region=us`

  **Note**: Alternatively, you can use the `x-us-env: true` header instead of the region query parameter.
</ParamField>

## Request Body

<ParamField body="address" type="string" required>
  Solana wallet public key that will be delegated. Must be a valid base58-encoded Solana public key (32-44 characters).

  **Pattern**: `^[1-9A-HJ-NP-Za-km-z]{32,44}$`

  **Example**: `DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK`

  This address must match the one that signed the delegation transaction.
</ParamField>

<ParamField body="network" type="string" required>
  Must be `solana` for Solana blockchain.

  **Allowed values**:

  * `solana` - Solana mainnet
</ParamField>

<ParamField body="currency" type="string" required>
  SPL token that was approved for delegation.

  **Allowed values**:

  * `usdc` - USD Coin (SPL)
  * `usdt` - Tether USD (SPL)
</ParamField>

<ParamField body="amount" type="string" required>
  Spending limit approved in the delegation. Specified in the currency's base unit (e.g., 5000 for 5000 USDC). This is the maximum amount the platform can spend from the delegated wallet.

  **Pattern**: `^\d+(\.\d+)?$`

  **Example**: `"5000"` or `"5000.50"`
</ParamField>

<ParamField body="txHash" type="string" required>
  Solana transaction signature of the token account delegation. Must be a valid base58-encoded signature (87-88 characters).

  **Pattern**: `^[1-9A-HJ-NP-Za-km-z]{87,88}$`

  **Example**: `5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW`

  The API verifies this transaction exists on-chain and is confirmed.
</ParamField>

<ParamField body="sigHash" type="string" required>
  Solana signature hash proving wallet ownership. Result of signing `sigMessage` with the wallet's private key. Must be a valid base58-encoded signature (87-88 characters).

  **Pattern**: `^[1-9A-HJ-NP-Za-km-z]{87,88}$`

  **Example**: `2Uhj5WqpLvZmJqKGx3WKvSC5K1m4YCp1eK3jcGY7GgRqNnBQEXhP9XjWCv4M3nZKF7RqWpLvZmJqKGx3WKvSC5K1`
</ParamField>

<ParamField body="sigMessage" type="string" required>
  The message that was signed by the Solana wallet to prove ownership. Can be any string that proves ownership, but should be meaningful.

  **Minimum length**: 10 characters

  **Example**: `"Prove wallet ownership for delegation"`

  **Recommended format**: Include purpose, timestamp, and nonce for security
</ParamField>

<ParamField body="token" type="string" required>
  Single-use delegation token obtained from `GET /v1/delegation/token` (Step 1). Must be a valid UUID.

  **Format**: UUID v4

  **Example**: `100a99cf-f4d3-4fa1-9be9-2e9828b20ebc`

  **Note**: Token expires after \~10 minutes or after successful use.
</ParamField>

## Response

<ResponseField name="success" type="boolean" required>
  Indicates whether the wallet delegation was completed successfully.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://dev.api.baanx.com/v1/delegation/solana/post-approval' \
    --header 'x-client-key: YOUR_PUBLIC_KEY' \
    --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
    --header 'Content-Type: application/json' \
    --data '{
      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "network": "solana",
      "currency": "usdc",
      "amount": "5000",
      "txHash": "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW",
      "sigHash": "2Uhj5WqpLvZmJqKGx3WKvSC5K1m4YCp1eK3jcGY7GgRqNnBQEXhP9XjWCv4M3nZKF7RqWpLvZmJqKGx3WKvSC5K1",
      "sigMessage": "Prove wallet ownership for delegation",
      "token": "100a99cf-f4d3-4fa1-9be9-2e9828b20ebc"
    }'
  ```

  ```python Python theme={null}
  import requests
  from typing import Dict

  def complete_solana_delegation(
      delegation_token: str,
      wallet_address: str,
      currency: str,
      amount: str,
      tx_hash: str,
      sig_hash: str,
      sig_message: str
  ) -> Dict:
      url = "https://dev.api.baanx.com/v1/delegation/solana/post-approval"

      headers = {
          "x-client-key": "YOUR_PUBLIC_KEY",
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json"
      }

      payload = {
          "address": wallet_address,
          "network": "solana",
          "currency": currency,
          "amount": amount,
          "txHash": tx_hash,
          "sigHash": sig_hash,
          "sigMessage": sig_message,
          "token": delegation_token
      }

      response = requests.post(url, headers=headers, json=payload)
      return response.json()

  # Usage
  result = complete_solana_delegation(
      delegation_token="100a99cf-f4d3-4fa1-9be9-2e9828b20ebc",
      wallet_address="DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      currency="usdc",
      amount="5000",
      tx_hash="5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW",
      sig_hash="2Uhj5WqpLvZmJqKGx3WKvSC5K1m4YCp1eK3jcGY7GgRqNnBQEXhP9XjWCv4M3nZKF7RqWpLvZmJqKGx3WKvSC5K1",
      sig_message="Prove wallet ownership for delegation"
  )
  ```

  ```javascript JavaScript theme={null}
  const completeDelegation = async (delegationData) => {
    const url = 'https://dev.api.baanx.com/v1/delegation/solana/post-approval';

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'x-client-key': 'YOUR_PUBLIC_KEY',
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        address: delegationData.address,
        network: 'solana',
        currency: delegationData.currency,
        amount: delegationData.amount,
        txHash: delegationData.txHash,
        sigHash: delegationData.sigHash,
        sigMessage: delegationData.sigMessage,
        token: delegationData.token
      })
    });

    return await response.json();
  };

  // Usage
  const result = await completeDelegation({
    address: 'DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK',
    currency: 'usdc',
    amount: '5000',
    txHash: '5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW',
    sigHash: '2Uhj5WqpLvZmJqKGx3WKvSC5K1m4YCp1eK3jcGY7GgRqNnBQEXhP9XjWCv4M3nZKF7RqWpLvZmJqKGx3WKvSC5K1',
    sigMessage: 'Prove wallet ownership for delegation',
    token: '100a99cf-f4d3-4fa1-9be9-2e9828b20ebc'
  });
  ```

  ```typescript TypeScript theme={null}
  interface SolanaDelegationRequest {
    address: string;
    network: 'solana';
    currency: 'usdc' | 'usdt';
    amount: string;
    txHash: string;
    sigHash: string;
    sigMessage: string;
    token: string;
  }

  interface DelegationResponse {
    success: boolean;
  }

  async function completeSolanaDelegation(
    data: SolanaDelegationRequest
  ): Promise<DelegationResponse> {
    const url = 'https://dev.api.baanx.com/v1/delegation/solana/post-approval';

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'x-client-key': 'YOUR_PUBLIC_KEY',
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

    if (!response.ok) {
      throw new Error(`Delegation failed: ${response.statusText}`);
    }

    return await response.json();
  }

  // Usage
  const result = await completeSolanaDelegation({
    address: 'DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK',
    network: 'solana',
    currency: 'usdc',
    amount: '5000',
    txHash: '5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW',
    sigHash: '2Uhj5WqpLvZmJqKGx3WKvSC5K1m4YCp1eK3jcGY7GgRqNnBQEXhP9XjWCv4M3nZKF7RqWpLvZmJqKGx3WKvSC5K1',
    sigMessage: 'Prove wallet ownership for delegation',
    token: '100a99cf-f4d3-4fa1-9be9-2e9828b20ebc'
  });
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Success theme={null}
  {
    "success": true
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "message": "Invalid Solana address format"
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "message": "Invalid or expired access token"
  }
  ```

  ```json 422 Validation Error theme={null}
  {
    "message": "Validation failed",
    "errors": [
      {
        "field": "txHash",
        "message": "Invalid transaction signature format. Must be base58-encoded, 87-88 characters"
      }
    ]
  }
  ```

  ```json 500 Internal Server Error theme={null}
  {
    "message": "An unexpected error occurred. Please try again later."
  }
  ```
</ResponseExample>

## Response Codes

| Code | Description                                              |
| ---- | -------------------------------------------------------- |
| 201  | Wallet delegation completed successfully                 |
| 400  | Bad request - invalid data format or verification failed |
| 401  | Authentication failed - invalid or expired access token  |
| 422  | Validation error - invalid request parameters            |
| 498  | Invalid client key                                       |
| 499  | Missing client key                                       |
| 500  | Internal server error                                    |

## What Happens After Success

When this endpoint returns successfully:

1. **Wallet Registration**: The external wallet is registered and linked to the user's account
2. **Card Payments Enabled**: User can now make card purchases using delegated wallet funds
3. **Wallet Visibility**: Wallet appears in `GET /v1/wallet/external` endpoint response
4. **Priority Assignment**: Wallet is assigned a default priority for transaction processing
5. **Balance Tracking**: Platform begins tracking wallet balance and allowance

## Solana Token Delegation

On Solana, delegation uses SPL Token's approve instruction to delegate token account authority:

```typescript theme={null}
import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
import { Connection, PublicKey } from '@solana/web3.js';

const connection = new Connection('https://api.mainnet-beta.solana.com');

// Create approve instruction
const approveInstruction = Token.createApproveInstruction(
  TOKEN_PROGRAM_ID,
  tokenAccountAddress,      // User's token account
  delegateAddress,          // Platform's delegate address
  walletPublicKey,          // User's wallet
  [],                       // Signers (empty for wallet adapter)
  amount                    // Amount to approve
);
```

## Complete Implementation Example

Here's a full end-to-end example of the Solana delegation flow:

<CodeGroup>
  ```typescript Complete Flow - Phantom Wallet theme={null}
  import { Connection, PublicKey, Transaction } from '@solana/web3.js';
  import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
  import bs58 from 'bs58';

  async function delegateSolanaWallet(delegationToken: string, amount: string) {
    try {
      // Step 1: Check if Phantom is installed
      const provider = (window as any).solana;
      if (!provider?.isPhantom) {
        throw new Error('Phantom wallet not found');
      }

      // Step 2: Connect wallet
      await provider.connect();
      const walletPublicKey = new PublicKey(provider.publicKey.toString());
      console.log('Connected to wallet:', walletPublicKey.toBase58());

      // Step 3: Setup connection and token accounts
      const connection = new Connection('https://api.mainnet-beta.solana.com');
      const tokenMintAddress = new PublicKey(
        'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC mint
      );

      // Get user's token account
      const tokenAccounts = await connection.getParsedTokenAccountsByOwner(
        walletPublicKey,
        { mint: tokenMintAddress }
      );

      if (tokenAccounts.value.length === 0) {
        throw new Error('No USDC token account found');
      }

      const tokenAccountAddress = tokenAccounts.value[0].pubkey;

      // Step 4: Create delegation transaction
      const delegateAddress = new PublicKey('YOUR_PLATFORM_DELEGATE_ADDRESS');
      const amountLamports = parseFloat(amount) * 1_000_000; // USDC has 6 decimals

      const transaction = new Transaction().add(
        Token.createApproveInstruction(
          TOKEN_PROGRAM_ID,
          tokenAccountAddress,
          delegateAddress,
          walletPublicKey,
          [],
          amountLamports
        )
      );

      // Set recent blockhash
      const { blockhash } = await connection.getRecentBlockhash();
      transaction.recentBlockhash = blockhash;
      transaction.feePayer = walletPublicKey;

      // Step 5: Sign and send delegation transaction
      const signedTx = await provider.signTransaction(transaction);
      const txSignature = await connection.sendRawTransaction(
        signedTx.serialize()
      );

      console.log('Delegation transaction sent:', txSignature);

      // Wait for confirmation
      await connection.confirmTransaction(txSignature, 'confirmed');
      console.log('Delegation transaction confirmed');

      // Step 6: Sign message for ownership proof
      const message = `Prove wallet ownership for delegation\nTimestamp: ${Date.now()}\nNonce: ${Math.random().toString(36).substring(7)}`;
      const encodedMessage = new TextEncoder().encode(message);
      const signedMessage = await provider.signMessage(encodedMessage, 'utf8');
      const signature = bs58.encode(signedMessage.signature);

      console.log('Message signed successfully');

      // Step 7: Submit to API
      const response = await fetch(
        'https://dev.api.baanx.com/v1/delegation/solana/post-approval',
        {
          method: 'POST',
          headers: {
            'x-client-key': 'YOUR_PUBLIC_KEY',
            'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            address: walletPublicKey.toBase58(),
            network: 'solana',
            currency: 'usdc',
            amount: amount,
            txHash: txSignature,
            sigHash: signature,
            sigMessage: message,
            token: delegationToken
          })
        }
      );

      const result = await response.json();

      if (response.ok) {
        console.log('Delegation completed successfully!');
        return { success: true, data: result };
      } else {
        console.error('Delegation failed:', result);
        return { success: false, error: result };
      }

    } catch (error) {
      console.error('Error during delegation:', error);
      return { success: false, error: (error as Error).message };
    }
  }

  // Usage
  const result = await delegateSolanaWallet(
    '100a99cf-f4d3-4fa1-9be9-2e9828b20ebc',
    '5000'
  );
  ```

  ```typescript Using @solana/wallet-adapter theme={null}
  import { useWallet, useConnection } from '@solana/wallet-adapter-react';
  import { Transaction } from '@solana/web3.js';
  import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
  import bs58 from 'bs58';

  function DelegationComponent() {
    const { publicKey, signTransaction, signMessage } = useWallet();
    const { connection } = useConnection();

    const handleDelegation = async (delegationToken: string, amount: string) => {
      if (!publicKey || !signTransaction || !signMessage) {
        throw new Error('Wallet not connected');
      }

      try {
        // Get token account
        const tokenMintAddress = new PublicKey(
          'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
        );

        const tokenAccounts = await connection.getParsedTokenAccountsByOwner(
          publicKey,
          { mint: tokenMintAddress }
        );

        const tokenAccountAddress = tokenAccounts.value[0].pubkey;
        const delegateAddress = new PublicKey('YOUR_PLATFORM_DELEGATE_ADDRESS');
        const amountLamports = parseFloat(amount) * 1_000_000;

        // Create and send delegation transaction
        const transaction = new Transaction().add(
          Token.createApproveInstruction(
            TOKEN_PROGRAM_ID,
            tokenAccountAddress,
            delegateAddress,
            publicKey,
            [],
            amountLamports
          )
        );

        const { blockhash } = await connection.getRecentBlockhash();
        transaction.recentBlockhash = blockhash;
        transaction.feePayer = publicKey;

        const signed = await signTransaction(transaction);
        const txSignature = await connection.sendRawTransaction(
          signed.serialize()
        );

        await connection.confirmTransaction(txSignature);

        // Sign ownership message
        const message = `Prove wallet ownership for delegation\nTimestamp: ${Date.now()}`;
        const encodedMessage = new TextEncoder().encode(message);
        const signedMsg = await signMessage(encodedMessage);
        const signature = bs58.encode(signedMsg);

        // Submit to API
        const response = await fetch(
          'https://dev.api.baanx.com/v1/delegation/solana/post-approval',
          {
            method: 'POST',
            headers: {
              'x-client-key': process.env.NEXT_PUBLIC_CLIENT_KEY!,
              'Authorization': `Bearer ${accessToken}`,
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              address: publicKey.toBase58(),
              network: 'solana',
              currency: 'usdc',
              amount: amount,
              txHash: txSignature,
              sigHash: signature,
              sigMessage: message,
              token: delegationToken
            })
          }
        );

        return await response.json();

      } catch (error) {
        console.error('Delegation error:', error);
        throw error;
      }
    };

    return (
      <button onClick={() => handleDelegation(token, '5000')}>
        Delegate Wallet
      </button>
    );
  }
  ```
</CodeGroup>

## Message Signing

For Solana, the `sigMessage` should be a clear, descriptive message. Here's a recommended format:

```typescript theme={null}
function generateSolanaMessage(): string {
  const timestamp = Date.now();
  const nonce = Math.random().toString(36).substring(7);

  return `Prove wallet ownership for delegation
Timestamp: ${timestamp}
Nonce: ${nonce}
Action: Delegate spending authority to Baanx platform`;
}

// Sign the message
const message = generateSolanaMessage();
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await wallet.signMessage(encodedMessage, 'utf8');
const signature = bs58.encode(signedMessage.signature);
```

## Redelegation

To update an existing delegation (change allowance, upgrade contracts, etc.), simply call this endpoint again with the same wallet address. The new delegation will replace the previous one.

**Common redelegation scenarios:**

* **Increase spending limit**: User wants to approve a higher amount
* **Contract upgrade**: Platform deploys new smart contracts
* **Token account change**: User wants to delegate a different token account

<Warning>
  When redelegating, the user must complete a new token account delegation transaction with the updated parameters before calling this endpoint.
</Warning>

## Verification After Delegation

After successful delegation, verify the wallet was registered:

<CodeGroup>
  ```bash Verify Wallet theme={null}
  curl --request GET \
    --url 'https://dev.api.baanx.com/v1/wallet/external' \
    --header 'x-client-key: YOUR_PUBLIC_KEY' \
    --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
  ```

  ```json Expected Response theme={null}
  [
    {
      "id": 552,
      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "currency": "usdc",
      "balance": "5000.00",
      "allowance": "5000",
      "network": "solana",
      "priority": 1
    }
  ]
  ```
</CodeGroup>

## Common Error Scenarios

### Invalid Transaction Signature

```json theme={null}
{
  "message": "Transaction not found on blockchain"
}
```

**Causes:**

* Transaction hasn't been confirmed yet
* Invalid transaction signature format
* Wrong network (e.g., devnet instead of mainnet)

**Solutions:**

* Wait for transaction confirmation (typically 10-30 seconds)
* Verify signature is base58-encoded and 87-88 characters
* Ensure transaction was sent to mainnet

### Signature Verification Failed

```json theme={null}
{
  "message": "Signature verification failed"
}
```

**Causes:**

* `sigHash` doesn't match the wallet that signed
* `sigMessage` was modified after signing
* Wrong encoding used for signature

**Solutions:**

* Ensure the same wallet signs both the delegation and message
* Don't modify `sigMessage` after user signs it
* Use `bs58.encode()` for signature encoding

### Invalid Address Format

```json theme={null}
{
  "message": "Invalid Solana address format"
}
```

**Causes:**

* Address is not base58-encoded
* Address length is incorrect
* Contains invalid base58 characters (0, O, I, l)

**Solutions:**

* Use `publicKey.toBase58()` to get correct format
* Verify address is 32-44 characters
* Don't include prefixes or suffixes

### Expired Delegation Token

```json theme={null}
{
  "message": "Delegation token has expired or already been used"
}
```

**Causes:**

* More than 10 minutes passed since token generation
* Token was already used in a previous request

**Solutions:**

* Generate a new delegation token from Step 1
* Complete the flow more quickly
* Don't reuse tokens

## SPL Token Addresses

Common SPL token addresses on Solana mainnet:

| Token | Mint Address                                   |
| ----- | ---------------------------------------------- |
| USDC  | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |
| USDT  | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` |

<Note>
  Always verify token addresses with official sources before using them in production.
</Note>

## Best Practices

<Accordion title="Transaction Confirmation">
  **Always wait for transaction confirmation** before calling this endpoint:

  * Wait for 'confirmed' commitment level minimum
  * For higher security, wait for 'finalized' commitment
  * Display transaction status to users
  * Implement timeout handling (typically 60 seconds)
  * Provide transaction link to Solana Explorer
</Accordion>

<Accordion title="Wallet Support">
  **Support popular Solana wallets**:

  * Phantom (most popular)
  * Solflare
  * Backpack
  * Glow
  * Use @solana/wallet-adapter for easy integration
  * Handle wallet not installed gracefully
</Accordion>

<Accordion title="Error Handling">
  **Implement comprehensive error handling**:

  * Handle user rejection gracefully
  * Retry failed transactions with same parameters
  * Provide clear error messages to users
  * Log errors for debugging (without exposing sensitive data)
  * Implement exponential backoff for API retries
</Accordion>

<Accordion title="Security">
  **Follow security best practices**:

  * Never store private keys
  * Validate all addresses before submission
  * Use HTTPS only for all API calls
  * Implement rate limiting on your backend
  * Verify transaction on blockchain before submitting to API
  * Use recent blockhashes (prevent replay attacks)
</Accordion>

<Accordion title="User Experience">
  **Create a smooth user experience**:

  * Show progress indicators during each step
  * Display transaction fees before approval
  * Explain delegation in simple terms
  * Provide transaction links to Solana Explorer
  * Allow users to easily retry on failure
  * Show estimated confirmation time
</Accordion>

## Solana-Specific Considerations

### Transaction Fees

Solana transactions require SOL for transaction fees:

* Typical fee: 0.000005 SOL (\~\$0.0001)
* Ensure user has small amount of SOL for fees
* Display estimated fee before transaction

### Token Accounts

Users must have a token account for the SPL token:

* Check if token account exists before delegation
* Create token account if needed (costs \~0.002 SOL)
* Handle associated token account vs regular token account

### Network Congestion

During high network activity:

* Transactions may take longer to confirm
* Consider using higher priority fees
* Implement retry logic with exponential backoff
* Display status updates to user

## Related Endpoints

* [GET /v1/delegation/token](/api-reference/delegation/token) - Generate delegation token (Step 1)
* [POST /v1/delegation/evm/post-approval](/api-reference/delegation/evm-post-approval) - Complete EVM wallet delegation
* [GET /v1/wallet/external](/api-reference/wallet/external) - List delegated wallets
* [Manage External Wallet Priority](/api-reference/wallet/external-priority) - Get and update wallet priority order

## Further Reading

* [Delegation Overview](/guides/delegation/overview) - Understand delegation concepts
* [Implementation Guide](/guides/delegation/implementation) - Complete integration walkthrough
* [Solana Implementation](/guides/delegation/solana) - Detailed Solana-specific implementation
* [Priority Management](/guides/delegation/priority) - Managing multiple wallets
* [Redelegation](/guides/delegation/redelegation) - Updating existing delegations

## External Resources

* [Solana Web3.js Documentation](https://solana-labs.github.io/solana-web3.js/)
* [SPL Token Program](https://spl.solana.com/token)
* [Phantom Wallet Documentation](https://docs.phantom.app/)
* [@solana/wallet-adapter](https://github.com/solana-labs/wallet-adapter)
* [Solana Explorer](https://explorer.solana.com/)
