Skip to content

woonetwork/woofi-cli

Repository files navigation

WOOFi CLI

Agent-first CLI and Python SDK monorepo for querying public WOOFi protocol data from the official WOOFi API.

The repository currently exposes these public read-only endpoints:

  • GET /stat
  • GET /source_stat
  • GET /yield
  • GET /stakingv2

It also reserves the future CLI namespaces quote and build-txes, which currently return a deterministic placeholder response.

What Is In This Repo

  • packages/woofi: synchronous Python client, endpoint fetchers, schemas, and normalization/summary services
  • packages/woofi-cli: click-based CLI published as the woofi command
  • root pyproject.toml: shared dev tooling config for the monorepo
  • cli_docs/: supporting product and technical notes

Current Command Surface

Command Upstream endpoint Status
stats series GET /stat implemented
stats summary GET /stat implemented
stats sources GET /source_stat implemented
stats top-source GET /source_stat implemented
yield vaults GET /yield implemented
yield vault GET /yield implemented
yield summary GET /yield implemented
yield top GET /yield implemented
staking info GET /stakingv2 implemented
quote none yet placeholder
build-txes none yet placeholder

Repo Layout

woofi-cli/
├── README.md
├── pyproject.toml
├── cli_docs/
├── packages/
│   ├── woofi/
│   │   ├── pyproject.toml
│   │   ├── src/woofi/
│   │   └── tests/
│   └── woofi-cli/
│       ├── pyproject.toml
│       ├── src/woofi_cli/
│       └── tests/
└── ...

Quick Start

Install the CLI from this monorepo

The root package is workspace metadata. For local development, install the two leaf packages:

python3 -m venv .venv
source .venv/bin/activate

pip install -e ./packages/woofi
pip install -e "./packages/woofi-cli[dev]"

woofi --help

If you use pyenv and the woofi command is missing after installation, run pyenv rehash.

Run directly from source without installing the console script

PYTHONPATH=packages/woofi/src:packages/woofi-cli/src \
python -m woofi_cli.main --help

Global Options

Option Default Description
`--format json table` json
--raw off Return the raw upstream payload instead of the CLI envelope
--pretty off Pretty-print JSON
--timeout INTEGER 30 HTTP timeout in seconds

Notes:

  • --network is command-specific, not global.
  • staking is global and does not accept a network parameter.

Commands

stats

Trading statistics built from /stat and /source_stat.

Command Purpose Key options
stats series bucketed trading series for one network and period --period, --network, --select, --from-ts, --to-ts
stats summary derived summary of total volume and tx counts --period, --network, --from-ts, --to-ts
stats sources source-level volume breakdown --period, --network, --sort-by, --order, --limit, --include-other/--no-include-other
stats top-source top source helper query --period, --network, --exclude-other/--no-exclude-other

Supported periods:

  • 1d, 1w, 1m, 3m, 1y, all

Important guardrails:

  • traders from /stat is bucket-scoped only and must not be summed into a period-wide unique trader count.
  • period=1w may return only 6 days because of bucket boundaries. Use period=1m plus --from-ts and --to-ts if you need an exact 7-day window.
  • /source_stat does not support Solana, so stats sources and stats top-source reject --network solana.

yield

Earn vault data built from /yield.

Command Purpose Key options
yield vaults list vaults with filtering, sorting, and optional limit --network, --symbol, --source, --sort-by, --order, --limit
yield vault lookup a single vault by address --network, --address
yield summary derived network summary --network
yield top top N vaults ranked by APY or TVL-related metrics --network, --sort-by, --limit

Supported yield networks:

  • bsc, avax, polygon, arbitrum, optimism, linea, base, mantle, sonic, berachain

The CLI preserves raw vault fields and adds normalized helper fields such as:

  • address
  • tvl_token_decimal
  • tvl_usd_decimal

staking

Global WOO staking metrics from /stakingv2.

Command Purpose
staking info APR breakdown and total WOO staked

This endpoint is global and does not accept --network.

Reserved Commands

Command Current behavior Exit code
quote placeholder JSON error 12
build-txes placeholder JSON error 12

Both currently return:

