Repository navigation
Add YieldSignal plugin: six x402-paid yield and risk tools - #596
Stakemate369 wants to merge 11 commits into
Conversation
|
|
Friendly follow-up on this one 🙏 The plugin is tested against the real |
The plugin only offered USDC/WETH lending and built the URL by transforming
the asset name (`${asset.toLowerCase()}-base-yield`). That shortcut cannot
reach ETH liquid staking - it is neither on Base nor lending - and the same
shortcut shipped in a sibling plugin where it silently requested a 404 path.
Replaced with an explicit path map, which is also the only place a new asset
has to be registered.
ETH_STAKING is now selectable and is the asset with the strongest verified
record of the three. The tool description states the comparison basis (base
interest plus incentives) and points at the free accuracy endpoint, so the
model can tell a full reading from a partial one.
|
Pushed a substantive update rather than a ping — the branch had a real gap. ETH liquid staking was unreachable. The client derived the URL from the asset name ( The tool description now states the comparison basis. Upstream, every protocol is compared on base interest plus incentives, and the response lists any protocol it could not read ( Verified: unpaid Free, unpaid endpoint to check the service against: https://yieldsignal.vercel.app/accuracy.json 🤖 Generated with Claude Code |
Three things the earlier revision of this branch got wrong. The plugin shipped ONE tool while the service sells six. The five it hid are the ones that aren't a commodity: a MOVE/HOLD decision that accounts for the cost of moving, incentive durability (how much of an APY survives if rewards stop), exit capacity (whether a given size can actually be withdrawn), borrow-rate sensitivity (distance to the kink, read from the protocol's own curve) and shared exposure (how much capital sits behind the same collateral or oracle across venues). A raw "who pays most" reading is available free elsewhere; those five are not. It forced @coinbase/cdp-sdk on every consumer by provisioning its own wallet from CDP env vars. The x402 client is now injected, so the package depends only on @goat-sdk/core, zod and the published yieldsignal-client, and anyone with an @x402/fetch-compatible signer can use it. The README hardcoded "$0.01 USDC per call", which is no longer the price. Prices now come from the 402 challenge and are not restated in docs that can drift. Also adds the changeset this branch was missing, and unit tests over the parameter schemas. The service itself isn't unit-tested on purpose: @tool resolves its schema through design:paramtypes reflection metadata, which esbuild-based runners (vitest included) do not emit, so importing it under vitest would throw regardless of correctness.
Summary
Adds
@goat-sdk/plugin-yieldsignal, a GOAT plugin for YieldSignal — yield and risk data for lending on Base and ETH liquid staking on Ethereum, paid per call over the x402 protocol.I couldn't find existing x402 support in the GOAT plugin catalog, so this also happens to be a first example of an x402-paid data plugin here, in case that pattern is useful for other paid-API integrations later.
Six tools
yieldsignal_get_yield_signalyieldsignal_get_yield_decisionyieldsignal_get_yield_durabilityyieldsignal_get_exit_capacityyieldsignal_get_rate_sensitivityyieldsignal_get_shared_exposureA raw "who pays most" reading is available free elsewhere; the other five are the reason the API exists.
Design notes
The x402 client is injected, not provisioned. An earlier revision of this branch built its own CDP wallet from env vars, which forced
@coinbase/cdp-sdkonto every consumer. The plugin now takes anx402Client— anything@x402/fetchaccepts — so its dependencies are just@goat-sdk/core,zodand the publishedyieldsignal-client.Prices are not restated in the docs. They come from the 402 challenge, so the README can't drift out of date when they change.
The four risk reports cover lending only (
USDC,WETH). Liquid staking has no utilization curve, no borrow side and no itemized incentive component, so those reports would have nothing to compute against. The parameter schemas enforce this, and there are unit tests over exactly that boundary.The service class is not unit-tested on purpose.
@Toolresolves its schema throughdesign:paramtypesreflection metadata, which esbuild-based runners (vitest included) do not emit — importing the service under vitest throws regardless of correctness. The parameter schemas, which are what the model actually sees, are covered.Verification
biome check --diagnostic-level=error— clean, using this repo's config@goat-sdk/coresource and the publishedyieldsignal-clienttypes@goat-sdk/core/accuracy.jsonThe changeset lives in
typescript/.changeset/next to this repo'sconfig.json. The changeset bot reports "No Changeset found" because it looks at the repository root, where this monorepo has no.changesetdirectory — that warning appears on every PR here.pnpm-lock.yamlis intentionally untouched: my local Node version is outside this repo'senginesrange, so a lockfile generated here would prune unrelated entries. It needs a regularpnpm installon a supported Node to pick up the new package.