---
title: Deposits and Funding
description: Configure wallet deposits, add THRUSD, verify balances, and
  distinguish native fees from test-token funding.
source_url:
  html: https://thru.org/docs/wallet/deposits-and-funding/
  md: https://thru.org/docs/wallet/deposits-and-funding.md
---

# Deposits and Funding

## Choose the funding path

| Need | Path | What you receive |
| - | - | - |
| Native transaction fees | [Native faucet commands](https://thru.org/docs/cli-reference/faucet-commands.md) | Native THRU, not THRUSD |
| Add funds through the hosted wallet | The wallet’s deposit provider flow | THRUSD in the prepared token account |
| Test THRUSD | Restricted staging faucet, when access is provided | Test tokens for an allowed mint and network, in an existing token account |

A public, self-service Alphanet THRUSD faucet has not been verified for this guide. Ask your environment operator for the supported test-funding route. Do not assume Add funds is a free test faucet: the provider flow can involve an actual payment. THRUSD does not replace native THRU for fees.

The published 0.3.16 source still defaults some display symbols to `CREDITS`; the repository source normalizes those legacy symbols to `THRUSD`. The deposit methods used below exist in both. Read mint metadata from the prepared destination instead of hardcoding it.

## Configure the wallet

This example was checked against published `@thru/wallet@0.3.16` on September 18, 2026. Install that package; `@thru/wallet/react` is its React import path.

```bash
npm install @thru/wallet@0.3.16
```

Use a client component in Next.js. Configure both the RPC and the deposit network:

```tsx
import type { ReactNode } from "react";
import { ThruNetwork } from "@thru/wallet";
import { ThruProvider } from "@thru/wallet/react";

export function WalletProvider({ children }: { children: ReactNode }) {
  return (
    <ThruProvider config={{
      iframeUrl: "https://app.tid.sh/embedded",
      rpcUrl: "https://rpc.alphanet.thru.org",
      network: ThruNetwork.Alphanet,
    }}>
      {children}
    </ThruProvider>
  );
}
```

The RPC and network must identify the same chain. `rpcUrl` alone does not select a deposit network. The hosted wallet must also have a deposit target and provider configured for that network; the dApp cannot supply that configuration by changing its RPC.

Use `https://app.tid.sh/embedded` for embedding. [wallet.tid.sh](https://wallet.tid.sh/) is a standalone link and blocks framing, even though the SDK trusts its origin.

## Add funds and verify the balance

Connect first using [Embedded Wallet Integration](https://thru.org/docs/wallet/embedded-wallet-integration.md). Obtain `deposits` from `useWallet()` or `BrowserSDK.deposits`, then call this helper from your Add funds handler:

```ts
import { DepositTarget, type DepositsApi } from "@thru/wallet";

// Call with useWallet().deposits after connecting. Disable repeat clicks
// while this promise is pending. Prepare again after changing wallet/network.
export async function addFunds(deposits: DepositsApi) {
  const destination = await deposits.prepare(DepositTarget.THRUSD);
  const before = await deposits.ensureAccount({ destination });
  const result = await deposits.open({ destination });

  if (result.status === "cancelled") {
    return { status: "cancelled" as const };
  }

  try {
    const balance = await deposits.waitForDeposit({
      destination,
      minimumBalanceRaw: before.balanceRaw + 1n,
      signature: result.signature,
    });
    return { status: "credited" as const, balance };
  } catch (error) {
    // A timeout or RPC error does not prove the payment failed.
    // Retain destination for a later getAccountState({ destination }) call.
    return { status: "unverified" as const, destination, signature: result.signature, error };
  }
}
```

- `prepare(DepositTarget.THRUSD)` resolves the destination and mint metadata inside the wallet. Do not construct or alter the destination yourself. The enum retains the legacy wire value `credits`.
- `ensureAccount({ destination })` creates a missing token account or validates an existing one, then returns its balance. A new account may require wallet approval and setup fees; an existing account is reused.
- `open({ destination })` opens the provider flow. In this SDK release its result is `completed`, `cancelled`, or `pending`. A pending payment may still be credited asynchronously; do not ask the user to pay again.
- `waitForDeposit()` observes the prepared account’s on-chain balance. The example’s one-base-unit increase detects a balance change, not a specific payment’s exact amount or identity. Use a known expected amount when your application needs amount reconciliation.
- `getAccountState({ destination })` refreshes the same account after a wait error or page refresh. Persist the baseline and destination for recovery, and revalidate them with `prepare()` for the same wallet and network before reuse. Display `balanceLabel` or use `formatAmount(balanceRaw, destination)`.

Handle errors thrown by `prepare`, `ensureAccount`, and `open` in your UI, including rejected account-setup approval. Always clear the busy state in `finally`. A rejected request has no success result; an error after payment may require reconciliation. Do not automatically reopen the payment flow.

Closing the wallet UI is not proof that funds arrived. The `credited` result above follows an observed balance increase. For `unverified`, show that the balance could not be verified, retain any payment signature, and offer a balance refresh. After changing wallet or network, prepare a new destination instead of reusing the old one.

## Troubleshoot configuration

`Deposit network is not configured` originates in the hosted wallet when no supported deposit network reaches it. Check `config.network` first. A selected network with an unavailable target or provider is a separate hosted-wallet configuration problem; ask the wallet operator to verify support. Keep provider secrets and mint credentials out of the frontend.

See [Wallet Troubleshooting](https://thru.org/docs/wallet/troubleshooting.md) for iframe and configuration checks.