{
  "schema_version": "1.0",
  "success": false,
  "error": {
    "code": "not_implemented",
    "message": "building in progress..."
  }
}

Supported Networks

Network stats stats sources yield staking
bsc yes yes yes global only
avax yes yes yes global only
polygon yes yes yes global only
arbitrum yes yes yes global only
optimism yes yes yes global only
linea yes yes yes global only
base yes yes yes global only
mantle yes yes yes global only
sonic yes yes yes global only
berachain yes yes yes global only
hyperevm yes yes no global only
monad yes yes no global only
solana yes no no global only

Output Contract

Default JSON mode

Successful commands return a stable JSON envelope:

{
  "schema_version": "1.0",
  "success": true,
  "command": "stats summary",
  "params": {
    "period": "1d",
    "network": "arbitrum"
  },
  "data": {},
  "meta": {
    "endpoint": "/stat",
    "generated_at": "2026-03-10T12:00:00+00:00",
    "warnings": []
  }
}

Raw mode

--raw bypasses CLI normalization and returns the upstream payload for the selected endpoint.

Table mode

--format table prints a human-readable table instead of the JSON envelope. This mode is for operators, not machine parsing.

Errors

Error payloads are written to stderr as JSON:

{
  "schema_version": "1.0",
  "success": false,
  "error": {
    "code": "invalid_argument",
    "message": "network=solana is not supported for /source_stat",
    "hint": "Use one of: bsc, avax, polygon, arbitrum, optimism, linea, base, mantle, sonic, berachain, hyperevm, monad"
  }
}

Numeric Precision Rules

Precision is part of the public contract.

  • raw integer-like upstream fields remain strings
  • normalized money and quantity fields are emitted as strings
  • volume_usd, total_deposit, and total_woo_staked are converted with 18 decimals
  • vault tvl values from /yield are converted using each vault's own decimals

Architecture

The implementation is layered on purpose:

  • commands layer: CLI parsing, command-local validation, presentation choice
  • API layer: one upstream endpoint per function, HTTP status handling, JSON parsing
  • services layer: normalization, sorting, filtering, summaries, warnings
  • presenters layer: JSON/table rendering and stdout/stderr separation

Current source layout:

packages/
├── woofi/
│   └── src/woofi/
│       ├── api/
│       ├── schemas/
│       ├── services/
│       ├── utils/
│       ├── client.py
│       ├── constants.py
│       └── exceptions.py
└── woofi-cli/
    └── src/woofi_cli/
        ├── commands/
        ├── presenters/
        ├── schemas/
        ├── cli_context.py
        ├── exit_codes.py
        └── main.py

Exit Codes

Code Meaning
0 success
2 invalid argument
3 upstream HTTP error
4 upstream timeout
5 invalid upstream payload
12 not implemented

Usage Examples

# Trading stats
woofi stats summary --period 1d --network arbitrum
woofi stats series --period 1m --network base --select volume_usd
woofi stats sources --period 1d --network base --limit 3
woofi stats top-source --period 1d --network arbitrum

# Exact 7-day window using 1m plus timestamps
woofi stats summary --period 1m --network arbitrum --from-ts 1709251200 --to-ts 1709855999

# Earn vaults
woofi yield vaults --network arbitrum
woofi yield top --network base --sort-by tvl_usd --limit 2
woofi yield summary --network bsc
woofi yield vault --network arbitrum --address 0xA780432f495E5C6851fd7903FE49ad77C952F7D8

# Staking
woofi staking info
woofi --pretty staking info

# Human-friendly output
woofi --format table yield top --network arbitrum

# Raw upstream payload
woofi --raw stats series --period 1d --network solana

Development

# Test
pytest -q

# Lint
ruff check packages/woofi/src packages/woofi-cli/src packages/woofi/tests packages/woofi-cli/tests

# Type check
mypy packages/woofi/src packages/woofi-cli/src

Verification

Recommended verification loop after changes:

  1. Run focused tests for the modified package or command.
  2. Run pytest -q.
  3. Run ruff check on both package source trees and tests.
  4. Run mypy on both package source trees.
  5. Run a few live sample commands against the real WOOFi API when network access is available.

About

CLI tool for woofi swap

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages