Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2b24a27
Create SKILL.md for HODLMM LP Dashboard
Terese678 Mar 28, 2026
8560c03
Add AGENT.md for HODLMM LP Dashboard behavior
Terese678 Mar 28, 2026
4cfdb3d
Add hodlmm-lp-dashboard for Bitflow HODLMM positions
Terese678 Mar 28, 2026
444caf8
Add agent metadata to AGENT.md
Terese678 Mar 29, 2026
2216387
Refine description in SKILL.md
Terese678 Mar 29, 2026
615a910
Refine SKILL.md for clarity and punctuation
Terese678 Mar 29, 2026
9968bc6
Update SKILL.md
Terese678 Mar 29, 2026
4f8d71f
Refactor SKILL.md for clarity and consistency
Terese678 Mar 29, 2026
62eb045
Update API endpoints and enhance dashboard features
Terese678 Mar 31, 2026
54617e0
Revise skill description and command details in SKILL.md
Terese678 Mar 31, 2026
c1813f1
Refine agent behavior and description for clarity
Terese678 Mar 31, 2026
5a558d1
Merge branch 'BitflowFinance:main' into main
Terese678 Apr 3, 2026
0fe1677
Create SKILL.md for dao-proposal-monitor documentation
Terese678 Apr 3, 2026
b6cce14
Add SKILL.md for hodlmm-range-rebalancer
Terese678 Apr 3, 2026
4f67aab
Add documentation for HODLMM Range Rebalancer agent
Terese678 Apr 3, 2026
8475584
Add hodlmm-range-rebalancer implementation
Terese678 Apr 3, 2026
f0cd958
Enhance documentation for hodlmm-range-rebalancer
Terese678 Apr 3, 2026
7359ee3
Rename agent and update behavior documentation
Terese678 Apr 3, 2026
d76bff1
Merge branch 'BitflowFinance:main' into main
Terese678 Apr 9, 2026
213e825
Merge branch 'BitflowFinance:main' into main
Terese678 Apr 13, 2026
285b33a
feat: add hodlmm-yield-router — autonomous HODLMM + Zest APY capital …
Terese678 Apr 16, 2026
87f4081
Implement safety guardrails for wallet and actions
Terese678 Apr 21, 2026
6b2d2d3
Refine agent description and enforce guardrail conditions
Terese678 Apr 21, 2026
6cdd1fa
Add 'safety' tag to SKILL.md
Terese678 Apr 21, 2026
694a730
Update author-agent in SKILL.md
Terese678 Apr 21, 2026
f64895d
Refactor wallet handling and add balance checks
Terese678 Apr 21, 2026
b1d5416
Refactor wallet key derivation method
Terese678 Apr 21, 2026
4aa2131
Fix Bitflow API URLs and add safety guardrails
Terese678 Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions dao-proposal-monitor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
name: dao-proposal-monitor
description: "Monitors Stacks DAO governance proposals for unauthorized execution, status changes, and voting activity, alerting agents before on-chain actions are taken."
metadata:
author: "Terese678"
author-agent: "Bitflow Agent"
user-invocable: "false"
arguments: "doctor | status | run"
entry: "dao-proposal-monitor/dao-proposal-monitor.ts"
requires: "wallet, settings"
tags: "defi, read, governance, dao, stacks, mainnet-only"
---

# dao-proposal-monitor

Monitors Stacks DAO governance proposals for unauthorized execution attempts, status changes, and voting threshold events. Alerts agents before on-chain actions are taken so they can respond or escalate.

## What It Does

- Polls active DAO proposals on Stacks via the Stacks API
- Detects proposals that are nearing execution threshold
- Flags proposals that have been executed without expected quorum
- Tracks new proposals submitted since last check
- Emits structured JSON alerts with severity levels: `info`, `warning`, `critical`

## Subcommands

| Command | Description |
|---------|-------------|
| `doctor` | Validates API connectivity, wallet config, and environment |
| `status` | Returns current snapshot of all active proposals |
| `run` | Starts continuous monitoring loop with alert emission |

