Depositing and Withdrawing

This page discusses how to deposit and withdraw funds from the Drift Protocol with DriftPy. The steps in Setup are required before using any code provided here.

In order to trade on Drift, you'll need to deposit some funds. And once you've traded and made a nice profit (or lost 95% leverage longing WIF-PERP), you'll want to withdraw those funds to your wallet. Here's how you can do that!

There are a couple methods by which you can deposit. The first, and easiest, is simply calling the DriftClient.deposit() function like this:

spot_market_index = 0 # USDC
amount_in_spot_market_precision = drift_client.convert_to_spot_precision(spot_market_index, 100) # $100

try:
    tx_sig_and_slot = await drift_client.deposit(
        amount_in_spot_market_precision,
        spot_market_index
    )
    print(f"Deposited successfully: {tx_sig_and_slot.tx_sig}")
except Exception as e:
    print(f"Failed to deposit: {e}")
    

Note the convert_to_spot_market_precision function call. Deposits and withdrawals on Drift require that the amount you pass in to be deposited is represented in the underlying spot market's precision. You can think of this like how when you transfer SOL in a smart contract, you specify 1 billion lamports and not 1 SOL, because SOL has 9 decimal points of precision. Under the hood all this does is multiply the amount you pass in by 10eSPOT_DECIMALS.

# assume spot_market is a valid SpotMarketAccount
precision = 10**spot_market.decimals
converted_amount = int(amount * precision)

If you'd like to bundle the deposit instruction with some other instructions, you can get the necessary deposit instructions by calling get_deposit_collateral_ix , which will return the necessary Instruction objects to make your deposit. Here's how you can do that:

from solders.instruction import Instruction

spot_market_index = 0 # USDC
amount_in_spot_market_precision = drift_client.convert_to_spot_precision(spot_market_index, 100) # $100

ixs: list[Instruction] = []

deposit_ix = drift_client.get_deposit_collateral_ix(
    amount_in_spot_market_precision,
    spot_market_index
)

ixs.append(deposit_ix)

# add some other instructions to ixs here..

try:
    tx_sig_and_slot = await drift_client.send_ixs(ixs)
    print(f"Successfully sent ixs: {tx_sig_and_slot.tx_sig}")
except Exception as e:
    print(f"Failed to send ixs: {e}")

Now, let's look at how to withdraw from Drift. Similar to depositing, there a couple different ways by which you can withdraw.

The simplest is calling the DriftClient.withdraw() function. Here's how to do that:

spot_market_index = 0 # USDC
amount_in_spot_market_precision = drift_client.convert_to_spot_precision(spot_market_index, 100) # $100

user_token_account = drift_client.get_associated_token_account_public_key(spot_market_index)

try:
    tx_sig_and_slot = await drift_client.withdraw(
        amount_in_spot_market_precision,
        spot_market_index,
        user_token_account
    )
    print(f"Withdrew successfully: {tx_sig_and_slot.tx_sig}")
except Exception as e:
    print(f"Failed to withdraw: {e}")

Note that withdrawal functions also require an additional user_token_account parameter corresponding to the Associated Token Account for the Keypair with which the Drift Client was created. This may be changed in a future version of DriftPy. More on Associated Token Accounts here: https://spl.solana.com/associated-token-account

To get the raw withdrawal instructions, you can follow a similar method as we did for getting the raw deposit instructions. Here's how you can do it:

from solders.instruction import Instruction

spot_market_index = 0 # USDC
amount_in_spot_market_precision = drift_client.convert_to_spot_precision(spot_market_index, 100) # $100

user_token_account = drift_client.get_associated_token_account_public_key(spot_market_index)

ixs: list[Instruction] = []

withdrawal_ix = drift_client.get_withdraw_collateral_ix(
    amount_in_spot_market_precision,
    spot_market_index,
    user_token_account
)

ixs.append(withdrawal_ix)

# add some other instructions to ixs here..

try:
    tx_sig_and_slot = await drift_client.send_ixs(ixs)
    print(f"Successfully sent ixs: {tx_sig_and_slot.tx_sig}")
except Exception as e:
    print(f"Failed to send ixs: {e}")

All functions shown here have some optional arguments that we haven't covered. Here's what they are and what they mean:

reduce_only: bool (Defaults to False)

Deposits:

True : You intend to repay a borrow.

False : You intend to deposit new collateral.

Withdrawals:

True : You intend to only withdraw from existing collateral

False : You are okay with opening a borrow to withdraw. Note: This will fail if your withdrawal size exceeds your account's margin requirements.

sub_account_id: int (Defaults to None , which is 0 in practice)

For both deposits and withdrawals, this represents the sub_account_id to or from which you intend to perform the operation.

Last updated