@metalend/widget
v1.0.2
Published
MetaLend widget - A reusable React component for integrating MetaLend DeFi functionality into any application.
Maintainers
Readme
MetaLend Widget
A drop-in React component for integrating MetaLend DeFi yield optimization rebalancer into any application. The widget provides a complete interface for depositing, withdrawing, and rebalancing positions across multiple chains and lending protocols — powered by the MetaLend Rebalancing API.
Access
MetaLendWidget component requires API key which you can obtain in MetaLend developer dashboard.
Features
- Single-Component Integration — one
<MetaLendWidget />with an API key and connectors - Multi-Chain — Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, Linea
- Multi-Token — USDC, USDT, RLUSD, MUSD
- Multi-Protocol — Aave, Morpho, Euler with automatic rebalancing
- Project Settings — supported tokens, chains, and protocols are configured per API key via the MetaLend dashboard; no prop-level filtering needed
- Flexible Wallet Support — works with any wagmi-compatible connector (MetaMask, Coinbase Wallet, WalletConnect, Privy, etc.)
- RPC Failover — multiple RPC endpoints per chain with automatic fallback
- Coinbase Miniapp Mode — smart wallet + paymaster-sponsored transactions out of the box
- Analytics Ready — plug in any analytics SDK via the
TrackingProviderinterface
Installation
npm install @metalend/widgetor with yarn:
yarn add @metalend/widgetPeer Dependencies
These must be installed in your application:
| Package | Version |
| ----------------------- | -------------------- |
| react | ^18.0.0 || ^19.0.0 |
| react-dom | ^18.0.0 || ^19.0.0 |
| wagmi | ^2.19.5 |
| viem | ^2.27.0 |
| @tanstack/react-query | ^5.90.16 |
npm install react react-dom wagmi viem @tanstack/react-queryQuick Start
import { MetaLendWidget } from '@metalend/widget'
import '@metalend/widget/style.css'
import { injected } from 'wagmi/connectors'
function App() {
return <MetaLendWidget apiKey="your-metalend-api-key" connectors={[injected()]} />
}That's it. The widget handles wallet connection, chain management, deposits, withdrawals, rebalancer configuration, and rewards — all scoped to the tokens, chains, and protocols enabled for your API key in the MetaLend dashboard.
Use Cases
1. Full DApp Integration (with Privy) - injecting existing wagmi context
For DApps that already manage their own wagmi provider (f.e. via Privy):
import { MetaLendWidget } from '@metalend/widget'
import '@metalend/widget/style.css'
import { PrivyProvider } from '@privy-io/react-auth'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider, createConfig, http } from 'wagmi'
import { arbitrum, base, mainnet, optimism, polygon } from 'wagmi/chains'
const wagmiConfig = createConfig({
chains: [base, mainnet, arbitrum, optimism, polygon],
transports: {
[base.id]: http(),
[mainnet.id]: http(),
[arbitrum.id]: http(),
[optimism.id]: http(),
[polygon.id]: http(),
},
})
const queryClient = new QueryClient()
function App() {
return (
<PrivyProvider appId="your-privy-app-id">
<QueryClientProvider client={queryClient}>
<WagmiProvider config={wagmiConfig}>
<MetaLendWidget apiKey="your-metalend-api-key" useExternalWagmiProvider={true} />
</WagmiProvider>
</QueryClientProvider>
</PrivyProvider>
)
}Key points:
- Set
useExternalWagmiProvider={true}so the widget uses your existing wagmi context - All wallet connectors configured in your wagmi config work automatically
- Privy handles the wallet connection UI
2. Coinbase Miniapp
For miniapps running inside the Coinbase Wallet with sponsored transactions:
import { MetaLendWidget } from '@metalend/widget'
import '@metalend/widget/style.css'
import { coinbaseWallet } from 'wagmi/connectors'
function MiniApp() {
return (
<MetaLendWidget
apiKey="your-metalend-api-key"
connectors={[
coinbaseWallet({
appName: 'My MiniApp',
preference: 'smartWalletOnly',
}),
]}
isMiniappMode={true}
paymasterUrl="https://api.developer.coinbase.com/rpc/v1/base/YOUR_KEY"
/>
)
}Key points:
isMiniappModeenables Coinbase Smart Wallet defaultspaymasterUrlenables gasless (sponsored) transactions- Typically scoped to a single chain and token via project settings
- URL: portal.cdp.coinbase.com
3. Default Connectors (Zero Config)
If you omit the connectors prop and useExternalWagmiProvider is false, the widget uses sensible defaults:
- Standard mode:
injected(MetaMask, Brave, etc.) +baseAccount - Miniapp mode (
isMiniappMode={true}):injected+coinbaseWallet
<MetaLendWidget apiKey="your-metalend-api-key" />API Reference
<MetaLendWidget />
| Prop | Type | Required | Default | Description |
| -------------------------- | --------------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| apiKey | string | Yes | — | MetaLend API key. Determines project settings (tokens, chains, protocols). |
| connectors | CreateConnectorFn[] | No | Built-in | Wagmi connectors for wallet connections. Required when useExternalWagmiProvider is false and you want to override the defaults. |
| useExternalWagmiProvider | boolean | No | false | Skip creating an internal WagmiProvider — use the parent app's provider instead. |
| showWalletConnect | boolean | No | false | Show the built-in wallet connection UI inside the widget. |
| customRpcUrls | CustomRpcUrls | No | Built-in | Custom RPC endpoints per chain name (see below). |
| isMiniappMode | boolean | No | false | Enable Coinbase miniapp mode (smart wallet defaults + paymaster support). |
| paymasterUrl | string | No | — | Paymaster URL for sponsored (gasless) transactions. Used with isMiniappMode. |
| trackingProvider | TrackingProvider | No | — | Analytics integration (see below). |
| theme | WidgetTheme | No | MetaLend | Theme overrides — merged with the default theme. |
| className | string | No | '' | CSS class name for the widget container. |
CustomRpcUrls
type ChainKind = 'base' | 'ethereum' | 'polygon' | 'arbitrum' | 'optimism' | 'avalanche' | 'linea'
type CustomRpcUrls = Partial<Record<ChainKind, string[]>>Provide an array of RPC URLs per chain. The widget ensures at least 3 endpoints per chain by merging your URLs with built-in defaults:
<MetaLendWidget
apiKey="your-api-key"
customRpcUrls={{
base: ['https://my-base-rpc.example.com', 'https://my-base-rpc-2.example.com'],
ethereum: ['https://my-eth-rpc.example.com'],
}}
/>WidgetTheme
interface WidgetTheme {
colors?: {
primary?: string
secondary?: string
background?: string
backgroundLight?: string
text?: string
border?: string
error?: string
success?: string
}
borderRadius?: string
fontFamily?: string
}Only specified properties are overridden — the rest use the MetaLend defaults:
<MetaLendWidget
apiKey="your-api-key"
theme={{
colors: {
primary: '#8B5CF6',
background: '#0A0A0F',
},
borderRadius: '16px',
fontFamily: 'Inter, sans-serif',
}}
/>TrackingProvider
interface TrackingProvider {
init?: () => void | Promise<void>
identify?: (userId: string, properties?: Record<string, unknown>) => void | Promise<void>
track: (event: string, properties?: Record<string, unknown>) => void | Promise<void>
}Wrap any analytics SDK behind this interface:
import mixpanel from 'mixpanel-browser'
;<MetaLendWidget
apiKey="your-api-key"
trackingProvider={{
init: () => mixpanel.init('your-mixpanel-token'),
identify: (userId) => mixpanel.identify(userId),
track: (event, props) => mixpanel.track(event, props),
}}
/>Events emitted by the widget:
| Event | Description |
| -------------------------------- | -------------------------------------------- |
| UserLoggedIn | Wallet connected and authenticated |
| PageView URL | User view given URL |
| Open ToS/Privacy Modal | ToS/Privacy link opened |
| RebalancingCreated | Rebalancer config created (first setup) |
| RebalancingUpdated | Rebalancer config updated |
| RebalancingDeposit | Deposit completed successfully |
| DepositBlockedByCountry | Deposit blocked due to Geography regulations |
| RebalancingDepositFailed | Deposit failed |
| RebalancingWithdraw | Withdrawal completed successfully |
| RebalancingClaimRewardsSuccess | Rewards claimed successfully |
| RebalancingClaimRewardsError | Rewards claim failed |
| ErrorLoadingBlockchainData | Error fetching blockchain data from RPC |
Geography Limitations
MetaLend complies with international regulations by restricting deposit functionality in certain countries. When a user attempts to make a deposit, the widget performs an IP-based geolocation check. If the user is detected to be in one of the restricted jurisdictions listed below, deposits will be blocked. Users can still view their balances and withdraw funds regardless of their location.
Countries currently restricted from deposits:
- Bosnia and Herzegovina (BA)
- Serbia (RS)
- Belarus (BY)
- Myanmar (MM)
- Côte d’Ivoire / Ivory Coast (CI)
- Cuba (CU)
- Congo (Democratic Republic) (CD)
- Iran (IR)
- Iraq (IQ)
- Liberia (LR)
- North Korea (KP)
- Sudan (SD)
- Syria (SY)
- Zimbabwe (ZW)
How It Works
Project Settings
Supported tokens, chains, and protocols are configured per API key through the MetaLend dashboard. When the widget mounts, it fetches your project settings from the API and scopes all UI and blockchain interactions accordingly.
This means two integrators with different API keys can show different token/chain combinations without changing any code.
The widget also merges in the user's own signed rebalancer configuration, so users can always see balances for tokens/chains they previously set up — even if you later disable them in your project settings. This ensures users can still view their positions and withdraw at any time.
Example: your project settings enable USDC on Base and Ethereum; a user previously configured USDT on Ethereum. The widget shows USDC (Base, Ethereum) + USDT (Ethereum) for that user.
Provider Architecture
<MetaLendWidget>
└── WagmiProvider (conditional — skipped when useExternalWagmiProvider is true)
└── QueryClientProvider
└── ProjectAndUserSettingsProvider
└── ToastProvider
└── RouterProvider (TanStack Router, in-memory)
└── Dashboard / Deposit / Withdraw / Rewards viewsAuthentication Flow
The widget uses a challenge-verify flow for JWT issuance:
- Wallet connects via wagmi
- Widget requests a challenge from the MetaLend API
- User signs the challenge message
- Widget verifies the signature and receives a JWT
- JWT is used for deposit, withdrawal, and config update operations
- JWT is automatically invalidated on wallet disconnect or account switch
Wallet Support
The widget works with any wagmi-compatible connector:
- MetaMask
- Coinbase Wallet (including Smart Wallet)
- WalletConnect
- Brave Wallet
- Trust Wallet
- Rainbow Wallet
- Any EIP-6963 compliant wallet
When using useExternalWagmiProvider={true}, all connectors from the parent wagmi config work automatically.
API Documentation
The MetaLend Rebalancing API documentation is available at: https://metalend-defi.github.io/public-api-swagger/
License
MIT © MetaLend
Support
- API Docs: MetaLend API Documentation
- Email: [email protected]
- Litepaper: MetaLend Litepaper
- Terms of Service: MetaLend Terms of Service