## Output Contract

All output is strict JSON to stdout.

**doctor:**
```json
{
"status": "ok",
"checks": {
"api": "reachable",
"wallet": "loaded",
"network": "mainnet"
}
}
```

**status:**
```json
{
"status": "success",
"proposals": [
{
"id": "proposal-id",
"title": "Proposal Title",
"state": "active",
"votesFor": 1200000,
"votesAgainst": 300000,
"quorum": 1000000,
"executionBlock": 145000,
"blocksRemaining": 120,
"alert": null
}
],
"timestamp": 1712000000
}
```

**run (alert emission):**
```json
{
"status": "alert",
"severity": "critical",
"alertType": "unauthorized-execution",
"proposalId": "proposal-id",
"message": "Proposal executed below quorum threshold",
"data": {},
"timestamp": 1712000000
}
```

## Alert Types

| Alert Type | Severity | Description |
|-----------|----------|-------------|
| `new-proposal` | info | A new proposal has been submitted |
| `quorum-approaching` | warning | Votes within 10% of quorum threshold |
| `execution-imminent` | warning | Less than 144 blocks (~24h) to execution window |
| `unauthorized-execution` | critical | Executed below quorum |
| `quorum-reached` | info | Proposal has reached quorum |
| `proposal-expired` | info | Proposal passed execution window without executing |

## Safety

- Read-only: no transactions are signed or broadcast
- Rate limited: max 1 API call per 10 seconds
- Hard stop: monitoring loop exits after 1000 cycles
- No private key access required

## Example Usage

```bash
# Check environment
bun run dao-proposal-monitor.ts doctor

# Get current proposal snapshot
bun run dao-proposal-monitor.ts status

# Start monitoring loop
bun run dao-proposal-monitor.ts run

# Monitor specific DAO contract
bun run dao-proposal-monitor.ts run --dao SP000000000000000000002Q6VF78.my-dao
```
44 changes: 44 additions & 0 deletions skills/hodlmm-lp-dashboard/AGENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
name: hodlmm-lp-dashboard-agent
skill: hodlmm-lp-dashboard
description: "Monitors active Bitflow HODLMM positions and alerts immediately when a position goes out of range and stops earning fees."
---

# Agent Behavior — HODLMM LP Dashboard

## Decision order
1. Run `doctor` first. If it fails, stop and surface the blocker to the user.
2. Run `my-position` with the user's STX address.
3. Parse the JSON output and route on `details.inRange`.
4. If out of range, alert immediately with `details.binsFromRange` and `details.actionReason`.
5. If in range, report current status and schedule next check.

## On in-range result
- Report composition, earnings, and active bin position
- Recommend: HOLD
- Schedule next check in 5 minutes

## On out-of-range result
- Alert immediately: "Your position is earning 0% fees right now"
- Report exactly how many bins out of range using `details.binsFromRange`
- Report how far the active bin is from the user's range floor
- Recommend: REBALANCE
- Do not wait for user to ask — surface this proactively

## On API error
- Log the full error payload
- Do not retry silently
- Surface to user with suggested next action
- Do not assume position is healthy if API is unreachable

## Guardrails
- Never submit any transactions
- Never move any funds
- Never expose private keys or wallet seeds in logs or arguments
- This skill is read-only — it observes and reports only
- Default to safe behavior when intent is ambiguous

## On success
- Confirm position status with a plain language summary
- Include `inRange`, `binsFromRange`, `composition`, and `action` in the report
- Report `earningsUsd` to show fees captured or missed
92 changes: 92 additions & 0 deletions skills/hodlmm-lp-dashboard/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
name: hodlmm-lp-dashboard
description: "Personal LP dashboard for active Bitflow HODLMM positions. Answers am I earning right now with range status, bin distance, token composition, and hold/watch/rebalance recommendation."
metadata:
author: "ter_chimbiv"
author-agent: "Merged Vale"
user-invocable: "false"
arguments: "doctor | my-position | pool-status"
entry: "hodlmm-lp-dashboard/hodlmm-lp-dashboard.ts"
requires: "wallet, signing, settings"
tags: "defi, read-only, mainnet-only, l2"
---

# HODLMM LP Dashboard

> **Note:** This skill is for LPs already IN a position. For pre-entry volatility risk assessment, see `hodlmm-risk`.

## What it does

Monitors your active HODLMM concentrated liquidity position on Bitflow in real time. Answers the one question every LP has after opening a position: **"Am I still earning right now?"**

HODLMM concentrates liquidity in discrete price bins. When price drifts outside your range, your position earns zero fees silently — no alert, no notification from Bitflow. This skill detects that immediately, calculates exactly how many bins out of range you are, and surfaces a clear recommendation.

## Why agents need it

Bitflow sends no alerts when a position goes out of range. On March 28 2026, the author's live STX/USDCx position went out of range silently — converting entirely to 5.0007 STX / 0.00 USDCx. The pool was generating $23.09K in daily fees on $25.23M volume. Out-of-range LPs received nothing. No notification. No warning. An autonomous agent without this skill would hold a dead position indefinitely, bleeding opportunity while the pool earns for everyone else. This skill closes that gap.

## Safety notes
- This skill is read-only. It never submits transactions.
- It never moves funds of any kind.
- Mainnet only — HODLMM positions do not exist on testnet.
- No irreversible actions. Safe to run repeatedly at any interval.

## Commands

### `doctor`
Checks Bitflow API connectivity.
```bash
bun run hodlmm-lp-dashboard/hodlmm-lp-dashboard.ts doctor
```

### `my-position`
Full dashboard — range status, bin distance, token composition, recommendation.
```bash
bun run hodlmm-lp-dashboard/hodlmm-lp-dashboard.ts my-position \
--address SP2A37MQTATZTY386B8NQR6RZA15GF0BQNFVZP79K
```

### `pool-status`
Current pool active bin and total bin count.
```bash
bun run hodlmm-lp-dashboard/hodlmm-lp-dashboard.ts pool-status
```

## Output contract

All outputs are JSON to stdout.

**Success:**
```json
{ "result": "success", "details": { "inRange": false, "activeBin": 279, "userBinRange": { "min": 340, "max": 421 }, "binsFromRange": 61, "composition": "100% STX — price is below your range", "earningsUsd": 0, "action": "rebalance", "actionReason": "Out of range by 61 bins. Active bin 279 is below your range floor of 340. Earning 0% fees." } }
```

**Error:**
```json
{ "error": "descriptive message" }
```

## Why This Skill Exists — First-Hand Discovery

On March 28 2026, the author opened a live STX/USDCx DLMM Spot position on beta.bitflow.finance. Within hours, the position went out of range:

- **Position converted entirely to: 5.0007 STX / 0.00 USDCx**
- **Fees earning: 0%**
- **Pool was generating: $23.09K in fees on $25.23M 24h volume**
- **Out-of-range LPs received: nothing — silently**
- **Distance out of range: 61 bins below the active bin**

The pool APY showed 3933% — but only in-range LPs capture it. This skill was built to surface that gap instantly.

## On-Chain Proof

Built and tested against a real live position — not theoretical:

- **STX Address:** `SP2A37MQTATZTY386B8NQR6RZA15GF0BQNFVZP79K`
- **Pool:** STX/USDCx DLMM — Spot strategy, opened March 28 2026
- **Active bin at time of observation:** 279
- **User bin range:** 340–421 (61 bins out of range)
- **Explorer:** https://explorer.stacks.co/address/SP2A37MQTATZTY386B8NQR6RZA15GF0BQNFVZP79K
- **Author Agent:** Merged Vale — AIBTC Agent #114, Genesis Level 2
- **Agent Profile:** https://aibtc.com/agents/bc1qud2unr2t4y402xwpffejd2uu4htxdvqjzryrnj
- **HODLMM integration:** Yes ✅
112 changes: 112 additions & 0 deletions skills/hodlmm-lp-dashboard/hodlmm-lp-dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env bun
import { Command } from "commander";

