Kaiber
Generate, edit, and beat-sync AI video with leading models in one workspace.
banking-bodyguard-cbbtc-signals
Banking Bodyguard provides scored cbBTC whale-transfer signals on Base via x402, scoring transfers BEARISH/NEUTRAL/BULLISH against a labelled-address graph and returning HOLD/TIGHTEN_STOP/EXIT recommendations with impact and confidence levels. Use when building Base-network trading agents that ho...
Full skill instructions
A teaching manifest for AI coding assistants helping developers integrate Banking Bodyguard's cbBTC whale signal API into trading agents on Base.
This document is a recipe, not a reference. The reference is llms.txt at https://bodyguard.finance/llms.txt — read it first if you haven't, then come back here. This file teaches an AI assistant how to walk a developer through building a real agent that consumes Banking Bodyguard signals.
Developers building autonomous or semi-autonomous agents that hold or manage cbBTC exposure on Base. Three concrete personas:
Banking Bodyguard is not for: BTC spot directional trading, multi-chain whale watching, or general market sentiment. It is a tool for cbBTC-on-Base decisions specifically.
Wire Banking Bodyguard signals into the agent's decision loop so that on each tick (or each signal-driven event), the agent gets a confidence-gated, scored read on whether a market-moving cbBTC whale flow just happened — and adjusts the position accordingly.
The operational value is lead time. High-confidence BEARISH+HIGH signals typically precede cbBTC oracle repricing on Base lending markets (Morpho, Aave, Moonwell) by 60–120 seconds. That window is enough to reduce collateral, tighten a health factor, or shift an LP range before the price move is fully reflected on-chain.
Banking Bodyguard has two access tiers. The free tier needs almost nothing; the paid tier needs an x402 wallet. Sequence the integration in that order.
For free-tier evaluation (first 20 calls per client):
requests in Python, fetch in TypeScript, curl from a shell. No SDK, no wallet, no signup.For paid usage (call 21 onward):
TransferWithAuthorization payload that x402 requires from call 21 onward. The wallet becomes the payment identity from that point.pip install x402; TypeScript: npm install x402-fetch viem).The agent owns the risk parameters. Banking Bodyguard owns the signal. The free tier exists to let you prove the integration shape before you commit a wallet.
Step 1 — Verify the integration with demo mode before touching real money.
import requests
resp = requests.get(
"https://bodyguard.finance/x402/signal/cbbtc/latest?demo=true"
)
sample_signal = resp.json()
assert sample_signal.get("demo") is True
print(sample_signal)
Demo mode returns a realistic sample payload, marked "demo": true, with no payment required. Use it to validate response parsing, field-handling logic, and the agent's gating code paths before connecting a real wallet. Unlimited calls, no cost.
Step 2 — Evaluate with plain HTTP. No wallet required for the first 20 calls.
import requests
r = requests.get("https://bodyguard.finance/x402/signal/cbbtc/latest")
signal = r.json()
print(f"Signal: {signal['recommendation']} (score {signal['sentiment_score']}, "
f"impact {signal['impact_level']}, confidence {signal['confidence']})")
print(f"Free tier remaining: {signal.get('free_tier_remaining', 'paid')}")
The first 20 real (non-demo) calls per client return live signals without charging. The response includes "free_tier_remaining": N counting down from 19 to 0. No wallet, no API key, no signup — the rate limit is keyed to the client. This is where you exercise the agent's gating logic against real production data and confirm the decision shape is right before any USDC moves.
After the 20th free call the same endpoint returns HTTP 402 with an x402 payment challenge instead of a signal. That's the signal to graduate to Step 3.
Step 3 — Graduate to paid: install the x402 SDK, fund a Base wallet with USDC, retry.
import os
from x402.clients.requests import x402_requests
from eth_account import Account
account = Account.from_key(os.environ["AGENT_WALLET_KEY"])
session = x402_requests(account)
r = session.get("https://bodyguard.finance/x402/signal/cbbtc/latest")
signal = r.json()
The SDK handles the 402 challenge, EIP-712 signing, and X-PAYMENT header construction automatically. The same GET that returned 402 with plain requests now returns 200 with a signal, and 0.10 USDC settles on-chain via the CDP facilitator. Gas is paid by the facilitator; the wallet only needs USDC.
A paid response does not carry the free_tier_remaining field — its absence is the signal that the call charged. If you want a programmatic check, key off signal.get("free_tier_remaining") being None.
Step 4 — Wire the signal into the agent's decision loop.
def consume_whale_signal(signal: dict, position_state: dict) -> dict:
"""
Return an action descriptor based on whale signal + current position.
The agent's main loop applies the action.
"""
# Gate first on confidence. LOW confidence = at least one address unknown.
if signal["confidence"] != "HIGH":
return {"action": "hold", "reason": "low_confidence"}
# Strongest action: bearish + high impact + high score.
if signal["recommendation"] == "EXIT" and signal["sentiment_score"] >= 8:
return {
"action": "reduce_exposure",
"reason": "bearish_high_impact",
"signal_id": signal["signal_id"],
}
# Bearish + medium impact: defensive adjustment.
if signal["recommendation"] == "TIGHTEN_STOP":
return {
"action": "defensive_adjustment",
"reason": "bearish_medium_impact",
"signal_id": signal["signal_id"],
}
# Bullish with non-trivial impact: accumulation candidate.
if (signal["sentiment_label"] == "BULLISH"
and signal["impact_level"] != "LOW"):
return {
"action": "increase_exposure",
"reason": "bullish_meaningful_impact",
"signal_id": signal["signal_id"],
}
return {"action": "hold", "reason": "noise_or_neutral"}
The function returns an action descriptor; it does not execute anything. The agent's main loop decides whether to act, with cooldowns, position sizing, and price confirmation layered on top.
Step 5 — Add a cooldown so the agent doesn't churn on every poll.
import time
class WhaleSignalConsumer:
def __init__(self, cooldown_seconds: int = 300):
self.cooldown_seconds = cooldown_seconds
self.last_action_at = 0
self.last_signal_id = None
def evaluate(self, signal: dict, position_state: dict) -> dict | None:
# Don't act on the same signal twice.
if signal["signal_id"] == self.last_signal_id:
return None
# Don't act inside the cooldown window.
if time.time() - self.last_action_at < self.cooldown_seconds:
return None
action = consume_whale_signal(signal, position_state)
if action["action"] != "hold":
self.last_action_at = time.time()
self.last_signal_id = signal["signal_id"]
return action
return None
Cooldown defaults to 5 minutes. For LP rebalancing on Aerodrome or Uniswap V3, push it higher (10–15 minutes) — gas costs on range shifts erode signal alpha if rebalances fire too often.
Step 6 — Confirm the action makes sense against current price.
def confirm_with_price(action: dict, current_price: float, prior_price_1h: float) -> bool:
"""
Add a price-confirmation gate. A whale moving cbBTC to an exchange means
less if price is already pricing it in.
"""
price_change_1h_pct = (current_price - prior_price_1h) / prior_price_1h * 100
if action["reason"] == "bearish_high_impact":
# Confirm bearish action only if price hasn't already dropped >2%.
return price_change_1h_pct > -2.0
if action["reason"] == "bullish_meaningful_impact":
# Confirm bullish action only if price hasn't already rallied >2%.
return price_change_1h_pct < 2.0
return True
This gate is the difference between a signal-driven agent and a signal-and-price-driven agent. The latter performs meaningfully better in backtest.
After steps 1–6, run the agent in dry-run mode for 24 hours. Log every signal, every action descriptor, and every confirm/skip decision. Compare against the live track record dashboard at https://bodyguard.finance/track-record.html. The agent should be acting on roughly 5–15% of incoming signals (high-confidence, non-NEUTRAL, non-LOW-impact). If it's acting on more, the gates are too loose. If it's acting on fewer than 1%, either the gates are too tight or recent market conditions are quiet.
Only after dry-run validation should the agent's action functions wire into real position adjustments.
A complete minimal agent that defends a cbBTC-collateralized loan against oracle-repricing risk.
import os
import time
import logging
import requests
from x402.clients.requests import x402_requests
from eth_account import Account
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("cbbtc_defender")
# --- Configuration ---
POLL_INTERVAL_S = 60 # 1-minute poll
COOLDOWN_S = 600 # 10 minutes between signal-triggered actions
REDUCE_FRACTION = 0.30 # Reduce collateral by 30% on EXIT
PRICE_CONFIRM_THRESHOLD = 2.0 # Skip if price already moved 2% in signal direction
# --- Setup ---
account = Account.from_key(os.environ["AGENT_WALLET_KEY"])
bb_session = x402_requests(account)
class Position:
"""Stub for the agent's position state. Replace with real protocol calls."""
def __init__(self):
self.cbbtc_collateral = 5.0 # 5 cbBTC posted
self.debt_usdc = 200_000.0 # $200k borrowed
self.last_action_at = 0
self.last_signal_id = None
position = Position()
# --- Signal consumption ---
def fetch_signal() -> dict | None:
try:
r = bb_session.get(
"https://bodyguard.finance/x402/signal/cbbtc/latest",
timeout=10,
)
r.raise_for_status()
return r.json()
except Exception as e:
log.warning(f"Signal fetch failed: {e}")
return None
def fetch_cbbtc_price() -> tuple[float, float]:
"""Return (current_price, price_1h_ago). Stub — replace with real oracle."""
return 79_000.0, 79_500.0 # example
def evaluate(signal: dict) -> str | None:
if signal["signal_id"] == position.last_signal_id:
return None
if time.time() - position.last_action_at < COOLDOWN_S:
return None
if signal["confidence"] != "HIGH":
return None
if (signal["recommendation"] == "EXIT"
and signal["sentiment_score"] >= 8):
return "reduce_collateral"
if signal["recommendation"] == "TIGHTEN_STOP":
return "tighten_health_factor"
return None
def execute(action: str, signal: dict) -> None:
current_price, prior_price = fetch_cbbtc_price()
price_change_pct = (current_price - prior_price) / prior_price * 100
if action == "reduce_collateral":
if price_change_pct < -PRICE_CONFIRM_THRESHOLD:
log.info(f"Skipping reduce_collateral — price already dropped "
f"{price_change_pct:.2f}%, signal {signal['signal_id']}")
return
amount = position.cbbtc_collateral * REDUCE_FRACTION
log.info(f"Signal {signal['signal_id']}: reducing collateral by "
f"{amount:.4f} cbBTC (BEARISH score {signal['sentiment_score']}, "
f"impact {signal['impact_level']})")
# withdraw_collateral(amount) <-- real protocol call goes here
position.cbbtc_collateral -= amount
position.last_action_at = time.time()
position.last_signal_id = signal["signal_id"]
elif action == "tighten_health_factor":
log.info(f"Signal {signal['signal_id']}: tightening health factor "
f"(BEARISH medium impact)")
# repay_partial_debt(...) <-- real protocol call goes here
position.last_action_at = time.time()
position.last_signal_id = signal["signal_id"]
# --- Main loop ---
while True:
signal = fetch_signal()
if signal is not None:
action = evaluate(signal)
if action:
execute(action, signal)
else:
log.debug(f"No action for signal {signal.get('signal_id')}")
time.sleep(POLL_INTERVAL_S)
This is about 80 lines of agent code. The Banking Bodyguard integration is roughly 15 of those lines — the rest is position state and the action functions, which belong to the agent.
A few things to notice in the example:
signal_id twice. Banking Bodyguard returns the most recent signal on each call; without this guard, a polling agent would re-act on the same whale movement repeatedly.signal_id for audit and post-hoc accuracy review against the track record dashboard.Mistake 1 — Trusting the recommendation field without gating on confidence.
The recommendation field is populated on every signal, including LOW-confidence ones. A signal with confidence: "LOW" and recommendation: "EXIT" is the system saying "if my labels were right, this would be an EXIT — but at least one address is unknown so I'm not sure." Auto-acting on LOW-confidence recommendations produces high false-positive rates.
Mistake 2 — Treating NEUTRAL as a market read.
NEUTRAL (score 4–7) is not "the market is sideways." It is "I cannot classify this transfer's intent." Usually because both addresses are unknown, or because the flow direction is ambiguous (e.g., one DEX pool to another). The right interpretation is "no decision input from this signal." Do not flip to defensive mode on NEUTRAL.
Mistake 3 — Re-acting on the same signal.
The /latest endpoint returns the most recent signal each time it's called. Without a signal_id deduplication check, an agent polling every 60 seconds will re-evaluate (and potentially re-act on) the same whale movement until the next one happens. Store last_signal_id and skip if matched.
Mistake 4 — Polling faster than 10 seconds.
The underlying watcher polls Base every 10 seconds. Faster client polling produces no new signals — just duplicate signal_ids and burned USDC. 60 seconds is a reasonable default for most agents; 10 seconds is the floor for liquidation protection.
Mistake 5 — Rebalancing LP ranges on every EXIT.
Gas + re-deposit cost on a concentrated liquidity range shift on Aerodrome or Uniswap V3 typically runs $5–20 per action on Base. A signal-triggered rebalance every 10 minutes burns more in gas than the whale-flow alpha generates. Threshold on impact_level == "HIGH" plus a 10–15 minute cooldown, and consider only acting on EXIT (not TIGHTEN_STOP) for range shifts.
Mistake 6 — Triggering an external hedge on a single signal.
Even high-confidence EXIT signals are wrong some percentage of the time. Opening a leveraged hedge on a CEX or external perp venue based on one signal exposes the agent to whipsaw losses if the signal turns out to be noise. Pair with current price action, or wait for a confirming second BEARISH signal in the same direction within a defined window (e.g., 30 minutes), before committing hedge capital.
Mistake 7 — Hardcoding the payment recipient or asset address.
The 402 challenge body carries network, asset contract address, and pay-to address as machine-readable fields. Read them from the response at runtime. Hardcoding them from documentation will break if the service ever migrates wallets or supports a second asset.
Banking Bodyguard is one signal source. The best agents combine it with at least one orthogonal input.
Pattern 1 — Signal + price action.
Add a price-confirmation gate. Skip BEARISH actions if price has already dropped >2% in the last hour (whale flow is already in the price); skip BULLISH actions if price has already rallied >2%. This is shown in step 6 above.
Pattern 2 — Signal + external hedge trigger (for spot risk managers).
If the agent holds cbBTC spot on Base and a hedge venue lives elsewhere (BTC perps on a CEX, or a BTC perp on Hyperliquid), use Banking Bodyguard signals to trigger the hedge open/close decision but execute on the external venue. Accept that cbBTC↔BTC basis risk is part of the cost; a hedge against directional risk is still net-positive when the alternative is unhedged spot exposure during a high-impact flow event.
Pattern 3 — Signal + position health factor (for lending agents).
Modulate the response by current position health. A BEARISH+HIGH+EXIT signal at health factor 1.8 might warrant a 20% reduction; at health factor 1.2 it might warrant 50%; at 1.05 it might warrant full exit regardless of signal strength. The signal is one input; the position's distance from liquidation is another.
Pattern 4 — Signal + LP range tightness (for liquidity rebalancers).
A whale signal matters more when the agent's LP range is narrow (high concentration, high impermanent loss risk on a price move). For a wide passive range covering ±20%, even HIGH-impact signals can usually be ignored. For a tight range of ±2%, the same signal warrants action. Composing impact_level with the position's range width gives a tighter trigger.
Pattern 5 — Signal + multi-signal confirmation.
Buffer the last N signals (e.g., last 30 minutes) and act only when two or more consecutive HIGH-confidence non-LOW-impact signals point the same direction. This trades latency for false-positive resistance. Good fit for agents where each action has a holding cost or transaction overhead.
Be honest about this. Banking Bodyguard is not the right signal for:
If the agent fits one of those descriptions, redirect the developer to other tools rather than wedging Banking Bodyguard into a use case it wasn't built for.
https://bodyguard.finance/llms.txthttps://bodyguard.finance/track-record.htmlhttps://bodyguard.finance/healthhttps://t.me/+V5QAfdHgW9wwZjdl@BankingBodygd on Xhttps://bodyguard.finance/docsRead llms.txt for the full response schema, field semantics, and payment protocol. This file teaches the integration shape; that file documents the contract.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience