Deposit & Transfer dfTokens
⏱️ 7 min read
📖 What You'll Learn
In this tutorial you'll build a TypeScript script that:
Deposits assets into a DeFindex vault and receives dfTokens in return
Transfers those dfTokens to another Stellar wallet
By the end, you'll have a working script that automates this entire flow — useful for vault managers who want to run raffles, airdrops, or distribute incentives to their users.
💡 Why Would I Want to Transfer dfTokens?
When you deposit into a DeFindex vault, the vault mints dfTokens — tokens that represent your proportional share of the vault's assets. These tokens:
Increase in value as the vault earns yield
Can be redeemed later for the underlying assets + profits
Are transferable, just like any other Stellar token
This means a vault manager can deposit funds, receive dfTokens, and then distribute them to other wallets. The recipients now hold vault shares without needing to deposit themselves. Some practical use cases:
🎁 Raffles & Giveaways
Deposit and distribute dfTokens as prizes
🏆 User Incentives
Reward active users with yield-bearing tokens
💼 Team Distribution
Split vault ownership across team members
🔄 OTC Transfers
Move vault positions between wallets
🎯 Prerequisites
Before starting, make sure you have:
Node.js (v18+) and a package manager (
npm,yarn, or similar)A Stellar wallet with enough balance for the deposit + transaction fees
A DeFindex API key (register at api.defindex.io or contact us on Discord)
Basic knowledge of TypeScript and the Stellar network
🧠 Key Concepts
Before diving into code, let's understand the two core operations we'll perform.
Deposit → Mint dfTokens
When you call deposit on a DeFindex vault, the contract:
Transfers your assets (e.g., XLM) from your wallet into the vault
Calculates how many shares you should receive, proportional to your contribution
Mints dfTokens to your wallet representing those shares
Optionally invests the deposited funds into the vault's strategies
The vault contract's deposit function signature looks like this:
It returns a tuple with: the actual deposited amounts, the number of dfTokens minted, and the investment allocations.
Transfer dfTokens
Here's something important: the vault contract itself is the dfToken contract. The vault implements the standard Stellar token interface, which means you can call transfer directly on the vault contract to move dfTokens between wallets:
No separate token contract needed — just call transfer on the vault address with the sender, receiver, and amount.
🏗️ Step-by-Step Implementation
Step 1: Project Setup
Create a new project and install the required dependencies:
Add a run script to your package.json:
Create a tsconfig.json:
Create a .env file with your configuration:
⚠️ Never commit your
.envfile to version control. Add it to your.gitignore.Note: This tutorial uses testnet for learning purposes. For production, change
SOROBAN_RPCto a mainnet endpoint (e.g.,https://soroban-rpc.mainnet.stellar.gateway.fm) and update the network references in the code toNetworks.PUBLIC/SupportedNetworks.MAINNET.
Step 2: Load Configuration
Create src/index.ts and start by importing dependencies and loading environment variables:
Define your constants. You'll need to update VAULT_ADDRESS to match the vault you want to deposit into:
About decimals: Stellar uses 7 decimal places for most assets. So
10 XLM=100,000,000stroops (base units). Always convert to raw amounts before calling contract functions. We useBigInt(Math.round(...))to avoid floating-point precision issues with non-integer amounts like0.5.
Now load and validate the environment variables:
Step 3: Transaction Helper
Both deposit and transfer need to submit a transaction and wait for on-chain confirmation. Let's create a reusable helper:
🔍 What this function does:
Submits the signed transaction to the Soroban RPC
Validates the transaction was accepted (status
PENDING)Polls every 2 seconds (up to 60s) until the transaction is confirmed or fails
Returns the transaction hash and the on-chain return value
Step 4: The Deposit Function 💰
This function uses the DeFindex SDK to build a deposit transaction, signs it locally, and submits it. The key part is extracting the minted dfTokens from the return value:
🔍 What this function does:
Builds an unsigned deposit transaction using the DeFindex SDK (
depositToVault)Signs the transaction with your keypair
Submits it to the network and waits for confirmation
Parses the return value to extract how many dfTokens were minted
Why
invest: true? When set totrue, the vault automatically allocates your deposited funds into its yield-generating strategies. Set tofalseif you want the funds to remain idle in the vault.Tip: You can also pass
slippageBpsin the deposit params (e.g.,slippageBps: 100for 1% tolerance) to control slippage during deposit.Note: The number of dfTokens minted is not 1:1 with the deposited amount. dfTokens represent your proportional share of the vault — their quantity depends on the vault's current share price, which changes as the vault earns yield.
Step 5: The Transfer Function 🔄
Now the interesting part — transferring dfTokens to another wallet. Since the vault contract implements the token interface, we call transfer directly on the vault contract address:
🔍 What this function does:
Creates a
Contractinstance pointing to the vault addressBuilds a
transfer(from, to, amount)call — this is the standard Soroban token transferSimulates the transaction to estimate the required resources (CPU, memory, ledger I/O)
Assembles the final transaction with the simulation results
Signs and submits it to the network
Why simulate first? Soroban smart contract calls require accurate resource estimation. The simulation step calculates CPU instructions, memory bytes, and ledger operations needed, so the transaction has the right resource limits to succeed on-chain.
About fees:
BASE_FEEis the minimum fee (100 stroops). On a congested network, transactions with the minimum fee may be dropped. For production, consider using a higher fee (e.g.,String(100 * 10)) or implementing a fee-bumping strategy.
Step 6: Put It All Together 🚀
Finally, wire everything up in a main function:
Run It
You should see output similar to:
🚨 Troubleshooting
Missing environment variables
Check that your .env file has all four variables filled in
Transaction rejected
Verify Wallet A has enough asset balance and XLM for fees
Transfer simulation failed
Confirm the vault address is correct and Wallet A holds dfTokens
Deposit returned no value
May be a network issue — check your Soroban RPC endpoint
Transaction failed on-chain
Check the transaction on Stellar Expert for details
Transaction not confirmed after 60s
The RPC node may have dropped the tx — check your Soroban RPC endpoint or retry with a higher fee
🎓 Next Steps
Withdraw — Redeem dfTokens back for the underlying assets: Withdraw Guide
Check Balances — Query dfToken holdings: Get Balance
Monitor APY — Track vault performance: Get APY
Explore the SDK — More features available in the TypeScript SDK
🤖 Build It with AI
Want to build this script quickly? Copy the prompt below and paste it into a new Claude Code session. It contains all the technical details needed to generate the complete implementation:
Last updated