Add an interest-bearing savings feature to your fintech app. Users deposit funds, earn yield automatically, and withdraw at any time, with no crypto knowledge required.
Use this file to discover all available pages before exploring further.
This guide shows how to build a yield account feature for a neobank or fintech app. Your users deposit funds, which are allocated to a Morpho lending vault via Trails. The blockchain layer is fully abstracted: your users see a savings balance and an interest rate, nothing else.
User taps "Move to Savings" → Your backend quotes the deposit route via Trails → User authorizes with a single tap (gasless, no fees to manage) → Trails routes funds into the yield vault → Yield accrues; user withdraws any time
Users never interact with a blockchain directly. Wallet creation, gas, and transaction signing all happen in the background via an embedded wallet tied to their account.
A wagmi-compatible embedded wallet provider (Polygon Wallet, Privy, Dynamic, or similar), which powers the invisible signing layer your users never see
Each user gets an embedded wallet created automatically at sign-up, with no crypto onboarding and no seed phrases. This wallet is the signing key for their yield account; users never see or interact with it directly.
import { PrivyProvider } from "@privy-io/react-auth";import { WagmiProvider } from "wagmi";import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import { polygon } from "viem/chains";const queryClient = new QueryClient();export const App = () => ( <PrivyProvider appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID} config={{ defaultChain: polygon, supportedChains: [polygon], embeddedWallets: { createOnLogin: "users-without-wallets", // automatic, no user action required }, }} > <QueryClientProvider client={queryClient}> <WagmiProvider config={wagmiConfig}> <YourApp /> </WagmiProvider> </QueryClientProvider> </PrivyProvider>);
Users log in with email, phone, or SSO via your standard auth flow. Privy silently provisions the wallet in the background:
Composable actions use market IDs instead of hand-encoded vault calldata. Fetch the available vaults, then pass the selected market’s id to the deposit action:
Use useQuote with the deposit action. Trails quotes the route, handles any bridge or swap, and executes the vault deposit from the destination intent wallet:
From the user’s perspective this is still one confirmation. From your app’s perspective, onStatusUpdate gives you progress events for the route and destination action so you can update the savings balance after settlement.
Users can withdraw their full balance (principal + accrued yield) at any time. Use useEarnBalances to read the user’s position, then build a plain ERC-4626 redeem transaction with viem:
useEarnBalances returns the normalized earn position for the wallet, including the market yieldId, the display balance, and protocol-specific share/output token balances. Until the SDK exposes a higher-level withdraw helper, you can encode the vault’s ERC-4626 redeem call directly and submit it with the user’s wallet.