For the complete documentation index, see llms.txt. This page is also available as Markdown.

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:

Use Case
Description

🎁 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:

  1. Transfers your assets (e.g., XLM) from your wallet into the vault

  2. Calculates how many shares you should receive, proportional to your contribution

  3. Mints dfTokens to your wallet representing those shares

  4. 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 .env file to version control. Add it to your .gitignore.

Note: This tutorial uses testnet for learning purposes. For production, change SOROBAN_RPC to a mainnet endpoint (e.g., https://soroban-rpc.mainnet.stellar.gateway.fm) and update the network references in the code to Networks.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,000 stroops (base units). Always convert to raw amounts before calling contract functions. We use BigInt(Math.round(...)) to avoid floating-point precision issues with non-integer amounts like 0.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:

  1. Submits the signed transaction to the Soroban RPC

  2. Validates the transaction was accepted (status PENDING)

  3. Polls every 2 seconds (up to 60s) until the transaction is confirmed or fails

  4. 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:

  1. Builds an unsigned deposit transaction using the DeFindex SDK (depositToVault)

  2. Signs the transaction with your keypair

  3. Submits it to the network and waits for confirmation

  4. Parses the return value to extract how many dfTokens were minted

Why invest: true? When set to true, the vault automatically allocates your deposited funds into its yield-generating strategies. Set to false if you want the funds to remain idle in the vault.

Tip: You can also pass slippageBps in the deposit params (e.g., slippageBps: 100 for 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:

  1. Creates a Contract instance pointing to the vault address

  2. Builds a transfer(from, to, amount) call — this is the standard Soroban token transfer

  3. Simulates the transaction to estimate the required resources (CPU, memory, ledger I/O)

  4. Assembles the final transaction with the simulation results

  5. 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_FEE is 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

Problem
Solution

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