Skip to main content
In headless mode you keep full control of the UI and wallet connection. Barker provides:
  • REST API for product metadata, APY history, fee stats, user position, vault health
  • Standard ERC-4626 contract (BarkerEngine) for deposit / withdraw — call it directly from your frontend with any wallet library
  • Webhooks for APY changes, TVL alerts, vault pauses
If you’d rather drop in a ready-made UI, see Embed instead.

End-to-end flow

1. List products and pick one

Cache this response for ~60 seconds — products change rarely.

2. Connect the user’s wallet

Use whatever you already have — Wagmi / RainbowKit / Privy / your own connector. Barker doesn’t care. The only requirement: by the time the user clicks “Deposit”, their wallet is connected to the same chain_id as the product (e.g. Base = 8453).

3. Deposit

BarkerEngine is a standard ERC-4626 vault. Two transactions: approve the underlying token, then deposit.
After the deposit confirms, refresh the user’s position (next step).
Tip — single-transaction UX: the underlying USDC contract on most chains supports EIP-2612 permit. If you collect a permit signature off-chain you can replace the approve tx with a no-cost signature, then bundle permit + deposit in a single transaction. See Smart Contracts → permit flow.

4. Show the user’s position

For real-time updates, also read engine.balanceOf(user) directly from the chain — the API serves the same value but with ~30s edge cache.

5. Withdraw / redeem

Two ERC-4626 entrypoints:
  • engine.redeem(shares, receiver, owner) — burn N shares, receive whatever assets they’re worth
  • engine.withdraw(assets, receiver, owner) — receive exactly N assets, burn whatever shares are required
Most UIs show “Withdraw X"useredeemafterconvertingX" → use `redeem` after converting `X → sharesviaengine.previewWithdraw(assets)`.
viem
redeem is one transaction — no approve needed (engine shares are owned by the user already).

6. Listen for on-chain events (optional)

If you want server-side reconciliation rather than polling, subscribe to engine events: ABI fragments and full event signatures: Smart Contracts → events.

7. Subscribe to webhooks (optional)

For events Barker pushes — lifecycle (deposit.confirmed, redeem.confirmed, redeem.requested) and operational (apy_change, tvl_alert, vault_pause) — see Webhooks and Deposit/Redeem Lifecycle. Not strictly required for a working UI (you can watch chain logs from the client — see the reference implementation below), but strongly recommended for backend reconciliation: DB writes, accounting, ops alerts.

Reference implementation — Next.js + wagmi

The snippets above show each step in isolation. Here’s the same flow as a single Next.js 16 App Router page that you can copy and adapt — three files, runnable end to end. Architecture in one sentence: server component fetches product metadata with the API key (which never leaves the server); client component drives wallet + writes + uses wagmi’s useWatchContractEvent for instant UI updates; a separate Route Handler receives Barker webhooks for backend reconciliation (DB, accounting). The two channels are independent — your UI doesn’t block on webhook delivery, and your backend doesn’t depend on the user keeping the tab open.
Two channels, two purposes — keep them straight: If the user closes the tab mid-deposit, the UI watcher misses the event but the webhook still fires — your backend stays consistent. If your backend webhook endpoint is down, the UI still updates instantly — Barker retries the webhook for you. Don’t try to make either channel do both jobs. What’s omitted from the snippet (kept tight on purpose; add as you go):

Sandbox checklist

Before you commit production engineering time, verify the headless flow against sandbox:
  • bk_test_* key issued (Portal → API Keys)
  • Sandbox product slug visible in GET /api/partner/products
  • Sandbox USDC obtained from the Sandbox page → Mint Test USDC
  • approve + deposit round-trips on testnet, position endpoint reflects new balance within 30s
  • redeem round-trips, position drops to 0
  • Same code path works against bk_live_* key (only the key changes, base URL is identical)

Production checklist

  • Production engine deployed (status active in Portal → Products)
  • Frontend reads chain_id from the product response and switches chain before signing
  • Error states surfaced: vault paused (poll /health), insufficient allowance, user rejected signature, network mismatch
  • Slippage guard / minimum shares check on deposit (previewDeposit matches your displayed APY ± a tolerance)
  • Compliance disclosures shown to user before deposit

What’s next