Skip to content

Deposits and Funding

View as Markdown
NeedPathWhat you receive
Transaction feesThru Developers or the THRU faucet commandTHRU, not THRUSD, in an existing wallet account
Add funds through the hosted walletThe wallet’s deposit provider flowTHRUSD in the prepared token account
Test THRUSDThru DevelopersTest tokens for an allowed mint and network, in an existing token account

Faucet funding requires a Developers GitHub/X account and an existing recipient: a wallet (EOA) account for THRU, or a THRUSD token account for THRUSD. THRUSD does not pay THRU fees. The separate deposit-provider flow below may involve a real payment.

  1. Prepare the token account in your wallet on Alphanet or Betanet.
  2. Open Developers Faucet, sign in, and confirm the network, token account, and amount.
  3. Request funds, then return to your app and refresh the balance.

Wallet handoffs prefill network, tokenAddress, and decimal amount; optional redirect_url supplies an HTTP(S) Back to app link. Example:

https://dev.thru.org/faucet?network=betanet&tokenAddress=ta...&amount=100&redirect_url=https%3A%2F%2Fwallet.tid.sh%2F

To prefill a THRU request instead, pass asset=thru, the wallet address as recipientAddress, and an integer amount in raw balance units (1 to 10,000):

https://dev.thru.org/faucet?asset=thru&network=betanet&recipientAddress=ta...&amount=10000&redirect_url=https%3A%2F%2Fwallet.tid.sh%2F

Opening or closing the faucet does not prove funding. Verify the balance before showing success. Browser, CLI, and API keys share 5 requests per minute per Developers account.

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.

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.

Terminal window
npm install @thru/wallet@0.3.16

Use 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.

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

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.