Skip to content

feat(paperboy): add paid signal distribution skill#1

Open
sonic-mast wants to merge 111 commits intomainfrom
feat/paperboy-skill
Open

feat(paperboy): add paid signal distribution skill#1
sonic-mast wants to merge 111 commits intomainfrom
feat/paperboy-skill

Conversation

@sonic-mast
Copy link
Owner

@sonic-mast sonic-mast commented Mar 25, 2026

Adds paperboy skill for distributing aibtc.news signals to agents and external audiences.

Subcommands: leaderboard, status, signals, recruit, log-delivery

Pay: 500 sats/placement, 2000 sats/recruit bonus.

Requesting Devin review before upstream PR.


Open with Devin

cocoa007 and others added 30 commits March 4, 2026 16:34
* feat: add nostr skill — protocol operations for AI agents

Adds nostr skill with 7 subcommands:
- post: Post kind:1 notes to relays (requires wallet)
- read-feed: Read recent notes from relays
- search-tags: Search by hashtag using NIP-12 #t filter
- get-profile: Get kind:0 profile metadata
- set-profile: Set kind:0 profile metadata (requires wallet)
- get-pubkey: Derive Nostr pubkey via NIP-06 from BIP84 path
- relay-list: List configured relay URLs

Key derivation uses BIP84 m/84'/0'/0'/0/0 — same secp256k1
keypair as the BTC wallet. Uses nostr-tools + ws packages.

* fix: address review feedback on nostr skill PR aibtcdev#73

- Rename 'NIP-06' references to 'BTC-shared key derivation' — we use
  m/84'/0'/0'/0/0 (BIP84), not m/44'/1237'/0'/0/0 (NIP-06). This is
  intentional (shared BTC+Nostr identity) but labeling was inaccurate.

- Fix publishToRelays timeout race — pool.publish() returns Promise[]
  in nostr-tools v2+, so Promise.race received an array (non-thenable)
  and resolved immediately. Now spreads the array properly.

- Fix set-profile field wipe — kind:0 is replaceable, so publishing
  with only --name would delete about/picture/etc. Now fetches existing
  profile and merges before publishing.

Co-reviewed-by: arc0btc

* chore: regenerate skills.json manifest

---------

Co-authored-by: cocoa007 <cocoa007@users.noreply.github.com>
Add scan-project-board.md to what-to-do/ with a 6-step workflow:
fetch open projects, match capabilities, claim, do work, report
to founder, and update the board. Integrates into the autonomous
loop Phase 2 (Observe) on a recommended every-5th-cycle cadence.

Also updates setup-autonomous-loop.md Phase 2 table and See Also
to reference the new skill, and adds it to INDEX.md.

Closes aibtcdev#28

Co-authored-by: JackBinswitch-btc <JackBinswitch-btc@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: warmidris <265621832+warmidris@users.noreply.github.com>
* feat(dual-stacking): add Dual Stacking enrollment skill

Adds a new skill for enrolling in Dual Stacking — earn BTC-denominated
rewards (paid in sBTC) by simply holding sBTC. No lockup required.

Contract: SP1HFCRKEJ8BYW4D0E3FAWHFDX8A25PPAA83HWWZ9.dual-stacking-v2_0_4

Subcommands:
- check-status [--address]: enrollment state, APR range, min amount, cycle overview
- enroll [--reward-address]: enroll in dual stacking (wallet required)
- opt-out: opt out of dual stacking (wallet required)
- get-rewards --cycle N [--address] [--rollback]: earned rewards for a cycle

APR: ~0.5% APY (sBTC only) up to ~5% APY with stacked STX (10x multiplier)
Minimum: 10,000 sats sBTC (0.0001 sBTC)

* fix: remove invalid tags from dual-stacking SKILL.md

* fix: address arc0btc review — parse cycleOverview, fix ClarityValue type, sync skills.json tags

* fix: sync SKILL.md output schema with actual code, add trailing newline to skills.json

- cycleOverview fields corrected: currentCycleId, snapshotIndex, snapshotsPerCycle
  (was incorrect: currentCycle, totalEnrolled, totalSbtcLocked)
- apr output example now includes 'note' field matching code output
- skills.json: add missing trailing newline

Addresses review feedback from arc0btc and JackBinswitch-btc

---------

Co-authored-by: sonic-mast <sonic-mast@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
)

* feat(styx): add BTC→sBTC conversion skill via Styx protocol

Headless BTC→sBTC deposits using @faktoryfun/styx-sdk:
- pool-status, pools, fees, price (read-only queries)
- deposit (full flow: reserve → build PSBT → sign → broadcast → update)
- status, history (deposit tracking)

Uses @scure/btc-signer for local PSBT construction and signing,
mempool.space for broadcast. No browser wallet required.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(styx): add required YAML frontmatter to AGENT.md

CI validator requires name, skill, and description fields in AGENT.md
frontmatter. Missing these caused the validate step to fail.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(styx): add allowUnknownOutputs flag and fix OP_RETURN script handling

- Enable allowUnknownOutputs flag in Transaction to properly handle OP_RETURN outputs
- Fix OP_RETURN script decoding: SDK provides already-formatted script hex, don't re-encode
- Add clarifying comment on opReturnData format

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix(styx): add ordinal protection, input validation, and status update retry

- Filter ordinal UTXOs on mainnet via OrdinalIndexer to prevent destroying
  inscriptions (same pattern as btc/btc.ts and sbtc-deposit.service.ts)
- Remove unused MAX_DEPOSIT_SATS import
- Validate --fee priority against allowed values before casting
- Use Math.round instead of Math.floor for float-to-sats conversion
- Consolidate btcAmount conversion to single .toFixed(8) via parseFloat
- Add retry on updateDepositStatus failure with recovery info output
- Fix status command: use else-if chain instead of non-null assertion
- Fix history command: explicit null check instead of null-dereference
- Add network field to all subcommand outputs for consistency
- Remove unused txid variable (broadcastTxid is the canonical reference)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(styx): address Copilot review feedback

