{"id":"322b7707-f948-48c2-815e-55d9b25fcbee","entityType":"agent","slug":"clawhub-canuc-wayfinder","name":"Wayfinder","canonicalUrl":"https://www.xpersona.co/agent/clawhub-canuc-wayfinder","canonicalPath":"/agent/clawhub-canuc-wayfinder","generatedAt":"2026-10-11T20:58:40.931Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":null},"description":"DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swa... Skill: Wayfinder Owner: canuc Summary: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (poetry run wayfinder). Use when the user wants to check balances, swa... Tags: latest:0.0.4 Version history: v0.4.1 | 2026-02-13T22:20:27.670Z | user wayfinder 0.4.1 - Added CCTX -> so that binance can be used. - Added defaiut api RPCs for all ETH + PLASMA + BASE + EFC rpc urls - to avoid publi","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s174zm9aaky0s4yesxeczv7pw1885ats:wayfinder","sourceUrl":"https://clawhub.ai/canuc/wayfinder","homepage":"https://clawhub.ai/canuc/skills/wayfinder","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/canuc/wayfinder","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/canuc/skills/wayfinder","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swa..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":null},"stars":null,"forks":null,"downloads":1034,"packageName":null,"latestVersion":"0.4.1","tractionLabel":"1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:53:17.325Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T15:53:17.399Z","lastCrawledAt":"2026-10-11T15:53:17.325Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T15:53:17.325Z","lastVerifiedAt":null,"highlights":[{"version":"0.4.1","createdAt":"2026-02-13T22:20:27.670Z","changelog":"wayfinder 0.4.1 - Added CCTX -> so that binance can be used. - Added defaiut api RPCs for all ETH + PLASMA + BASE + EFC rpc urls - to avoid public RPC ratelimiting","fileCount":20,"zipByteSize":66409},{"version":"0.0.4","createdAt":"2026-02-13T05:29:25.571Z","changelog":"- Enforced installation from GitHub only – “pip install” from PyPI is no longer supported. - Added requirement to obtain and provide a Wayfinder API key during initial setup. - Updated first-time setup steps to emphasize wallet security: never output private keys or seed phrases into the conversation. - Clarified guidance for seed phrase handling, recommending secure storage and limiting exposure. - Expanded and clarified instructions for proper SDK installation and configuration.","fileCount":20,"zipByteSize":63457},{"version":"0.0.3","createdAt":"2026-02-13T04:08:32.158Z","changelog":"- Added detailed pre-flight check and setup instructions to ensure Wayfinder Paths CLI and configuration are in place. - Expanded documentation for all resource commands, including usage patterns, asset lookup rules, and command reference tables. - Clarified wallet management and recommended secure handling for seed phrases, especially for bot or production usage. - Provided examples and standardized procedure for token and asset lookup (native gas and ERC20). - Improved Quick Start coverage, including guided setup and post-install verification steps.","fileCount":20,"zipByteSize":62816}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s174zm9aaky0s4yesxeczv7pw1885ats:wayfinder","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T20:58:40.929Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-canuc-wayfinder/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":null},"readme":"Skill: Wayfinder\n\nOwner: canuc\n\nSummary: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swa...\n\nTags: latest:0.0.4\n\nVersion history:\n\nv0.4.1 | 2026-02-13T22:20:27.670Z | user\n\nwayfinder 0.4.1\n\n- Added CCTX -> so that binance can be used.\n- Added defaiut api RPCs for all ETH + PLASMA + BASE + EFC rpc urls - to avoid public RPC ratelimiting\n\nv0.0.4 | 2026-02-13T05:29:25.571Z | user\n\n- Enforced installation from GitHub only – “pip install” from PyPI is no longer supported.\n- Added requirement to obtain and provide a Wayfinder API key during initial setup.\n- Updated first-time setup steps to emphasize wallet security: never output private keys or seed phrases into the conversation.\n- Clarified guidance for seed phrase handling, recommending secure storage and limiting exposure.\n- Expanded and clarified instructions for proper SDK installation and configuration.\n\nv0.0.3 | 2026-02-13T04:08:32.158Z | user\n\n- Added detailed pre-flight check and setup instructions to ensure Wayfinder Paths CLI and configuration are in place.\n- Expanded documentation for all resource commands, including usage patterns, asset lookup rules, and command reference tables.\n- Clarified wallet management and recommended secure handling for seed phrases, especially for bot or production usage.\n- Provided examples and standardized procedure for token and asset lookup (native gas and ERC20).\n- Improved Quick Start coverage, including guided setup and post-install verification steps.\n\nArchive index:\n\nArchive v0.4.1: 20 files, 66409 bytes\n\nFiles: references/adapters.md (14495b), references/boros.md (7630b), references/ccxt.md (6412b), references/coding-interface.md (14766b), references/hyperlend.md (4228b), references/hyperliquid.md (13158b), references/moonwell.md (5354b), references/pendle.md (5324b), references/polymarket.md (4492b), references/projectx.md (5385b), references/setup.md (6125b), references/strategies.md (10038b), references/tokens-and-pools.md (11335b), references/uniswap.md (2405b), scripts/pull-sdk-ref.sh (7219b), scripts/sync-skill-json-from-sdk.py (5314b), sdk-version.md (5b), skill.json (1992b), SKILL.md (54745b), _meta.json (128b)\n\nFile v0.4.1:SKILL.md\n\n---\nname: wayfinder\ndescription: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swap tokens, bridge assets, trade perps, trade prediction markets (Polymarket), run automated yield strategies (stablecoin yield, basis trading, Moonwell loops, HyperLend, Boros HYPE), manage wallets, discover DeFi pools, look up token metadata, manage LP positions (Uniswap V3 / ProjectX), or execute one-off DeFi scripts. Supports Ethereum, Base, Arbitrum, Polygon, BSC, Avalanche, Plasma, and HyperEVM via protocol adapters.\nmetadata: {\"openclaw\":{\"emoji\":\"🧭\",\"homepage\":\"https://github.com/WayfinderFoundation/wayfinder-paths-sdk\",\"requires\":{\"bins\":[\"poetry\"]},\"install\":[{\"id\":\"brew\",\"kind\":\"brew\",\"formula\":\"poetry\",\"bins\":[\"poetry\"],\"label\":\"Install poetry\"}]}}\n---\n\n# Wayfinder\n\nDeFi trading, yield strategies, and portfolio management powered by [poetry run wayfinder Paths](https://github.com/WayfinderFoundation/wayfinder-paths-sdk).\n\n## Pre-Flight Check\n\nBefore running any commands, verify that poetry run wayfinder Paths is installed and reachable:\n\n```bash\n# SDK location (override by setting WAYFINDER_SDK_PATH)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\n\n# Check if wayfinder-paths-sdk directory exists\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  echo \"ERROR: wayfinder-paths-sdk is not installed at: $WAYFINDER_SDK_PATH\"\n  echo \"Set WAYFINDER_SDK_PATH or run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Config path (override by setting WAYFINDER_CONFIG_PATH)\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\n\n# Check if the config exists\nif [ ! -f \"$WAYFINDER_CONFIG_PATH\" ]; then\n  echo \"ERROR: config not found at $WAYFINDER_CONFIG_PATH. Run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Check if the CLI is functional\ncd \"$WAYFINDER_SDK_PATH\"\nif ! poetry run wayfinder --help > /dev/null 2>&1; then\n  echo \"ERROR: poetry run wayfinder CLI is not working. Run 'cd $WAYFINDER_SDK_PATH && poetry install' to fix.\"\n  exit 1\nfi\n\necho \"poetry run wayfinder Paths is installed and ready.\"\n```\n\nIf either check fails, follow the **First-Time Setup** instructions below before proceeding.\n\n## Quick Start\n\n### First-Time Setup\n\n**Important:** The SDK must be installed from GitHub via `git clone`. Do NOT install from PyPI (`pip install wayfinder-paths` will not work).\n\n**Before starting:** You need a Wayfinder API key (format: `wk_...`). Get one at **https://strategies.wayfinder.ai**. The guided setup will prompt you for this key.\n\n```bash\n# Clone wayfinder-paths-sdk from GitHub (required — do NOT pip install)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  git clone https://github.com/WayfinderFoundation/wayfinder-paths-sdk.git \"$WAYFINDER_SDK_PATH\"\nfi\n\ncd \"$WAYFINDER_SDK_PATH\"\npoetry install\n\n# Run guided setup (creates/updates config.json + local dev wallets + MCP config)\n# You will need your API key from https://strategies.wayfinder.ai (format: wk_...)\npython3 scripts/setup.py\n```\n\n**Wallet security:**\n- **NEVER output private keys or seed phrases into the conversation.** These are secrets — they must stay on the machine, never in chat.\n- For a long-running bot, prefer a seed phrase stored in your backend/secret manager rather than generating random wallets on the server.\n- On first-time setup, the user should retrieve the seed phrase directly from their machine or secret manager. Only offer to display the seed phrase if the user explicitly confirms they cannot access the machine to retrieve it themselves.\n- See `references/setup.md` for detailed wallet setup instructions.\n\n### Verify Setup\n\n```bash\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\ncd \"$WAYFINDER_SDK_PATH\"\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://balances/main\n```\n\n## Command Reference\n\nAll commands should be run from `$WAYFINDER_SDK_PATH` and require `WAYFINDER_CONFIG_PATH` (default: `$WAYFINDER_SDK_PATH/config.json`). All responses return `{\"ok\": true, \"result\": {...}}` on success or `{\"ok\": false, \"error\": {\"code\": \"...\", \"message\": \"...\"}}` on failure.\n\n---\n\n### `resource` — Read MCP resources by URI\n\nRead-only access to adapters, strategies, wallets, balances, tokens, and Hyperliquid market data via URI-based resources. Use `--list` to see all available resources and templates.\n\n**Asset/data sourcing rule:** When the user asks you to look up token/pool/market/protocol data, first use Wayfinder’s adapter/strategy discovery resources (`poetry run wayfinder resource wayfinder://adapters`, `wayfinder://adapters/{name}`, `wayfinder://strategies`, `wayfinder://tokens/*`). Only fall back to other methods if Wayfinder doesn’t expose the required data or the user explicitly asks.\n\n```bash\n# List all available resources and templates\npoetry run wayfinder resource --list\n```\n\n#### Static Resources\n\n| URI | Description |\n|-----|-------------|\n| `wayfinder://adapters` | List all adapters with capabilities |\n| `wayfinder://strategies` | List all strategies with adapter dependencies |\n| `wayfinder://wallets` | List all configured wallets |\n| `wayfinder://hyperliquid/prices` | All Hyperliquid mid prices |\n| `wayfinder://hyperliquid/markets` | Perp market metadata, funding rates, and asset contexts |\n| `wayfinder://hyperliquid/spot-assets` | Spot asset metadata |\n\n```bash\npoetry run wayfinder resource wayfinder://adapters\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://hyperliquid/prices\npoetry run wayfinder resource wayfinder://hyperliquid/markets\npoetry run wayfinder resource wayfinder://hyperliquid/spot-assets\n```\n\n#### Resource Templates\n\n| URI Template | Description |\n|--------------|-------------|\n| `wayfinder://adapters/{name}` | Describe a single adapter (e.g. `moonwell_adapter`) |\n| `wayfinder://strategies/{name}` | Describe a single strategy (e.g. `stablecoin_yield_strategy`) |\n| `wayfinder://wallets/{label}` | Get a single wallet by label |\n| `wayfinder://balances/{label}` | Enriched multi-chain balances for a wallet |\n| `wayfinder://activity/{label}` | Recent transaction activity for a wallet |\n| `wayfinder://tokens/search/{chain_code}/{query}` | **Fuzzy token search** (hits `/tokens/fuzzy/`) — ALWAYS use this first |\n| `wayfinder://tokens/resolve/{query}` | Resolve a token by known ID (hits `/tokens/detail/`) — only use with IDs from search |\n| `wayfinder://tokens/gas/{chain_code}` | **Native gas token** for a chain (ETH, HYPE) — use for native tokens |\n| `wayfinder://hyperliquid/{label}/state` | Perp positions + PnL for a wallet |\n| `wayfinder://hyperliquid/{label}/spot` | Spot balances on Hyperliquid for a wallet |\n| `wayfinder://hyperliquid/prices/{coin}` | Mid price for a single coin |\n| `wayfinder://hyperliquid/book/{coin}` | Order book for a coin |\n\n**Token lookup order — always search or use gas endpoint first:**\n\n```bash\n# 1. For native gas tokens (ETH, HYPE): use the gas endpoint\npoetry run wayfinder resource wayfinder://tokens/gas/ethereum    # ETH on Ethereum\npoetry run wayfinder resource wayfinder://tokens/gas/base        # ETH on Base\npoetry run wayfinder resource wayfinder://tokens/gas/hyperevm    # HYPE on HyperEVM\n\n# 2. For ERC20 tokens: ALWAYS fuzzy search first\npoetry run wayfinder resource wayfinder://tokens/search/base/usdc\npoetry run wayfinder resource wayfinder://tokens/search/arbitrum/eth\npoetry run wayfinder resource wayfinder://tokens/search/ethereum/weth\n\n# 3. Then resolve with the exact ID from search results\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base\n```\n\n```bash\npoetry run wayfinder resource wayfinder://adapters/moonwell_adapter\npoetry run wayfinder resource wayfinder://strategies/stablecoin_yield_strategy\npoetry run wayfinder resource wayfinder://wallets/main\npoetry run wayfinder resource wayfinder://balances/main\npoetry run wayfinder resource wayfinder://activity/main\npoetry run wayfinder resource wayfinder://hyperliquid/main/state\npoetry run wayfinder resource wayfinder://hyperliquid/main/spot\npoetry run wayfinder resource wayfinder://hyperliquid/prices/ETH\npoetry run wayfinder resource wayfinder://hyperliquid/book/ETH\n```\n\n---\n\n### `wallets` — Manage wallets and discover positions\n\nCreate, annotate, and discover cross-protocol positions. Use `resource wayfinder://wallets` to list wallets and `resource wayfinder://wallets/{label}` to get a single wallet.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `\"create\"` \\| `\"annotate\"` \\| `\"discover_portfolio\"` | **Yes** | — | — |\n| `label` | string | **create** | — | Must be non-empty; duplicate labels are idempotent |\n| `wallet_label` | string | **annotate, discover_portfolio** | — | Or use `wallet_address` |\n| `wallet_address` | string | No | — | Alternative to `wallet_label` |\n| `protocol` | string | **annotate** | — | Protocol name for annotation |\n| `annotate_action` | string | **annotate** | — | Action being annotated |\n| `tool` | string | **annotate** | — | Tool name for annotation |\n| `status` | string | **annotate** | — | Status for annotation |\n| `chain_id` | string | No | — | — |\n| `details` | string (JSON) | No | — | Extra metadata for annotation |\n| `protocols` | string (JSON) | No | — | Filter `discover_portfolio` to specific protocols |\n| `parallel` | bool | No | `false` | **Required if querying >= 3 protocols** without a `protocols` filter |\n| `include_zero_positions` | bool | No | `false` | Include empty positions in portfolio |\n\nSupported protocols for `discover_portfolio`: `hyperliquid`, `hyperlend`, `moonwell`, `boros`, `pendle`.\n\n```bash\npoetry run wayfinder wallets --action create --label my_new_strategy\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --parallel\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"hyperliquid\",\"moonwell\"]'\n```\n\n**Validations:**\n- `create`: `label` must be non-empty. Duplicate labels return the existing wallet (idempotent).\n- `annotate`/`discover_portfolio`: must resolve a wallet address from `wallet_label` or `wallet_address`.\n- `annotate`: all of `protocol`, `annotate_action`, `tool`, `status` are required.\n- `discover_portfolio` with >= 3 protocols requires `parallel=true` or an explicit `protocols` filter (returns `requires_confirmation` otherwise).\n\n---\n\n### `quote_swap` — Get a swap/bridge quote (read-only)\n\nReturns a quote for swapping or bridging tokens. No on-chain effects.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `wallet_label` | string | **Yes** | — | Must resolve to a wallet with an address |\n| `from_token` | string | **Yes** | — | Token ID from search results (e.g. `usd-coin-base`). **Always search first** — do not guess. |\n| `to_token` | string | **Yes** | — | Token ID from search results. **Always search first.** |\n| `amount` | string | **Yes** | — | Human-readable amount (e.g. `\"500\"`). Must be positive, Decimal-parseable, and > 0 after scaling to token decimals |\n| `slippage_bps` | int | No | `50` | Slippage tolerance in basis points (50 = 0.5%) |\n| `recipient` | string | No | — | Defaults to sender address |\n| `include_calldata` | bool | No | `false` | Include raw calldata in response |\n\n**Always resolve token IDs before calling quote_swap.** Run `poetry run wayfinder resource wayfinder://tokens/search/<chain>/<symbol>` for each token first, then use the exact ID from the result. Do not pass raw symbols or guessed `symbol-chain` strings — they may resolve incorrectly or fail.\n\n**Note:** Native gas tokens (e.g., unwrapped ETH) may fail in swaps with `from_token_address: null`. Use the wrapped ERC20 version instead (e.g., WETH). Search for it: `resource wayfinder://tokens/search/<chain>/weth`.\n\n**Bridging to a new chain for the first time:** the wallet needs **native gas on the destination chain** before it can do anything. Bridge the native gas token (e.g. ETH) to the destination chain first, then bridge or swap for the target token. Use the native token IDs from the supported-chains table below (e.g. `ethereum-base` for ETH on Base).\n- Use the native token IDs from the supported-chains table below when bridging gas (e.g. `ethereum-base` for ETH on Base, `plasma-plasma` for PLASMA on Plasma).\n\n```bash\npoetry run wayfinder quote_swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 500\npoetry run wayfinder quote_swap --wallet_label main --from_token \"USDC-base\" --to_token \"ETH-base\" --amount 1000 --slippage_bps 100\n```\n\n**Errors:** `not_found` (wallet), `invalid_wallet`, `token_error`, `invalid_token` (missing chain_id/address), `invalid_amount`, `quote_error`.\n\n---\n\n### `execute` — Execute on-chain transactions\n\nExecute swaps, token sends, or Hyperliquid deposits. **This broadcasts transactions** and can move real funds.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `kind` | `swap` \\| `send` \\| `hyperliquid_deposit` | **Yes** | — | Operation type |\n| `wallet_label` | string | **Yes** | — | Must resolve to a wallet with private key |\n| `amount` | string | **Yes** | — | Human-readable amount (e.g. `\"500\"`) |\n| `from_token` | string | **swap** | — | Source token ID. **Always search first.** |\n| `to_token` | string | **swap** | — | Destination token ID. **Always search first.** |\n| `slippage_bps` | int | No | `50` | Swap only; basis points |\n| `deadline_seconds` | int | No | `300` | Swap only |\n| `recipient` | string | **send** | — | Recipient address |\n| `token` | string | **send** | — | Token ID (or `\"native\"` with `chain_id`). **Always search first.** |\n| `chain_id` | string | No | — | Required for `send` when `token=\"native\"` |\n| `force` | flag | No | `false` | Do not rely on this as a “dry-run vs live” gate. Treat `execute` as live and require explicit user confirmation before calling it. |\n\n**Hyperliquid deposit validations (critical):**\n- Amount **must be >= 5 USDC** (deposits below 5 are lost on the bridge).\n- Hard-codes: token = Arbitrum USDC, recipient = `HYPERLIQUID_BRIDGE_ADDRESS`, chain = Arbitrum (42161).\n\n**Additional runtime validations:**\n- Wallet must have both `address` and `private_key_hex`.\n- Token resolution must succeed (chain_id + token address required).\n- Swap quotes must return a `best_quote` with `calldata`.\n- For USDT-style tokens, a zero-allowance reset transaction is sent before approval.\n\n```bash\n# Swap\npoetry run wayfinder execute --kind swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 500\n\n# Send tokens\npoetry run wayfinder execute --kind send --wallet_label main --token usd-coin-base --recipient 0x... --amount 100\n\n# Hyperliquid deposit (min 5 USDC)\npoetry run wayfinder execute --kind hyperliquid_deposit --wallet_label main --amount 100\n```\n\n---\n\n### `hyperliquid` — Wait for Hyperliquid deposits/withdrawals\n\nWait for deposits or withdrawals to settle on Hyperliquid. For read-only queries (user state, prices, order books), use the `resource` command with Hyperliquid URIs.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `\"wait_for_deposit\"` \\| `\"wait_for_withdrawal\"` | **Yes** | — | — |\n| `wallet_label` | string | No | — | Or use `wallet_address` |\n| `wallet_address` | string | No | — | Alternative to `wallet_label` |\n| `expected_increase` | string | No | — | Expected USDC increase for deposit |\n| `timeout_s` | int | No | `120` | Timeout for `wait_for_deposit` |\n| `poll_interval_s` | int | No | `5` | Poll interval for wait actions |\n| `lookback_s` | int | No | `5` | For `wait_for_withdrawal` |\n| `max_poll_time_s` | int | No | `900` | Max wait for `wait_for_withdrawal` (15 min) |\n\n```bash\npoetry run wayfinder hyperliquid --action wait_for_deposit --wallet_label main --expected_increase 100\npoetry run wayfinder hyperliquid --action wait_for_withdrawal --wallet_label main\n```\n\n**Read-only queries via resources:**\n\n```bash\n# Perp positions + PnL\npoetry run wayfinder resource wayfinder://hyperliquid/main/state\n\n# Spot balances\npoetry run wayfinder resource wayfinder://hyperliquid/main/spot\n\n# All mid prices\npoetry run wayfinder resource wayfinder://hyperliquid/prices\n\n# Single coin price\npoetry run wayfinder resource wayfinder://hyperliquid/prices/ETH\n\n# Market metadata + funding rates\npoetry run wayfinder resource wayfinder://hyperliquid/markets\n\n# Spot asset metadata\npoetry run wayfinder resource wayfinder://hyperliquid/spot-assets\n\n# Order book\npoetry run wayfinder resource wayfinder://hyperliquid/book/ETH\n```\n\n---\n\n### `hyperliquid_execute` — Hyperliquid trading operations\n\nPlace/cancel orders, update leverage, and withdraw USDC. **These operations are live** and can place real orders / move real funds.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `place_order` \\| `cancel_order` \\| `update_leverage` \\| `withdraw` \\| `spot_to_perp_transfer` \\| `perp_to_spot_transfer` | **Yes** | — | — |\n| `wallet_label` | string | **Yes** | — | Must resolve to wallet with private key |\n| `coin` | string | **place_order, cancel_order, update_leverage** | — | Or use `asset_id`. Strips `-perp`/`_perp` suffixes automatically |\n| `asset_id` | string | No | — | Direct asset ID (alternative to `coin`) |\n| `is_spot` | string | No | — | `true` for spot orders, `false` for perp. **Must be explicit for place_order.** |\n| `order_type` | `market` \\| `limit` | No | `market` | — |\n| `is_buy` | string | **place_order** | — | `true` or `false` |\n| `size` | string | No | — | **Mutually exclusive with `usd_amount`**; coin units |\n| `usd_amount` | string | No | — | **Mutually exclusive with `size`**; USD amount |\n| `usd_amount_kind` | string | **when `usd_amount` is used** | — | `notional` or `margin` |\n| `leverage` | string | **when `usd_amount_kind=margin`; update_leverage** | — | Must be positive |\n| `price` | string | **limit orders** | — | Must be positive |\n| `slippage` | float | No | `0.01` | Market orders only; 0–0.25 (25% cap) |\n| `reduce_only` | flag | No | `false` | `--reduce_only` / `--no-reduce_only` |\n| `cloid` | string | No | — | Client order ID |\n| `order_id` | string | **cancel_order** | — | Or use `cancel_cloid` |\n| `cancel_cloid` | string | No | — | Alternative to `order_id` for cancel |\n| `is_cross` | flag | No | `true` | `--is_cross` / `--no-is_cross` |\n| `amount_usdc` | string | **withdraw, transfers** | — | USDC amount for withdraw or transfers |\n| `builder_fee_tenths_bp` | string | No | — | Falls back to config default |\n| `force` | flag | No | `false` | Do not rely on this as a “dry-run vs live” gate. Treat `hyperliquid_execute` as live and require explicit user confirmation before calling it. |\n\n**Key validations for `place_order`:**\n- Exactly one of `size` or `usd_amount` (not both, not neither).\n- If `usd_amount` is used, `usd_amount_kind` is required.\n- If `usd_amount_kind=margin`, then `leverage` is required.\n- Limit orders require `price` > 0.\n- After lot-size rounding, size must still be > 0.\n- Builder fee is mandatory (auto-configured; approval is auto-submitted if needed).\n\n```bash\n# Market buy\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main --coin ETH --is_buy true --usd_amount 200 --usd_amount_kind margin --leverage 5\n\n# Spot buy\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main --coin HYPE --is_spot true --is_buy true --usd_amount 20\n\n# Limit sell\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main --coin ETH --is_buy false --size 0.1 --price 4000 --order_type limit\n\n# Close position (reduce-only)\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main --coin ETH --is_buy false --size 0.5 --reduce_only\n\n# Update leverage\npoetry run wayfinder hyperliquid_execute --action update_leverage --wallet_label main --coin ETH --leverage 5\n\n# Cancel order\npoetry run wayfinder hyperliquid_execute --action cancel_order --wallet_label main --coin ETH --order_id 12345\n\n# Withdraw USDC\npoetry run wayfinder hyperliquid_execute --action withdraw --wallet_label main --amount_usdc 100\n\n# Transfer USDC between spot and perp wallets\npoetry run wayfinder hyperliquid_execute --action spot_to_perp_transfer --wallet_label main --amount_usdc 50\npoetry run wayfinder hyperliquid_execute --action perp_to_spot_transfer --wallet_label main --amount_usdc 50\n```\n\n---\n\n### `polymarket` — Polymarket market + account reads\n\nRead-only access to Polymarket markets, prices, order books, and user status.\n\n**Tradability filter:** a market can be “found” but not tradable. Filter for `enableOrderBook`, `acceptingOrders`, `active`, `closed != true`, and non-empty `clobTokenIds`.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `status` \\| `search` \\| `trending` \\| `get_market` \\| `get_event` \\| `price` \\| `order_book` \\| `price_history` \\| `bridge_status` \\| `open_orders` | **Yes** | — | — |\n| `wallet_label` | string | No | — | Resolves `account` from config; required for `open_orders` |\n| `wallet_address` | string | No | — | Alternative to `wallet_label` for account-based reads |\n| `account` | string | No | — | Direct account address (alternative to wallet inputs) |\n| `include_orders` | bool | No | `true` | `status` only |\n| `include_activity` | bool | No | `false` | `status` only |\n| `activity_limit` | int | No | `50` | `status` only |\n| `include_trades` | bool | No | `false` | `status` only |\n| `trades_limit` | int | No | `50` | `status` only |\n| `positions_limit` | int | No | `500` | `status` only |\n| `max_positions_pages` | int | No | `10` | `status` only |\n| `query` | string | **search** | — | Query string for fuzzy market search |\n| `limit` | int | No | `10` | `search`, `trending` |\n| `page` | int | No | `1` | `search` |\n| `keep_closed_markets` | bool | No | `false` | `search` |\n| `rerank` | bool | No | `true` | `search` |\n| `offset` | int | No | `0` | `trending` |\n| `market_slug` | string | **get_market** | — | Market slug |\n| `event_slug` | string | **get_event** | — | Event slug |\n| `token_id` | string | **price, order_book, price_history** | — | Polymarket CLOB token id (optional for `open_orders` filter) |\n| `side` | `BUY` \\| `SELL` | No | `BUY` | `price` only |\n| `interval` | string | No | `\"1d\"` | `price_history` only |\n| `start_ts` | int | No | — | `price_history` only (unix seconds) |\n| `end_ts` | int | No | — | `price_history` only (unix seconds) |\n| `fidelity` | int | No | — | `price_history` only |\n\n**Action-specific requirements:**\n- `status`, `bridge_status`: require an `account` (via `--account`, `--wallet_address`, or `--wallet_label`).\n- `open_orders`: requires `--wallet_label` and a wallet with `private_key_hex` in `config.json` (Level-2 auth). Optional: `--token_id` to filter.\n\n```bash\n# Search markets\npoetry run wayfinder polymarket --action search --query \"bitcoin above 100k\" --limit 5\n\n# User status (positions + balances)\npoetry run wayfinder polymarket --action status --wallet_label main\n\n# CLOB order book\npoetry run wayfinder polymarket --action order_book --token_id 123456\n```\n\n---\n\n### `polymarket_execute` — Polymarket execution (bridge + orders)\n\nExecute Polymarket actions (bridging and trading). **This command is live (no dry-run flag).**\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `bridge_deposit` \\| `bridge_withdraw` \\| `buy` \\| `sell` \\| `close_position` \\| `place_limit_order` \\| `cancel_order` \\| `redeem_positions` | **Yes** | — | — |\n| `wallet_label` | string | **Yes** | — | Wallet must include `address` and `private_key_hex` in config |\n| `from_chain_id` | int | No | `137` | `bridge_deposit` only |\n| `from_token_address` | string | No | Polygon USDC | `bridge_deposit` only |\n| `amount` | float | **bridge_deposit** | — | Amount of USDC to deposit |\n| `recipient_address` | string | No | sender | `bridge_deposit` only |\n| `amount_usdce` | float | **bridge_withdraw** | — | Amount of USDC.e to withdraw |\n| `to_chain_id` | int | No | `137` | `bridge_withdraw` only |\n| `to_token_address` | string | No | Polygon USDC | `bridge_withdraw` only |\n| `recipient_addr` | string | No | sender | `bridge_withdraw` only |\n| `token_decimals` | int | No | `6` | Bridge token decimals |\n| `market_slug` | string | No | — | Used by `buy`, `sell`, `close_position` |\n| `outcome` | string \\| int | No | `\"YES\"` | Used with `market_slug` (e.g. `YES`/`NO`) |\n| `token_id` | string | No | — | Alternative to `market_slug` for `buy`, `sell`, `place_limit_order` |\n| `amount_usdc` | float | **buy** | — | Buy amount in USDC |\n| `shares` | float | **sell** | — | Shares to sell |\n| `side` | `BUY` \\| `SELL` | No | `BUY` | `place_limit_order` only |\n| `price` | float | **place_limit_order** | — | Limit price (0–1) |\n| `size` | float | **place_limit_order** | — | Order size (shares) |\n| `post_only` | bool | No | `false` | `place_limit_order` only |\n| `order_id` | string | **cancel_order** | — | — |\n| `condition_id` | string | **redeem_positions** | — | Required for `redeem_positions`; also accepted by `close_position` as a fallback |\n\n**Approvals + API creds:** handled automatically before order placement (idempotent).\n\n**Collateral:** Polymarket CLOB trading collateral is **USDC.e on Polygon**, not native Polygon USDC. Use `bridge_deposit` / `bridge_withdraw` to convert. These methods prefer a fast on-chain BRAP swap on Polygon when possible (sender == recipient); otherwise they fall back to the Polymarket Bridge service (`method: \"polymarket_bridge\"` in the result) and you can monitor via `polymarket --action bridge_status`.\n\n**Trade semantics:**\n- `buy` uses `amount_usdc` as **collateral ($) to spend**\n- `sell` uses `shares` as **shares to sell**\n\n**Always require explicit user confirmation before running `polymarket_execute`.**\n\n```bash\n# Bridge USDC -> USDC.e collateral (Polymarket)\npoetry run wayfinder polymarket_execute --action bridge_deposit --wallet_label main --amount 10\n\n# Buy shares by market slug + outcome\npoetry run wayfinder polymarket_execute --action buy --wallet_label main --market_slug \"some-market-slug\" --outcome YES --amount_usdc 2\n\n# Close a position (sells full size; resolves token_id from market slug)\npoetry run wayfinder polymarket_execute --action close_position --wallet_label main --market_slug \"some-market-slug\" --outcome YES\n```\n\n---\n\n### `run_strategy` — Strategy lifecycle management\n\nRun strategy actions: check status, analyze, quote, deposit, update, withdraw, or exit.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `strategy` | string | **Yes** | — | Strategy directory name; must have `manifest.yaml` |\n| `action` | `status` \\| `analyze` \\| `snapshot` \\| `policy` \\| `quote` \\| `deposit` \\| `update` \\| `withdraw` \\| `exit` | **Yes** | — | — |\n| `amount_usdc` | float | No | `1000.0` | **Read-only analysis:** hypothetical deposit for `analyze`, `snapshot`, `quote` |\n| `amount` | string | No | — | Generic amount parameter (strategy-specific) |\n| `main_token_amount` | string | **deposit** | — | **Actual deposit:** amount of strategy's deposit token |\n| `gas_token_amount` | float | No | `0.0` | **Actual deposit:** optional gas token amount |\n\n**Amount parameter rules:**\n- **For read-only analysis** (`analyze`, `snapshot`, `quote`): use `--amount_usdc`\n- **For actual deposits** (`deposit`): use `--main_token_amount` (required) + optionally `--gas_token_amount`\n- The deposit token varies by strategy (USDC on Base for stablecoin_yield, USDC on Arbitrum for boros_hype, etc.)\n\n```bash\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action status\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action analyze --amount_usdc 100\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action quote --amount_usdc 100\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action deposit --main_token_amount 100 --gas_token_amount 0.01\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action update\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action withdraw\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action exit\n```\n\n**Errors:** `invalid_request` (empty strategy), `not_found` (missing manifest), `not_supported` (strategy lacks the method), `strategy_error` (runtime exception).\n\n**Note:** `withdraw` liquidates positions but funds stay in the strategy wallet. `exit` transfers funds from the strategy wallet back to the main wallet. These are separate steps.\n\n---\n\n### `run_script` — Execute sandboxed Python scripts\n\nRun a local Python script in a subprocess. Scripts must live inside the runs directory (`$WAYFINDER_RUNS_DIR` or `.wayfinder_runs/`).\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `script_path` | string | **Yes** | — | Must be `.py`, must exist, **must be inside the runs directory** |\n| `args` | string | No | — | Arguments passed to the script (JSON list) |\n| `timeout_s` | int | No | `600` | Clamped to min 1 second |\n| `env` | string | No | — | Additional env vars for subprocess (JSON object) |\n| `wallet_label` | string | No | — | For profile annotation |\n| `force` | flag | No | `false` | Do not rely on this as a “dry-run vs live” gate. Prefer implementing `--dry-run` / `--force` inside your script and passing it via `--args`. |\n\n**Validations:**\n- Script path must resolve to inside the runs directory (sandboxed — no arbitrary file execution).\n- Must be a `.py` file.\n- Must exist on disk.\n- Output is truncated to 20,000 chars.\n\n```bash\n# Recommended: implement --dry-run / --force in your script and pass it via --args\npoetry run wayfinder run_script --script_path .wayfinder_runs/my_flow.py --args '[\"--dry-run\"]' --wallet_label main\npoetry run wayfinder run_script --script_path .wayfinder_runs/my_flow.py --args '[\"--force\"]' --wallet_label main\n\n# With timeout\npoetry run wayfinder run_script --script_path .wayfinder_runs/my_flow.py --wallet_label main --timeout_s 120\n```\n\n---\n\n## Config Structure\n\nConfig is loaded from `$WAYFINDER_CONFIG_PATH` (default: `$WAYFINDER_SDK_PATH/config.json`).\n\n```json\n{\n  \"system\": {\n    \"api_base_url\": \"https://strategies.wayfinder.ai/api/v1\",\n    \"api_key\": \"wk_...\"\n  },\n  \"strategy\": {\n    \"rpc_urls\": {}\n  },\n  \"wallets\": [\n    {\n      \"label\": \"main\",\n      \"address\": \"0x...\",\n      \"private_key_hex\": \"0x...\"\n    }\n  ],\n  \"ccxt\": {\n    \"aster\": { \"apiKey\": \"\", \"secret\": \"\" },\n    \"binance\": { \"apiKey\": \"\", \"secret\": \"\" }\n  }\n}\n```\n\n- `system.api_key` falls back to `$WAYFINDER_API_KEY` env var.\n- `strategy.rpc_urls` is optional; if a chain id is not configured, on-chain calls use Wayfinder’s RPC proxy at `system.api_base_url` (auth via your API key).\n- Most write operations require a wallet entry with `address` + `private_key_hex`.\n\n## Available Strategies\n\n| Strategy | Status | Chain | Token | Risk | Description |\n|----------|--------|-------|-------|------|-------------|\n| `basis_trading_strategy` | stable | Hyperliquid | USDC | Medium | Delta-neutral funding rate capture with matched spot/perp positions |\n| `boros_hype_strategy` | stable | Arbitrum + HyperEVM + Hyperliquid | HYPE/USDC | Medium | Multi-leg HYPE yield with fixed-rate funding lock via Boros |\n| `hyperlend_stable_yield_strategy` | stable | HyperEVM | USDT0 | Low | Stablecoin yield optimization on HyperLend with rotation policy |\n| `moonwell_wsteth_loop_strategy` | stable | Base | USDC/WETH/wstETH | Medium-High | Leveraged wstETH carry trade via Moonwell looping |\n| `stablecoin_yield_strategy` | wip | Base | USDC | Low | Auto-rotates across best stablecoin pools on Base |\n| `projectx_thbill_usdc_strategy` | wip | HyperEVM | THBILL/USDC | Medium | Concentrated liquidity market making on ProjectX (V3 fork) |\n\n**Reference**: [references/strategies.md](references/strategies.md)\n\n## Available Adapters\n\n| Adapter | Protocol | Capabilities |\n|---------|----------|-------------|\n| `balance_adapter` | EVM wallets | `balance.read`, `transfer.main_to_strategy`, `transfer.strategy_to_main`, `transfer.send` |\n| `boros_adapter` | Boros (Arbitrum) | `market.read`, `market.quote`, `position.open`, `position.close`, `collateral.deposit`, `collateral.withdraw` |\n| `brap_adapter` | Cross-chain swaps | `swap.quote`, `swap.execute`, `swap.compare_routes`, `bridge.quote`, `gas.estimate` |\n| `ccxt_adapter` | Centralized exchanges (CCXT) | `exchange.factory` |\n| `hyperlend_adapter` | HyperLend (HyperEVM) | `market.stable_markets`, `market.assets_view`, `market.rate_history`, `lending.lend`, `lending.unlend` |\n| `hyperliquid_adapter` | Hyperliquid DEX | `market.read`, `market.meta`, `market.funding`, `market.candles`, `market.orderbook`, `order.execute`, `order.cancel`, `position.manage`, `transfer`, `withdraw` |\n| `ledger_adapter` | Local bookkeeping | `ledger.read`, `ledger.record`, `ledger.snapshot` |\n| `moonwell_adapter` | Moonwell (Base) | `lending.lend`, `lending.unlend`, `lending.borrow`, `lending.repay`, `collateral.set`, `collateral.remove`, `rewards.claim`, `position.read`, `market.apy`, `market.collateral_factor` |\n| `multicall_adapter` | EVM batch calls | `multicall.aggregate` |\n| `pendle_adapter` | Pendle | `pendle.markets.read`, `pendle.market.snapshot`, `pendle.swap.quote`, `pendle.swap.execute`, `pendle.convert.quote`, `pendle.positions.database`, and more |\n| `polymarket_adapter` | Polymarket | `market.read`, `market.search`, `market.orderbook`, `market.candles`, `position.read`, `order.execute`, `order.cancel`, `bridge.deposit`, `bridge.withdraw` |\n| `pool_adapter` | DeFi Llama | `pool.read`, `pool.discover` |\n| `projectx_adapter` | ProjectX (V3 fork) | `projectx.pool.overview`, `projectx.positions.list`, `projectx.liquidity.mint`, `projectx.liquidity.increase`, `projectx.liquidity.decrease`, `projectx.fees.collect`, `projectx.swap.exact_in` |\n| `token_adapter` | Token metadata | `token.read`, `token.price`, `token.gas` |\n| `uniswap_adapter` | Uniswap V3 | `uniswap.liquidity.add`, `uniswap.liquidity.increase`, `uniswap.liquidity.remove`, `uniswap.fees.collect`, `uniswap.position.get`, `uniswap.positions.list`, `uniswap.fees.uncollected`, `uniswap.pool.get` |\n\n**Reference**: [references/adapters.md](references/adapters.md)\n\n## Token ID Format — ALWAYS SEARCH FIRST\n\n**CRITICAL: NEVER guess or construct token IDs.** Always look up the correct token using the appropriate endpoint before using it in any command.\n\n**Three token endpoints — know which to use:**\n- **`tokens/search`** → fuzzy search (hits `/blockchain/tokens/fuzzy/`) — **always use this first for ERC20 tokens**\n- **`tokens/resolve`** → exact lookup (hits `/blockchain/tokens/detail/`) — only use with an ID you got from search\n- **`tokens/gas`** → native gas tokens (hits `/blockchain/tokens/gas/`) — **use for ETH, HYPE, and other native tokens**\n\nToken IDs use `<coingecko_id>-<chain_code>` format (NOT symbol-chain):\n- `usd-coin-base` (USDC on Base) — NOT `usdc-base`\n- `ethereum-arbitrum` (ETH on Arbitrum) — NOT `ETH-arbitrum`\n- `usdt0-arbitrum` (USDT on Arbitrum) — NOT `USDT-arbitrum`\n- `hyperliquid-hyperevm` (HYPE on HyperEVM) — NOT `HYPE-hyperevm`\n\n**You cannot reliably guess coingecko IDs from token symbols.** For example, ETH's coingecko ID is `ethereum`, USDC's is `usd-coin`, HYPE's is `hyperliquid`. These are not derivable from the symbol alone.\n\n**Native gas tokens** are best discovered via `tokens/gas/<chain_code>`. Use the table below as a convenient reference, but prefer `tokens/gas` when in doubt.\n\nValid chain codes (common): `ethereum`, `base`, `arbitrum`, `polygon`, `bsc`, `avalanche`, `plasma`, `hyperevm`. Note: `mainnet` is NOT a valid chain code — use `ethereum` instead.\n\n### Supported chains\n\n| Chain | ID | Code | Symbol | Native token ID |\n|------|----|------|--------|-----------------|\n| Ethereum | 1 | `ethereum` | ETH | `ethereum-ethereum` |\n| Base | 8453 | `base` | ETH | `ethereum-base` |\n| Arbitrum | 42161 | `arbitrum` | ETH | `ethereum-arbitrum` |\n| Polygon | 137 | `polygon` | POL | `polygon-ecosystem-token-polygon` |\n| BSC | 56 | `bsc` | BNB | `binancecoin-bsc` |\n| Avalanche | 43114 | `avalanche` | AVAX | `avalanche-avalanche` |\n| Plasma | 9745 | `plasma` | PLASMA | `plasma-plasma` |\n| HyperEVM | 999 | `hyperevm` | HYPE | `hyperliquid-hyperevm` |\n\n**Before every swap, send, or token operation:**\n```bash\n# For native gas tokens (ETH, HYPE):\npoetry run wayfinder resource wayfinder://tokens/gas/<chain_code>\n\n# For ERC20 tokens — REQUIRED: fuzzy search first\npoetry run wayfinder resource wayfinder://tokens/search/<chain_code>/<symbol>\n# Then use the exact token ID from the search result\n```\n\n## Sizing for Perp Orders\n\nWhen a user says \"$X at Yx leverage\", clarify:\n- `--usd_amount_kind margin` = $X is collateral (notional = X * leverage)\n- `--usd_amount_kind notional` = $X is position size\n\n`--usd_amount` and `--size` are mutually exclusive. When using `--usd_amount` with `--usd_amount_kind margin`, `--leverage` is required.\n\n## Safety\n\n- **NEVER output private keys or seed phrases into the conversation.** These are secrets that must stay on the machine. Only offer to display a seed phrase if the user explicitly confirms they cannot access the machine to retrieve it themselves.\n- **Execution commands are live.** Require explicit user confirmation before running `execute`, `hyperliquid_execute`, `polymarket_execute`, or any script that broadcasts transactions.\n- **NEVER guess or fabricate token IDs.** Before any token operation (swap, send, quote, balance check):\n  - For **native gas tokens** (ETH, HYPE): use `poetry run wayfinder resource wayfinder://tokens/gas/<chain_code>`\n  - For **ERC20 tokens**: use `poetry run wayfinder resource wayfinder://tokens/search/<chain_code>/<query>` (fuzzy search) and use the exact token ID from the result\n  - Do not construct IDs by combining symbols with chain names — the coingecko ID is unpredictable. Do not call `tokens/resolve` with a guessed ID — it hits a different API than search.\n- **Bridging to a new chain (first time):** bridge native gas to the destination chain first (use the supported-chains table or `tokens/gas/<chain_code>`), then bridge/swap for the target asset.\n- Start with small test amounts.\n- Withdraw and exit are separate steps: `withdraw` liquidates positions, `exit` transfers funds home.\n- **Hyperliquid deposits must be >= 5 USDC** — amounts below 5 are lost on the bridge.\n- Market order slippage is capped at 25% (`--slippage 0.25`).\n- Scripts are sandboxed to the runs directory — no arbitrary file execution.\n\n## Common Workflows\n\n### Check Before Trading\n\n```bash\npoetry run wayfinder resource wayfinder://balances/main\n# ALWAYS look up tokens first — never guess IDs\npoetry run wayfinder resource wayfinder://tokens/search/base/usdc   # Search for USDC → get token ID from result\npoetry run wayfinder resource wayfinder://tokens/gas/base            # Get native ETH on Base\n# Use the exact token IDs from the lookup results\npoetry run wayfinder resource wayfinder://hyperliquid/prices/ETH\npoetry run wayfinder quote_swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 1000\n```\n\n### Deploy a Strategy\n\n```bash\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action status\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action deposit --main_token_amount 100 --gas_token_amount 0.01\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action update\n```\n\n### Open a Hyperliquid Position\n\n```bash\npoetry run wayfinder resource wayfinder://hyperliquid/main/state\npoetry run wayfinder hyperliquid_execute --action update_leverage --wallet_label main --coin ETH --leverage 5\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main --coin ETH --is_buy true --usd_amount 200 --usd_amount_kind margin --leverage 5\n```\n\n### Wind Down Everything\n\n```bash\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action withdraw\npoetry run wayfinder run_strategy --strategy stablecoin_yield_strategy --action exit\n```\n\n## Custom Scripts via the Coding Interface\n\n**For any operation that goes beyond a single CLI command, you SHOULD write a custom Python script.** The `wayfinder-paths-sdk` provides a full coding interface — use it whenever you need multi-step flows, conditional logic, batched operations, or protocol combinations.\n\n### When to Write a Script\n\n- **Multi-step atomic flows** — operations that must succeed together\n- **Custom logic** — conditional execution based on market state\n- **Batched operations** — multiple protocol interactions in sequence\n- **Protocol combinations** — bridging multiple adapters in one flow\n- **Complex calculations** — position sizing, rebalancing, PnL analysis\n- **Anything the user asks that isn't a single CLI call**\n\n### Script Location\n\nAll generated scripts **must** be saved to `.wayfinder_runs/` inside the SDK directory:\n\n```\n$WAYFINDER_SDK_PATH/.wayfinder_runs/my_script.py\n```\n\nThis directory is sandboxed — `run_script` only executes scripts inside it. Create it if it doesn't exist:\n\n```bash\nmkdir -p \"$WAYFINDER_SDK_PATH/.wayfinder_runs\"\n```\n\n### Referencing the SDK Source\n\nBefore writing any script, **pull the detailed reference docs** for the adapter or strategy you're working with. The SDK ships comprehensive skill docs covering method signatures, gotchas, unit conventions, and execution patterns.\n\n**Use the reference script** (bash or PowerShell):\n\n```bash\n# List available topics\n./wayfinder/scripts/pull-sdk-ref.sh --list\n\n# Pull docs for specific adapters (supports multiple topics)\n./wayfinder/scripts/pull-sdk-ref.sh moonwell\n./wayfinder/scripts/pull-sdk-ref.sh boros hyperliquid\n./wayfinder/scripts/pull-sdk-ref.sh strategies\n\n# Pull everything\n./wayfinder/scripts/pull-sdk-ref.sh --all\n\n# Check the pinned SDK version\n./wayfinder/scripts/pull-sdk-ref.sh --version\n\n# Override with a specific commit\n./wayfinder/scripts/pull-sdk-ref.sh --commit abc123 moonwell\n```\n\n```powershell\n# Windows\n.\\wayfinder\\scripts\\pull-sdk-ref.ps1 moonwell\n.\\wayfinder\\scripts\\pull-sdk-ref.ps1 -All\n.\\wayfinder\\scripts\\pull-sdk-ref.ps1 -Version\n.\\wayfinder\\scripts\\pull-sdk-ref.ps1 -Commit abc123 moonwell\n```\n\n**Available topics:** `strategies`, `setup`, `boros`, `brap`, `hyperlend`, `hyperliquid`, `polymarket`, `moonwell`, `pendle`, `uniswap`, `projectx`, `data`\n\nThe SDK ref is tracked in `wayfinder/sdk-version.md` (default: `main`). The pull script checks out that ref when reading docs, then restores the SDK to its previous state.\n\n**Always run this before writing a script** — the docs cover critical details like:\n- Exact method signatures and required parameters\n- Unit conventions (raw base units vs human-readable, wei vs native)\n- Gotchas (e.g., `unlend()` takes mToken amounts not underlying, withdrawal cooldowns, funding sign conventions)\n- Execution patterns and safety rails\n- Token/contract addresses\n\nYou can also read the adapter source code directly:\n\n```\n$WAYFINDER_SDK_PATH/wayfinder_paths/adapters/          # All adapter implementations\n$WAYFINDER_SDK_PATH/wayfinder_paths/mcp/scripting.py   # get_adapter() helper\n$WAYFINDER_SDK_PATH/wayfinder_paths/strategies/        # Strategy implementations\n```\n\n### Quick Start\n\n```python\n#!/usr/bin/env python3\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.moonwell_adapter import MoonwellAdapter\n\nasync def main():\n    adapter = get_adapter(MoonwellAdapter, \"main\")  # Auto-wires config + signing\n    success, result = await adapter.lend(mtoken=\"0x...\", amount=100_000_000)\n    print(f\"Result: {result}\" if success else f\"Error: {result}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Testing Workflow\n\n**Always test before live execution.** Follow this workflow:\n\n1. **Write** the script to `.wayfinder_runs/`\n2. **Safe run** — run the script in a non-fund-moving mode first (recommended: implement `--dry-run` / `--force` in your script and pass it via `--args`):\n   ```bash\n   cd \"$WAYFINDER_SDK_PATH\"\n   poetry run wayfinder run_script --script_path .wayfinder_runs/my_script.py --args '[\"--dry-run\"]' --wallet_label main\n   ```\n3. **Review** the output. Verify the operations, amounts, and addresses are correct.\n4. **Live execution** — only after confirming the safe run looks right, run with `--force`:\n   ```bash\n   poetry run wayfinder run_script --script_path .wayfinder_runs/my_script.py --args '[\"--force\"]' --wallet_label main\n   ```\n\n**Never skip the safe-run step for scripts that move funds.**\n\n**Reference**: [references/coding-interface.md](references/coding-interface.md) — Full adapter API reference, examples, and patterns\n\n## Protocol References\n\n- [references/setup.md](references/setup.md) — First-time setup, configuration, and wallet management\n- [references/strategies.md](references/strategies.md) — Strategy details, parameters, and workflows\n- [references/adapters.md](references/adapters.md) — Adapter capabilities and method signatures\n- [references/coding-interface.md](references/coding-interface.md) — Custom Python scripting with adapters\n- [references/hyperliquid.md](references/hyperliquid.md) — Hyperliquid trading, deposits, funding\n- [references/polymarket.md](references/polymarket.md) — Polymarket markets, bridging, and trading\n- [references/ccxt.md](references/ccxt.md) — Centralized exchanges (Aster/Binance/etc.) via CCXT (use carefully)\n- [references/moonwell.md](references/moonwell.md) — Moonwell lending, mToken addresses, gotchas\n- [references/pendle.md](references/pendle.md) — Pendle PT/YT markets, swap execution\n- [references/boros.md](references/boros.md) — Boros fixed-rate markets, rate locking\n- [references/uniswap.md](references/uniswap.md) — Uniswap V3 LP positions and fee collection\n- [references/projectx.md](references/projectx.md) — ProjectX (V3 fork) LP positions, swaps, and strategy notes\n- [references/tokens-and-pools.md](references/tokens-and-pools.md) — Token IDs, pool discovery, balance reads\n- [references/hyperlend.md](references/hyperlend.md) — HyperLend lending, supply/withdraw flows\n\n## Error Handling\n\nAll errors return structured JSON: `{\"ok\": false, \"error\": {\"code\": \"...\", \"message\": \"...\", \"details\": ...}}`.\n\n### Error Categories\n\n#### Validation Errors — bad input, fixable by the caller\n\n| Error Code | Meaning | Common Causes | User-Facing Guidance |\n|------------|---------|---------------|----------------------|\n| `invalid_request` | Missing or invalid required parameters | Omitted `action`, empty `strategy`, missing `token_id` for balance query | Tell the user which parameter is missing and show the correct command format |\n| `invalid_wallet` | Wallet missing `address` or `private_key_hex` | Wallet label exists but entry is incomplete; read-only wallet used for execution | Ask the user to check their config.json wallet entry has both fields |\n| `invalid_token` | Token resolution failed — missing `chain_id` or contract `address` after lookup | Typo in token ID, token not indexed, ambiguous symbol without chain qualifier | Suggest running `resource wayfinder://tokens/search/<chain>/<query>` and show the closest matches |\n| `invalid_amount` | Amount not parseable, not positive, or zero after decimal scaling | Non-numeric string, negative value, amount like `0.000000001` that rounds to 0 for a low-decimal token | Show the parsed value and the token's decimals so the user understands the rounding |\n\n#### Resource Errors — something doesn't exist\n\n| Error Code | Meaning | Common Causes | User-Facing Guidance |\n|------------|---------|---------------|----------------------|\n| `not_found` | Directory, manifest, wallet, or resource not found | Strategy name typo, adapter not installed, wallet label doesn't match config | List available resources (`resource wayfinder://strategies`) so the user can pick the right name |\n| `not_supported` | Strategy does not implement the requested action | Calling `withdraw` on a strategy that only supports `status`/`deposit` | Show which actions the strategy does support (from its manifest) |\n| `requires_confirmation` | Operation needs explicit user confirmation before proceeding | `discover_portfolio` across >= 3 protocols without `--parallel` flag | Explain the operation scope and ask the user to confirm or pass `--parallel` |\n\n#### API & Integration Errors — upstream service failures\n\n| Error Code | Meaning | Common Causes | User-Facing Guidance |\n|------------|---------|---------------|----------------------|\n| `token_error` | Token adapter API call failed | Wayfinder API down, network timeout, invalid API key | Check API key validity; retry after a moment; show the raw error message from details |\n| `quote_error` | Swap/bridge quote generation failed | No liquidity for pair, amount too small for routing, bridge route unavailable | Suggest trying a different amount, checking if the pair is supported, or using a different route |\n| `balance_error` | Balance query failed | RPC node down, rate-limited, invalid chain_id | Retry; if persistent, check RPC URL configuration |\n| `activity_error` | Activity/transaction history query failed | Indexer lag, unsupported chain for activi\n\nFile v0.4.1:_meta.json\n\n{\n  \"ownerId\": \"kn70kfnzaghvt4fcq75v9wqa9h80epek\",\n  \"slug\": \"wayfinder\",\n  \"version\": \"0.4.1\",\n  \"publishedAt\": 1771021227670\n}\n\nFile v0.4.1:references/adapters.md\n\n# Adapters\n\n## Overview\n\nAdapters are protocol integrations that provide read and write capabilities. Strategies compose adapters to build trading logic.\n\n## Discovering Adapters\n\n```bash\n# List all adapters with capabilities\npoetry run wayfinder resource wayfinder://adapters\n\n# Describe a specific adapter\npoetry run wayfinder resource wayfinder://adapters/moonwell_adapter\n```\n\n## Adapter Reference\n\n### Balance Adapter (`balance_adapter`)\n\n- **Type**: `BALANCE`\n- **Module**: `wayfinder_paths.adapters.balance_adapter.adapter.BalanceAdapter`\n- **Protocol**: EVM wallets (Base, Arbitrum, Ethereum, HyperEVM)\n- **Capabilities**: `balance.read`, `transfer.main_to_strategy`, `transfer.strategy_to_main`, `transfer.send`\n\nProvides token balance queries for any wallet, cross-wallet transfers between main and strategy wallets, and automatic ledger recording for deposits/withdrawals.\n\n```bash\npoetry run wayfinder resource wayfinder://balances/main\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base\npoetry run wayfinder resource wayfinder://activity/main\n```\n\n### BRAP Adapter (`brap_adapter`)\n\n- **Type**: `BRAP`\n- **Module**: `wayfinder_paths.adapters.brap_adapter.adapter.BRAPAdapter`\n- **Protocol**: Cross-chain swap aggregator (Bridge/Router/Adapter Protocol)\n- **Capabilities**: `swap.quote`, `swap.execute`, `swap.compare_routes`, `bridge.quote`, `gas.estimate`\n\nHandles cross-chain swaps and bridges with quote fetching, route optimization, and execution.\n\n```bash\npoetry run wayfinder quote_swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 100\npoetry run wayfinder execute --kind swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 100\n```\n\n**Key Methods:**\n- `BRAPClient.get_quote(from_token, to_token, from_chain, to_chain, from_wallet, from_amount, slippage?)` — Low-level quote (amount in **raw base units** as string)\n- `BRAPAdapter.best_quote(...)` — Returns single best route; supports `preferred_providers`\n- `BRAPAdapter.swap_from_token_ids(from_token_id, to_token_id, from_address, amount, slippage, ...)` — Execute swap by token IDs\n- `BRAPAdapter.swap_from_quote(from_token, to_token, from_address, quote, ...)` — Execute from a pre-fetched quote\n\n**Recommended Quote Loop:**\n1. Call `quote_swap` (does token lookup + human→raw conversion + returns preview)\n2. Inspect `from_token`/`to_token` in response to verify correct asset + chain\n3. Pass `suggested_execute_request` directly into `execute`\n\n**BRAP Gotchas:**\n- **Broadcast ≠ success**: A tx hash does not mean the swap succeeded. The SDK waits for receipt and raises `TransactionRevertedError` on `status=0`.\n- **Units**: Quote input `from_amount` is **raw base units**. Resolve decimals via TokenClient first.\n- **Slippage formats**: BRAP adapter uses **decimal fraction** (`0.005` = 0.5%). MCP may use bps (`50` = 0.5%). Don't mix.\n- **Approvals**: Some tokens are \"strict approve\" and require setting allowance to 0 before increasing — the adapter has a built-in allowlist.\n- **Recipient safety**: Treat `recipient != sender` as high-risk; require explicit user confirmation.\n- **USD enrichment is best-effort**: USD fields in quotes may fail; rely on raw amounts for correctness.\n- **Native token sends**: For tiny amounts use scientific notation (`\"1e-18\"`); long decimal strings may cause serialization errors.\n- **Native sends**: Require `token: \"native\"` and `chain_id` in the request.\n\n### CCXT Adapter (`ccxt_adapter`)\n\n- **Type**: `CCXT`\n- **Module**: `wayfinder_paths.adapters.ccxt_adapter.adapter.CCXTAdapter`\n- **Protocol**: Centralized exchanges (CEXes) via CCXT\n- **Capabilities**: `exchange.factory`\n\nUse this only when the user explicitly wants CEX data/trading and has API credentials configured in `config.json` under `ccxt`. For Hyperliquid, prefer the native Hyperliquid tools/adapters unless the user explicitly asks for CCXT.\n\nSee [ccxt.md](ccxt.md) for setup + examples.\n\n### Boros Adapter (`boros_adapter`)\n\n- **Type**: `BOROS`\n- **Module**: `wayfinder_paths.adapters.boros_adapter.adapter.BorosAdapter`\n- **Protocol**: Boros (Arbitrum) - Fixed-rate funding markets\n- **Capabilities**: `market.read`, `market.quote`, `position.open`, `position.close`, `collateral.deposit`, `collateral.withdraw`\n\nProvides fixed-rate market discovery, quoting, orderbook data, deposits, withdrawals, and position management on Boros.\n\nSee [boros.md](boros.md) for details.\n\n### HyperLend Adapter (`hyperlend_adapter`)\n\n- **Type**: `HYPERLEND`\n- **Module**: `wayfinder_paths.adapters.hyperlend_adapter.adapter.HyperlendAdapter`\n- **Protocol**: HyperLend (HyperEVM)\n- **Capabilities**: `market.stable_markets`, `market.assets_view`, `market.rate_history`, `lending.lend`, `lending.unlend`\n\nProvides stable market snapshots, rate history time series, and stablecoin supply/withdraw operations on HyperLend.\n\nSee [hyperlend.md](hyperlend.md) for details.\n\n### Hyperliquid Adapter (`hyperliquid_adapter`)\n\n- **Type**: `HYPERLIQUID`\n- **Module**: `wayfinder_paths.adapters.hyperliquid_adapter.adapter.HyperliquidAdapter`\n- **Protocol**: Hyperliquid DEX\n- **Capabilities**: `market.read`, `market.meta`, `market.funding`, `market.candles`, `market.orderbook`, `order.execute`, `order.cancel`, `position.manage`, `transfer`, `withdraw`\n\nComprehensive Hyperliquid integration for perp/spot state, funding rates, mid prices, order books, candles, market/limit orders, leverage, deposits, and withdrawals.\n\nSee [hyperliquid.md](hyperliquid.md) for details.\n\n### Polymarket Adapter (`polymarket_adapter`)\n\n- **Type**: `POLYMARKET`\n- **Module**: `wayfinder_paths.adapters.polymarket_adapter.adapter.PolymarketAdapter`\n- **Protocol**: Polymarket (prediction markets)\n- **Capabilities**: `market.read`, `market.search`, `market.orderbook`, `market.candles`, `position.read`, `order.execute`, `order.cancel`, `bridge.deposit`, `bridge.withdraw`\n\nRead Polymarket markets/events, prices and order books, and (with a signing key) place trades and bridge collateral.\n\n**Read-only examples:**\n\n```bash\npoetry run wayfinder polymarket --action search --query \"bitcoin above\" --limit 5\npoetry run wayfinder polymarket --action status --wallet_label main\n```\n\n**Execution examples (live):**\n\n```bash\npoetry run wayfinder polymarket_execute --action bridge_deposit --wallet_label main --amount 10\npoetry run wayfinder polymarket_execute --action buy --wallet_label main --market_slug \"some-market\" --outcome YES --amount_usdc 2\n```\n\nSee [polymarket.md](polymarket.md) for details.\n\n### Ledger Adapter (`ledger_adapter`)\n\n- **Type**: `LEDGER`\n- **Module**: `wayfinder_paths.adapters.ledger_adapter.adapter.LedgerAdapter`\n- **Protocol**: Local bookkeeping\n- **Capabilities**: `ledger.read`, `ledger.record`, `ledger.snapshot`\n\nProvides transaction history tracking, net deposit calculations, deposit/withdrawal recording, and strategy operation logging.\n\n### Moonwell Adapter (`moonwell_adapter`)\n\n- **Type**: `MOONWELL`\n- **Module**: `wayfinder_paths.adapters.moonwell_adapter.adapter.MoonwellAdapter`\n- **Protocol**: Moonwell (Base)\n- **Capabilities**: `lending.lend`, `lending.unlend`, `lending.borrow`, `lending.repay`, `collateral.set`, `collateral.remove`, `rewards.claim`, `position.read`, `market.apy`, `market.collateral_factor`\n\nFull Moonwell integration including lending (supply/withdraw), borrowing (borrow/repay), collateral management, WELL rewards claiming, and position/market queries.\n\n**Supported Markets (Base)**:\n\n| Token | mToken Address | Underlying Address |\n|-------|----------------|-------------------|\n| USDC | `0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22` | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |\n| WETH | `0x628ff693426583D9a7FB391E54366292F509D457` | `0x4200000000000000000000000000000000000006` |\n| wstETH | `0x627Fe393Bc6EdDA28e99AE648fD6fF362514304b` | `0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452` |\n\nSee [moonwell.md](moonwell.md) for details.\n\n### Multicall Adapter (`multicall_adapter`)\n\n- **Type**: `MULTICALL`\n- **Module**: `wayfinder_paths.adapters.multicall_adapter.adapter.MulticallAdapter`\n- **Protocol**: EVM batch calls\n- **Capabilities**: `multicall.aggregate`\n\nBatches multiple on-chain read calls into a single RPC request for efficiency.\n\n### Pendle Adapter (`pendle_adapter`)\n\n- **Type**: `PENDLE`\n- **Module**: `wayfinder_paths.adapters.pendle_adapter.adapter.PendleAdapter`\n- **Protocol**: Pendle\n- **Capabilities**: `pendle.markets.read`, `pendle.market.snapshot`, `pendle.market.history`, `pendle.prices.ohlcv`, `pendle.prices.assets`, `pendle.swap.quote`, `pendle.swap.best_pt`, `pendle.swap.execute`, `pendle.convert.quote`, `pendle.convert.best_pt`, `pendle.convert.execute`, `pendle.positions.database`, `pendle.limit_orders.taker.read`, `pendle.limit_orders.maker.read`, `pendle.limit_orders.maker.write`, `pendle.deployments.read`, `pendle.router_static.rates`\n\nComprehensive Pendle integration for PT/YT market discovery, historical metrics, execution planning, swap quotes, and limit orders via the Pendle Hosted SDK.\n\nSee [pendle.md](pendle.md) for details.\n\n### Uniswap Adapter (`uniswap_adapter`)\n\n- **Type**: `UNISWAP`\n- **Module**: `wayfinder_paths.adapters.uniswap_adapter.adapter.UniswapAdapter`\n- **Protocol**: Uniswap V3 (concentrated liquidity)\n- **Capabilities**: `uniswap.liquidity.add`, `uniswap.liquidity.increase`, `uniswap.liquidity.remove`, `uniswap.fees.collect`, `uniswap.position.get`, `uniswap.positions.list`, `uniswap.fees.uncollected`, `uniswap.pool.get`\n\nProvides Uniswap V3 LP position reads and liquidity/fee management.\n\nSee [uniswap.md](uniswap.md) for details.\n\n### ProjectX Adapter (`projectx_adapter`)\n\n- **Type**: `PROJECTX`\n- **Module**: `wayfinder_paths.adapters.projectx_adapter.adapter.ProjectXLiquidityAdapter`\n- **Protocol**: ProjectX (Uniswap V3 fork on HyperEVM)\n- **Capabilities**: `projectx.pool.overview`, `projectx.positions.list`, `projectx.liquidity.mint`, `projectx.liquidity.increase`, `projectx.liquidity.decrease`, `projectx.fees.collect`, `projectx.position.burn`, `projectx.swap.exact_in`\n\nProvides concentrated liquidity reads and execution on ProjectX, plus exact-in swaps.\n\nSee [projectx.md](projectx.md) for details.\n\n### Pool Adapter (`pool_adapter`)\n\n- **Type**: `POOL`\n- **Module**: `wayfinder_paths.adapters.pool_adapter.adapter.PoolAdapter`\n- **Protocol**: DeFi Llama pool data\n- **Capabilities**: `pool.read`, `pool.discover`\n\nProvides pool information, yield analytics via DeFi Llama integration, and pool discovery with filtering.\n\n```bash\npoetry run wayfinder resource wayfinder://adapters/pool_adapter\n```\n\n### Token Adapter (`token_adapter`)\n\n- **Type**: `TOKEN`\n- **Module**: `wayfinder_paths.adapters.token_adapter.adapter.TokenAdapter`\n- **Protocol**: Token metadata service\n- **Capabilities**: `token.read`, `token.price`, `token.gas`\n\nProvides token metadata (address, decimals, symbol), live price data, and gas token lookups by chain.\n\n```bash\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base\npoetry run wayfinder resource wayfinder://tokens/search/base/usdc\npoetry run wayfinder resource wayfinder://tokens/gas/base\n```\n\n---\n\n## Presenting Adapter Data to Users\n\nAdapters return raw JSON results. When presenting this data to users, follow these patterns to make the information clear and actionable.\n\n### Balance Presentation\n\nWhen showing `resource wayfinder://balances/{label}` results:\n\n- **Group by chain** — show Base tokens, Arbitrum tokens, etc. as separate sections\n- **Lead with USD value** — users care about dollar amounts first, then token quantities\n- **Hide dust** — tokens worth less than $0.01 are noise; mention their count but don't list them\n- **Show totals** — always include a total portfolio value across all chains\n\nExample format:\n```\nBase ($2,450.32)\n  1,200.00 USDC     $1,200.00\n  0.5123   ETH      $1,230.32\n  150.00   USDbC    $20.00\n\nArbitrum ($500.00)\n  500.00   USDC     $500.00\n\nTotal: $2,950.32 across 2 chains (3 dust tokens hidden)\n```\n\n### Token Resolution Presentation\n\nWhen showing `resource wayfinder://tokens/search/{chain}/{query}` results:\n\n- **Show top 3-5 matches** with their full token ID, chain, and contract address\n- **Highlight the best match** if the score is significantly higher than others\n- **Always show the canonical ID** that the user should use in subsequent commands\n\n### Swap Quote Presentation\n\nWhen showing `quote_swap` results:\n\n- **Show the exchange rate** — e.g., \"1 ETH = 2,460.50 USDC\"\n- **Show price impact** — if available in the quote response\n- **Show fees** — gas cost estimate, protocol fees, bridge fees (if cross-chain)\n- **Show the net amount received** — this is what the user ultimately cares about\n- **Compare to mid price** — if you have `mid_prices` data, show how the quote compares\n\n### Strategy Status Presentation\n\nWhen showing `run_strategy --action status` results:\n\n- **Show current positions** — what's deployed and where\n- **Show P&L** — unrealized gains/losses if available\n- **Show APY** — current yield rate\n- **Show health** — any warnings (low health factor, approaching liquidation, etc.)\n\n### Hyperliquid State Presentation\n\nWhen showing `resource wayfinder://hyperliquid/{label}/state` results:\n\n- **Separate perp positions from account summary** — show margin, equity, and unrealized PnL at the top, then list positions\n- **Per-position details** — coin, side, size, entry price, mark price, unrealized PnL, leverage\n- **Funding rate context** — if showing positions, include current funding rate so the user knows their carry cost/income\n\n### Error Presentation\n\nSee the Error Handling section in the main SKILL.md for how to translate error codes into user-friendly messages with actionable recovery steps.\n\n### General Principles\n\n1. **Numbers need context** — raw wei amounts or 18-decimal values are useless. Always convert to human-readable amounts.\n2. **Currency formatting** — use commas for thousands, 2 decimal places for USD, appropriate decimals for crypto (4 for ETH, 2 for stablecoins, 6+ for micro-cap).\n3. **Timestamps** — convert Unix timestamps to relative time (\"2 hours ago\") or readable dates.\n4. **Addresses** — truncate to `0x1234...abcd` unless the user needs the full address.\n5. **Status indicators** — use clear labels: \"Active\", \"Pending\", \"Failed\" rather than numeric status codes.\n6. **Chain labels** — always include the chain name next to token amounts when showing multi-chain data.\n\nFile v0.4.1:references/boros.md\n\n# Boros\n\n## Overview\n\nBoros provides fixed-rate markets on Arbitrum. It allows locking in a fixed funding rate for delta-neutral strategies, removing variable rate risk.\n\n- **Type**: `BOROS`\n- **Module**: `wayfinder_paths.adapters.boros_adapter.adapter.BorosAdapter`\n- **Capabilities**: `market.read`, `market.quote`, `position.open`, `position.close`, `collateral.deposit`, `collateral.withdraw`\n\n## Market Data\n\n```bash\n# Describe Boros adapter\npoetry run wayfinder resource wayfinder://adapters/boros_adapter\n\n# Discover positions\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"boros\"]'\n```\n\n## Execution\n\nBoros operations are executed via one-off scripts:\n\n```bash\n# Run a Boros script (dry run)\npoetry run wayfinder run_script --script_path .wayfinder_runs/boros_lock_rate.py --wallet_label main\n\n# Run live\npoetry run wayfinder run_script --script_path .wayfinder_runs/boros_lock_rate.py --wallet_label main --force\n```\n\n### Script Example\n\n```python\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.boros_adapter import BorosAdapter\n\nadapter = get_adapter(BorosAdapter, \"main\")\nmarkets = await adapter.discover_markets()\n```\n\n## Key Concepts\n\n- **Yield Units (YU)**: The core trading unit. 1 YU ≈ $1 for USDT collateral; 1 YU = 1 HYPE (at unit price) for HYPE collateral. YU sizing is determined by margin formula, not 1:1 with collateral.\n- **Implied APR**: The orderbook price — what the market expects the rate to be.\n- **Underlying APR**: The actual funding rate that settles (e.g., Hyperliquid hourly funding).\n- **Settlement cadence**: Mirrors the underlying venue — hourly for Hyperliquid, 8-hour for Binance/OKX. Must sample funding and rates on the same cadence.\n- **Margin types**: **Cross** (shared across all positions) vs **Isolated** (locked to a specific market).\n- **Collateral types**: WBTC (1), WETH (2), USDT (3), BNB (4), HYPE (5).\n- **Funding sign convention**: Negative = shorts pay longs (longs receive). Positive = longs pay shorts.\n\n### Rate Locking Recipes\n\n- **Short hedge** (you're short a perp with positive funding): Open a **SHORT YU** on Boros to lock fixed funding you're paying.\n- **Long hedge** (you're long a perp with positive funding): Open a **LONG YU** on Boros to lock fixed funding payment.\n- \"Current rate\" = `BorosMarketQuote.mid_apr` — always fetch fresh via adapter.\n\n## High-Value Reads\n\nAll BorosAdapter methods return `tuple[bool, result]` — always unpack. All fields use **snake_case** (not camelCase).\n\n| Method | Purpose | Best For |\n|--------|---------|----------|\n| `list_tenor_quotes(underlying_symbol, platform)` | Fast market+rate snapshot (no orderbooks) | Quick tenor-level APR scan |\n| `quote_market(market)` / `quote_market_by_id(market_id)` | Detailed APR quote with orderbook data | Single market analysis |\n| `quote_markets_for_underlying(underlying_symbol)` | Quotes across all tenors for an underlying | Tenor curve building |\n| `list_markets()` / `list_markets_all()` | Discover all markets (auto-paginates) | Market discovery |\n| `get_orderbook(market_id, tick_size)` | Raw orderbook snapshot | Slippage estimation |\n| `get_assets()` / `get_asset_by_token_id(token_id)` | Collateral asset addresses and metadata | Token address lookups |\n| `list_available_underlyings(active_only)` | Unique underlying symbols with market counts | What's tradeable |\n| `list_markets_by_collateral(token_id)` | Filter markets by collateral type | Collateral-specific queries |\n| `get_enriched_market(market_id)` | Single market with all metadata joined | Full market context |\n| `get_market_history(market_id, time_frame)` | OHLCV + rate history (`5m`, `1h`, `1d`, `1w`) | Historical analysis |\n\n### Quote Fields (BorosMarketQuote)\n\n- `mid_apr`, `best_bid_apr`, `best_ask_apr` — current implied fixed rates\n- `mark_apr`, `floating_apr`, `long_yield_apr` — mark and floating rates\n- `funding_7d_ma_apr`, `funding_30d_ma_apr` — moving averages\n- `volume_24h`, `notional_oi`, `asset_mark_price` — market data\n\n### Account State Reads (MUST check before trading)\n\n**Always fetch current state before suggesting or executing any Boros trade:**\n\n| Method | Purpose |\n|--------|---------|\n| `get_active_positions()` | Existing rate positions |\n| `get_account_balances(token_id)` | Collateral summary (isolated/cross/total) |\n| `get_collaterals()` | Full raw collateral data |\n| `get_open_limit_orders()` | Pending limit orders |\n| `get_withdrawal_status()` / `get_pending_withdrawal_amount()` | Withdrawal state |\n\n**Why check first:** Avoid duplicate positions, unnecessary deposits, or trading with pending withdrawals.\n\n## Collateral Types\n\n| token_id | Token | Decimals | How to acquire on Arbitrum |\n|----------|-------|----------|---------------------------|\n| 1 | WBTC | 8 | BRAP swap |\n| 2 | WETH | 18 | BRAP swap |\n| 3 | USDT | 6 | BRAP swap to `usdt0-arbitrum` |\n| 4 | BNB | 18 | BRAP swap |\n| 5 | HYPE | 18 | OFT bridge from HyperEVM |\n\nEach market accepts a specific collateral — check `market[\"tokenId\"]` to know which one. Use `get_assets()` or `get_asset_by_token_id()` to get token addresses dynamically.\n\n## YU Sizing (critical for order placement)\n\n| Collateral | YU Meaning | $50 Position |\n|------------|------------|--------------|\n| USDT (token_id=3) | 1 YU ≈ $1 | `size_yu = 50` |\n| HYPE (token_id=5) | 1 YU = 1 HYPE | `size_yu = 50 / hype_price` |\n\n**Do NOT** set `target_yu = deposit_amount` — collateral does not cap YU 1:1. Max YU is determined by the margin formula. Apply a safety buffer (e.g., 50-70% of theoretical max) to avoid liquidation.\n\n## Rate Locking Flow\n\n1. **Pre-trade check** — Always fetch positions, balances, and collateral state first\n2. **Discover markets** — Find available markets and tenors\n3. **Get quote** — Check current fixed rates for your desired size (`mid_apr`)\n4. **Check market collateral type** → acquire collateral if needed\n5. **Deposit collateral** — Fund your Boros margin account\n6. **Sweep isolated→cross** — If deposits land in isolated, sweep with `cash_transfer`\n7. **Place order** — `place_rate_order(market_id, token_id, size_yu_wei, side, ...)`\n8. **Monitor** — Track position until expiry or early close\n\n## Gotchas\n\n- **Units are not uniform**: Different calls use different decimals — native decimals vs 1e18 cash units vs YU. Always check what each method expects.\n- **Collateral vs YU sizing**: Deposited collateral does NOT cap YU 1:1. Max YU is determined by margin formula.\n- **Withdrawal cooldowns**: Withdrawals are two-step — request → cooldown period → finalize. Monitor withdrawal status.\n- **Isolated cash issue**: Deposits can land in isolated margin even when requesting cross. Sweep with `cash_transfer`.\n- **Min cross cash**: Some actions require minimum cross cash (`MMInsufficientMinCash` error).\n- **Calldata sequencing**: Multi-tx payloads must execute sequentially (approve → deposit → place). Never parallelize.\n- **Tick math**: Use adapter helpers for tick↔rate conversions. Don't compute manually.\n- **Chain**: Boros operates on Arbitrum (42161). Ensure your wallet has Arbitrum ETH for gas.\n- **HYPE acquisition paths**: Either BRAP→HyperEVM HYPE→OFT bridge, or Hyperliquid spot→HyperEVM→OFT bridge. OFT bridge requires `msg.value = amount + fee`, amounts rounded to `decimalConversionRate()`.\n- **Markets endpoint**: `marketId` queries return lists. Underlying symbol lives at `metadata.assetSymbol`.\n- **Funding sign convention**: Negative = shorts pay longs. Positive = longs pay shorts. Get this wrong and your hedge is backwards.\n\nFile v0.4.1:references/ccxt.md\n\n# CCXT (Centralized Exchanges)\n\n## Overview\n\nThe SDK includes a `ccxt_adapter` that acts as a **multi-exchange factory** for centralized exchanges (CEXes). Each configured exchange becomes a property on the adapter (e.g. `adapter.aster`, `adapter.binance`), and you call the CCXT unified API on that exchange object.\n\n- **Type**: `CCXT`\n- **Module**: `wayfinder_paths.adapters.ccxt_adapter.adapter.CCXTAdapter`\n- **Capabilities**: `exchange.factory`\n\n## When to use (and when not to)\n\n- Use for CEX workflows (Aster, Binance, etc.) **when the user has API credentials** and explicitly wants centralized exchange data or trading.\n- Do **not** use CCXT for Hyperliquid by default. Prefer the native Wayfinder Hyperliquid surfaces (`hyperliquid` resources + `hyperliquid_execute`) unless the user explicitly asks for CCXT/Hyperliquid.\n\n## Config (`config.json`)\n\nAdd a `ccxt` section with exchange IDs and credentials (exchange IDs must match CCXT exchange ids):\n\n```json\n{\n  \"ccxt\": {\n    \"aster\": { \"apiKey\": \"…\", \"secret\": \"…\" },\n    \"binance\": { \"apiKey\": \"…\", \"secret\": \"…\", \"enableRateLimit\": true },\n    \"hyperliquid\": { \"walletAddress\": \"0x...\", \"privateKey\": \"0x...\" }\n  }\n}\n```\n\nNotes:\n- Credentials are passed straight through to each CCXT exchange constructor; exchange-specific params (e.g. `password`, `uid`, `options`) are supported.\n- Exchange IDs must match CCXT’s exchange ids (e.g. `binance`, `bybit`, `aster`, `hyperliquid`).\n\n### Credentials quick reference\n\n| Exchange | Required params |\n|----------|----------------|\n| binance | `apiKey`, `secret` |\n| hyperliquid | `walletAddress`, `privateKey` |\n| aster | `apiKey`, `secret` |\n| bybit | `apiKey`, `secret` |\n| dydx | `apiKey`, `secret`, `password` |\n\n## Init patterns\n\n### Config-driven (recommended)\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        ticker = await adapter.binance.fetch_ticker(\"BTC/USDT\")\n        print(ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\n### Explicit exchanges kwarg (no `config.json` required)\n\n```python\nimport asyncio\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = CCXTAdapter(exchanges={\"aster\": {}, \"binance\": {}})\n    try:\n        ticker = await adapter.aster.fetch_ticker(\"ETH/USDT\")\n        print(ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\nThe `exchanges=` kwarg takes priority over `config[\"ccxt\"]`.\n\n## Running CCXT scripts\n\nCCXT is not exposed as a top-level `poetry run wayfinder` command. Use a one-off script via `run_script`.\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        ticker = await adapter.aster.fetch_ticker(\"ETH/USDT\")\n        print(ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\nRun it:\n\n```bash\npoetry run wayfinder run_script --script_path .wayfinder_runs/ccxt_ticker.py --wallet_label main\n```\n\n## Examples\n\n### Multi-exchange comparison\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        binance = await adapter.binance.fetch_ticker(\"ETH/USDT\")\n        aster = await adapter.aster.fetch_ticker(\"ETH/USDT\")\n        print(\"Binance:\", binance.get(\"last\"))\n        print(\"Aster:  \", aster.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\n### Hyperliquid via CCXT (when explicitly requested)\n\nHyperliquid defaults to swap/perps in CCXT; perp symbols use the `:USDC` suffix:\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        ticker = await adapter.hyperliquid.fetch_ticker(\"ETH/USDC:USDC\")\n        print(\"ETH perp last:\", ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\n## Gotchas (read before writing automation)\n\n- **Always close**: Each exchange holds open HTTP sessions; always `await adapter.close()` in a `finally`.\n- **Hyperliquid auth**: Hyperliquid CCXT uses wallet auth (`walletAddress`, `privateKey`), not `apiKey`/`secret`.\n- **Hyperliquid spot vs perp**: CCXT Hyperliquid defaults to `swap`. For spot, use spot symbols and set `params={\"type\":\"spot\"}` as needed.\n- **Symbol formats vary**: Many perps/futures use suffixes like `ETH/USDT:USDT`. Always `await exchange.load_markets()` and inspect `exchange.markets` for available symbols.\n- **Rate limits**: If you’re making many calls, set `enableRateLimit: true` (or manage concurrency yourself). Don’t double-throttle with both strict semaphores and `enableRateLimit`.\n- **`get_adapter(CCXTAdapter)` with no `ccxt` config is “empty”**: If `config.json` has no `ccxt` section, `get_adapter(CCXTAdapter)` loads zero exchanges (accessing `adapter.binance` raises `AttributeError`). For public-data-only access, construct `CCXTAdapter(exchanges={...})` directly.\n- **Prefer native Hyperliquid surfaces for reads**: For funding history/meta/orderbooks, prefer the SDK/Wayfinder Hyperliquid adapter and resources unless CCXT is explicitly required.\n- **Exchange instances are properties**: `await adapter.binance.fetch_ticker(...)` is correct; `await adapter.fetch_ticker(\"binance\", ...)` is not.\n- **Aster quirks**:\n  - Minimum order sizes can be large (e.g., BTC min ~0.001). Check `exchange.markets[symbol][\"limits\"][\"amount\"][\"min\"]` before ordering.\n  - `fetch_balance()` may underreport futures margin; don’t hard-gate execution on it.\n  - Market orders can return `status=\"open\"` and `filled=0` initially; confirm via `fetch_positions()` after a short delay.\n\n## Common CCXT calls\n\n- `fetch_ticker(symbol)` / `fetch_order_book(symbol)`\n- `fetch_balance()`\n- `create_order(symbol, \"market\"|\"limit\", \"buy\"|\"sell\", amount, price?)`\n- `cancel_order(id, symbol?)`\n- `fetch_open_orders(symbol?)`\n\nAlways `await adapter.close()` to avoid leaking sessions.\n\nFile v0.4.1:references/coding-interface.md\n\n# Coding Interface for Custom Operations\n\nUse this guide when pre-built commands aren't sufficient and you need to write custom Python scripts for complex multi-step DeFi operations.\n\n## When to Use Custom Scripts\n\n- **Multi-step atomic flows** — operations that must succeed together or not at all\n- **Custom logic** — conditional execution based on market state\n- **Batched operations** — multiple protocol interactions in sequence\n- **Complex calculations** — position sizing, rebalancing logic\n- **Protocol combinations** — bridging multiple adapters in one flow\n\n## Script Location\n\nAll scripts must live in the `.wayfinder_runs/` directory inside `$WAYFINDER_SDK_PATH` (default: `$HOME/wayfinder-paths-sdk`) (or `$WAYFINDER_RUNS_DIR`). This directory is:\n- Git-ignored (except README.md)\n- Sandboxed — `run_script` only executes scripts inside this directory\n- Session-specific — use for one-off executions, not permanent strategies\n\n```bash\nmkdir -p \"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}/.wayfinder_runs\"\n```\n\n## Referencing the SDK Source\n\nBefore writing a script, **pull the detailed reference docs** for the relevant adapter or strategy:\n\n```bash\n# Pull docs for the adapter you're using (reads from pinned SDK version in sdk-version.md)\n./wayfinder/scripts/pull-sdk-ref.sh moonwell\n./wayfinder/scripts/pull-sdk-ref.sh boros hyperliquid\n\n# Available topics: strategies, setup, boros, brap, hyperlend, hyperliquid, polymarket, moonwell, pendle, uniswap, projectx, data\n./wayfinder/scripts/pull-sdk-ref.sh --list\n\n# Check the pinned SDK version\n./wayfinder/scripts/pull-sdk-ref.sh --version\n\n# Override the pinned version for a specific pull\n./wayfinder/scripts/pull-sdk-ref.sh --commit abc123 moonwell\n```\n\nThese docs cover method signatures, unit conventions, gotchas, execution patterns, and contract addresses. **Always pull them before writing a script.**\n\nThe SDK ref is tracked in `wayfinder/sdk-version.md`. The pull script checks out that ref when reading docs, then restores the SDK to its previous state.\n\nYou can also read the adapter source code directly:\n\n```\n$WAYFINDER_SDK_PATH/wayfinder_paths/adapters/          # All adapter implementations\n$WAYFINDER_SDK_PATH/wayfinder_paths/mcp/scripting.py   # get_adapter() helper\n$WAYFINDER_SDK_PATH/wayfinder_paths/strategies/        # Strategy implementations\n```\n\nNever guess adapter method names or parameters — read the reference docs or source first.\n\n## Basic Script Structure\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nScript: my_complex_operation.py\nDescription: Brief description of what this script does\n\"\"\"\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\n\nasync def main():\n    # Your logic here\n    pass\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Using `get_adapter()`\n\nThe `get_adapter()` helper auto-wires configuration and signing:\n\n```python\nfrom wayfinder_paths.mcp.scripting import get_adapter\n\n# Pattern: get_adapter(AdapterClass, wallet_label, **config_overrides)\n\n# For write operations (need signing)\nfrom wayfinder_paths.adapters.moonwell_adapter import MoonwellAdapter\nadapter = get_adapter(MoonwellAdapter, \"main\")\n\n# For read-only operations (no wallet needed)\nfrom wayfinder_paths.adapters.pool_adapter import PoolAdapter\npool_adapter = get_adapter(PoolAdapter)\n\n# With config overrides\nadapter = get_adapter(MoonwellAdapter, \"main\", config_overrides={\"custom_key\": \"value\"})\n```\n\n### What `get_adapter()` Does\n\n1. Loads `config.json` from `$WAYFINDER_CONFIG_PATH`\n2. Finds wallet by label from `config[\"wallets\"]`\n3. Extracts `private_key_hex` and creates a signing callback\n4. Detects the adapter's signing callback parameter names\n5. Passes everything to the adapter constructor\n\n## Web3 / RPC Access\n\nIf you need raw on-chain reads/writes that aren’t exposed by an adapter, use the SDK’s chain helper:\n\n```python\nimport asyncio\n\nfrom wayfinder_paths.core.utils.web3 import web3_from_chain_id\n\nCHAIN_ID = 8453  # Base\n\n\nasync def main():\n    async with web3_from_chain_id(CHAIN_ID) as w3:\n        block = await w3.eth.block_number\n        print(\"block:\", block)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\nDo **not** hardcode RPC URLs in scripts. `web3_from_chain_id(...)` resolves RPCs from `strategy.rpc_urls` when set; otherwise it falls back to Wayfinder’s RPC proxy at `system.api_base_url` (auth via `system.api_key` / `WAYFINDER_API_KEY`).\n\n## Adapter Quick Reference\n\n### BalanceAdapter — Wallet Operations\n\n```python\nfrom wayfinder_paths.adapters.balance_adapter import BalanceAdapter\n\nadapter = get_adapter(BalanceAdapter, \"main\")\n\n# Read balances\nsuccess, balances = await adapter.get_balances(chain_id=8453)  # Base\n\n# Transfer tokens\nsuccess, result = await adapter.transfer(\n    token_address=\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",  # USDC\n    to_address=\"0x...\",\n    amount=100_000_000,  # 100 USDC (6 decimals)\n    chain_id=8453\n)\n```\n\n### TokenAdapter — Token Metadata\n\n```python\nfrom wayfinder_paths.adapters.token_adapter import TokenAdapter\n\nadapter = get_adapter(TokenAdapter)\n\n# Resolve token by ID or query\nsuccess, token = await adapter.get_token(\"usd-coin-base\")\nsuccess, token = await adapter.get_token(\"USDC\", chain_id=8453)\n\n# Get gas token for chain\nsuccess, gas_token = await adapter.get_gas_token(chain_id=8453)\n\n# Fuzzy search\nsuccess, results = await adapter.search_tokens(\"usdc\", chain_id=8453)\n```\n\n### BRAPAdapter — Swaps and Bridges\n\n```python\nfrom wayfinder_paths.adapters.brap_adapter import BRAPAdapter\n\nadapter = get_adapter(BRAPAdapter, \"main\")\n\n# Get quote\nsuccess, quote = await adapter.get_quote(\n    from_token_id=\"usd-coin-base\",\n    to_token_id=\"ethereum-base\",\n    amount=100.0,  # Human-readable\n    wallet_address=\"0x...\"\n)\n\n# Execute swap (if quote successful)\nif success and quote.get(\"best_quote\"):\n    success, result = await adapter.execute_swap(quote[\"best_quote\"])\n```\n\n### MoonwellAdapter — Lending Protocol\n\n```python\nfrom wayfinder_paths.adapters.moonwell_adapter import MoonwellAdapter\n\nadapter = get_adapter(MoonwellAdapter, \"main\")\n\n# mToken addresses (Base)\nUSDC_MTOKEN = \"0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22\"\nWETH_MTOKEN = \"0x628ff693426583D9a7FB391E54366292F509D457\"\n\n# Supply (lend)\nsuccess, result = await adapter.lend(\n    mtoken=USDC_MTOKEN,\n    amount=100_000_000  # 100 USDC in wei\n)\n\n# Set as collateral\nsuccess, result = await adapter.set_collateral(mtoken=USDC_MTOKEN)\n\n# Borrow\nsuccess, result = await adapter.borrow(\n    mtoken=WETH_MTOKEN,\n    amount=50_000_000_000_000_000  # 0.05 WETH in wei\n)\n\n# Repay\nsuccess, result = await adapter.repay(\n    mtoken=WETH_MTOKEN,\n    amount=50_000_000_000_000_000\n)\n\n# Withdraw (unlend)\nsuccess, result = await adapter.unlend(\n    mtoken=USDC_MTOKEN,\n    amount=100_000_000\n)\n```\n\n### HyperliquidAdapter — Perps Trading\n\n```python\nfrom wayfinder_paths.adapters.hyperliquid_adapter import HyperliquidAdapter\n\nadapter = get_adapter(HyperliquidAdapter, \"main\")\n\n# Get account state\nsuccess, state = await adapter.get_user_state()\n\n# Place market order\nsuccess, result = await adapter.place_order(\n    coin=\"ETH\",\n    is_buy=True,\n    sz=0.1,  # Size in base asset\n    order_type=\"market\",\n    slippage=0.01  # 1%\n)\n\n# Place limit order\nsuccess, result = await adapter.place_order(\n    coin=\"ETH\",\n    is_buy=True,\n    sz=0.1,\n    order_type=\"limit\",\n    limit_px=3000.0\n)\n\n# Update leverage\nsuccess, result = await adapter.update_leverage(\n    coin=\"ETH\",\n    leverage=5,\n    is_cross=True\n)\n\n# Close position (reduce-only)\nsuccess, result = await adapter.place_order(\n    coin=\"ETH\",\n    is_buy=False,  # Opposite of position direction\n    sz=0.1,\n    order_type=\"market\",\n    reduce_only=True\n)\n```\n\n### PendleAdapter — PT/YT Markets\n\n```python\nfrom wayfinder_paths.adapters.pendle_adapter import PendleAdapter\n\nadapter = get_adapter(PendleAdapter, \"main\")\n\n# Discover markets\nsuccess, markets = await adapter.get_markets(chain_id=8453)\n\n# Get market time series\nsuccess, series = await adapter.get_market_time_series(\n    market_address=\"0x...\",\n    chain_id=8453\n)\n\n# Execute swap via Pendle Hosted SDK\nsuccess, result = await adapter.swap(\n    market_address=\"0x...\",\n    token_in=\"0x...\",\n    token_out=\"0x...\",\n    amount_in=100_000_000,\n    chain_id=8453\n)\n```\n\n### BorosAdapter — Fixed-Rate Markets\n\n```python\nfrom wayfinder_paths.adapters.boros_adapter import BorosAdapter\n\nadapter = get_adapter(BorosAdapter, \"main\")\n\n# Discover markets\nsuccess, markets = await adapter.get_markets()\n\n# Quote a rate lock\nsuccess, quote = await adapter.quote(\n    market_id=\"...\",\n    size=1000.0,\n    direction=\"long\"  # or \"short\"\n)\n\n# Open position\nsuccess, result = await adapter.open_position(\n    market_id=\"...\",\n    size=1000.0,\n    direction=\"long\",\n    max_rate=0.10  # Max acceptable rate\n)\n```\n\n### HyperlendAdapter — HyperEVM Lending\n\n```python\nfrom wayfinder_paths.adapters.hyperlend_adapter import HyperlendAdapter\n\nadapter = get_adapter(HyperlendAdapter, \"main\")\n\n# Get market snapshot\nsuccess, snapshot = await adapter.get_market_snapshot()\n\n# Supply\nsuccess, result = await adapter.supply(\n    token=\"USDT0\",\n    amount=100_000_000  # 100 USDT0 in wei\n)\n\n# Withdraw\nsuccess, result = await adapter.withdraw(\n    token=\"USDT0\",\n    amount=100_000_000\n)\n```\n\n## Example: Complex Multi-Step Flow\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nScript: moonwell_supply_and_borrow.py\nDescription: Supply USDC as collateral and borrow ETH on Moonwell\n\"\"\"\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.moonwell_adapter import MoonwellAdapter\n\nUSDC_MTOKEN = \"0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22\"\nWETH_MTOKEN = \"0x628ff693426583D9a7FB391E54366292F509D457\"\n\nasync def main():\n    adapter = get_adapter(MoonwellAdapter, \"main\")\n\n    # Step 1: Supply USDC\n    print(\"Supplying 100 USDC...\")\n    success, result = await adapter.lend(mtoken=USDC_MTOKEN, amount=100_000_000)\n    if not success:\n        print(f\"Supply failed: {result}\")\n        return\n    print(f\"Supply tx: {result}\")\n\n    # Step 2: Enable as collateral\n    print(\"Enabling USDC as collateral...\")\n    success, result = await adapter.set_collateral(mtoken=USDC_MTOKEN)\n    if not success:\n        print(f\"Set collateral failed: {result}\")\n        return\n    print(f\"Collateral tx: {result}\")\n\n    # Step 3: Borrow ETH (conservative amount)\n    print(\"Borrowing 0.01 ETH...\")\n    success, result = await adapter.borrow(mtoken=WETH_MTOKEN, amount=10_000_000_000_000_000)\n    if not success:\n        print(f\"Borrow failed: {result}\")\n        return\n    print(f\"Borrow tx: {result}\")\n\n    print(\"Done! Position opened successfully.\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Example: Conditional Execution Based on Market State\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nScript: conditional_swap.py\nDescription: Only swap if price is favorable\n\"\"\"\nimport asyncio\nfrom decimal import Decimal\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.brap_adapter import BRAPAdapter\nfrom wayfinder_paths.adapters.token_adapter import TokenAdapter\n\nTARGET_RATE = Decimal(\"2500\")  # Only swap if ETH < $2500\n\nasync def main():\n    brap = get_adapter(BRAPAdapter, \"main\")\n    token = get_adapter(TokenAdapter)\n\n    # Get current ETH price\n    success, eth_token = await token.get_token(\"ethereum-base\")\n    if not success:\n        print(f\"Failed to get ETH token: {eth_token}\")\n        return\n\n    current_price = Decimal(str(eth_token.get(\"price_usd\", 0)))\n    print(f\"Current ETH price: ${current_price}\")\n\n    if current_price >= TARGET_RATE:\n        print(f\"Price ${current_price} >= target ${TARGET_RATE}, skipping swap\")\n        return\n\n    # Price is favorable, get quote\n    success, quote = await brap.get_quote(\n        from_token_id=\"usd-coin-base\",\n        to_token_id=\"ethereum-base\",\n        amount=100.0,\n        wallet_address=\"0x...\"  # Your address\n    )\n\n    if not success:\n        print(f\"Quote failed: {quote}\")\n        return\n\n    print(f\"Quote received: {quote}\")\n\n    # Execute swap\n    if quote.get(\"best_quote\"):\n        success, result = await brap.execute_swap(quote[\"best_quote\"])\n        print(f\"Swap result: {result}\" if success else f\"Swap failed: {result}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n## Running Scripts\n\n**Always test before live execution.** Follow this workflow:\n\n### 1. Safe Run (recommended)\n\n```bash\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\ncd \"$WAYFINDER_SDK_PATH\"\n\n# Recommended: implement your own --dry-run / --force flags inside the script\npoetry run wayfinder run_script --script_path .wayfinder_runs/my_script.py --args '[\"--dry-run\"]' --wallet_label main\n```\n\nReview the output carefully — verify operations, amounts, and addresses are correct.\n\n### 2. Live Execution (only after safe run passes)\n\n```bash\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\ncd \"$WAYFINDER_SDK_PATH\"\npoetry run wayfinder run_script --script_path .wayfinder_runs/my_script.py --args '[\"--force\"]' --wallet_label main\n```\n\n**Never skip the safe-run step for scripts that move funds.**\n\n### 3. Direct Execution (bypasses sandbox — use sparingly)\n\n```bash\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\ncd \"$WAYFINDER_SDK_PATH\"\npoetry run python .wayfinder_runs/my_script.py\n```\n\n## Return Pattern Convention\n\nAll adapter mutation methods return `(success: bool, result_or_error: Any)`:\n\n```python\nsuccess, result = await adapter.some_method(...)\nif success:\n    # result contains the data (tx hash, response object, etc.)\n    print(f\"Success: {result}\")\nelse:\n    # result contains error message\n    print(f\"Error: {result}\")\n```\n\n## Error Handling Best Practices\n\n```python\nasync def safe_operation():\n    adapter = get_adapter(SomeAdapter, \"main\")\n\n    success, result = await adapter.risky_operation()\n    if not success:\n        # Log error, don't proceed\n        print(f\"Operation failed: {result}\")\n        return None\n\n    # Continue with next step\n    return result\n```\n\n## Environment Variables\n\nScripts inherit these from the execution environment:\n\n| Variable | Purpose |\n|----------|---------|\n| `WAYFINDER_CONFIG_PATH` | Path to config.json |\n| `WAYFINDER_RUNS_DIR` | Override runs directory |\n| `WAYFINDER_API_KEY` | Fallback API key |\n\n## Security Notes\n\n1. **Scripts are sandboxed** — only `.wayfinder_runs/` scripts can be executed via `run_script`\n2. **Private keys stay in config.json** — never hardcode keys in scripts\n3. **Safe run first** — implement a non-fund-moving mode in your script and run it before `--force`\n4. **Review before execution** — safety hooks show confirmation prompts for fund-moving operations\n\nFile v0.4.1:references/hyperlend.md\n\n# HyperLend\n\n## Overview\n\nHyperLend is a lending protocol on HyperEVM. It provides stablecoin lending yield with straightforward supply/withdraw mechanics.\n\n- **Type**: `HYPERLEND`\n- **Module**: `wayfinder_paths.adapters.hyperlend_adapter.adapter.HyperlendAdapter`\n- **Capabilities**: `market.stable_markets`, `market.assets_view`, `market.rate_history`, `lending.lend`, `lending.unlend`\n\n## Market Data\n\n```bash\n# Describe HyperLend adapter\npoetry run wayfinder resource wayfinder://adapters/hyperlend_adapter\n\n# Discover positions\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"hyperlend\"]'\n```\n\n### High-Value Reads\n\n| Method | Purpose | Output |\n|--------|---------|--------|\n| `get_stable_markets(chain_id, ...)` | Opportunity list | `list[StableMarket]` — `chain_id`, `token_address`, `symbol`, liquidity/buffer fields |\n| `get_assets_view(chain_id, user_address)` | Portfolio view | `AssetsView` — `assets: list[dict]`, optional `total_value` |\n| `get_lend_rate_history(chain_id, token_address, lookback_hours)` | Rate time series | `LendRateHistory` — `rates: list[dict]` (timestamped records) |\n\n### Data Accuracy\n\n- Only report values fetched from HyperLend endpoints (`market_entry`, `lend_rate_history`). Do **not** estimate or invent APYs.\n- HyperlendClient methods use `_authed_request(...)` even for `/public/hyperlend/*` routes — auth via `config.json` or env vars is always required.\n\n## Execution\n\nHyperLend operations are executed via one-off scripts:\n\n```bash\n# Run a HyperLend script (dry run)\npoetry run wayfinder run_script --script_path .wayfinder_runs/hyperlend_supply.py --wallet_label main\n\n# Run live\npoetry run wayfinder run_script --script_path .wayfinder_runs/hyperlend_supply.py --wallet_label main --force\n```\n\n### Script Example (lend)\n\n```python\nimport asyncio\n\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.hyperlend_adapter import HyperlendAdapter\n\nCHAIN_ID = 999  # HyperEVM\nUNDERLYING_TOKEN = \"0x...\"  # HyperEVM underlying token address\nQTY = 100_000_000  # raw base units (example only)\n\n\nasync def main():\n    adapter = get_adapter(HyperlendAdapter, \"main\")\n    ok, tx_hash = await adapter.lend(\n        underlying_token=UNDERLYING_TOKEN,\n        qty=QTY,\n        chain_id=CHAIN_ID,\n    )\n    print(ok, tx_hash)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Execution Methods\n\n| Method | Purpose | Notes |\n|--------|---------|-------|\n| `lend(underlying_token, qty, chain_id, native=False)` | Supply to HyperLend | `qty` is raw int (wei); handles ERC20 approval automatically |\n| `unlend(underlying_token, qty, chain_id, native=False)` | Withdraw from HyperLend | Same unit rules as `lend` |\n\n### Unit Conversion Best Practice\n\n1. Resolve token decimals via TokenClient\n2. Convert human-readable → raw int units\n3. Call `lend`/`unlend` with raw units\n\n## HyperLend Stable Yield Strategy\n\nFor automated yield on HyperLend, use the dedicated strategy:\n\n```bash\npoetry run wayfinder run_strategy --strategy hyperlend_stable_yield_strategy --action status\npoetry run wayfinder run_strategy --strategy hyperlend_stable_yield_strategy --action analyze --amount_usdc 100\npoetry run wayfinder run_strategy --strategy hyperlend_stable_yield_strategy --action deposit --main_token_amount 100 --gas_token_amount 0.1\npoetry run wayfinder run_strategy --strategy hyperlend_stable_yield_strategy --action update\n```\n\n## Gotchas\n\n- **Chain**: HyperLend runs on HyperEVM. Ensure your wallet has HyperEVM gas tokens.\n- **RPC resolution**: Don’t hardcode RPC URLs in scripts. The SDK resolves JSON-RPC via `web3_from_chain_id(999)` using `strategy.rpc_urls` when set, otherwise it falls back to Wayfinder’s RPC proxy at `system.api_base_url` (auth via `system.api_key` / `WAYFINDER_API_KEY`).\n- **Units are raw ints**: `lend`/`unlend` expect **raw integer units** (wei for ERC20). Do not pass floats or human-readable values directly.\n- **Supported assets**: Primarily stablecoins (USDT0). Check market snapshots for current offerings.\n- **No guessing yields**: Do not claim extra yield sources (e.g. \"~3-4% staking APY\") unless fetched from a concrete data source. Rates change frequently.\n\nFile v0.4.1:references/hyperliquid.md\n\n# Hyperliquid\n\n## Overview\n\nHyperliquid is a decentralized perpetuals exchange with spot trading. The Hyperliquid adapter provides comprehensive trading capabilities.\n\n- **Type**: `HYPERLIQUID`\n- **Module**: `wayfinder_paths.adapters.hyperliquid_adapter.adapter.HyperliquidAdapter`\n- **Capabilities**: `market.read`, `market.meta`, `market.funding`, `market.candles`, `market.orderbook`, `order.execute`, `order.cancel`, `position.manage`, `transfer`, `withdraw`\n\n## Market Data (via Resources)\n\n```bash\n# For any of the commands make sure you are in the SDK dir\ncd \"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\n\n# Perp positions + PnL\npoetry run wayfinder resource wayfinder://hyperliquid/main/state\n\n# Spot balances on Hyperliquid\npoetry run wayfinder resource wayfinder://hyperliquid/main/spot\n\n# All mid prices\npoetry run wayfinder resource wayfinder://hyperliquid/prices\n\n# Single coin price\npoetry run wayfinder resource wayfinder://hyperliquid/prices/ETH\n\n# Funding rates + metadata for all assets\npoetry run wayfinder resource wayfinder://hyperliquid/markets\n\n# Spot asset metadata\npoetry run wayfinder resource wayfinder://hyperliquid/spot-assets\n\n# Order book\npoetry run wayfinder resource wayfinder://hyperliquid/book/ETH\n```\n\n### High-Value Read Methods\n\n| Method | Purpose |\n|--------|---------|\n| `get_meta_and_asset_ctxs()` | Perp market metadata + contexts (enumerate markets, map asset_id↔coin) |\n| `get_spot_meta()` | Spot metadata (tokens + universe pairs) |\n| `get_spot_assets()` | Spot asset mapping (e.g. `{\"HYPE/USDC\": 10107}`) |\n| `get_l2_book(coin)` | Perp/spot order book by coin string |\n| `get_spot_l2_book(spot_asset_id)` | Spot order book by asset ID |\n| `get_user_state(address)` | Perp account state |\n| `get_spot_user_state(address)` | Spot balances |\n| `get_open_orders(address)` | Open orders |\n| `get_frontend_open_orders(address)` | Open + trigger orders |\n| `get_user_fills(address)` | Recent fills |\n| `get_order_status(address, order_id)` | Single order status |\n\n### Funding History\n\nThere is **no** `HyperliquidAdapter.get_funding_history()` method. Use one of:\n- **Wayfinder API** (preferred): `HyperliquidDataClient.get_funding_history(coin, start_ms, end_ms)`\n- **SDK direct**: `adapter.info.funding_history(name, startTime, endTime)` (milliseconds, not async)\n\n### Hyperliquid deposits + withdrawals (Bridge2)\n\nThis repo uses Hyperliquid’s **Bridge2** deposit/withdraw flow and assumes **Arbitrum (chain_id = 42161)** as the EVM side.\n\n**TL;DR:** To deposit to Hyperliquid, you send **native USDC on Arbitrum** to the Hyperliquid Bridge2 address. Do **not** send USDC from other chains or other assets.\n\nPrimary reference:\n- Hyperliquid docs: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/bridge2\n- Funding cadence (hourly): https://hyperliquid.gitbook.io/hyperliquid-docs/trading/funding\n\n## What you can deposit/withdraw\n\n- **Deposit asset:** native **USDC on Arbitrum**\n  - This repo’s constant: `ARBITRUM_USDC_ADDRESS = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831`\n- **Deposit target:** Bridge2 address on Arbitrum\n  - This repo’s constant: `HYPERLIQUID_BRIDGE_ADDRESS = 0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7`\n\n## Minimums, fees + timing (operational expectations)\n\nFrom Hyperliquid's Bridge2 docs:\n- **Minimum deposit is 5 USDC**; deposits below that are **lost**.\n- Deposits are typically credited **in < 1 minute**.\n- Withdrawals typically arrive **in several minutes** (often longer than deposits).\n- **Withdrawal fee is $1 USDC** — deducted from the withdrawn amount (e.g., withdraw $6.93 → receive $5.93).\n\nTreat these as *best-effort expectations*, not guarantees. In orchestration code, always:\n- poll for confirmation\n- time out safely\n- avoid taking downstream risk (hedges/allocations) until funds are confirmed\n\n## Who gets credited (common pitfall)\n\nBaseline Bridge2 deposit behavior:\n- **The Hyperliquid account credited is the sender** of the Arbitrum USDC transfer to the bridge address.\n\nBridge2 also supports “deposit on behalf” via a permit flow (`batchedDepositWithPermit`) per the docs, but this repo’s strategy patterns assume the simple “send USDC to bridge” path.\n\n## How to monitor deposits/withdrawals\n\nAdapter: `wayfinder_paths/adapters/hyperliquid_adapter/adapter.py`\n\n### Deposit initiation\n\nBash shortcut:\n```bash\npoetry run wayfinder execute --kind hyperliquid_deposit --wallet_label main --amount 8\n```\n\nThis hard-codes:\n- token: native Arbitrum USDC (`usd-coin-arbitrum`)\n- recipient: `HYPERLIQUID_BRIDGE_ADDRESS`\n- chain: Arbitrum (42161)\n\n### Withdrawal initiation\n\n- Call: `HyperliquidAdapter.withdraw(amount, address)` (USDC withdraw to Arbitrum via executor)\n\nBash shortcut:\n```bash\npoetry run wayfinder hyperliquid_execute --action withdraw --wallet_label main --amount_usdc 100\n```\n\n### Deposit monitoring (recommended)\n\n- Call: `HyperliquidAdapter.wait_for_deposit(address, expected_increase, timeout_s=..., poll_interval_s=...)`\n- Mechanism: polls `get_user_state(address)` and checks perp margin increase.\n\nBash shortcut:\n```bash\npoetry run wayfinder hyperliquid --action wait_for_deposit --wallet_label main --expected_increase 100 --timeout_s 300\n```\n\n### Withdrawal monitoring (best-effort)\n\n- Call: `HyperliquidAdapter.wait_for_withdrawal(address, max_poll_time_s=..., poll_interval_s=...)`\n- Mechanism: polls Hyperliquid ledger updates for a `withdraw` record.\n\nBash shortcut:\n```bash\npoetry run wayfinder hyperliquid --action wait_for_withdrawal --wallet_label main\n```\n\nIf you need strict \"arrived on Arbitrum\" confirmation, add an Arbitrum-side receipt check (RPC/Explorer) for the resulting tx hash.\n\n## Orchestration tips\n\n- **Hyperliquid funding is paid hourly**; if you're rate-locking funding with Boros, align your observations to this cadence.\n- Prefer explicit \"funding stages\" in strategies:\n  1) deposit to Hyperliquid\n  2) wait for credit\n  3) open/adjust hedge\n  4) only then deploy spot/yield legs\n\n\n## Trading\n\n### Market Orders\n\n```bash\n# Market buy\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin ETH --is_buy true --usd_amount 200 --usd_amount_kind margin --leverage 5\n\n# Market sell / short\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin ETH --is_buy false --usd_amount 200 --usd_amount_kind margin --leverage 5\n```\n\n### Limit Orders\n\n```bash\n# Limit buy\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin ETH --is_buy true --size 0.1 --price 3000 --order_type limit\n\n# Limit sell\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin ETH --is_buy false --size 0.1 --price 4000 --order_type limit\n```\n\n### Close Position\n\n```bash\n# Close with reduce-only\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin ETH --is_buy false --size 0.5 --reduce_only\n```\n\n### Leverage\n\n```bash\n# Update leverage (cross margin)\npoetry run wayfinder hyperliquid_execute --action update_leverage --wallet_label main \\\n  --coin ETH --leverage 5 --is_cross\n\n# Update leverage (isolated margin)\npoetry run wayfinder hyperliquid_execute --action update_leverage --wallet_label main \\\n  --coin ETH --leverage 5 --no-is_cross\n```\n\n### Cancel Orders\n\n```bash\n# Cancel by order ID\npoetry run wayfinder hyperliquid_execute --action cancel_order --wallet_label main \\\n  --coin ETH --order_id 12345\n\n# Cancel by client order ID\npoetry run wayfinder hyperliquid_execute --action cancel_order --wallet_label main \\\n  --coin ETH --cancel_cloid my-order-1\n```\n\n## Transfers\n\n### Internal Transfers\n\nUSDC transfers between spot and perp wallets are available via `hyperliquid_execute`:\n\n```bash\n# Move USDC from spot wallet to perp wallet\npoetry run wayfinder hyperliquid_execute --action spot_to_perp_transfer --wallet_label main --amount_usdc 50\n\n# Move USDC from perp wallet to spot wallet\npoetry run wayfinder hyperliquid_execute --action perp_to_spot_transfer --wallet_label main --amount_usdc 50\n```\n\n> **Note:** Other internal transfers (HyperCore→HyperEVM, arbitrary spot transfers) require a custom script via the [coding interface](coding-interface.md).\n\nAvailable adapter methods for scripting: `transfer_spot_to_perp()`, `transfer_perp_to_spot()`, `spot_transfer()`, `hypercore_to_hyperevm()`.\n\n\n### Deposit USDC to Hyperliquid\n\n```bash\n# Deposit\npoetry run wayfinder execute --kind hyperliquid_deposit --wallet_label main --amount 100\n\n# Wait for deposit to arrive (polls perp margin increase)\npoetry run wayfinder hyperliquid --action wait_for_deposit --wallet_label main \\\n  --expected_increase 100 --timeout_s 300\n```\n\n### Withdraw USDC from Hyperliquid\n\n```bash\n# Withdraw\npoetry run wayfinder hyperliquid_execute --action withdraw --wallet_label main \\\n  --amount_usdc 100\n\n# Wait for withdrawal to settle (polls ledger for withdraw record)\npoetry run wayfinder hyperliquid --action wait_for_withdrawal --wallet_label main\n```\n\n### Orchestration Tips\n\n- Always poll for confirmation and time out safely before taking downstream risk.\n- Hyperliquid funding is paid hourly — if rate-locking with Boros, align observations to this cadence.\n- Prefer explicit funding stages: deposit → wait for credit → open hedge → then deploy other legs.\n\n## Sizing\n\nWhen a user says \"$X at Yx leverage\", clarify intent:\n\n| `--usd_amount_kind` | Meaning | Example ($200 at 5x) |\n|---------------------|---------|----------------------|\n| `margin` | $X is collateral | Notional = $1,000 |\n| `notional` | $X is position size | Margin = $40 |\n\n## Execution Architecture\n\n- **Read methods** work with the `Info` client only — no executor needed.\n- **Write methods** require a `HyperliquidExecutor` with signing configured. Without it, execution methods raise `NotImplementedError`.\n\n### Execution Methods\n\n| Method | Purpose |\n|--------|---------|\n| `place_market_order(asset_id, is_buy, slippage, size, ...)` | Market order |\n| `place_limit_order(asset_id, is_buy, price, size, ...)` | Limit order |\n| `place_stop_loss(asset_id, is_buy, trigger_price, size, ...)` | Stop loss |\n| `cancel_order(asset_id, order_id, ...)` | Cancel by order ID |\n| `cancel_order_by_cloid(asset_id, cloid, ...)` | Cancel by client order ID |\n| `update_leverage(asset_id, leverage, is_cross, ...)` | Set leverage + margin mode |\n| `approve_builder_fee(builder, max_fee_rate, ...)` | Approve builder fee |\n| `withdraw(amount, address)` | USDC withdraw to Arbitrum |\n\n### Builder Fee\n\nBuilder attribution uses a fixed wallet `0xaA1D89f333857eD78F8434CC4f896A9293EFE65c`. Fee value `f` is in **tenths of a basis point** (e.g. `30` = 0.030%). Set in `config.json` under `strategy.builder_fee`. The CLI auto-approves if needed.\n\n## Spot Orders\n\nFor spot trading, you **must** set `is_spot` explicitly when using `hyperliquid_execute`:\n\n```bash\n# Spot buy\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin HYPE --is_spot true --is_buy true --usd_amount 20\n\n# Perp buy (default)\npoetry run wayfinder hyperliquid_execute --action place_order --wallet_label main \\\n  --coin HYPE --is_spot false --is_buy true --usd_amount 20 --usd_amount_kind notional\n```\n\n**Available spot pairs are limited.** Common assets like BTC and ETH are NOT directly available. Use wrapped versions:\n- `UBTC/USDC` for wrapped BTC\n- `UETH/USDC` for wrapped ETH\n- `HYPE/USDC` is native and available\n\nSpot orders don't use leverage — `usd_amount` is always treated as notional. `leverage` and `reduce_only` are ignored for spot.\n\n**Spot balance location:** Spot tokens live in your spot wallet, separate from perp margin. Use scripts with `transfer_spot_to_perp()` / `transfer_perp_to_spot()` to move USDC between them.\n\n## Gotchas\n\n- **Minimum amounts**: Deposits require **>= $5 USDC** (below $5 is lost). All orders (perp and spot) require a minimum of **$10 USD notional**.\n- **Asset IDs**: Perp assets: `asset_id < 10000`. Spot assets: `asset_id >= 10000` (spot_index = asset_id - 10000).\n- **Spot naming quirks**: Spot index 0 uses `\"PURR/USDC\"`, otherwise `\"@{spot_index}\"`. Use `get_spot_assets()` for the mapping.\n- **`is_spot` must be explicit**: When placing orders, `is_spot=True` for spot, `is_spot=False` for perp. Omitting returns an error.\n- **Funding**: Funding is paid/received every hour. Use `resource wayfinder://hyperliquid/markets` for current funding rates.\n- **Slippage**: Default slippage is applied to market orders. Override with `--slippage` (as a decimal, e.g., 0.01 = 1%).\n- **No guessing**: Do not invent funding rates or prices. Always fetch via adapter and label timestamps.\n- **USD sizing ambiguity**: When a user says \"$X at Yx leverage\", always clarify if $X is notional (position size) or margin (collateral). See the Sizing table above.\n- **Builder fee approvals**: Builder fees are opt-in per user/builder pair. Fee value `f` is in **tenths of a basis point** (e.g. `30` = 0.030%). The CLI auto-approves if needed.\n- **Funding history**: There is no `HyperliquidAdapter.get_funding_history()` — use `HyperliquidDataClient` or the SDK's `Info.funding_history()` directly.\n\nFile v0.4.1:references/moonwell.md\n\n# Moonwell\n\n## Overview\n\nMoonwell is a lending/borrowing protocol on Base. The Moonwell adapter provides market data reads and execution for lend/borrow/collateral operations.\n\n- **Type**: `MOONWELL`\n- **Module**: `wayfinder_paths.adapters.moonwell_adapter.adapter.MoonwellAdapter`\n- **Capabilities**: `lending.lend`, `lending.unlend`, `lending.borrow`, `lending.repay`, `collateral.set`, `collateral.remove`, `rewards.claim`, `position.read`, `market.apy`, `market.collateral_factor`\n\n## Market Data\n\n```bash\n# Describe the adapter (capabilities + market info)\npoetry run wayfinder resource wayfinder://adapters/moonwell_adapter\n\n# Check positions via wallet discovery\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"moonwell\"]'\n```\n\n### Key Read Methods\n\n| Method | Purpose | Wallet needed? |\n|--------|---------|----------------|\n| `get_apy(mtoken, apy_type, include_rewards)` | Supply/borrow APY | No |\n| `get_collateral_factor(mtoken)` | Collateral factor (e.g. 0.88) | No |\n| `get_pos(mtoken, account?, include_usd?)` | Single market position | Yes (or pass account) |\n| `get_full_user_state(account?, include_rewards?, include_usd?, include_apy?)` | All positions + rewards | Yes (or pass account) |\n| `is_market_entered(mtoken, account?)` | Check if collateral enabled | Yes (or pass account) |\n| `get_borrowable_amount(account?)` | Account liquidity (USD) | Yes (or pass account) |\n| `max_withdrawable_mtoken(mtoken, account?)` | Max withdraw without liquidation | Yes (or pass account) |\n\n- **Comptroller**: `0xfbb21d0380bee3312b33c4353c8936a0f13ef26c` (Base)\n- Only report values fetched from Moonwell contracts. Do not invent or estimate APYs.\n\n## Execution\n\nMoonwell operations are executed via one-off scripts under `.wayfinder_runs/`:\n\n```bash\n# Run a Moonwell script (dry run)\npoetry run wayfinder run_script --script_path .wayfinder_runs/moonwell_lend.py --wallet_label main\n\n# Run live\npoetry run wayfinder run_script --script_path .wayfinder_runs/moonwell_lend.py --wallet_label main --force\n```\n\n### Script Example (supply USDC)\n\n```python\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.moonwell_adapter import MoonwellAdapter\n\nUSDC_MTOKEN = \"0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22\"\nBASE_USDC = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\"\n\nadapter = get_adapter(MoonwellAdapter, \"main\")\nok, result = await adapter.lend(mtoken=USDC_MTOKEN, underlying_token=BASE_USDC, amount=10_000_000)  # 10 USDC\n```\n\n### Key Execution Methods\n\n| Method | Purpose | Params |\n|--------|---------|--------|\n| `lend(mtoken, underlying_token, amount)` | Supply underlying | amount in raw units |\n| `unlend(mtoken, amount)` | Withdraw (takes **mToken amount**, not underlying!) | amount in raw mToken units |\n| `borrow(mtoken, amount)` | Borrow against collateral | amount in raw units |\n| `repay(mtoken, underlying_token, amount, repay_full=False)` | Repay borrow | amount in raw units |\n| `set_collateral(mtoken)` | Enable as collateral | — |\n| `remove_collateral(mtoken)` | Disable collateral | — |\n| `claim_rewards(min_rewards_usd?)` | Claim WELL rewards | returns dict of claimed rewards |\n| `wrap_eth(amount)` | Wrap ETH to WETH | amount in raw units (wei) |\n\n## Gotchas\n\n- **mToken addresses, not underlying**: All adapter methods take **mToken addresses**, not underlying token addresses. `adapter.lend(\"0x833...\", amount)` is wrong — use `adapter.lend(\"0xEdc...\", amount)`.\n- **Units are raw ints**: All `amount` parameters are **raw int units** (USDC: 6 decimals, so 10 USDC = `10_000_000`; WETH: 18 decimals; mTokens: 8 decimals).\n- **unlend() takes mToken amount**: `unlend()` calls `redeem()` expecting **mToken amount**, not underlying. Use `max_withdrawable_mtoken()` first to get the correct value.\n- **Exchange rate scaling**: When manually converting: `underlying = mTokenBalance * exchangeRate / 1e18`.\n- **Collateral must be explicitly enabled**: Supplying tokens does NOT auto-enable them as collateral. Call `set_collateral()` separately.\n- **Check before borrow**: Always call `get_borrowable_amount()` before borrowing — returns account liquidity in USD. Reverts are expensive.\n- **Two USDC markets on Base**: Main: `0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22` (use this). Secondary: `0x703843C3379b52F9FF486c9f5892218d2a065cC8`.\n- **Transaction receipts**: A tx hash does **not** mean success. The SDK waits for receipt and raises `TransactionRevertedError` when `status=0`. If a step reverts, stop and fix before proceeding.\n- **Health factor**: Monitor health factor before borrowing — liquidation risk increases with leverage.\n- **APY composition**: Supply APY includes base rate + WELL token rewards. Both are shown in market data.\n- **`get_borrowable_amount()` has no mtoken param**: Returns account-level liquidity in USD, not per-market.\n- **Script execution**: Always run scripts via `run_script` with `--wallet_label` so the wallet profile tracks the Moonwell interaction for portfolio discovery.\n\n## Moonwell wstETH Loop Strategy\n\nFor automated leveraged wstETH yield via Moonwell, use the dedicated strategy:\n\n```bash\npoetry run wayfinder run_strategy --strategy moonwell_wsteth_loop_strategy --action status\npoetry run wayfinder run_strategy --strategy moonwell_wsteth_loop_strategy --action analyze --amount_usdc 500\n```\n\nFile v0.4.1:references/pendle.md\n\n# Pendle\n\n## Overview\n\nPendle splits yield-bearing assets into Principal Tokens (PTs) and Yield Tokens (YTs). PTs offer fixed yield at a discount; YTs offer leveraged exposure to variable yield.\n\n- **Type**: `PENDLE`\n- **Module**: `wayfinder_paths.adapters.pendle_adapter.adapter.PendleAdapter`\n- **Capabilities**: `pendle.markets.read`, `pendle.market.snapshot`, `pendle.market.history`, `pendle.prices.ohlcv`, `pendle.prices.assets`, `pendle.swap.quote`, `pendle.swap.best_pt`, `pendle.swap.execute`, `pendle.convert.quote`, `pendle.convert.best_pt`, `pendle.convert.execute`, `pendle.positions.database`, `pendle.limit_orders.taker.read`, `pendle.limit_orders.maker.read`, `pendle.limit_orders.maker.write`, `pendle.deployments.read`, `pendle.router_static.rates`\n\n## PT vs YT Mental Model\n\n- **PT (Principal Token)**: \"Fixed yield\" leg. `fixedApy` = Pendle's `impliedApy`. Buy PT to lock in a fixed rate at a discount.\n- **YT (Yield Token)**: \"Floating yield\" leg. `floatingApy` = `underlyingApy - impliedApy`. Leveraged exposure to variable yield.\n\n## Market Discovery\n\n```bash\n# Describe Pendle adapter capabilities\npoetry run wayfinder resource wayfinder://adapters/pendle_adapter\n\n# Discover via wallet positions\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"pendle\"]'\n```\n\n### Discovery Methods\n\n| Method | Returns | Best for |\n|--------|---------|----------|\n| `list_active_pt_yt_markets(chain)` | Flattened list with `fixedApy`, `underlyingApy`, `liquidityUsd`, `daysToExpiry` | Market discovery, scanners (RECOMMENDED) |\n| `fetch_markets(chain_id)` | Raw API (data **nested under `details`**) | When you need all raw fields |\n| `fetch_market_snapshot(chain_id, market)` | Single market state | Point-in-time checks |\n| `fetch_market_history(chain_id, market)` | Time series | Historical analysis |\n\n### Chain IDs\n\nPendle-supported chain strings in this SDK:\n\n`ethereum` → `1`, `bsc` → `56`, `arbitrum` → `42161`, `base` → `8453`, `plasma` → `9745`, `hyperevm` → `999`\n\n## Execution\n\nPendle swaps are executed via one-off scripts using the Pendle Hosted SDK:\n\n```bash\n# Run a Pendle script (dry run)\npoetry run wayfinder run_script --script_path .wayfinder_runs/pendle_buy_pt.py --wallet_label main\n\n# Run live\npoetry run wayfinder run_script --script_path .wayfinder_runs/pendle_buy_pt.py --wallet_label main --force\n```\n\n### Execution Methods\n\n| Method | Purpose |\n|--------|---------|\n| `execute_swap(chain, market_address, token_in, token_out, amount_in, slippage, ...)` | Full execution: quote → approvals → broadcast. Returns `(True, {\"tx_hash\": ..., \"quote\": ...})`. Requires `strategy_wallet_signing_callback`. |\n| `sdk_swap_v2(...)` | Quote only — returns `tx`, `tokenApprovals`, and quote metadata (`amountOut`, `priceImpact`, `impliedApy`) |\n| `build_best_pt_swap_tx(...)` | Auto-selects best PT by `effectiveApy`, filters by liquidity/volume/expiry, quotes up to `max_markets_to_quote` |\n\n**`execute_swap` inputs:**\n- `amount_in` — **string in raw base units** (convert using token decimals)\n- `slippage` — **decimal fraction** (`0.01` = 1%)\n- `token_in` / `token_out` — ERC20 addresses (PTs and YTs are both valid `token_out` targets)\n\n### Script Example (swap USDC into PT)\n\n```python\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.pendle_adapter import PendleAdapter\n\nadapter = get_adapter(PendleAdapter, \"main\")\n\n# Discover best markets\nmarkets = await adapter.list_active_pt_yt_markets(chain=\"base\", min_liquidity_usd=250_000, sort_by=\"fixed_apy\", descending=True)\nmarket = markets[0]\n\n# Execute swap into PT (amount_in is STRING in raw base units)\nsuccess, result = await adapter.execute_swap(\n    chain=\"base\",\n    market_address=market[\"marketAddress\"],\n    token_in=\"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",  # USDC\n    token_out=market[\"ptAddress\"],\n    amount_in=\"1000000\",  # 1 USDC (6 decimals)\n    slippage=0.01,  # 1% as decimal fraction\n)\n```\n\n## Gotchas\n\n- **`fetch_markets()` vs `list_active_pt_yt_markets()` (CRITICAL)**: `fetch_markets()` nests data under `details` — `m.get(\"impliedApy\")` returns 0! Use `m.get(\"details\", {}).get(\"impliedApy\")`. `list_active_pt_yt_markets()` returns **flattened** data with renamed fields (e.g. `fixedApy`). **Always prefer `list_active_pt_yt_markets()` for discovery.**\n- **Units are raw strings**: Hosted SDK expects `amountIn` in **raw base units as a string**. Resolve token decimals and convert explicitly.\n- **Address formats**: `fetch_markets()` returns IDs like `\"42161-0xabc...\"`. `list_active_pt_yt_markets()` normalizes to plain `0x...` addresses.\n- **Chain IDs**: Accepts both `chain=42161` and `chain=\"arbitrum\"`.\n- **Expiry**: PTs have fixed expiry dates. After expiry, PTs can be redeemed 1:1 for the underlying.\n- **Liquidity**: Check pool liquidity and volume before large trades — thin pools have high slippage.\n- **Approvals**: `execute_swap()` handles approvals automatically. For `sdk_swap_v2()`, you must execute `tokenApprovals` yourself before broadcasting.\n- **Quote fields optional**: Hosted SDK may omit `effectiveApy`/`impliedApy` depending on market state. Always use `.get()` with defaults.\n- **Receiver vs signer**: If `receiver != signer`, treat as high-risk and require explicit user confirmation.\n\nFile v0.4.1:references/polymarket.md\n\n# Polymarket\n\n## Overview\n\nPolymarket is a prediction market platform. The Polymarket adapter supports:\n- Market discovery (search/trending)\n- Market/event details\n- Prices, order books, and price history\n- User status (balances, positions, orders)\n- Collateral bridging and trade execution (requires signing wallet)\n\n- **Type**: `POLYMARKET`\n- **Module**: `wayfinder_paths.adapters.polymarket_adapter.adapter.PolymarketAdapter`\n- **Capabilities**: `market.read`, `market.search`, `market.orderbook`, `market.candles`, `position.read`, `order.execute`, `order.cancel`, `bridge.deposit`, `bridge.withdraw`\n\n## Read-Only Actions (CLI)\n\nPolymarket reads use the `polymarket` tool (not `resource` URIs):\n\n```bash\n# Search markets\npoetry run wayfinder polymarket --action search --query \"bitcoin above\" --limit 5\n\n# Trending markets (by 24h volume)\npoetry run wayfinder polymarket --action trending --limit 10\n\n# Market details\npoetry run wayfinder polymarket --action get_market --market_slug \"some-market-slug\"\n\n# Account status (positions + balances; provide wallet_label or account)\npoetry run wayfinder polymarket --action status --wallet_label main\n\n# CLOB order book + price for a specific token_id\npoetry run wayfinder polymarket --action order_book --token_id 123456\npoetry run wayfinder polymarket --action price --token_id 123456 --side BUY\n```\n\n## Execution (CLI) — Live\n\nPolymarket execution uses `polymarket_execute` and is **always live** (no dry-run flag).\n\n**Wallet requirement:** `wallet_label` must resolve to a wallet in `config.json` that includes **both** `address` and `private_key_hex` (local dev only).\n\n```bash\n# Bridge USDC -> USDC.e collateral (Polymarket)\npoetry run wayfinder polymarket_execute --action bridge_deposit --wallet_label main --amount 10\n\n# Buy shares by market slug + outcome\npoetry run wayfinder polymarket_execute --action buy --wallet_label main --market_slug \"some-market-slug\" --outcome YES --amount_usdc 2\n\n# Close position (convenience: sells full size for the resolved token_id)\npoetry run wayfinder polymarket_execute --action close_position --wallet_label main --market_slug \"some-market-slug\" --outcome YES\n```\n\n## Gotchas\n\n- **USDC vs USDC.e (collateral mismatch):** Polymarket trading collateral is **USDC.e** on Polygon (`0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`, 6 decimals), not native Polygon USDC (`0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359`). Use `bridge_deposit` / `bridge_withdraw` to convert.\n- **Bridge utilities (BRAP vs bridge service):** `bridge_deposit` (USDC → USDC.e) and `bridge_withdraw` (USDC.e → USDC/destination token) prefer a fast on-chain BRAP swap on Polygon when possible (sender == recipient). Otherwise they fall back to the Polymarket Bridge service; the result includes `method: \"polymarket_bridge\"` and you may need to poll `polymarket --action bridge_status` until it clears.\n- **`market_slug` vs `token_id`:** You can trade using `market_slug`+`outcome` or directly via the CLOB `token_id`. Prefer `market_slug` when possible.\n- **Market found but not tradable:** Filter for `enableOrderBook`, `acceptingOrders`, `active`, `closed != true`, and non-empty `clobTokenIds`. Fallback to `trending` when fuzzy search returns stale/closed items.\n- **Outcomes are not always YES/NO:** Some markets are multi-outcome. If `YES` doesn’t exist, retry with `outcome=0` (first outcome) or pick the exact outcome string from the market’s outcomes list.\n- **Approvals:** Trading requires on-chain approvals on Polygon. These are handled automatically before order placement (idempotent).\n- **Bridging:** Collateral flows may involve USDC/USDC.e conversions. Always verify balances via `polymarket --action status` after bridge operations.\n- **Open orders:** `polymarket --action open_orders` requires a signing wallet (private key) due to Level-2 auth. Optional: pass `--token_id` to filter.\n- **Buy then immediately sell can fail:** CLOB settlement/match can lag; you may not have shares available to sell instantly. If chaining BUY → SELL, wait for the buy confirmation first.\n- **Rate limiting:** Avoid large concurrent scans of `price_history`. Use a semaphore (e.g. 4–8 concurrent calls) and retry/backoff on 429s.\n- **Token IDs aren’t ERC20 addresses:** `clobTokenIds` are CLOB identifiers. Outcome shares are ERC1155 positions under ConditionalTokens.\n- **Redemption requires `conditionId`:** Resolved markets redeem via ConditionalTokens `redeemPositions()` using the market’s `conditionId`.\n\nFile v0.4.1:references/projectx.md\n\n# ProjectX (HyperEVM)\n\n## Overview\n\nProjectX is a Uniswap V3-style concentrated-liquidity DEX on HyperEVM. The ProjectX adapter supports:\n- Pool overview reads (tick/price/liquidity + token metadata)\n- Listing positions for a specific pool\n- Minting/increasing liquidity using wallet balances (with optional balancing swaps)\n- Fee collection / burning positions\n- Exact-in swaps via the ProjectX router\n\n- **Type**: `PROJECTX`\n- **Module**: `wayfinder_paths.adapters.projectx_adapter.adapter.ProjectXLiquidityAdapter`\n- **Capabilities**: `projectx.pool.overview`, `projectx.positions.list`, `projectx.liquidity.mint`, `projectx.liquidity.increase`, `projectx.liquidity.decrease`, `projectx.fees.collect`, `projectx.position.burn`, `projectx.swap.exact_in`\n\n## Configuration\n\n- **RPC resolution (chain id 999 / HyperEVM)**: Do not hardcode RPC URLs in scripts. Use `web3_from_chain_id(999)` (internally used by the adapter). If `strategy.rpc_urls[\"999\"]` is not set, the SDK falls back to Wayfinder’s RPC proxy at `system.api_base_url` (auth via `system.api_key` / `WAYFINDER_API_KEY`).\n- **`pool_address` is optional**, but many pool-specific methods require it.\n- The adapter accepts `pool_address` via config in multiple keys (including nested `strategy` config): `pool_address`, `pool`, `projectx_pool_address`, `projectx_pool`.\n\n## Usage (via custom scripts)\n\nProjectX operations are executed via one-off scripts under `.wayfinder_runs/`:\n\n```bash\npoetry run wayfinder run_script --script_path .wayfinder_runs/projectx_lp.py --wallet_label main\n```\n\n### Pool-agnostic mode (no `pool_address`)\n\nUse this for cross-pool reads and operations that don’t need a specific pool:\n- `get_full_user_state()` (positions + points; skips pool overview/balances without a configured pool)\n- `_list_all_positions()` (all active positions across all pools)\n- `fetch_prjx_points()` (points lookup)\n- `burn_position(token_id)` (close any position by NFT token id)\n- `swap_exact_in(...)` (routes automatically; no fee hint from a configured pool)\n\n```python\nimport asyncio\n\nfrom wayfinder_paths.adapters.projectx_adapter.adapter import ProjectXLiquidityAdapter\nfrom wayfinder_paths.mcp.scripting import get_adapter\n\n\nasync def main():\n    adapter = get_adapter(ProjectXLiquidityAdapter, \"main\")\n    ok, state = await adapter.get_full_user_state()\n    print(\"ok:\", ok)\n    if ok:\n        print(\"positions:\", state.get(\"positions\"))\n        print(\"points:\", state.get(\"points\"))\n\n\nasyncio.run(main())\n```\n\n### Pool-scoped mode (with `pool_address`)\n\nRequired for pool-specific reads and helpers:\n- `pool_overview()` / `current_balances()` / `list_positions()`\n- `fetch_swaps()` (subgraph swap history for a specific pool)\n- `live_fee_snapshot()`\n- `mint_from_balances()` / `increase_liquidity_balanced()`\n\n```python\nimport asyncio\n\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.projectx_adapter import ProjectXLiquidityAdapter\n\nPOOL = \"0x...\"  # ProjectX pool address\n\n\nasync def main():\n    adapter = get_adapter(ProjectXLiquidityAdapter, \"main\", config_overrides={\"pool_address\": POOL})\n    ok, overview = await adapter.pool_overview()\n    ok, positions = await adapter.list_positions()\n    print(\"overview ok:\", ok)\n    print(\"positions ok:\", ok, \"n=\", len(positions) if ok else None)\n\n\nasyncio.run(main())\n```\n\n## High-value methods\n\n| Method | Purpose | Notes |\n|--------|---------|-------|\n| `get_full_user_state(...)` | One-shot state (positions/balances/overview/points) | Pool-agnostic (overview/balances require pool) |\n| `pool_overview()` | Pool tick/spacing/fee + token metadata | Requires `pool_address` |\n| `current_balances(owner=...)` | Raw balances for pool token0/token1 | Requires `pool_address` |\n| `list_positions(owner=...)` | Active NPM positions for this pool | Requires `pool_address` |\n| `fetch_swaps(...)` | Swap history | Subgraph (HTTP), requires `pool_address` |\n| `fetch_prjx_points(wallet_address)` | Points | HTTP API |\n| `mint_from_balances(tick_lower, tick_upper, slippage_bps=...)` | Mint new position using balances | Uses pool tick spacing |\n| `increase_liquidity_balanced(...)` | Increase liquidity after balancing | Uses pool tick spacing |\n| `burn_position(token_id)` | Remove liquidity + collect + burn | Does not require `pool_address` |\n| `swap_exact_in(from_token, to_token, amount_in, slippage_bps=...)` | Swap exact-in | Routes automatically |\n\n## Strategy Note\n\nThe `projectx_thbill_usdc_strategy` strategy uses this adapter for concentrated-liquidity market making on the THBILL/USDC stable pair.\n\n## Gotchas\n\n- **`pool_address` is optional (two modes):** Pool-scoped methods raise `ValueError(\"pool_address is required …\")` when called without a configured pool.\n- **ProjectX pools can have non-standard tick spacing:** Prefer `mint_from_balances()` / `increase_liquidity_balanced()` (they use the pool’s `tick_spacing`). If you call low-level Uniswap-style methods directly, pass `tick_spacing=...` explicitly.\n- **`fetch_swaps()` is subgraph-based:** Swap history reads can fail due to subgraph downtime or missing config. Always check `(ok, swaps)` and fall back to on-chain reads when needed.\n- **Units are raw ints:** amounts are raw base units (respect token decimals).\n- **ERC20-only swaps:** `swap_exact_in(...)` uses ERC20 addresses; for “native HYPE” behavior, use the wrapped ERC20 address.\n\nArchive v0.0.4: 20 files, 63457 bytes\n\nFiles: references/adapters.md (14495b), references/boros.md (7630b), references/ccxt.md (2018b), references/coding-interface.md (14078b), references/hyperlend.md (3828b), references/hyperliquid.md (13158b), references/moonwell.md (5354b), references/pendle.md (5324b), references/polymarket.md (4492b), references/projectx.md (2459b), references/setup.md (5954b), references/strategies.md (10038b), references/tokens-and-pools.md (11335b), references/uniswap.md (2405b), scripts/pull-sdk-ref.sh (7219b), scripts/sync-skill-json-from-sdk.py (5314b), sdk-version.md (5b), skill.json (1992b), SKILL.md (54772b), _meta.json (128b)\n\nFile v0.0.4:SKILL.md\n\n---\nname: wayfinder\ndescription: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swap tokens, bridge assets, trade perps, trade prediction markets (Polymarket), run automated yield strategies (stablecoin yield, basis trading, Moonwell loops, HyperLend, Boros HYPE), manage wallets, discover DeFi pools, look up token metadata, manage LP positions (Uniswap V3 / ProjectX), or execute one-off DeFi scripts. Supports Ethereum, Base, Arbitrum, Polygon, BSC, Avalanche, Plasma, and HyperEVM via protocol adapters.\nmetadata: {\"openclaw\":{\"emoji\":\"🧭\",\"homepage\":\"https://github.com/WayfinderFoundation/wayfinder-paths-sdk\",\"requires\":{\"bins\":[\"poetry\"]},\"install\":[{\"id\":\"brew\",\"kind\":\"brew\",\"formula\":\"poetry\",\"bins\":[\"poetry\"],\"label\":\"Install poetry\"}]}}\n---\n\n# Wayfinder\n\nDeFi trading, yield strategies, and portfolio management powered by [poetry run wayfinder Paths](https://github.com/WayfinderFoundation/wayfinder-paths-sdk).\n\n## Pre-Flight Check\n\nBefore running any commands, verify that poetry run wayfinder Paths is installed and reachable:\n\n```bash\n# SDK location (override by setting WAYFINDER_SDK_PATH)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\n\n# Check if wayfinder-paths-sdk directory exists\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  echo \"ERROR: wayfinder-paths-sdk is not installed at: $WAYFINDER_SDK_PATH\"\n  echo \"Set WAYFINDER_SDK_PATH or run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Config path (override by setting WAYFINDER_CONFIG_PATH)\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\n\n# Check if the config exists\nif [ ! -f \"$WAYFINDER_CONFIG_PATH\" ]; then\n  echo \"ERROR: config not found at $WAYFINDER_CONFIG_PATH. Run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Check if the CLI is functional\ncd \"$WAYFINDER_SDK_PATH\"\nif ! poetry run wayfinder --help > /dev/null 2>&1; then\n  echo \"ERROR: poetry run wayfinder CLI is not working. Run 'cd $WAYFINDER_SDK_PATH && poetry install' to fix.\"\n  exit 1\nfi\n\necho \"poetry run wayfinder Paths is installed and ready.\"\n```\n\nIf either check fails, follow the **First-Time Setup** instructions below before proceeding.\n\n## Quick Start\n\n### First-Time Setup\n\n**Important:** The SDK must be installed from GitHub via `git clone`. Do NOT install from PyPI (`pip install wayfinder-paths` will not work).\n\n**Before starting:** You need a Wayfinder API key (format: `wk_...`). Get one at **https://strategies.wayfinder.ai**. The guided setup will prompt you for this key.\n\n```bash\n# Clone wayfinder-paths-sdk from GitHub (required — do NOT pip install)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  git clone https://github.com/WayfinderFoundation/wayfinder-paths-sdk.git \"$WAYFINDER_SDK_PATH\"\nfi\n\ncd \"$WAYFINDER_SDK_PATH\"\npoetry install\n\n# Run guided setup (creates/updates config.json + local dev wallets + MCP config)\n# You will need your API key from https://strategies.wayfinder.ai (format: wk_...)\npython3 scripts/setup.py\n```\n\n**Wallet security:**\n- **NEVER output private keys or seed phrases into the conversation.** These are secrets — they must stay on the machine, never in chat.\n- For a long-running bot, prefer a seed phrase stored in your backend/secret manager rather than generating random wallets on the server.\n- On first-time setup, the user should retrieve the seed phrase directly from their machine or secret manager. Only offer to display the seed phrase if the user explicitly confirms they cannot access the machine to retrieve it themselves.\n- See `references/setup.md` for detailed wallet setup instructions.\n\n### Verify Setup\n\n```bash\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\ncd \"$WAYFINDER_SDK_PATH\"\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://balances/main\n```\n\n## Command Reference\n\nAll commands should be run from `$WAYFINDER_SDK_PATH` and require `WAYFINDER_CONFIG_PATH` (default: `$WAYFINDER_SDK_PATH/config.json`). All responses return `{\"ok\": true, \"result\": {...}}` on success or `{\"ok\": false, \"error\": {\"code\": \"...\", \"message\": \"...\"}}` on failure.\n\n---\n\n### `resource` — Read MCP resources by URI\n\nRead-only access to adapters, strategies, wallets, balances, tokens, and Hyperliquid market data via URI-based resources. Use `--list` to see all available resources and templates.\n\n**Asset/data sourcing rule:** When the user asks you to look up token/pool/market/protocol data, first use Wayfinder’s adapter/strategy discovery resources (`poetry run wayfinder resource wayfinder://adapters`, `wayfinder://adapters/{name}`, `wayfinder://strategies`, `wayfinder://tokens/*`). Only fall back to other methods if Wayfinder doesn’t expose the required data or the user explicitly asks.\n\n```bash\n# List all available resources and templates\npoetry run wayfinder resource --list\n```\n\n#### Static Resources\n\n| URI | Description |\n|-----|-------------|\n| `wayfinder://adapters` | List all adapters with capabilities |\n| `wayfinder://strategies` | List all strategies with adapter dependencies |\n| `wayfinder://wallets` | List all configured wallets |\n| `wayfinder://hyperliquid/prices` | All Hyperliquid mid prices |\n| `wayfinder://hyperliquid/markets` | Perp market metadata, funding rates, and asset contexts |\n| `wayfinder://hyperliquid/spot-assets` | Spot asset metadata |\n\n```bash\npoetry run wayfinder resource wayfinder://adapters\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://hyperliquid/prices\npoetry run wayfinder resource wayfinder://hyperliquid/markets\npoetry run wayfinder resource wayfinder://hyperliquid/spot-assets\n```\n\n#### Resource Templates\n\n| URI Template | Description |\n|--------------|-------------|\n| `wayfinder://adapters/{name}` | Describe a single adapter (e.g. `moonwell_adapter`) |\n| `wayfinder://strategies/{name}` | Describe a single strategy (e.g. `stablecoin_yield_strategy`) |\n| `wayfinder://wallets/{label}` | Get a single wallet by label |\n| `wayfinder://balances/{label}` | Enriched multi-chain balances for a wallet |\n| `wayfinder://activity/{label}` | Recent transaction activity for a wallet |\n| `wayfinder://tokens/search/{chain_code}/{query}` | **Fuzzy token search** (hits `/tokens/fuzzy/`) — ALWAYS use this first |\n| `wayfinder://tokens/resolve/{query}` | Resolve a token by known ID (hits `/tokens/detail/`) — only use with IDs from search |\n| `wayfinder://tokens/gas/{chain_code}` | **Native gas token** for a chain (ETH, HYPE) — use for native tokens |\n| `wayfinder://hyperliquid/{label}/state` | Perp positions + PnL for a wallet |\n| `wayfinder://hyperliquid/{label}/spot` | Spot balances on Hyperliquid for a wallet |\n| `wayfinder://hyperliquid/prices/{coin}` | Mid price for a single coin |\n| `wayfinder://hyperliquid/book/{coin}` | Order book for a coin |\n\n**Token lookup order — always search or use gas endpoint first:**\n\n```bash\n# 1. For native gas tokens (ETH, HYPE): use the gas endpoint\npoetry run wayfinder resource wayfinder://tokens/gas/ethereum    # ETH on Ethereum\npoetry run wayfinder resource wayfinder://tokens/gas/base        # ETH on Base\npoetry run wayfinder resource wayfinder://tokens/gas/hyperevm    # HYPE on HyperEVM\n\n# 2. For ERC20 tokens: ALWAYS fuzzy search first\npoetry run wayfinder resource wayfinder://tokens/search/base/usdc\npoetry run wayfinder resource wayfinder://tokens/search/arbitrum/eth\npoetry run wayfinder resource wayfinder://tokens/search/ethereum/weth\n\n# 3. Then resolve with the exact ID from search results\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base\n```\n\n```bash\npoetry run wayfinder resource wayfinder://adapters/moonwell_adapter\npoetry run wayfinder resource wayfinder://strategies/stablecoin_yield_strategy\npoetry run wayfinder resource wayfinder://wallets/main\npoetry run wayfinder resource wayfinder://balances/main\npoetry run wayfinder resource wayfinder://activity/main\npoetry run wayfinder resource wayfinder://hyperliquid/main/state\npoetry run wayfinder resource wayfinder://hyperliquid/main/spot\npoetry run wayfinder resource wayfinder://hyperliquid/prices/ETH\npoetry run wayfinder resource wayfinder://hyperliquid/book/ETH\n```\n\n---\n\n### `wallets` — Manage wallets and discover positions\n\nCreate, annotate, and discover cross-protocol positions. Use `resource wayfinder://wallets` to list wallets and `resource wayfinder://wallets/{label}` to get a single wallet.\n\n| Parameter | Type | Required | Default | Notes |\n|-----------|------|----------|---------|-------|\n| `action` | `\"create\"` \\| `\"annotate\"` \\| `\"discover_portfolio\"` | **Yes** | — | — |\n|\n\nArchive v0.0.3: 20 files, 62816 bytes\n\nFiles: references/adapters.md (14495b), references/boros.md (7630b), references/ccxt.md (2018b), references/coding-interface.md (14078b), references/hyperlend.md (3828b), references/hyperliquid.md (13158b), references/moonwell.md (5354b), references/pendle.md (5324b), references/polymarket.md (4492b), references/projectx.md (2459b), references/setup.md (5149b), references/strategies.md (10038b), references/tokens-and-pools.md (11335b), references/uniswap.md (2405b), scripts/pull-sdk-ref.sh (7219b), scripts/sync-skill-json-from-sdk.py (5314b), sdk-version.md (5b), skill.json (1987b), SKILL.md (53906b), _meta.json (128b)","readmeExcerpt":"Skill: Wayfinder Owner: canuc Summary: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (poetry run wayfinder). Use when the user wants to check balances, swa... Tags: latest:0.0.4 Version history: v0.4.1 | 2026-02-13T22:20:27.670Z | user wayfinder 0.4.1 - Added CCTX -> so that binance can be used. - Added defaiut api RPCs for all ETH + PLASMA + BASE + EFC rpc urls - to avoid publi","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# SDK location (override by setting WAYFINDER_SDK_PATH)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\n\n# Check if wayfinder-paths-sdk directory exists\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  echo \"ERROR: wayfinder-paths-sdk is not installed at: $WAYFINDER_SDK_PATH\"\n  echo \"Set WAYFINDER_SDK_PATH or run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Config path (override by setting WAYFINDER_CONFIG_PATH)\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\n\n# Check if the config exists\nif [ ! -f \"$WAYFINDER_CONFIG_PATH\" ]; then\n  echo \"ERROR: config not found at $WAYFINDER_CONFIG_PATH. Run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Check if the CLI is functional\ncd \"$WAYFINDER_SDK_PATH\"\nif ! poetry run wayfinder --help > /dev/null 2>&1; then\n  echo \"ERROR: poetry run wayfinder CLI is not working. Run 'cd $WAYFINDER_SDK_PATH && poetry install' to fix.\"\n  exit 1\nfi\n\necho \"poetry run wayfinder Paths is installed and ready.\""},{"language":"bash","snippet":"# Clone wayfinder-paths-sdk from GitHub (required — do NOT pip install)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  git clone https://github.com/WayfinderFoundation/wayfinder-paths-sdk.git \"$WAYFINDER_SDK_PATH\"\nfi\n\ncd \"$WAYFINDER_SDK_PATH\"\npoetry install\n\n# Run guided setup (creates/updates config.json + local dev wallets + MCP config)\n# You will need your API key from https://strategies.wayfinder.ai (format: wk_...)\npython3 scripts/setup.py"},{"language":"bash","snippet":"export WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\ncd \"$WAYFINDER_SDK_PATH\"\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://balances/main"},{"language":"bash","snippet":"# List all available resources and templates\npoetry run wayfinder resource --list"},{"language":"bash","snippet":"poetry run wayfinder resource wayfinder://adapters\npoetry run wayfinder resource wayfinder://strategies\npoetry run wayfinder resource wayfinder://wallets\npoetry run wayfinder resource wayfinder://hyperliquid/prices\npoetry run wayfinder resource wayfinder://hyperliquid/markets\npoetry run wayfinder resource wayfinder://hyperliquid/spot-assets"},{"language":"bash","snippet":"# 1. For native gas tokens (ETH, HYPE): use the gas endpoint\npoetry run wayfinder resource wayfinder://tokens/gas/ethereum    # ETH on Ethereum\npoetry run wayfinder resource wayfinder://tokens/gas/base        # ETH on Base\npoetry run wayfinder resource wayfinder://tokens/gas/hyperevm    # HYPE on HyperEVM\n\n# 2. For ERC20 tokens: ALWAYS fuzzy search first\npoetry run wayfinder resource wayfinder://tokens/search/base/usdc\npoetry run wayfinder resource wayfinder://tokens/search/arbitrum/eth\npoetry run wayfinder resource wayfinder://tokens/search/ethereum/weth\n\n# 3. Then resolve with the exact ID from search results\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: wayfinder\ndescription: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swap tokens, bridge assets, trade perps, trade prediction markets (Polymarket), run automated yield strategies (stablecoin yield, basis trading, Moonwell loops, HyperLend, Boros HYPE), manage wallets, discover DeFi pools, look up token metadata, manage LP positions (Uniswap V3 / ProjectX), or execute one-off DeFi scripts. Supports Ethereum, Base, Arbitrum, Polygon, BSC, Avalanche, Plasma, and HyperEVM via protocol adapters.\nmetadata: {\"openclaw\":{\"emoji\":\"🧭\",\"homepage\":\"https://github.com/WayfinderFoundation/wayfinder-paths-sdk\",\"requires\":{\"bins\":[\"poetry\"]},\"install\":[{\"id\":\"brew\",\"kind\":\"brew\",\"formula\":\"poetry\",\"bins\":[\"poetry\"],\"label\":\"Install poetry\"}]}}\n---\n\n# Wayfinder\n\nDeFi trading, yield strategies, and portfolio management powered by [poetry run wayfinder Paths](https://github.com/WayfinderFoundation/wayfinder-paths-sdk).\n\n## Pre-Flight Check\n\nBefore running any commands, verify that poetry run wayfinder Paths is installed and reachable:\n\n```bash\n# SDK location (override by setting WAYFINDER_SDK_PATH)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\n\n# Check if wayfinder-paths-sdk directory exists\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  echo \"ERROR: wayfinder-paths-sdk is not installed at: $WAYFINDER_SDK_PATH\"\n  echo \"Set WAYFINDER_SDK_PATH or run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Config path (override by setting WAYFINDER_CONFIG_PATH)\nexport WAYFINDER_CONFIG_PATH=\"${WAYFINDER_CONFIG_PATH:-$WAYFINDER_SDK_PATH/config.json}\"\n\n# Check if the config exists\nif [ ! -f \"$WAYFINDER_CONFIG_PATH\" ]; then\n  echo \"ERROR: config not found at $WAYFINDER_CONFIG_PATH. Run the First-Time Setup below.\"\n  exit 1\nfi\n\n# Check if the CLI is functional\ncd \"$WAYFINDER_SDK_PATH\"\nif ! poetry run wayfinder --help > /dev/null 2>&1; then\n  echo \"ERROR: poetry run wayfinder CLI is not working. Run 'cd $WAYFINDER_SDK_PATH && poetry install' to fix.\"\n  exit 1\nfi\n\necho \"poetry run wayfinder Paths is installed and ready.\"\n```\n\nIf either check fails, follow the **First-Time Setup** instructions below before proceeding.\n\n## Quick Start\n\n### First-Time Setup\n\n**Important:** The SDK must be installed from GitHub via `git clone`. Do NOT install from PyPI (`pip install wayfinder-paths` will not work).\n\n**Before starting:** You need a Wayfinder API key (format: `wk_...`). Get one at **https://strategies.wayfinder.ai**. The guided setup will prompt you for this key.\n\n```bash\n# Clone wayfinder-paths-sdk from GitHub (required — do NOT pip install)\nexport WAYFINDER_SDK_PATH=\"${WAYFINDER_SDK_PATH:-$HOME/wayfinder-paths-sdk}\"\nif [ ! -d \"$WAYFINDER_SDK_PATH\" ]; then\n  git clone https://github.com/WayfinderFoundation/wayfinder-paths-sdk.git \"$WAYFINDER_SDK_PATH\"\nfi\n\ncd \"$WAYFINDER_SDK_PATH\"\npoetry install\n\n# Run guided setup (creates/updates config.json + loc"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn70kfnzaghvt4fcq75v9wqa9h80epek\",\n  \"slug\": \"wayfinder\",\n  \"version\": \"0.4.1\",\n  \"publishedAt\": 1771021227670\n}"},{"path":"references/adapters.md","content":"# Adapters\n\n## Overview\n\nAdapters are protocol integrations that provide read and write capabilities. Strategies compose adapters to build trading logic.\n\n## Discovering Adapters\n\n```bash\n# List all adapters with capabilities\npoetry run wayfinder resource wayfinder://adapters\n\n# Describe a specific adapter\npoetry run wayfinder resource wayfinder://adapters/moonwell_adapter\n```\n\n## Adapter Reference\n\n### Balance Adapter (`balance_adapter`)\n\n- **Type**: `BALANCE`\n- **Module**: `wayfinder_paths.adapters.balance_adapter.adapter.BalanceAdapter`\n- **Protocol**: EVM wallets (Base, Arbitrum, Ethereum, HyperEVM)\n- **Capabilities**: `balance.read`, `transfer.main_to_strategy`, `transfer.strategy_to_main`, `transfer.send`\n\nProvides token balance queries for any wallet, cross-wallet transfers between main and strategy wallets, and automatic ledger recording for deposits/withdrawals.\n\n```bash\npoetry run wayfinder resource wayfinder://balances/main\npoetry run wayfinder resource wayfinder://tokens/resolve/usd-coin-base\npoetry run wayfinder resource wayfinder://activity/main\n```\n\n### BRAP Adapter (`brap_adapter`)\n\n- **Type**: `BRAP`\n- **Module**: `wayfinder_paths.adapters.brap_adapter.adapter.BRAPAdapter`\n- **Protocol**: Cross-chain swap aggregator (Bridge/Router/Adapter Protocol)\n- **Capabilities**: `swap.quote`, `swap.execute`, `swap.compare_routes`, `bridge.quote`, `gas.estimate`\n\nHandles cross-chain swaps and bridges with quote fetching, route optimization, and execution.\n\n```bash\npoetry run wayfinder quote_swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 100\npoetry run wayfinder execute --kind swap --wallet_label main --from_token usd-coin-base --to_token ethereum-base --amount 100\n```\n\n**Key Methods:**\n- `BRAPClient.get_quote(from_token, to_token, from_chain, to_chain, from_wallet, from_amount, slippage?)` — Low-level quote (amount in **raw base units** as string)\n- `BRAPAdapter.best_quote(...)` — Returns single best route; supports `preferred_providers`\n- `BRAPAdapter.swap_from_token_ids(from_token_id, to_token_id, from_address, amount, slippage, ...)` — Execute swap by token IDs\n- `BRAPAdapter.swap_from_quote(from_token, to_token, from_address, quote, ...)` — Execute from a pre-fetched quote\n\n**Recommended Quote Loop:**\n1. Call `quote_swap` (does token lookup + human→raw conversion + returns preview)\n2. Inspect `from_token`/`to_token` in response to verify correct asset + chain\n3. Pass `suggested_execute_request` directly into `execute`\n\n**BRAP Gotchas:**\n- **Broadcast ≠ success**: A tx hash does not mean the swap succeeded. The SDK waits for receipt and raises `TransactionRevertedError` on `status=0`.\n- **Units**: Quote input `from_amount` is **raw base units**. Resolve decimals via TokenClient first.\n- **Slippage formats**: BRAP adapter uses **decimal fraction** (`0.005` = 0.5%). MCP may use bps (`50` = 0.5%). Don't mix.\n- **Approvals**: Some tokens are \"strict approve\" and require setting allowance to 0 before incr"},{"path":"references/boros.md","content":"# Boros\n\n## Overview\n\nBoros provides fixed-rate markets on Arbitrum. It allows locking in a fixed funding rate for delta-neutral strategies, removing variable rate risk.\n\n- **Type**: `BOROS`\n- **Module**: `wayfinder_paths.adapters.boros_adapter.adapter.BorosAdapter`\n- **Capabilities**: `market.read`, `market.quote`, `position.open`, `position.close`, `collateral.deposit`, `collateral.withdraw`\n\n## Market Data\n\n```bash\n# Describe Boros adapter\npoetry run wayfinder resource wayfinder://adapters/boros_adapter\n\n# Discover positions\npoetry run wayfinder wallets --action discover_portfolio --wallet_label main --protocols '[\"boros\"]'\n```\n\n## Execution\n\nBoros operations are executed via one-off scripts:\n\n```bash\n# Run a Boros script (dry run)\npoetry run wayfinder run_script --script_path .wayfinder_runs/boros_lock_rate.py --wallet_label main\n\n# Run live\npoetry run wayfinder run_script --script_path .wayfinder_runs/boros_lock_rate.py --wallet_label main --force\n```\n\n### Script Example\n\n```python\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.boros_adapter import BorosAdapter\n\nadapter = get_adapter(BorosAdapter, \"main\")\nmarkets = await adapter.discover_markets()\n```\n\n## Key Concepts\n\n- **Yield Units (YU)**: The core trading unit. 1 YU ≈ $1 for USDT collateral; 1 YU = 1 HYPE (at unit price) for HYPE collateral. YU sizing is determined by margin formula, not 1:1 with collateral.\n- **Implied APR**: The orderbook price — what the market expects the rate to be.\n- **Underlying APR**: The actual funding rate that settles (e.g., Hyperliquid hourly funding).\n- **Settlement cadence**: Mirrors the underlying venue — hourly for Hyperliquid, 8-hour for Binance/OKX. Must sample funding and rates on the same cadence.\n- **Margin types**: **Cross** (shared across all positions) vs **Isolated** (locked to a specific market).\n- **Collateral types**: WBTC (1), WETH (2), USDT (3), BNB (4), HYPE (5).\n- **Funding sign convention**: Negative = shorts pay longs (longs receive). Positive = longs pay shorts.\n\n### Rate Locking Recipes\n\n- **Short hedge** (you're short a perp with positive funding): Open a **SHORT YU** on Boros to lock fixed funding you're paying.\n- **Long hedge** (you're long a perp with positive funding): Open a **LONG YU** on Boros to lock fixed funding payment.\n- \"Current rate\" = `BorosMarketQuote.mid_apr` — always fetch fresh via adapter.\n\n## High-Value Reads\n\nAll BorosAdapter methods return `tuple[bool, result]` — always unpack. All fields use **snake_case** (not camelCase).\n\n| Method | Purpose | Best For |\n|--------|---------|----------|\n| `list_tenor_quotes(underlying_symbol, platform)` | Fast market+rate snapshot (no orderbooks) | Quick tenor-level APR scan |\n| `quote_market(market)` / `quote_market_by_id(market_id)` | Detailed APR quote with orderbook data | Single market analysis |\n| `quote_markets_for_underlying(underlying_symbol)` | Quotes across all tenors for an underlying | Tenor curve building |\n| `list_markets()` /"},{"path":"references/ccxt.md","content":"# CCXT (Centralized Exchanges)\n\n## Overview\n\nThe SDK includes a `ccxt_adapter` that acts as a **multi-exchange factory** for centralized exchanges (CEXes). Each configured exchange becomes a property on the adapter (e.g. `adapter.aster`, `adapter.binance`), and you call the CCXT unified API on that exchange object.\n\n- **Type**: `CCXT`\n- **Module**: `wayfinder_paths.adapters.ccxt_adapter.adapter.CCXTAdapter`\n- **Capabilities**: `exchange.factory`\n\n## When to use (and when not to)\n\n- Use for CEX workflows (Aster, Binance, etc.) **when the user has API credentials** and explicitly wants centralized exchange data or trading.\n- Do **not** use CCXT for Hyperliquid by default. Prefer the native Wayfinder Hyperliquid surfaces (`hyperliquid` resources + `hyperliquid_execute`) unless the user explicitly asks for CCXT/Hyperliquid.\n\n## Config (`config.json`)\n\nAdd a `ccxt` section with exchange IDs and credentials (exchange IDs must match CCXT exchange ids):\n\n```json\n{\n  \"ccxt\": {\n    \"aster\": { \"apiKey\": \"…\", \"secret\": \"…\" },\n    \"binance\": { \"apiKey\": \"…\", \"secret\": \"…\", \"enableRateLimit\": true },\n    \"hyperliquid\": { \"walletAddress\": \"0x...\", \"privateKey\": \"0x...\" }\n  }\n}\n```\n\nNotes:\n- Credentials are passed straight through to each CCXT exchange constructor; exchange-specific params (e.g. `password`, `uid`, `options`) are supported.\n- Exchange IDs must match CCXT’s exchange ids (e.g. `binance`, `bybit`, `aster`, `hyperliquid`).\n\n### Credentials quick reference\n\n| Exchange | Required params |\n|----------|----------------|\n| binance | `apiKey`, `secret` |\n| hyperliquid | `walletAddress`, `privateKey` |\n| aster | `apiKey`, `secret` |\n| bybit | `apiKey`, `secret` |\n| dydx | `apiKey`, `secret`, `password` |\n\n## Init patterns\n\n### Config-driven (recommended)\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        ticker = await adapter.binance.fetch_ticker(\"BTC/USDT\")\n        print(ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\n### Explicit exchanges kwarg (no `config.json` required)\n\n```python\nimport asyncio\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = CCXTAdapter(exchanges={\"aster\": {}, \"binance\": {}})\n    try:\n        ticker = await adapter.aster.fetch_ticker(\"ETH/USDT\")\n        print(ticker.get(\"last\"))\n    finally:\n        await adapter.close()\n\nasyncio.run(main())\n```\n\nThe `exchanges=` kwarg takes priority over `config[\"ccxt\"]`.\n\n## Running CCXT scripts\n\nCCXT is not exposed as a top-level `poetry run wayfinder` command. Use a one-off script via `run_script`.\n\n```python\nimport asyncio\nfrom wayfinder_paths.mcp.scripting import get_adapter\nfrom wayfinder_paths.adapters.ccxt_adapter import CCXTAdapter\n\nasync def main():\n    adapter = get_adapter(CCXTAdapter)\n    try:\n        ticker = await adapter.aster.fetch_t"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (`poetry run wayfinder`). Use when the user wants to check balances, swa... Skill: Wayfinder Owner: canuc Summary: DeFi trading, yield strategies, and portfolio management via the Wayfinder Paths CLI (poetry run wayfinder). Use when the user wants to check balances, swa... Tags: latest:0.0.4 Version history: v0.4.1 | 2026-02-13T22:20:27.670Z | user wayfinder 0.4.1 - Added CCTX -> so that binance can be used. - Added defaiut api RPCs for all ETH + PLASMA + BASE + EFC rpc urls - to avoid publi","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1070,"uniquenessScore":48,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T15:53:17.399Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T20:58:40.931Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}