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

# createKrakenExchangeTransfer

# createKrakenExchangeTransfer

Creates a transfer from a Kraken exchange account to an external wallet address. This allows users to withdraw cryptocurrency from their Kraken holdings to a wallet they control.

Before calling this function, use [`getKrakenAccounts`](/javascript/reference/client/get-kraken-accounts) to get the `accountId` and verify available balance, and [`getKrakenWhitelistedAddresses`](/javascript/reference/client/get-kraken-whitelisted-addresses) to check if the destination address is valid.

## Usage

```javascript theme={"system"}
import {
  createKrakenExchangeTransfer,
  getKrakenAccounts,
} from '@dynamic-labs-sdk/client';

// Get the user's Kraken accounts
const accounts = await getKrakenAccounts();

// Create a transfer from the first account
const transfer = await createKrakenExchangeTransfer({
  accountId: accounts[0].id,
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f7ABCD',
  amount: 0.5,
  currency: 'ETH',
});

console.log('Transfer ID:', transfer.id);
console.log('Status:', transfer.status);
```

## Parameters

| Parameter                 | Type                       | Description                                                                                       |
| ------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------- |
| `accountId`               | `string`                   | The Kraken account ID to transfer from. Get this from `getKrakenAccounts()`.                      |
| `to`                      | `string`                   | The destination wallet address. Must be whitelisted if the user has address whitelisting enabled. |
| `amount`                  | `number`                   | The amount to transfer.                                                                           |
| `currency`                | `string`                   | The cryptocurrency to transfer (e.g., `'ETH'`, `'BTC'`, `'USDC'`).                                |
| `description`             | `string` (optional)        | A description for the transfer.                                                                   |
| `network`                 | `string` (optional)        | Network name (e.g., `'ethereum'`, `'polygon'`).                                                   |
| `networkObject`           | `object` (optional)        | Network details with `chainName` and `networkId`. Use this for multi-network tokens.              |
| `networkObject.chainName` | `string`                   | The chain name (e.g., `'EVM'`).                                                                   |
| `networkObject.networkId` | `string`                   | The network ID (e.g., `'1'` for Ethereum mainnet, `'137'` for Polygon).                           |
| `mfaCode`                 | `string` (optional)        | MFA code if required by the user's Kraken account settings.                                       |
| `id`                      | `string` (optional)        | Idempotency key to prevent duplicate transfers on retry.                                          |
| `client`                  | `DynamicClient` (optional) | The Dynamic client instance. Only required when using multiple clients.                           |

## Returns

`Promise<ExchangeTransferResponse>` - A promise that resolves to the transfer details:

```typescript theme={"system"}
type ExchangeTransferResponse = {
  id: string;                  // Unique transfer ID
  exchangeAccountId?: string;  // The Kraken account ID
  status?: string;             // Transfer status: 'pending', 'completed', 'failed', etc.
  amount: number;              // Amount transferred
  currency: string;            // Currency code
  createdAt?: Date;            // When the transfer was created
};
```

## Transfer Status Values

| Status      | Description                                        |
| ----------- | -------------------------------------------------- |
| `pending`   | Transfer has been submitted and is being processed |
| `completed` | Transfer has been successfully completed           |
| `failed`    | Transfer failed (check error details)              |

## Examples

### Basic transfer

```javascript theme={"system"}
import {
  createKrakenExchangeTransfer,
  getKrakenAccounts,
} from '@dynamic-labs-sdk/client';

const transferEth = async (destinationAddress, amount) => {
  // Get accounts and find one with ETH balance
  const accounts = await getKrakenAccounts();

  const accountWithEth = accounts.find(acc =>
    acc.balances.some(
      b => b.currency === 'ETH' && parseFloat(b.balance) >= amount
    )
  );

  if (!accountWithEth) {
    throw new Error('No account with sufficient ETH balance');
  }

  const transfer = await createKrakenExchangeTransfer({
    accountId: accountWithEth.id,
    to: destinationAddress,
    amount,
    currency: 'ETH',
    description: 'Withdraw ETH to wallet',
  });

  return transfer;
};

// Usage
const transfer = await transferEth('0x742d35Cc...', 0.1);
console.log('Transfer created:', transfer.id);
```

### Transfer USDC on a specific network

When transferring tokens that exist on multiple networks, specify the target network:

```javascript theme={"system"}
import { createKrakenExchangeTransfer } from '@dynamic-labs-sdk/client';

// Transfer USDC to Polygon
const transfer = await createKrakenExchangeTransfer({
  accountId: 'acc_123',
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f7ABCD',
  amount: 100,
  currency: 'USDC',
  networkObject: {
    chainName: 'EVM',
    networkId: '137', // Polygon
  },
  description: 'USDC to Polygon wallet',
});

// Transfer USDC to Ethereum mainnet
const mainnetTransfer = await createKrakenExchangeTransfer({
  accountId: 'acc_123',
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f7ABCD',
  amount: 100,
  currency: 'USDC',
  networkObject: {
    chainName: 'EVM',
    networkId: '1', // Ethereum mainnet
  },
});
```

### Transfer with MFA

If the user has MFA enabled on their Kraken account:

```javascript theme={"system"}
import { createKrakenExchangeTransfer } from '@dynamic-labs-sdk/client';

const transferWithMfa = async (params, mfaCode) => {
  const transfer = await createKrakenExchangeTransfer({
    ...params,
    mfaCode, // User-provided MFA code from their authenticator app
  });

  return transfer;
};

// Usage with user-provided MFA code
const transfer = await transferWithMfa(
  {
    accountId: 'acc_123',
    to: '0x742d35...',
    amount: 1.0,
    currency: 'BTC',
  },
  '123456' // MFA code from user
);
```

