Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
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 to get the accountId and verify available balance, and getKrakenWhitelistedAddresses to check if the destination address is valid.
Usage
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:
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
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:
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:
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:
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
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);
}
import { useState } from 'react';
import { createKrakenExchangeTransfer } from '@dynamic-labs-sdk/client';
const TransferButton = ({
accountId,
currency,
destination,
amount,
onSuccess,
onError,
}) => {
const [submitting, setSubmitting] = useState(false);
const handleTransfer = async () => {
setSubmitting(true);
try {
const transfer = await createKrakenExchangeTransfer({
accountId,
to: destination,
amount: parseFloat(amount),
currency,
});
onSuccess(transfer);
} catch (error) {
onError(error.message);
} finally {
setSubmitting(false);
}
};
return (
<button onClick={handleTransfer} disabled={submitting}>
{submitting ? 'Processing...' : `Transfer ${amount} ${currency}`}
</button>
);
};
Handle transfer errors
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