feat: add zest-yield-manager (BFF Skills Comp winner by @secret-mars)#246
feat: add zest-yield-manager (BFF Skills Comp winner by @secret-mars)#246diegomey wants to merge 1 commit intoaibtcdev:mainfrom
Conversation
arc0btc
left a comment
There was a problem hiding this comment.
Adds autonomous sBTC yield management for Zest Protocol — supply, withdraw, claim rewards, monitor positions. Competition-validated with mainnet proof, and the implementation holds up.
What works well:
- Pre-flight safety checks (gas, balance, spend limit) are thorough and consistently applied across all write paths
Promise.allfor parallel fetches inrunStatus,runSupply,runWithdraw,runClaim— good pattern- Structured
SkillOutputcontract with explicitblockedvserrorvssuccessstates makes agent routing deterministic getStxBalancecorrectly subtracts locked STX — that would silently break agents running Stacking positions- SKILL.md constraints section is honest and specific: pool utilization failure, oracle outages, borrow-helper versioning
[suggestion] Dead try/catch in runSupply (zest-yield-manager.ts:340–354)
The try/catch wraps only output() — which never throws. The actual network calls (getStxBalance, getSbtcBalance) happen in the Promise.all above it, outside the try block. The catch branch (error("supply_failed", ...)) is unreachable dead code. Either remove the try/catch entirely, or wrap the whole function body including the Promise.all:
output({
status: "success",
action: "Execute supply transaction via MCP zest_supply tool",
data: {
operation: "supply",
asset: "sBTC",
amount_sats: amountSats,
contract: BORROW_HELPER,
function: "supply",
args: {
asset: SBTC_TOKEN,
amount: amountSats.toString(),
note: "Uses borrow-helper-v2-1-7 which handles Pyth oracle fee automatically",
},
mcp_command: {
tool: "zest_supply",
params: { asset: "sBTC", amount: amountSats.toString() },
},
pre_checks_passed: {
gas_sufficient: true,
balance_sufficient: true,
within_spend_limit: true,
stx_balance: stxBalance,
sbtc_balance: sbtcBalance,
},
},
error: null,
});
[suggestion] Unused ZSBTC constant (zest-yield-manager.ts:42)
ZSBTC = "SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N.zsbtc-v2-0" is defined but never referenced anywhere in the implementation. If it's for future borrow support, add a comment; otherwise remove it.
[nit] install-packs --pack arg is vestigial
SKILL.md shows install-packs --pack all but the --pack arg is never read in the implementation — it always checks all deps. Either remove the --pack flag from the documented example or implement pack filtering. As-is, the flag is documented but silently ignored.
Code quality notes:
The 5 doctor checks run sequentially. Promise.all would cut the diagnostic time by ~4x — small improvement for a command that hits external APIs. Not blocking, just worth noting for follow-up.
Operational context:
We run Zest V2 (SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N.pool-borrow-v2-3) in production for task #6808. Contract addresses here match what we know — pool-borrow-v2-3, borrow-helper-v2-1-7, same deployer. The sBTC token principal also matches our arc-payments skill config.
Worth making explicit for new integrators: this skill generates MCP command parameters for zest_supply/zest_withdraw/zest_claim_rewards — it doesn't broadcast transactions itself. The MCP server must be running with Zest tools loaded. SKILL.md's requires: "wallet, signing, settings" hints at this but calling it out directly in AGENT.md's decision order would save confusion.
biwasxyz
left a comment
There was a problem hiding this comment.
Review: zest-yield-manager (BFF Competition Winner)
Great submission — the skill has solid design (structured output contract, spend-limit guardrails, on-chain proof of mainnet testing). Congrats to @secret-mars on the Day 1 win!
The main issue is that the competition-to-registry conversion is incomplete. The bff-skills repo has different conventions than aibtcdev/skills, and the automated conversion only partially bridged the gap. Here's what still needs attention:
CI Blocker
zest-yield-manager/AGENT.md is missing YAML frontmatter. The bff-skills repo doesn't require it, but our validator does. Needs:
---
name: zest-yield-manager-agent
skill: zest-yield-manager
description: Autonomous sBTC yield management on Zest Protocol — supply, withdraw, claim rewards, and monitor positions with safety controls.
---Convention Alignment
These aren't blockers but would bring the skill in line with the rest of the registry:
-
Commander.js — The competition repo uses a custom
parseArgs+switchpattern. Skills in this repo use Commander.js for argument parsing (see CLAUDE.md CLI Script Conventions). -
Shared infrastructure — The script hardcodes
https://api.hiro.soand rolls its own wallet address resolution via env vars. Existing skills usesrc/lib/services/hiro-api.ts,src/lib/services/wallet-manager.ts, andsrc/lib/config/networks.tsfor this. -
Transaction pattern — The skill outputs MCP command payloads (
mcp_command.tool: "zest_supply") for the agent framework to execute, rather than building and broadcasting transactions directly. This is the bff-skills convention and works fine, but it's worth noting it differs from how most skills in this repo handle writes.
What's Valuable Here
The withdraw and claim rewards capabilities don't exist in the current yield-hunter or yield-dashboard skills, so this is a genuine addition to the ecosystem. The doctor pre-flight check pattern and the standardized {status, action, data, error} output envelope are well thought out.
Thanks @diegomey for bringing this over from the competition, and @secret-mars for the original work!
|
@whoabuddy — wanted to get your take on how we should handle competition winners coming in from bff-skills. This one has a CI failure (missing AGENT.md frontmatter) and uses the competition's conventions (custom arg parser, no shared infra) instead of ours. Should we:
The skill itself adds real value (Zest withdraw + claim rewards), just needs the conversion finished. |
|
Thanks for upstreaming this, @diegomey. The frontmatter conversion to aibtcdev/skills convention looks right. Happy to address any changes needed for the registry format. For reference, the skill is actively running on mainnet — our agent (SP4DXVEC16FS6QR7RBKGWZYJKTXPC81W49W0ATJE) has a live Zest position using these exact functions. |
zest-yield-manager
Author: @secret-mars (Secret Mars)
Competition PR: BitflowFinance/bff-skills#11
This skill was submitted to the AIBTC x Bitflow Skills Pay the Bills competition, reviewed by judging agents and the human panel, and approved as a Day 1 winner.
Frontmatter has been converted to the aibtcdev/skills
metadata:convention. Command paths updated to match this repo root-level skill layout.Files
zest-yield-manager/SKILL.md— Skill definition with AIBTC-format frontmatterzest-yield-manager/AGENT.md— Agent behavior rules and guardrailszest-yield-manager/zest-yield-manager.ts— TypeScript implementationAttribution
Original author: @secret-mars. The
metadata.authorfield in SKILL.md preserves their attribution permanently.Automated by BFF Skills Bot.