Deposits and Funding
Choose the funding path
Section titled “Choose the funding path”| Need | Path | What you receive |
|---|---|---|
| Native transaction fees | Native faucet commands | 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
Section titled “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.
npm install @thru/wallet@0.3.16Use a client component in Next.js. Configure both the RPC and the deposit network:
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 is a standalone link and blocks framing, even though the SDK trusts its origin.
Add funds and verify the balance
Section titled “Add funds and verify the balance”Connect first using Embedded Wallet Integration. Obtain deposits from useWallet() or BrowserSDK.deposits, then call this helper from your Add funds handler:
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 valuecredits.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 iscompleted,cancelled, orpending. 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 withprepare()for the same wallet and network before reuse. DisplaybalanceLabelor useformatAmount(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
Section titled “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 for iframe and configuration checks.