- Validate --btc-sender matches active wallet before reserving liquidity
- Recompute change amount after filtering ordinal UTXOs to keep tx balanced
- Merge status update warning into success JSON (single stdout object)
- Cancel deposit reservation on post-reservation failure (best-effort cleanup)
- Fix SKILL.md "How It Works" step 3 to match actual flow (no SDK-provided PSBT)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…nce (aibtcdev#85)

Styx protocol requires the OP_RETURN output at index 0, but it was being
added after the deposit output (index 1). This caused deposit tracking
failures. Swap output ordering so OP_RETURN is added first.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add author attribution to skill frontmatter

Add `author` (GitHub username) and `author_agent` (agent display name)
fields to the SKILL.md frontmatter spec. This enables aibtc.com/skills
to show who built each skill, turning skill-building into a reputation play.

Changes:
- CONTRIBUTING.md: document author and author_agent fields in frontmatter spec
- scripts/generate-manifest.ts: parse and include author fields in skills.json
- 5 existing SKILL.md files updated with actual authors from git history:
  - ceo: arc0btc / Trustless Indra
  - business-dev: pbtc21 / Tiny Marten
  - nostr: cocoa007
  - wallet: whoabuddy / Trustless Indra
  - bitflow: whoabuddy / Trustless Indra
- skills.json: regenerated with author metadata

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback on author attribution

- CONTRIBUTING.md: clarify author field is "required for new skills" not universally required
- skills.json: regenerate via bun run manifest (timestamp update only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
* feat(scripts): add skill scaffolding script for new contributors

Adds `bun run scaffold <skill-name>` which generates a complete skill
directory with SKILL.md (frontmatter + docs template), AGENT.md
(delegation rules template), and a Commander CLI entry file with
printJson/handleError boilerplate. Validates kebab-case naming and
prevents overwriting existing skills.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(scaffold): use empty defaults, add author fields, cleanup

- Change requires/tags from hardcoded [wallet]/[l2] to empty [] with
  guidance in generated markdown body for contributors to fill in
- Add author and author_agent placeholder fields to SKILL.md template
- Remove unused kebabToCamel helper and programName variable
- Use node: import prefix for consistency with other scripts
- Replace emoji in console output with plain text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
Add new onboarding skill for first-hour AIBTC setup automation with doctor, install-packs, and run subcommands. Supports optional registration + heartbeat check-in and curated skill-pack installs.

Includes onboarding/SKILL.md, AGENT.md, onboarding.ts, workflow guide, signing.ts unlockWalletFromOptions helper, author attribution, and regenerated skills.json.

Safety: wallet password flows via AIBTC_WALLET_PASSWORD env var (not CLI argv), finance pack is opt-in, community step is non-blocking.

Co-Authored-By: k9dreamer <k9dreamer@gmail.com>
…v#92)

Extends the nostr skill with two new subcommands for broadcasting
aibtc.news signals to the Nostr network:

- amplify-signal: fetch a signal by ID from aibtc.news and broadcast
  it as a formatted kind:1 note (auto-tags: #bitcoin, #aibtcnews, #nostr)
- amplify-text: broadcast signal content directly without an API fetch

Both commands use the BTC-shared key derivation (same identity as post),
publish to the default relay set, and support --relays override.

Updates SKILL.md, AGENT.md, and skills.json accordingly.

Co-authored-by: Sonic Mast <sonic-mast@aibtc.dev>
aibtcdev#82)

* feat: add yield-dashboard skill — cross-protocol DeFi yield aggregator

Adds a read-only yield dashboard skill that aggregates DeFi positions
across Zest Protocol, ALEX DEX, Bitflow, and STX stacking.

Subcommands:
- overview: total portfolio value, weighted APY, per-protocol breakdown
- positions: detailed per-protocol position data
- apy-breakdown: current APY rates across all protocols (pure market data)
- rebalance: allocation suggestions based on risk-adjusted yield

Uses on-chain read-only contract calls via Hiro API. No transactions,
no API keys required.

* fix: address review feedback — ESM imports, unit separation, aBTC label

- Move standardPrincipalCV to top-level ES import (was inline require())
- Add valueUnit field to ProtocolPosition interface
- Separate sats vs microSTX in overview output (no more mixed units)
- Rename ALEX asset label from sBTC/STX to aBTC/STX (accurate trust model)
- Add Known Limitations section to SKILL.md
- Document Bitflow API fallback behavior

* fix: CI tag, positions unit display, cleanup per review

- tags: read → read-only (CI validation fix)
- positions command: separate sats/microSTX display (was showing microSTX as BTC)
- ALEX + stacking: apySource = 'static estimate, not live'
- Remove unnecessary IIFE in Zest reader
- Remove unused ZEST_V2_REWARDS constant

* fix(yield-dashboard): regenerate skills.json manifest

Run `bun run manifest` to include the yield-dashboard skill entry
in skills.json, fixing the CI manifest freshness check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: cocoa007 <cocoa007@users.noreply.github.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(ordinals-p2p): add P2P ordinals trading skill via trade ledger

Agent-to-agent ordinals trading CLI for ledger.drx4.xyz:
- create-offer, counter, transfer, cancel, psbt-swap write operations
- list-trades, get-trade, my-trades, agents read operations
- BIP-137 authenticated writes with replay protection
- Full SKILL.md + AGENT.md documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address review feedback on ordinals-p2p skill

- Fix BIP-137 signing: use `as any` for format:"recovered" (v2 API
  supports it but types don't expose it)
- Fix SKILL.md: BIP-322 → BIP-137 to match actual implementation
- Make --tx-hash optional on transfer (supports sBTC/off-chain)
- Add --address flag to my-trades (read-only without wallet)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add frontmatter to AGENT.md for CI validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ordinals-p2p): use correct @noble/curves Signature API for BIP-137

secp256k1.sign() returns a Signature object with .recovery and
.toCompactRawBytes(), not a raw byte array. The "format: recovered"
option does not exist in @noble/curves. Fixes blocking review feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ordinals-p2p): address review suggestions

- my-trades: graceful fallback when wallet locked without --address
- Add parseIntSafe() to validate amount/parent args (NaN guard)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use @noble/hashes for SHA-256, add btcPrivateKey type guard

Addresses review feedback:
1. Replace hashSha256Sync with @noble/hashes/sha256 for guaranteed
   Uint8Array output (no hex string ambiguity)
2. Add ensureBytes() guard on btcPrivateKey to handle both Uint8Array
   and hex string from wallet-manager
3. Import hexToBytes from @noble/hashes/utils

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: multi-author support and full author attribution (aibtcdev#95, aibtcdev#93)

Add bracket-list syntax for author/author_agent fields in SKILL.md
frontmatter, with validation for parallel array lengths. Backfill
author attribution across all 35 skills based on PR merge history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ceo): correct author attribution to pbtc21/Tiny Marten

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…btcdev#102)

* refactor(wallet): improve AGENT.md structure and fix null-assertion pattern

Add five standard sections to AGENT.md: prerequisites, decision logic
(table), safety checks, error handling (table), and output handling.
This structure enables downstream agents to understand the skill without
reading the full SKILL.md documentation.

In wallet.ts, replace the `activeId!` non-null assertion pattern in
unlock, export, and rotate-password with a safe `?? await` resolution
followed by an early `return` after handleError. This removes TypeScript
non-null assertions at runtime error boundaries.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(credentials): improve AGENT.md structure and fix parseAsync inconsistency

Add five standard sections to AGENT.md: prerequisites, decision logic
(table), safety checks, error handling (table), and output handling.
Consistent structure across all infrastructure skill AGENT.md files
enables agents to reason about skill selection and chaining.

Change program.parseAsync to program.parse for consistency with wallet.ts
and settings.ts — Commander.js handles async action handlers correctly
with synchronous parse, making parseAsync unnecessary here.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(settings): improve AGENT.md structure with standard sections

Add five standard sections to AGENT.md: prerequisites, decision logic
(table), safety checks, error handling (table), and output handling.
The settings skill has the most subcommands of the three infrastructure
skills — the decision logic table makes subcommand selection clear for
agents choosing between hiro API key vs stacks URL vs relay health checks.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(btc): standardize AGENT.md to 5-section format

Rewrote AGENT.md to match the Phase 1 canonical structure:
- Added Prerequisites section covering wallet unlock and mainnet constraints
- Added Decision Logic table covering all 7 subcommands
- Added Safety Checks with UTXO type, balance, and address verification
- Added Error Handling table with exact error strings and fixes
- Added Output Handling documenting key fields for downstream use
- Fixed example invocation (--to → --recipient to match actual CLI flag)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(ordinals): standardize AGENT.md to 5-section format

Rewrote AGENT.md to match the Phase 1 canonical structure:
- Added Prerequisites covering wallet unlock, BTC balance, and base64 encoding requirement
- Added Decision Logic table covering all 5 subcommands
- Added Safety Checks emphasizing two-step commit/reveal workflow and UTXO protection
- Added Error Handling table with exact error strings from ordinals.ts
- Added Output Handling documenting critical fields (commitTxid, revealAmount, feeRate)
- Fixed example invocations (--content → --content-base64 to match actual CLI flags)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(ordinals-p2p): standardize AGENT.md and fix non-null assertion

AGENT.md:
- Fixed frontmatter name field (ordinals-p2p → ordinals-p2p-agent)
- Converted prose Decision Logic to proper table format covering all 9 subcommands
- Expanded Error Handling table with Cause column and exact HTTP error messages
- Added Output Handling section documenting trade.id extraction and status transitions
- Added Example Invocations section with 3 bun run examples

ordinals-p2p.ts:
- Replaced non-null assertion (btcAddress!) with explicit null check and early return
  to match the null-safe pattern established in Phase 1 PATTERNS.md

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(taproot-multisig): standardize AGENT.md to 5-section format

Rewrote AGENT.md from a long step-by-step guide to the canonical 5-section format
while preserving all critical technical content:
- Added concise intro paragraph with mainnet proof references
- Added Prerequisites section (wallet unlock, signing skill dependency, mainnet note)
- Added Decision Logic table for all 3 subcommands plus signing skill delegation
- Added Safety Checks emphasizing internal vs tweaked key gotcha and blind-sign review
- Added Error Handling table with exact error strings and resolution steps
- Added Output Handling documenting internalPubKey sharing and isValid check
- Preserved the critical BIP-86 internal vs tweaked key warning in Safety Checks
- Kept 3 concise Example Invocations covering the main workflow steps

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(stx): standardize AGENT.md to 5-section format

Rewrites the stx AGENT.md to include all required sections from PATTERNS.md:
Prerequisites, Decision Logic table, Safety Checks, Error Handling table,
and Output Handling. Previous file used Capabilities/When to Delegate/Key
Constraints structure that blocked downstream agents from mapping errors
to fixes or understanding which fields to extract.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(tokens): standardize AGENT.md and simplify address resolution

Rewrites tokens AGENT.md with the 5-section format from PATTERNS.md:
Prerequisites, Decision Logic table, Safety Checks, Error Handling table,
and Output Handling. Adds safety guidance on checking decimals before
specifying amounts, and verifying balance before transfer.

Also simplifies the if/else address resolution blocks in get-balance and
list-user-tokens to use the nullish coalescing pattern consistently with
other skills in the codebase.

Fixes the example invocation which used --to instead of --recipient.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(nft): standardize AGENT.md and simplify address resolution

Rewrites nft AGENT.md with the 5-section format from PATTERNS.md:
Prerequisites, Decision Logic table, Safety Checks, Error Handling table,
and Output Handling. Adds ownership verification check before transfer
and clarifies token ID format expectations.

Simplifies the if/else address resolution block in get-holdings to use
the nullish coalescing pattern. Fixes the example invocation which used
--to instead of --recipient.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(bns): standardize AGENT.md and remove unused import

Rewrites bns AGENT.md with the 5-section format from PATTERNS.md:
Prerequisites, Decision Logic table, Safety Checks, Error Handling table,
and Output Handling. Adds critical guidance on saving the preorder salt,
waiting for confirmation between steps, and preferring claim-fast.

Removes the unused getWalletManager import from bns.ts — only
getAccount and getWalletAddress from x402.service were actually used.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(identity): rewrite AGENT.md to 5-section format

Replaces the informal Capabilities/When to Delegate/Key Constraints
structure with the canonical 5-section format: Prerequisites, Decision
Logic table, Safety Checks, Error Handling table, Output Handling, and
Example Invocations. Covers all 10 subcommands, operator vs owner
permissions, transfer irreversibility, and hex encoding requirements.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(signing): rewrite AGENT.md to 5-section format; mark wallet-password as sensitive

Replaces the informal Capabilities/When to Delegate/Key Constraints
structure with the canonical 5-section format: Prerequisites, Decision
Logic table (all 10 subcommands), Safety Checks, Error Handling table,
Output Handling, and Example Invocations. Adds guidance on Schnorr
blind-signing risk, Nostr key source selection, and SIP-018 domain
binding. Also marks --wallet-password option as (sensitive) in both
stacks-sign and btc-sign commands per CLI conventions.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(reputation): rewrite AGENT.md to 5-section format

Replaces the informal Capabilities/When to Delegate/Key Constraints
structure with the canonical 5-section format: Prerequisites, Decision
Logic table (all 11 subcommands), Safety Checks, Error Handling table,
Output Handling, and Example Invocations. Clarifies revoke-only-by-
submitter constraint, approve-client permission requirements, WAD
average interpretation, and cursor-based pagination behavior.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(validation): rewrite AGENT.md to 5-section format

Replaces the informal Capabilities/When to Delegate/Key Constraints
structure with the canonical 5-section format: Prerequisites, Decision
Logic table (all 6 subcommands), Safety Checks, Error Handling table,
Output Handling, and Example Invocations. Clarifies respond-only-by-
validator constraint, progressive score updates, 0-100 range
enforcement, and request-hash lookup workflow for validators.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate skills.json manifest

Auto-generated from SKILL.md frontmatter after phase 4 AGENT.md updates.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(sbtc): audit improvements — AGENT.md 5-section rewrite, simplify fee resolution

- Rewrote AGENT.md with full 5-section structure (Prerequisites, Decision
  Logic, Safety Checks, Error Handling, Output Handling) per PATTERNS.md
- Fixed incorrect example invocation: --to -> --recipient
- Added Decision Logic table covering all 6 subcommands
- Added Error Handling table with exact error strings and fixes
- Added Output Handling section explaining status values and downstream fields
- Replaced switch/case fee tier resolution with array lookup + index access,
  eliminating unreachable default branch

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(dual-stacking): add missing AGENT.md with 5-section format

dual-stacking had no AGENT.md. Created one covering prerequisites
(10,000 sat minimum, mainnet-only, unlock for write ops), decision
logic table for all 4 subcommands, safety checks (mid-cycle enrollment
timing, opt-out irreversibility), error handling, and output handling.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(defi): rewrite AGENT.md to full 5-section format

Previous AGENT.md used freeform sections (Capabilities, When to
Delegate, Key Constraints) instead of the canonical 5-section format.
Rewrote to include Prerequisites, Decision Logic table covering all 11
subcommands, Safety Checks (slippage, collateral ratio, units), Error
Handling table, Output Handling, and correct example invocations using
actual CLI flags.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(bitflow): rewrite AGENT.md to full 5-section format and fix example flags

Previous AGENT.md used freeform sections and had incorrect example
invocations (--from/--to flags that don't exist; correct flags are
--token-x/--token-y). Rewrote to 5-section format covering all 11
subcommands, high-impact swap safety gate, Keeper order lifecycle,
and correct example invocations using actual CLI flags.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(stacking): rewrite AGENT.md to full 5-section format and fix example flags

Previous AGENT.md used freeform sections and had incorrect example
invocations (--cycles and --pox-address flags that don't exist). Rewrote
to 5-section format covering all 4 subcommands, Bitcoin address version
table, prepare-phase timing requirements, and correct example invocations
using actual CLI flags (--lock-period, --pox-address-version, etc.).

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(pillar): rewrite AGENT.md to full 5-section format

Previous AGENT.md used freeform sections. Rewrote to 5-section format
covering both pillar.ts (browser-handoff) and pillar-direct.ts (agent
direct) operation modes, full decision logic table for all subcommands,
safety checks for boost/unwind slippage and collateral ratio monitoring,
error handling for key/session/network errors, and output handling
linking quote outputs to boost inputs.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(pillar): remove non-null assertion and replace direct fetch with shared hiro-api

pillar-direct.ts key-unlock command used session!.pubkey non-null
assertion after getActiveKey(), which is unsafe if unlock fails
silently. Replaced with a null check and early return via handleError.

pillar.ts position command used raw fetch() to call the Hiro API
directly instead of the shared getHiroApi() service. Replaced with
the shared service to be consistent with all other skills.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(stacks-market): rewrite AGENT.md to canonical 5-section format

Replaces informal Capabilities/When-to-Delegate/Key-Constraints structure
with the required Prerequisites, Decision Logic, Safety Checks, Error
Handling, and Output Handling sections. Adds explicit LMSR quote-before-
trade workflow, error table with exact CLI strings, and NETWORK=mainnet
prefix on all example invocations.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(yield-hunter): canonical AGENT.md format and replace process.exit(1) with handleError

Rewrites AGENT.md from informal to required 5-section structure: Prerequisites,
Decision Logic, Safety Checks, Error Handling, Output Handling. Adds explicit
guardrails for autonomous financial operations — STX fee check, reserve reasoning,
stop-before-withdraw guidance.

In yield-hunter.ts, replaces printJson({error})+process.exit(1) patterns in
start (already-running guard) and stop (no PID, stale PID) with handleError()
and early return, consistent with canonical CLI patterns.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(yield-dashboard): canonical AGENT.md format and use handleError for mainnet guard

Rewrites AGENT.md from informal to required 5-section structure: Prerequisites,
Decision Logic, Safety Checks, Error Handling, Output Handling. Explicitly documents
known limitations (ALEX/Bitflow LP balance reads not yet implemented, static APY
estimates) and the wallet-not-needed exception for apy-breakdown.

In yield-dashboard.ts, replaces printJson({error})+process.exit(1) in overview,
positions, and rebalance mainnet guards with handleError(new Error(...))+return,
consistent with canonical CLI patterns. Removes stray blank line in readStackingPosition.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(query): canonical AGENT.md and deduplicated import

- Rewrite AGENT.md with canonical 5-section structure: Prerequisites,
  Decision Logic, Safety Checks, Error Handling, Output Handling
- Fix example invocation: use --contract-id instead of deprecated
  --contract-address/--contract-name flags
- Deduplicate NETWORK import (was split across two import statements
  from the same module)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(x402): canonical AGENT.md and try/catch coverage for sync actions

- Rewrite AGENT.md with canonical 5-section structure: Prerequisites,
  Decision Logic, Safety Checks, Error Handling, Output Handling
- Add payment safety checks: verify sBTC/STX balance before executing
  paid endpoints, always probe before auto-approve
- Wrap list-endpoints, openrouter-guide, and openrouter-models action
  handlers in try/catch so unexpected errors route through handleError
  rather than surfacing as unhandled exceptions

Co-Authored-By: Claude <noreply@anthropic.com>

* audit(nostr): fix tags, canonical AGENT.md, inline opts types

- Remove incorrect `l1` tag — Nostr is not Bitcoin L1
- Rewrite AGENT.md to follow canonical 5-section structure with
  proper Decision Logic table, Safety Checks (key safety, post rate
  limits, BTC-shared keypair risks), Error Handling table with exact
  error strings, and Output Handling section
- Add inline type annotations to all .action() opts parameters
- Remove unnecessary `as string` casts now that opts is typed

Co-Authored-By: Claude <noreply@anthropic.com>

* audit(styx): canonical AGENT.md with full 5-section structure

- Add opening paragraph explaining Styx vs native sBTC use case
- Rewrite Decision Logic as proper table covering all 7 subcommands
- Expand Safety Checks to include ordinal UTXO protection note,
  btc-sender wallet match requirement, and status-update recovery guidance
- Add Error Handling table with exact error strings from the CLI
- Add Output Handling section documenting all subcommand outputs
  and which fields to extract for downstream use

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(aibtc-news): rewrite AGENT.md to canonical 5-section format

All three aibtc-news skills (aibtc-news, aibtc-news-deal-flow,
aibtc-news-protocol) now follow the 5-section structure established in
phase 01: Prerequisites, Decision Logic table, Safety Checks, Error
Handling table, Output Handling, and Example Invocations.

Previous AGENT.md files used custom section names (Capabilities, When
to Delegate Here, Key Constraints) that were inconsistent with the
canonical pattern. Consistent structure allows downstream agents to
locate information predictably across all skills.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(business-dev): rewrite AGENT.md and fix CLI error handling

Rewrote AGENT.md to the canonical 5-section format (Prerequisites,
Decision Logic, Safety Checks, Error Handling, Output Handling,
Example Invocations) replacing the previous custom structure.

Fixed CLI error handling in business-dev.ts to use handleError()
with return instead of printJson({ error }) + process.exit(1), which
is the pattern established across all other skills. Also made
program.parse() explicit with process.argv.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(ceo): rewrite AGENT.md to canonical 5-section format

Rewrote AGENT.md to the canonical 5-section structure while preserving
the full strategic framework content. The previous AGENT.md was the
reference document itself with 13 numbered sections but no standardized
agent navigation structure.

The new format makes explicit that ceo is orchestration-only (no CLI),
maps each strategic goal to the relevant section as Decision Logic, and
documents how CEO framework outputs feed into other skills like
business-dev and stx.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(onboarding): rewrite AGENT.md and fix parseAsync usage

Rewrote AGENT.md from a minimal 4-section format to the canonical
5-section structure (Prerequisites, Decision Logic, Safety Checks,
Error Handling, Output Handling, Example Invocations). The previous
AGENT.md had only decision rules, execution order, output contract,
and guardrails — insufficient for agents navigating the skill.

Fixed onboarding.ts to use program.parse(process.argv) instead of
program.parseAsync(), which is the established pattern. Commander
handles async action handlers correctly with parse().

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(stackspot): rewrite AGENT.md to canonical 5-section format

Rewrote AGENT.md to the canonical 5-section structure (Prerequisites,
Decision Logic, Safety Checks, Error Handling, Output Handling,
Example Invocations) replacing the previous custom structure.

Key improvements: explicit NETWORK=mainnet requirement in Prerequisites
and all examples, PoX prepare phase timing guidance in Safety Checks,
and complete Output Handling mapping so downstream agents know which
fields to extract from each subcommand.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(aibtc-agents): fix stale workflow link in arc0btc README

The arc0btc README referenced a what-to-do file as
file-aibtc-news-signals.md which does not exist. The correct
filename is file-news-signal.md. Fixes a broken cross-reference
in the Workflows table.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(what-to-do): replace MCP tool name with bun run command in scan-project-board

The scan-project-board guide instructed agents to use the
send_inbox_message MCP tool by name. Per CLAUDE.md guidelines,
workflow steps must use bun run CLI invocations rather than
MCP tool names. Replaced with equivalent bun run x402/x402.ts
send-inbox-message command.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add missing scan-project-board workflow and agent entries to README

The README workflow discovery table was missing the
scan-project-board workflow which exists in what-to-do/ and is
listed in INDEX.md. Also added the spark0btc and testnet-explorer
agent entries to the community agents list which existed in
aibtc-agents/ but were not referenced from the README.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(src): replace non-null assertions with null-safe guards in shared lib

- sponsor-builder.ts: replace response.txid! with explicit null check and
  descriptive error so relay failures surface clearly instead of silently
  returning undefined as txid
- defi.service.ts: add private getContracts() getter on ZestProtocolService
  that throws a descriptive error when contracts are null (mainnet-only check),
  replacing all this.contracts! non-null assertions with typed accessor

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(src): replace console.info with console.error in fee.ts fallback log

console.info in Bun/Node goes to stdout, which would pollute the JSON
output of skill scripts that rely on clean stdout for JSON parsing.
Use console.error so the fallback fee notice goes to stderr instead,
matching the pattern used throughout the rest of the codebase.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(src): move HiroApiRateLimitError from type-only to value export

HiroApiRateLimitError is a class, not just a type interface. Exporting it
via 'export type' strips the runtime value, making instanceof checks fail
for consumers who catch rate-limit errors. Move it to the value export
alongside HiroApiService so it can be used as both a value and type.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore(yield-dashboard): remove TODO markers from functional code

Convert TODO comments in readZestPosition and readBitflowPosition to
descriptive notes — the code is functional and returns valid data;
the markers incorrectly implied broken stubs rather than known limitations.

Also regenerate skills.json timestamp via bun run manifest.

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: final code simplification pass

- sbtc.ts: use nullish coalescing for address resolution (consistent with other skills)
- defi.service.ts: remove redundant ensureMainnet() guard in ZestProtocolService

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback

- scan-project-board.md: fix send-inbox-message flags to match x402 CLI (--recipient-btc-address, --recipient-stx-address, --content)
- yield-dashboard/AGENT.md: update error message to match actual handleError output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
…v#103)

Applies convention from issue aibtcdev#94 audit: src/lib/ uses node:-prefixed
imports for portability. scripts/ already uses Bun-native APIs.

Files changed:
- src/lib/utils/storage.ts: fs/promises, path, os
- src/lib/utils/encryption.ts: crypto
- src/lib/services/signing-key.service.ts: fs/promises, path, os, crypto
- src/lib/services/scaffold.service.ts: fs/promises, path
- src/lib/services/x402.service.ts: crypto (named import)

Fixes aibtcdev#94

Co-authored-by: strange-lux-agent <strange-lux-agent@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The transferIdentity function was calling the SIP-009 transfer function
without a post-condition, allowing the transaction to succeed even if
the NFT was not actually transferred from the sender. Add a
createNftSendPostCondition asserting that sender sends the agent-identity
NFT with the specified tokenId.

Co-authored-by: Forge <forge@arc0btc.com>
…v#87) (aibtcdev#107)

* fix(wallet): persist session across process boundaries (issue aibtcdev#87)

When `wallet unlock` runs in one process, the session is held in-memory
only. Any subsequent process (e.g. `bitflow swap`, `zest supply`) calls
`getActiveAccount()` on a fresh WalletManager instance and gets null,
forcing a fallback to CLIENT_MNEMONIC or an error.

This change adds cross-process session persistence:

- `storage.ts`: `writeSessionFile` / `readSessionFile` / `deleteSessionFile`
  encrypt account data with AES-256-GCM using a machine-local 256-bit key
  stored at `~/.aibtc/sessions/.session-key` (mode 0o600). The key never
  leaves the machine and cannot decrypt the keystore — only the short-lived
  session file. Session files respect the existing `autoLockTimeout` expiry.

- `wallet-manager.ts`: `saveSessionToDisk()` is called at the end of a
  successful `unlock()`. `restoreSessionFromDisk(walletId)` reads and
  decrypts the session file, reconstructs the Account with correctly typed
  Uint8Array key fields, and restores the in-memory session. `lock()` now
  also calls `deleteSessionFile()` (best-effort) to clean up on explicit
  lock or auto-lock-timeout.

- `x402.service.ts`: `getAccount()` now has a second fallback path between
  the in-process session check and CLIENT_MNEMONIC: it reads `activeWalletId`
  from config, then calls `restoreSessionFromDisk()`. If the session file is
  missing, expired, or tampered the function silently falls through to the
  existing CLIENT_MNEMONIC fallback — no behaviour change for existing users.

Security notes:
- Private keys are serialised to hex inside the encrypted ciphertext only;
  they are never written in plaintext
- Session files are written with mode 0o600; the sessions directory is 0o700
- Decryption failure (tampered file or regenerated key) returns null cleanly
- `.aibtc/` is already covered by .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address review feedback — race condition, version gate, path traversal guard

- getOrCreateSessionKey: read back SESSION_KEY_FILE after rename so two
  racing processes converge on the winning key rather than each returning
  their own freshly generated bytes
- readSessionFile: reject session files whose version != 1 before any
  decryption attempt, guarding against future format changes or truncated writes
- getSessionFilePath: wrap walletId in path.basename() to prevent directory
  traversal when an attacker-controlled walletId contains "../" sequences

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ibtcdev#101)

* feat(aibtc-news-classifieds): add classified ads and extended aibtc.news API skill

New skill covering aibtc.news endpoints not in aibtc-news:
- Classifieds: list, get, post (x402, 5000 sats sBTC)
- Signals: get by ID, correct authored signals (BIP-322)
- Beats: update metadata for owned beats (BIP-322)
- Briefs: read latest/historical (x402, 1000 sats), inscribe, check inscription
- Discovery: streaks, editorial skill resources

11 subcommands total. Uses x402.service for paid endpoints and
signing skill for BIP-322 authenticated writes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(x402): detect sbtc-token contract identifier in detectTokenType

The detectTokenType function only matched 'sbtc' (bare name) or
'::token-sbtc' (legacy format). It missed the standard contract
identifier form used by aibtc.news and other x402 endpoints:
  SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token

Without this fix, sBTC payments were sent as STX transfers, causing
the server to reject payment and return a second 402, triggering the
"Payment retry limit exceeded" error.

Fix: also match any asset string containing 'sbtc-token'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(manifest): regenerate skills.json to include aibtc-news-classifieds

The classifieds skill files were added but skills.json needed regeneration
after conflict resolution during rebase on main.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
…gs (aibtcdev#106)

Register three Arc fleet agents in the AIBTC community registry:

- iris0btc: Signal reader (markets, mempools, metrics, on-chain analytics)
  BTC bc1q6savz94q7ps48y78gg3xcfvjhk6jmcgpmftqxe
  STX SP215BXCEYDT5NXGMPJJKXQADYQXDX92QHN464Y87

- loom0btc: Integrator (APIs, webhooks, cross-chain bridges, pipelines)
  BTC bc1q3qa3xuvk80j4zqnf9e9p7dext9e4jlsv79wgwq
  STX SP3X279HDPCHMB4YN6AHBYX2Y76Q4E20987BN3GHR

- forge0btc: Builder (implementation, features, services, products)
  BTC bc1q9hme5ayrtqd4s75dqq82g8ezzlhfj2m9efjz4h
  STX SP1BFDFJ3P2TGKF3QN5Z6BTTSSDAG4EXHXZZAYZBM

All three run arc-starter on dedicated VPS instances, managed by Arc
(arc0.btc) via fleet orchestration. Iris wallet was recreated before
submission — new addresses used.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ibtcdev#117)

getUserPosition() was reading current-a-token-balance from
get-user-reserve-data — a field that doesn't exist in the response
and always returns 0. Supply positions are held as LP token balances
(zsbtc-v2-0, zaeusdc-v2-0, etc.), not in the reserve data struct.

Fix:
- Supply: call get-balance on the LP token contract (assetConfig.lpToken)
- Borrow: use principal-borrow-balance (not current-variable-debt)

Same approach confirmed in aibtcdev/aibtc-mcp-server v1.33.3 (#283, #285).
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(bitflow): unify SDK and HODLMM routing and ranking

* fix(bitflow): clarify HODLMM units and output

* docs(bitflow): clarify public API access and units
* feat(aibtc-agents): add SKILL.md and regenerate manifest

Adds SKILL.md to the aibtc-agents directory so it is picked up by the
manifest generator and appears in skills.json. The skill was added in
v0.19.0 (feat: add iris0btc, loom0btc, forge0btc configs) but was
missing a SKILL.md entry, so it did not appear in the published manifest.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(aibtc-agents): add arguments value to SKILL.md frontmatter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
github-actions bot and others added 8 commits March 23, 2026 13:31
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…dev#216)

* fix(inscription-builder): fix 3 bugs in buildRevealTransaction preventing standalone reveals

- Use named `tapLeafScript` property instead of spreading the array (fixes silent signing failure)
- Add `allowUnknownOutputs` and `allowUnknownInputs` flags to Transaction (fixes finalization rejection)
- Calculate witness size from tap leaf script instead of P2TR output script (fixes fee miscalculation)

Closes aibtcdev#215

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(inscription-builder): add witness overhead and clarify tapLeafScript comment

- Add WITNESS_OVERHEAD_VBYTES (80) and 1.25x multiplier to match
  buildCommitTransaction's fee estimation model
- Clarify comment that tapLeafScript is an array of tuples

Addresses Copilot review feedback on aibtcdev#216

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(inscription-builder): add allowUnknownScripts flag to btc.p2tr call

Pass `true` as 4th arg to btc.p2tr() for micro-ordinals unknown leaf
scripts, matching the fix already applied in child-inscription-builder.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(x402): add --headers flag to execute-endpoint for custom request headers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(x402): strengthen --headers type guard with unknown + null/array checks

Use `unknown` for parsedHeaders to avoid implicit `any`, add explicit
object-shape guard (non-null, non-array) before casting to Record<string,string>.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(x402): include --headers in retryWith suggestion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Schrader <whoabuddy@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Bumps manifest from 0.30.0 → 0.32.0 by running `bun run manifest`.
Includes 61 skills. Fixes stale version shown on landing-page skills catalog.
* feat(clarity): add clarity-patterns, clarity-check, clarity-test-scaffold, clarity-audit skills

Add four new doc-only Clarity development skills that cover the full
contract lifecycle: patterns reference, pre-deployment validation,
test infrastructure scaffolding, and security auditing. Bundled patterns
from whoabuddy/claude-knowledge make aibtcdev/skills the canonical
Clarity reference. Closes aibtcdev#206.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(clarity): clarify doc-only usage in SKILL.md files

Add doc-only disclaimer to Usage sections noting these are planned CLI
interfaces, not yet implemented. Agents read the SKILL.md directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(clarity-patterns): bundle all pattern content and templates directly

Replace index-only SKILL.md with full bundled content: 16 code patterns,
12 registry patterns, testing reference, cost limits, and 3 complete
contract templates with source and tests. No external dependencies on
whoabuddy/claude-knowledge — aibtcdev/skills is now the canonical source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

sonic-mast and others added 3 commits March 25, 2026 11:07
…rmat (aibtcdev#232)

fix: update scaffold, docs, and bounty-scanner for nested metadata format

- Update CONTRIBUTING.md frontmatter example to nested metadata format
- Fix bounty-scanner parseFrontmatter to handle nested metadata: blocks
- Fix scaffold-skill to generate correct nested metadata format
- Support both flat (legacy) and nested tag formats in bounty-scanner

PR aibtcdev#232 by sonic-mast
… output is included (aibtcdev#230)

fix(rune-transfer-builder): only set changeOutput pointer when change output is included

Compute runeChangeSats before building Runestone so the change pointer
is only set when the change output will actually be added to the transaction.
When rune change sats are below dust threshold, the change output is omitted
and the Runestone no longer points to a non-existent output index (which
would burn the remaining runes).

Fixes aibtcdev#229
PR aibtcdev#230 by gregoryford963-sys
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@sonic-mast sonic-mast force-pushed the feat/paperboy-skill branch from db65389 to cc93b56 Compare March 25, 2026 18:52
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 11 additional findings in Devin Review.

Open in Devin Review

Comment on lines +225 to +226
(actualOutputCount - 1) * P2TR_OUTPUT_VBYTES + // non-OP_RETURN outputs
P2WPKH_OUTPUT_VBYTES; // one P2WPKH change
Copy link

@devin-ai-integration devin-ai-integration bot Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Rune transfer vsize calculation double-counts one P2TR output, overestimating fees

At rune-transfer-builder.ts:219-226, the fee estimation formula (actualOutputCount - 1) * P2TR_OUTPUT_VBYTES + P2WPKH_OUTPUT_VBYTES overcounts by one P2TR output. actualOutputCount includes the OP_RETURN output (already covered by OP_RETURN_VBYTES earlier in the sum), so subtracting 1 should remove the OP_RETURN, leaving only the non-OP_RETURN outputs. However, the formula treats all non-OP_RETURN outputs as P2TR and adds one extra P2WPKH. When there's no rune change output, actual non-OP_RETURN outputs are: 1 P2TR (recipient) + 1 P2WPKH (BTC change). But the formula computes (3-1)=2 P2TR outputs + 1 P2WPKH = 3 outputs, overcounting by 1 P2TR (~43 vbytes). This wastes sats on excess fees but does not cause transaction failures.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 465 to 512
async getUserPosition(
asset: string,
userAddress: string
): Promise<ZestUserPosition | null> {
this.ensureMainnet();

try {
const result = await this.hiro.callReadOnlyFunction(
this.contracts!.poolBorrow,
const assetConfig = this.getAssetConfig(asset);

// Supply: read LP token balance
const lpBalanceResult = await this.hiro.callReadOnlyFunction(
assetConfig.lpToken,
"get-balance",
[principalCV(userAddress)],
userAddress
);

// Borrow: read from pool-borrow reserve data
const reserveResult = await this.hiro.callReadOnlyFunction(
this.getContracts().poolBorrow,
"get-user-reserve-data",
[
principalCV(userAddress),
contractPrincipalCV(...parseContractIdTuple(asset)),
contractPrincipalCV(...parseContractIdTuple(assetConfig.token)),
],
userAddress
);

if (!result.okay || !result.result) {
return null;
let supplied = "0";
if (lpBalanceResult.okay && lpBalanceResult.result) {
const decoded = cvToJSON(hexToCV(lpBalanceResult.result));
supplied = decoded?.value?.value ?? decoded?.value ?? "0";
}

const decoded = cvToJSON(hexToCV(result.result));

if (decoded && typeof decoded === "object") {
return {
asset,
supplied: decoded["current-a-token-balance"]?.value || "0",
borrowed: decoded["current-variable-debt"]?.value || "0",
};
let borrowed = "0";
if (reserveResult.okay && reserveResult.result) {
const decoded = cvToJSON(hexToCV(reserveResult.result));
if (decoded && typeof decoded === "object") {
borrowed = decoded["principal-borrow-balance"]?.value || "0";
}
}

return null;
} catch {
return null;
return { asset, supplied, borrowed };
} catch (error) {
if (error instanceof Error && (error.message.includes("404") || error.message.includes("not found"))) {
return null;
}
throw error;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Zest getUserPosition now reads supply from LP token balance instead of reserve data

The getUserPosition method in src/lib/services/defi.service.ts:465-512 was significantly rewritten. Previously it read both supply and borrow from get-user-reserve-data. Now it reads supply from the LP token's get-balance and borrow from get-user-reserve-data's principal-borrow-balance field (instead of current-variable-debt). This is a behavioral change: the old current-a-token-balance from reserve data and the LP token balance may not always return identical values (e.g., during interest accrual). The comment attributes this to a fix in aibtc-mcp-server v1.33.3. The change to principal-borrow-balance from current-variable-debt also changes which borrow figure is reported — principal vs accrued.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

devin-ai-integration[bot]

This comment was marked as resolved.

whoabuddy and others added 2 commits March 25, 2026 13:40
…dev#237)

feat(paperboy): add paid signal distribution skill (docs-only)

Cherry-pick paperboy/SKILL.md from aibtcdev#221 by pbtc21, converted to nested
metadata format with arguments set to "reference" (doc-only, no CLI).
Adds AGENT.md, README entry, and regenerated manifest.

Closes aibtcdev#221

Co-Authored-By: pbtc21 <pbtc21@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
sonic-mast pushed a commit that referenced this pull request Mar 25, 2026
…dHeaders

getCredential() requires a master decryption password as second arg, not a
key name. The broken fallback always failed silently and even if it succeeded
would return a DecryptedCredential object not a string.

Fix: remove the credential store path entirely — MAXIMUMSATS_L402_TOKEN env
var is the correct approach for headless CLI use. Free tier works without it.

Flagged by Devin review on sonic-mast/skills PR #1.
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 18 additional findings in Devin Review.

Open in Devin Review

"arguments": [
"list-pools",
"assess-pool",
"assess-position",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 skills.json manifest lists 'assess-position' but actual CLI command is 'assess-pool-drift'

In skills.json:752, the hodlmm-risk skill lists assess-position as a subcommand argument, but the actual CLI implementation at hodlmm-risk/hodlmm-risk.ts:296 registers the command as assess-pool-drift. The SKILL.md frontmatter at hodlmm-risk/SKILL.md:8 correctly says assess-pool-drift. This means the manifest was likely generated before the rename or the SKILL.md was updated without regenerating the manifest. Any tool that discovers skills via skills.json would show the wrong subcommand name. Running bun run manifest should fix this.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 18 additional findings in Devin Review.

Open in Devin Review

entry: "hodlmm-risk/hodlmm-risk.ts"
requires: ""
tags: "l2, read"
---

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 hodlmm-risk SKILL.md uses invalid tag "read" — must be "read-only"

The hodlmm-risk/SKILL.md frontmatter specifies tags: "l2, read" but "read" is not in the controlled tag vocabulary. Per CONTRIBUTING.md, valid tag values are: l1, l2, read-only, write, mainnet-only, requires-funds, sensitive, infrastructure, defi. The correct tag is "read-only". This also propagates into the generated skills.json manifest at the hodlmm-risk entry.

Suggested change
---
tags: "l2, read-only"
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +415 to +419
const WITNESS_OVERHEAD_VBYTES = 80; // Control block + script + protocol framing
const leafScriptSize = revealScript.tapLeafScript?.[0]?.[1]?.length || 0;
const revealWitnessSize = Math.ceil(
(revealScript.script?.byteLength || 0) / 4
);
((leafScriptSize || revealScript.script?.byteLength || 0) / 4) * 1.25
) + WITNESS_OVERHEAD_VBYTES;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 inscription-builder reveal fee estimation significantly changed — verify against real transactions

The reveal fee estimation in inscription-builder.ts:415-419 was substantially rewritten. The old code used revealScript.script.byteLength / 4 (the P2TR output script, ~34 bytes → ~9 vbytes). The new code uses the tap leaf script size (which contains the full inscription body) with a 1.25x multiplier plus 80 vbytes overhead. For a 1KB inscription, old estimate was ~9 vbytes; new is ~(1024/4*1.25)+80 = ~400 vbytes. This is a much more accurate estimate but represents a major behavioral change for existing users — their estimate-fee results and required commit amounts will be significantly higher. The fix is correct (old estimates were severely underestimating), but it's a breaking change in economic behavior worth calling out.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sonic Mast added 8 commits March 26, 2026 21:03
Adds paperboy skill for distributing aibtc.news signals to agents and
external audiences. Paperboys earn 500 sats per verified placement and
2000 sats bonus per correspondent recruited.

Subcommands:
- leaderboard: list active paperboys, routes, earnings
- status: check your delivery count and earnings
- signals: fetch approved/brief-included signals to distribute
- recruit-targets: find agents without beats (prime recruits)
- deliver: log a delivery for operator verification and payment

Dashboard: paperboy-dash.p-d07.workers.dev
Closes aibtcdev#221
Adds read-only volatility risk monitoring for Bitflow DLMM pools.
No wallet or funds required. Mainnet only.

Subcommands:
- list-pools: list all active HODLMM pools
- assess-pool: compute volatility score (0-100) and regime classification
- assess-position: evaluate LP position drift and concentration risk
- regime-history: scan all pools sorted by risk level

Risk model weights three signals:
- Bin spread (30%): fraction of bins with liquidity — low = risky
- Reserve imbalance (40%): |X_usd - Y_usd| / total — high = skewed pool
- Active bin concentration (30%): active bin share of total liquidity

Regime classification:
- calm (0-33): proceed normally
- elevated (34-66): reduce exposure per maxExposurePct signal
- crisis (67-100): do not add liquidity

Fail-safe: API errors default to crisis regime.

Closes aibtcdev#224
- [blocking] Make --address required on log-delivery (was defaulting to
  sonic-mast address, which would route payment to wrong agent)
- [suggestion] Rename recruit-targets → recruit for cleaner CLI + fix
  SKILL.md arguments metadata to match
- [suggestion] Rename deliver → log-delivery to accurately reflect that
  command generates a local log, not a remote submission
- [nit] Replace totalAgents with fetchedForFiltering + totalAgentsOnPlatform
  to avoid misleading count when paginated; add cap comment on correspondents
  fetch
- AGENT.md: update decision table and daily cadence with correct command names
  (deliver->log-delivery, recruit-targets->recruit, add --address to log-delivery)
- paperboy.ts: add try/catch to all 4 commands (leaderboard, status, signals, recruit)
  matches hodlmm-risk error handling pattern throughout
…dHeaders

getCredential() requires a master decryption password as second arg, not a
key name. The broken fallback always failed silently and even if it succeeded
would return a DecryptedCredential object not a string.

Fix: remove the credential store path entirely — MAXIMUMSATS_L402_TOKEN env
var is the correct approach for headless CLI use. Free tier works without it.

Flagged by Devin review on sonic-mast/skills PR #1.
- Remove dead PRICE_SCALE constant (was defined but never referenced)
- Fix all catch blocks emitting crisis JSON to exit 0 instead of 1,
  so callers can read the JSON fail-safe signal (list-pools, assess-pool,
  assess-pool-drift, regime-history)
- Apply ?? nullish coalescing for activeBin fallbacks (already done in
  prior commit; confirmed no remaining || fallbacks)
- Rename assess-position -> assess-pool-drift and remove --address:
  bff.bitflowapis.finance has no per-address LP position endpoint
  (confirmed via API exploration). Command now performs pool-level
  drift analysis only and documents this limitation in output + docs.
- Update SKILL.md and AGENT.md to reflect assess-pool-drift rename
@sonic-mast sonic-mast force-pushed the feat/paperboy-skill branch from 1df6f7d to f792a1b Compare March 26, 2026 21:03
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 22 additional findings in Devin Review.

Open in Devin Review

Comment on lines +386 to +393
// Restore the in-memory session so subsequent in-process calls also work
const now = new Date();
this.session = {
walletId,
account,
unlockedAt: now,
expiresAt,
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Session restored from disk never starts the auto-lock timer

restoreSessionFromDisk at src/lib/services/wallet-manager.ts:364-396 creates a new in-memory session with an expiresAt field but never calls startAutoLockTimer(). In contrast, the unlock() method at line 287 always calls this.startAutoLockTimer(config.autoLockTimeout) after creating the session. This means a session restored from disk will never auto-lock — it remains unlocked indefinitely in the current process, even when the original unlock had a finite timeout. The expiresAt in the session object is only checked at disk-restore time, not enforced in-process.

Suggested change
// Restore the in-memory session so subsequent in-process calls also work
const now = new Date();
this.session = {
walletId,
account,
unlockedAt: now,
expiresAt,
};
// Restore the in-memory session so subsequent in-process calls also work
const now = new Date();
this.session = {
walletId,
account,
unlockedAt: now,
expiresAt,
};
// Start auto-lock timer if the restored session has an expiry
if (expiresAt) {
const remainingMs = expiresAt.getTime() - now.getTime();
const remainingMinutes = Math.max(Math.ceil(remainingMs / 60000), 1);
this.startAutoLockTimer(remainingMinutes);
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +1068 to +1069
functionName: "add-relative-liquidity-same-multi",
functionArgs: [

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 HODLMM addLiquiditySimple uses PostConditionMode.Allow — expected but worth noting

The addHodlmmLiquiditySimple and withdrawHodlmmLiquiditySimple methods in bitflow.service.ts both use PostConditionMode.Allow with empty post conditions. This means the Stacks transaction can move any tokens without guard rails. The comment at bitflow/AGENT.md documents this is intentional for HODLMM operations. However, this contrasts with the swap function which uses the SDK's built-in post conditions. For high-value liquidity operations, the lack of post conditions means a malicious or buggy contract could drain more tokens than expected.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.