post https://sandbox.kyan.sh/transfer
Transfer USDC collateral between your different margin accounts (e.g., from ETH_USDC to BTC_USDC account). This allows you to rebalance collateral without withdrawing to your wallet and re-depositing.
Requires signature: Include signature and signature_deadline fields in the request.
When to Use Transfers
- Rebalancing Collateral: Move excess funds from one pair to another
- Risk Management: Shift collateral to accounts needing more margin
- Efficient Capital Use: Avoid on-chain transactions when moving between accounts
- Quick Position Changes: Prepare collateral before opening positions in new pairs
How Transfers Work
- Instant Execution: No on-chain transaction required
- Atomic Operation: Transfer completes fully or not at all
- Risk Validation: Source account must maintain required margins after transfer
- Zero Fees: Internal transfers don't incur blockchain gas costs
Transfer Requirements
The source account must maintain after the transfer:
- Equity > Initial Margin (for new position capability)
- Equity > Maintenance Margin (to avoid liquidation)
- Account must not be in liquidation status
Example Scenarios
Scenario 1: Free up capital
- You closed all ETH positions but have 10,000 USDC locked in ETH_USDC account
- Transfer the full amount to BTC_USDC account for Bitcoin trading
Scenario 2: Emergency margin top-up
- Your BTC_USDC account is approaching liquidation
- Quickly transfer funds from ETH_USDC to increase BTC margin
Scenario 3: Portfolio rebalancing
- Market conditions change, you want more ETH exposure
- Transfer collateral from multiple accounts into ETH_USDC
Best Practices
- Always check source account state before transferring
- Leave safety buffer in accounts with open positions
- Consider pending orders that might require margin
- Use transfers instead of withdraw/deposit for efficiency
EIP-712 Signature Example (TypeScript)
import { parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
// Domain parameters for EIP-712 signature
const EIP712Domain = {
chainId: 421614, // Arbitrum Sepolia (use 42161 for Arbitrum One mainnet)
name: 'Premia',
verifyingContract: '0x...' // ClearingHouseProxy address from deployment
version: '1'
};
// Type definition for transfers
const UserTransfer = [
{ name: 'account', type: 'address' },
{ name: 'amount', type: 'uint256' },
{ name: 'fromPair', type: 'Pair' },
{ name: 'toPair', type: 'Pair' }
];
const Pair = [
{ name: 'base', type: 'address' },
{ name: 'quote', type: 'address' }
];
// Example transfer data
const transfer = {
account: '0xYourAddress',
amount: '1000.0', // Amount in USDC
from_pair: {
base: '0x...', // ETH token address
quote: '0x...' // USDC token address
},
to_pair: {
base: '0x...', // BTC token address
quote: '0x...' // USDC token address
}
};
// Calculate deadline (30 seconds from now)
const deadline = Math.floor(Date.now() / 1000) + 30;
// Setup wallet
const account = privateKeyToAccount('0xYourPrivateKey');
// Sign the typed data
const signature = await account.signTypedData({
domain: EIP712Domain,
types: { UserTransfer, Pair },
primaryType: 'UserTransfer',
message: {
account: transfer.account,
amount: parseUnits(transfer.amount, 6),
fromPair: transfer.from_pair,
toPair: transfer.to_pair
}
});
// Final request payload
const requestPayload = {
...transfer,
signature,
signature_deadline: deadline
};