Skip to main content
A common partner request: let end users pick between safe, balanced, and higher-yield options on one screen. Barker supports this with 3 independent product slugs, one per tier — same partner account, same fee split contract, different underlying vaults.

Why 3 slugs (not 1 product with 3 toggles)

Each Barker product maps to one BarkerEngine contract which routes to one underlying ERC-4626 vault. APY, liquidity, and risk profile are all properties of the underlying vault. Treating the 3 tiers as 3 first-class products keeps:
  • On-chain accounting clean — each tier’s AUM, shares, and fee accruals are independently auditable
  • API responses simple — latest_metrics.net_apy_for_user is a single number per slug
  • Vault upgrades isolated — migrating “aggressive” to a new underlying doesn’t affect the other tiers
  • Reconciliation per-tier — fee-stats endpoint already gives you tier-level yield breakdown for free

Naming convention

Use a stable suffix so your frontend can group them deterministically:
TierSuggested slugTypical underlyingTypical APY range
Conservative{partner}-conservative-{asset}-{chain}Aave / Compound / Spark stablecoin supply4–6%
Balanced{partner}-balanced-{asset}-{chain}Curated yield aggregator (Yearn V3, Morpho)6–10%
Aggressive{partner}-aggressive-{asset}-{chain}Looped / leveraged stablecoin (sUSDe, leveraged USDC)10–20%
Example for Acme Pay on Base:
  • acme-conservative-usdc-base
  • acme-balanced-usdc-base
  • acme-aggressive-usdc-base

Setup (one-time, in Portal)

For each tier:
  1. Open Portal → Products → New product
  2. Pick chain and underlying vault from the catalog
  3. Set the slug per the convention above
  4. Set risk_label to conservative / balanced / aggressive
  5. (Optional) Set display_name, description — shown verbatim if you ever fall back to the embed
  6. Submit. The engine is auto-deployed on-chain; status moves pending_deploy → active once confirmed (~5 minutes)
Three independent engines, three independent fee splits — both barkerFeeBps and partnerFeeBps can differ per tier.

Reading them in your frontend

const res = await fetch("https://api.barker.money/api/partner/products", {
  headers: { "X-Api-Key": process.env.BARKER_API_KEY! },
});
const { data: products } = await res.json();

const tiers = {
  conservative: products.find((p) => p.risk_label === "conservative"),
  balanced:     products.find((p) => p.risk_label === "balanced"),
  aggressive:   products.find((p) => p.risk_label === "aggressive"),
};
risk_label is null on legacy single-tier products. If you don’t use multi-tier, ignore the field.

UI patterns

Tabbed (recommended):
┌─ Earn ─────────────────────────────────────┐
│  [ Safe 4.9% ]  [ Balanced 7.2% ]  [ High 12.4% ] │
│  ─────────────                              │
│  Underlying: Aave V3 USDC                  │
│  [ Deposit Amount: $______ ]  [ Deposit ]  │
└────────────────────────────────────────────┘
User toggles tier → frontend swaps engine_contract_address and asset_address from the corresponding product, deposit flow is identical to single-tier. Comparison table (good for first-time users):
            Conservative   Balanced   Aggressive
APY              4.9%        7.2%       12.4%
Underlying       Aave        Morpho     Ethena sUSDe
Risk             Low         Medium     Higher
                 [Deposit]   [Deposit]  [Deposit]
Three iframes (embed mode fallback): if you’d rather not build custom UI, drop in three iframes side-by-side. Works but each tier is its own self-contained surface.

Shifting funds between tiers

There is no protocol-level “rebalance” endpoint — different tiers are different ERC-4626 vaults. To move funds between tiers, the user redeems from one and deposits into another (two transactions, two signatures). You can wrap this into a “Move funds” button in your UI. Pseudocode:
const sharesA = await readContract({ address: tierA.engine_contract_address, abi, functionName: "balanceOf", args: [user] });
await writeContract({ address: tierA.engine_contract_address, abi, functionName: "redeem", args: [sharesA, user, user] });
// wait for tx, read the assets received
await writeContract({ address: tierB.asset_address, abi: erc20Abi, functionName: "approve", args: [tierB.engine_contract_address, assetsReceived] });
await writeContract({ address: tierB.engine_contract_address, abi, functionName: "deposit", args: [assetsReceived, user] });

Fee policy

Default barkerFeeBps + partnerFeeBps is the same across all 3 tiers, but each tier can be configured independently if you want to charge users differently for higher-risk tiers (e.g. lower fee on Conservative to win price-sensitive deposits, higher fee on Aggressive). Talk to your account manager.

What’s next