const BASE = "https://beta.bitflow.finance/api/bff-proxy";
const POOL_ID = "dlmm_3";

const program = new Command();
program.name("hodlmm-lp-dashboard").description("Personal LP dashboard for active Bitflow HODLMM positions");

program.command("doctor")
.description("Check Bitflow API connectivity")
.action(async () => {
try {
const res = await fetch(`${BASE}/api/quotes/v1/bins/${POOL_ID}`);
if (res.ok) {
console.log(JSON.stringify({ result: "ok", message: "Bitflow API reachable", pool: POOL_ID }));
} else {
console.log(JSON.stringify({ error: `API returned ${res.status}` }));
}
} catch (e) {
console.log(JSON.stringify({ error: String(e) }));
}
});

program.command("my-position")
.description("Full dashboard for your active HODLMM position")
.requiredOption("--address <address>", "Your STX address")
.action(async (opts) => {
try {
const [posRes, poolRes] = await Promise.all([
fetch(`${BASE}/api/app/v1/users/${opts.address}/liquidity/${POOL_ID}`),
fetch(`${BASE}/api/quotes/v1/bins/${POOL_ID}`)
]);

if (!posRes.ok) {
console.log(JSON.stringify({ error: `No position found for ${opts.address}` }));
return;
}

const pos = await posRes.json();
const pool = await poolRes.json();

const inRange = pos.priceRange?.coversActiveBin ?? false;
const activeBin = pool.active_bin_id;
const userBins = pos.bins ?? [];
const minUserBin = userBins.length ? Math.min(...userBins.map((b: any) => b.bin_id)) : null;
const maxUserBin = userBins.length ? Math.max(...userBins.map((b: any) => b.bin_id)) : null;
const binsFromRange = minUserBin && activeBin < minUserBin ? minUserBin - activeBin : 0;

const stxAmount = pos.totalLiquidity?.tokenX?.amount ?? 0;
const usdcxAmount = pos.totalLiquidity?.tokenY?.amount ?? 0;
const totalUsd = pos.totalValueUsd ?? 0;
const earningsUsd = pos.userEarningsUsd ?? 0;

const composition = stxAmount > 0 && usdcxAmount === 0
? "100% STX — price is below your range"
: usdcxAmount > 0 && stxAmount === 0
? "100% USDCx — price is above your range"
: `${((stxAmount / (stxAmount + usdcxAmount)) * 100).toFixed(1)}% STX / ${((usdcxAmount / (stxAmount + usdcxAmount)) * 100).toFixed(1)}% USDCx`;

const action = inRange ? (binsFromRange < 5 ? "watch" : "hold") : "rebalance";
const actionReason = inRange
? `Position in range — earning fees. Active bin ${activeBin} is within your range.`
: `Out of range by ${binsFromRange} bins. Active bin ${activeBin} is below your range floor of ${minUserBin}. Earning 0% fees.`;

console.log(JSON.stringify({
result: "success",
details: {
address: opts.address,
pool: POOL_ID,
inRange,
activeBin,
userBinRange: { min: minUserBin, max: maxUserBin },
binsFromRange,
composition,
stxAmount,
usdcxAmount,
totalValueUsd: totalUsd,
earningsUsd,
action,
actionReason
}
}));
} catch (e) {
console.log(JSON.stringify({ error: String(e) }));
}
});

program.command("pool-status")
.description("Current pool active bin and range data")
.action(async () => {
try {
const res = await fetch(`${BASE}/api/quotes/v1/bins/${POOL_ID}`);
if (!res.ok) {
console.log(JSON.stringify({ error: `Pool fetch failed: ${res.status}` }));
return;
}
const data = await res.json();
console.log(JSON.stringify({
result: "success",
details: {
pool: POOL_ID,
activeBinId: data.active_bin_id,
totalBins: data.total_bins
}
}));
} catch (e) {
console.log(JSON.stringify({ error: String(e) }));
}
});

program.parse();
Loading
Loading