@stakekit/widget integration. If you already embed the widget for Earn, your Earn setup stays as it is. You update the widget to 0.0.290, add two config props and, if your app manages the wallet, add two methods to your wallet adapter.
Once Borrow is on, users supply collateral, borrow, manage positions, repay and withdraw collateral from the widget. To build your own Borrow interface instead, see the Borrow API guide.
At a glance
Prerequisites
- Borrow enabled for your project. Email hello@yield.xyz with the API key you test with. Start with your dev environment.
- A funded test wallet on Ethereum or Base, holding collateral (for example WETH or cbBTC) and native gas. Testing on Base costs less than on Ethereum.
Update the widget
SKApp, your app needs React 19. The widget now uses its own wallet dialogs instead of RainbowKit, so remove color.connectKit and borderRadius.connectKit from your theme if you set them.
Upgrading from an earlier version
Upgrading from an earlier version
react and react-dom peers are >=19. Upgrade your host app first if it is on React 18.Removed props and exports:sendTransaction can resolve { type: "cancelled" } when the user declines, and signMessage can resolve a result object (success, cancelled or error) as well as a plain signature string. Borrow methods accept result objects only. signTypedData moved off SKWallet and is now a required Borrow method.Browser renderer. renderSKWidget returns { rerender, unmount }. Call unmount() when your page removes the widget.External provider state sync. The widget syncs your provider snapshot (address, chain, supported chains and callbacks) on every update. Keep externalProviders present while the wallet is disconnected, with currentAddress: "". Adding or removing externalProviders needs a remount.Turn on Borrow
Borrow needs two props:dashboardVariant: true. Borrow appears in the dashboard tab bar, next to Manage and Activity.borrowEnabled: true.
dashboardVariant on, grouping defaults to "category", so remove yieldGrouping: "flat" if you set it.
If the widget connects the wallet
Add the two props:If your app manages the wallet
If you pass your own wallet throughexternalProviders, your adapter needs two more methods. Your Earn methods (signMessage, switchChain and sendTransaction) stay as they are.
borrow-provider-capability-missing.
The adapter: SKBorrowWallet
SKBorrowWallet is your Earn SKWallet plus the two Borrow methods. These types are exported from both @stakekit/widget and @stakekit/widget/bundle: SKWallet, SKBorrowWallet, SKBorrowTx, SKBorrowTxMeta, SKBorrowTxResult, SKBorrowSignatureResult, SKBorrowExternalProviders and SKEip712TypedData.
yourWallet calls are placeholders for your wallet SDK or custody provider. getTransactionReceipt remains optional, as it is for Earn.
Results
Both Borrow methods return a result object. A plain hash or signature string is rejected asInvalid external provider result.
error without a txHash.
What is in SKBorrowTx
SKBorrowTx is { type: "evm"; tx }, where tx has:
undefined unless the Borrow API quotes them; your signer estimates them in that case. Borrow transactions carry no nonce, so your wallet assigns it.
What is in SKBorrowTxMeta
actionType is what the user asked for. txType is what this one transaction does. Use these fields to label the request your users or approvers see.
How a Borrow action runs
One action can need several steps, for example anAPPROVAL, then a SUPPLY, then a BORROW. For each step:
- The widget asks your adapter for a transaction (
sendBorrowTransaction) or a signature (signTypedData). - Your adapter signs, and for a transaction, broadcasts.
- Your adapter returns the hash or the signature.
- For a transaction, the widget reports the hash to the Borrow API and polls for confirmation: 20 checks, 2 seconds apart, about 40 seconds in total. For a signature, the widget submits it to the Borrow API itself.
- Once the step is confirmed, the widget moves to the next one.
Pass your wallet to the widget
Keep passing your adapter throughexternalProviders, as you do for Earn.
currentChain and supportedChainIds, or validate the ids from your SDK, rather than casting a plain number.
- Disconnected wallet. Keep
externalProvidersand setcurrentAddress: "". Do not passnullorundefined, and do not remove the object. To add or removeexternalProvidersitself, remount the widget. - Rerender.
rerenderreplaces all props. It does not merge them, so pass the full set each time. - Read at mount.
apiKey,baseUrl,borrowApiUrl,yieldsApiUrlandborrowEnabledare read when the widget mounts. Remount to change them. Other props, includingborrowMarketsScope, update live. - During a flow. Each step uses the provider you passed most recently. Keep both Borrow methods on every rerender, or the next step fails.
X-API-KEY header to borrowApiUrl, which defaults to https://borrow.yield.xyz. You do not need to set borrowApiUrl.
Which markets appear
borrowMarketsScope sets which markets the Borrow tab lists for new borrows:
"enabled", send the Yield.xyz team the markets you want for your project. Until a list is set, "enabled" shows no markets, so keep "all" until then. Existing positions stay visible and manageable under either scope.
Markets load for the wallet’s current network only, on Ethereum, Base, Arbitrum and Optimism. A market is listed for new borrows only when:
- borrowing is enabled on it,
- it has at least $10,000 of available liquidity (a loan token with no USD price counts as no liquidity),
- its borrow rate is 100% or lower, and
- it has at least one collateral with a max LTV of 1% or more that is not the loan token itself.
What the user sees
Borrow tab
Pick a market and collateral
Review
Steps
Manage and Activity
tracking, Borrow adds these page names: "Borrow", "Borrow review", "Borrow steps" and "Borrow complete", and these events: "Borrow market selected", "Borrow collateral selected", "Borrow page max clicked" and "Borrow review clicked".
Testing
- Update to 0.0.290 and turn on Borrow in your dev environment.
- If you pass your own wallet, implement both Borrow methods.
- Connect the test wallet on Base or Ethereum.
- Open Borrow, pick a USDC market (for example on Aave V3 or Morpho Blue), supply collateral and borrow a small amount, such as 10 USDC.
- Approve each step in your wallet. If you pass your own wallet, check that each request shows the expected
txType. - Open Manage and check that the position shows the collateral and the debt. Check that the action shows in Activity.
- Repay in full, then withdraw all collateral. Check that the position is gone from Manage.
{ type: "cancelled" }, that signTypedData works when a step asks for it, that an empty currentAddress keeps the widget running, and that switching networks updates the market list. Compare the behavior with the demo.
Troubleshooting
The widget logs errors to the browser console. Configuration problems include an issue code and the prop path. Each entry is titled with the console message, or with the symptom when there is no message.Configuration
Initial Widget Configuration is invalid
Initial Widget Configuration is invalid
borrowEnabled, the Borrow tab does not appear or the widget does not start. The widget logs this message on first mount with one of these issues:Widget Configuration update rejected
Widget Configuration update rejected
rerender replaces everything) or a currentAddress of null or undefined, which shows as host-configuration-decode-failed. Set currentAddress: "" while the wallet is disconnected.The Borrow tab opens but shows no markets
The Borrow tab opens but shows no markets
supportedChainIds. With borrowMarketsScope: "enabled", check that markets are enabled for your project, or switch to "all".Signing
Invalid external provider result
Invalid external provider result
{ type: "success", txHash } or { type: "success", signature }.The signed transaction payload is not available.
The signed transaction payload is not available.
{ type: "error", error }.Confirmation
Transaction confirmation polling was exhausted.
Transaction confirmation polling was exhausted.
tx.tx.chainId.Borrow transaction ended with FAILED status.
Borrow transaction ended with FAILED status.
Borrow transaction ended with NOT_FOUND status. The transaction reverted, or the hash is wrong or on another chain. Compare the hash in your wallet with the one you returned.Wallet sync
Wallet Runtime invariant violated
Wallet Runtime invariant violated
externalProviders was added or removed after mount (external-provider-presence-changed). Keep the object present with currentAddress: "" while the wallet is disconnected, or remount the widget. Account and chain changes do not need a remount.External provider connection failed
External provider connection failed
currentAddress you passed and the connection failed. Check that the address and currentChain match the account and chain active in your wallet.Build
The build fails after the update
The build fails after the update
FAQ
Do we need a new API key for Borrow?
Do we need a new API key for Borrow?
Does turning on Borrow change our Earn integration?
Does turning on Borrow change our Earn integration?
Can we limit the widget to certain markets?
Can we limit the widget to certain markets?
borrowMarketsScope: "enabled".Why does the widget support only four networks?
Why does the widget support only four networks?
Does Borrow work with custody and multi-approval wallets?
Does Borrow work with custody and multi-approval wallets?
Are there fees?
Are there fees?