### Idempotent transfers

Use an idempotency key to safely retry failed requests without creating duplicate transfers:

```javascript theme={"system"}
import { createKrakenExchangeTransfer } from '@dynamic-labs-sdk/client';
import { v4 as uuidv4 } from 'uuid';

const createSafeTransfer = async (params) => {
  // Generate a unique ID for this transfer request
  const transferId = uuidv4();

  const transfer = await createKrakenExchangeTransfer({
    ...params,
    id: transferId, // Idempotency key
  });

  return transfer;
};

// If the network fails and you retry, the same transfer is returned
// instead of creating a duplicate
```

### Complete transfer flow with validation

```javascript theme={"system"}
import {
  getKrakenAccounts,
  getKrakenWhitelistedAddresses,
  createKrakenExchangeTransfer,
} from '@dynamic-labs-sdk/client';

const executeTransfer = async ({ currency, amount, destinationAddress }) => {
  // Step 1: Get accounts and verify balance
  const accounts = await getKrakenAccounts();

  let selectedAccount = null;
  let availableBalance = 0;

  for (const account of accounts) {
    const balance = account.balances.find(b => b.currency === currency);
    if (balance) {
      const available = parseFloat(balance.availableBalance || balance.balance);
      if (available >= amount) {
        selectedAccount = account;
        availableBalance = available;
        break;
      }
    }
  }

  if (!selectedAccount) {
    throw new Error(
      `Insufficient ${currency} balance. ` +
      `Requested: ${amount}, Available: ${availableBalance}`
    );
  }

  // Step 2: Verify destination address is whitelisted (if required)
  const { destinations, enforcesAddressWhitelist } =
    await getKrakenWhitelistedAddresses();

  if (enforcesAddressWhitelist) {
    const isWhitelisted = destinations.some(
      dest =>
        dest.address.toLowerCase() === destinationAddress.toLowerCase() &&
        dest.tokens?.includes(currency)
    );

    if (!isWhitelisted) {
      throw new Error(
        `Address ${destinationAddress} is not whitelisted for ${currency}. ` +
        'Add it in your Kraken account settings.'
      );
    }
  }

  // Step 3: Create the transfer
  const transfer = await createKrakenExchangeTransfer({
    accountId: selectedAccount.id,
    to: destinationAddress,
    amount,
    currency,
  });

  return {
    success: true,
    transferId: transfer.id,
    status: transfer.status,
    amount: transfer.amount,
    currency: transfer.currency,
  };
};

// Usage
try {
  const result = await executeTransfer({
    currency: 'ETH',
    amount: 0.5,
    destinationAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f7ABCD',
  });
  console.log('Transfer successful:', result);
} catch (error) {
  console.error('Transfer failed:', error.message);
}
```

### React component with transfer form

```tsx theme={"system"}
import { useCreateKrakenExchangeTransfer } from '@dynamic-labs-sdk/react-hooks';

const TransferButton = ({
  accountId,
  currency,
  destination,
  amount,
  onSuccess,
  onError,
}) => {
  const { mutate: createKrakenExchangeTransfer, isPending } = useCreateKrakenExchangeTransfer();

  const handleTransfer = () => {
    createKrakenExchangeTransfer(
      { accountId, to: destination, amount: parseFloat(amount), currency },
      {
        onSuccess: (transfer) => onSuccess(transfer),
        onError: (error) => onError(error.message),
      },
    );
  };

  return (
    <button onClick={handleTransfer} disabled={isPending}>
      {isPending ? 'Processing...' : `Transfer ${amount} ${currency}`}
    </button>
  );
};
```

### Handle transfer errors

```javascript theme={"system"}
import { createKrakenExchangeTransfer } from '@dynamic-labs-sdk/client';

const handleTransfer = async (params) => {
  try {
    const transfer = await createKrakenExchangeTransfer(params);
    return { success: true, transfer };
  } catch (error) {
    const message = error.message || 'Unknown error';

    // Handle specific error cases
    if (message.includes('insufficient') || message.includes('balance')) {
      return {
        success: false,
        error: 'Insufficient balance for this transfer',
        code: 'INSUFFICIENT_BALANCE',
      };
    }

    if (message.includes('whitelist')) {
      return {
        success: false,
        error: 'Destination address is not whitelisted',
        code: 'NOT_WHITELISTED',
      };
    }

    if (message.includes('mfa') || message.includes('authentication')) {
      return {
        success: false,
        error: 'MFA verification required',
        code: 'MFA_REQUIRED',
      };
    }

    return {
      success: false,
      error: message,
      code: 'UNKNOWN_ERROR',
    };
  }
};
```

## Prerequisites

* User must have connected their Kraken account through Dynamic
* The destination address must be whitelisted in Kraken if the user has address whitelisting enabled
* The Kraken account must have sufficient balance for the transfer

## Notes

* Transfers are processed by Kraken and may take time to complete depending on network conditions
* The `status` field indicates the current state of the transfer
* Use idempotency keys (`id` parameter) in production to prevent duplicate transfers from network retries
* For tokens on multiple networks (like USDC), always specify the `networkObject` to ensure the transfer goes to the correct chain

## Related

* [`getKrakenAccounts`](/javascript/reference/client/get-kraken-accounts) - Get user's Kraken account balances
* [`getKrakenWhitelistedAddresses`](/javascript/reference/client/get-kraken-whitelisted-addresses) - Get whitelisted withdrawal addresses
* [Kraken Integration Guide](/javascript/reference/client/kraken-integration) - Complete integration overview
