Funding Sources

depositOS supports three funding methods: Wallet, Deposit from Anywhere, and Private Deposit.

Wallet

The wallet funding method lets users connect their existing crypto wallet and pay with any token on any supported chain. The widget automatically discovers the optimal route and executes the cross-chain swap to deliver your chosen token at your destination address.

  • Supports 20+ EVM chains including Ethereum, Arbitrum, Optimism, Polygon, Base, and more
  • Real-time quotes with gas estimates and expected output
  • Automatic token approvals, swaps, and bridging
  • Live execution progress tracking

User flow: Connect Wallet → Select Source Chain & Token → Get Quote → Approve Token → Execute Swap → Bridge (if cross-chain) → Complete

const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourAddress",
  apiKey: "dos_live_…",
  enableWallet: true, // default — can be omitted
};

Wallet mode is enabled by default. Set enableWallet: false to disable it.

Private Deposit

Private deposit mode provides enhanced privacy for users who want to fund your application without creating an on-chain link between their source wallet and the deposit. No wallet connection is required.

  • Enhanced privacy — no on-chain link between sender and recipient
  • No wallet connection required
  • User selects a token, receives deposit details, and sends funds

User flow: Select Token → Get Quote → Receive Deposit Details → Send Funds → Await Confirmation → Complete

const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourAddress",
  apiKey: "dos_live_…",
  enablePrivateMode: true,
};

Private deposits are served by the depositOS API — nothing extra to configure on your side.

Deposit from Anywhere

"Deposit from anywhere" lets a user fund your app by sending a token to a deposit address — from any wallet, exchange withdrawal, or custody system. No wallet connection, no signatures, no approvals. depositOS watches the address and routes the funds to your destination.

  • No wallet connection required — works from exchange withdrawals and hardware wallets
  • Send any amount; the address is not tied to one figure. Deposits too small to cover fees are refunded.
  • Same-chain swaps and cross-chain bridging through one flow
  • ~64 source chains, including Solana, each with its own depositable tokens
  • The user's address is persistent — see below

User flow: Select source chain & token → Get deposit address → Send funds → Track to completion (or automatic refund)

const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourAddress",
  apiKey: "dos_live_…",
  userId: "your-user-123", // same user → same deposit address, every visit
  enableDepositAnywhere: true,
};

Persistent addresses

Each user gets one deposit address per route — a route being the source chain, source token, destination chain, destination token and recipient. Come back tomorrow, on another device, and the same address is shown.

The address is keyed on config.userId, so pass your own user id. Omit it and the SDK falls back to an id kept in the browser's localStorage, which won't follow the user to another device and is shared by everyone using that browser profile.

depositOS stores the address and re-verifies it before handing it back, minting a new one only if the old one stops being valid. Addresses accept repeat deposits: each one is detected and routed independently.

Refund addresses across chains

A failed or refunded deposit must go back to an address on the source chain's own network — a Solana deposit cannot refund to an EVM address, and vice versa.

The widget resolves the refund target in this order:

  1. config.refundAddresses for the source chain's VM — set this if your app has embedded wallets, and the user is never asked.
  2. Your destAddress, when it happens to live on that VM.
  3. Otherwise the widget asks the user for their address on that chain.
const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourTreasury",
  apiKey: "dos_live_…",
  userId: "your-user-123",
  refundAddresses: {
    evm: "0xUsersEvmWallet",
    svm: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
  },
  enableDepositAnywhere: true,
};

So with an EVM destAddress and no refundAddresses, an EVM source refunds silently to your destination, while a Solana source prompts the user. Supply refundAddresses.svm and that prompt disappears.

Solana also works as a destination — set destChain to Solana's chain id and destAddress to a base58 address, and recipients are validated as base58 rather than EVM.

Direction: deposit, transfer, withdraw

config.mode controls where the funds land.

| Mode | Recipient | Who sends | |---|---|---| | "deposit" (default) | Locked to your destAddress | The user | | "transfer" | Entered by the user | The user | | "withdraw" | Entered by the user | Your app |

In "withdraw" mode the widget mints the address and hands it to you via onWithdrawReady, then your app sends the funds:

<DepositOSWidget
  config={{ ...config, mode: "withdraw" }}
  onWithdrawReady={({ depositAddress, amount, fromChainId, fromTokenAddress, recipient }) => {
    // your app sends `amount` of `fromTokenAddress` on `fromChainId` to `depositAddress`;
    // it arrives at `recipient` on your destination chain.
  }}
/>

Provider keys live on the depositOS API and are never exposed to the browser — all traffic is proxied.

Enabling Multiple Methods

You can enable any combination. When multiple methods are enabled, the widget presents a selection screen where the user picks their preferred funding method.

Wallet + private enabled

const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourAddress",
  apiKey: "dos_live_…",
  enableWallet: true,
  enablePrivateMode: true,
};

Only non-wallet methods

const config: DepositOSConfig = {
  destChain: 42161,
  destToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
  destAddress: "0xYourAddress",
  apiKey: "dos_live_…",
  enableWallet: false,
  enablePrivateMode: true,
};

Setting a default mode

Use defaultMode to control which method is pre-selected when the widget opens:

const config: DepositOSConfig = {
  // ...
  enableWallet: true,
  enablePrivateMode: true,
  defaultMode: "private", // Opens to private deposit by default
};

Valid values are "standard" (default) and "private".