YieldSignal
APY de empréstimo USDC ponderado por risco em tempo real entre Aave, Compound, Morpho, Moonwell, Euler e Fluid na Base, pago por chamada via x402
Documentação
YieldSignal
Sinais de rendimento ponderados por risco para agentes autônomos, pagos por chamada via protocolo x402 — sem chave de API, sem cadastro. Toda rota de produto é paga: $0.10 sinal, $0.25 análises (durabilidade/capacidade/sensibilidade/exposição), $0.50 decisão, $1.00 persistência. Não há camada gratuita nem parâmetro de bypass.
- Staking líquido de ETH (mainnet Ethereum) em Lido, Rocket Pool, Coinbase Wrapped Staked ETH, Frax Ether e Binance Staked ETH
- Empréstimos de USDC e WETH (Base) em Aave, Compound, Morpho, Moonwell, Euler e Fluid
Sete produtos: o sinal bruto (o que paga melhor agora), a decisão (dado onde seu dinheiro já está, vale a pena movê-lo pelo custo — MOVE/HOLD com ganho líquido esperado e ponto de equilíbrio em dias), o relatório de durabilidade (quanto desse APY sobrevive se os incentivos pararem), o relatório de capacidade (você consegue realmente sacar seu tamanho daquele mercado), o relatório de sensibilidade (quão perto o mercado está do kink onde as taxas de empréstimo explodem), o relatório de exposição (quanto do seu portfólio está atrás do mesmo risco, não importa em quantos lugares esteja distribuído) e o relatório de persistência (por quanto tempo uma chamada aqui realmente se mantém antes que o líder mude — medido a partir das próprias atestações on-chain deste serviço, que é por que nenhum feed concorrente pode produzi-lo).
Ao vivo: https://yieldsignal.vercel.app
GET https://yieldsignal.vercel.app/signal/eth-staking-yield
GET https://yieldsignal.vercel.app/signal/usdc-base-yield
GET https://yieldsignal.vercel.app/signal/weth-base-yield
GET https://yieldsignal.vercel.app/decision/eth-staking-yield?position=lido&amountUsd=25000&horizonDays=30
GET https://yieldsignal.vercel.app/durability/weth-base-yield
GET https://yieldsignal.vercel.app/capacity/usdc-base-yield?amountUsd=200000
GET https://yieldsignal.vercel.app/sensitivity/usdc-base-yield
GET https://yieldsignal.vercel.app/exposure/usdc-base-yield?positions=aave:200000,morpho:150000
GET https://yieldsignal.vercel.app/persistence/usdc-base-yield
/signal e /decision nus (sem ativo) redirecionam para a rota de staking de ETH — o ativo com o histórico verificado mais forte. Formas curtas como /signal/usdc redirecionam para o caminho canônico.
Em qual ativo você deve confiar?
Não acredite em nossa palavra: GET /accuracy.json é gratuito e retorna a taxa de acerto dentro da tolerância por ativo e o arrependimento médio em bps, calculado 1:1 a partir do histórico público on-chain do EAS. No momento em que escrevo, o sinal de staking se sustenta muito melhor que o de empréstimo de USDC (USDC na Base gira rápido demais para uma chamada permanecer verdadeira) — que é exatamente por que o carro-chefe é o staking. Os números são recalculados a partir dos dados da chain, não afirmados aqui, então verifique você mesmo antes de pagar.
Chame sem pagamento primeiro e você receberá um 402 Payment Required com o preço/ativo/rede exatos para pagar. Qualquer cliente compatível com x402 pode completar o pagamento automaticamente — por exemplo com @x402/fetch:
import { wrapFetchWithPayment } from "@x402/fetch";
import { CdpX402Client } from "@coinbase/cdp-sdk/x402"; // or any other x402 client/signer
const client = new CdpX402Client(); // needs CDP_API_KEY_ID/SECRET/WALLET_SECRET + a funded wallet
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPayment("https://yieldsignal.vercel.app/signal/usdc-base-yield");
console.log(await res.json());
// { bestProtocol: "compound", gapBps: 57, rates: [...], asOf: "..." }
MCP
Também disponível como ferramentas MCP pagas em https://yieldsignal.vercel.app/mcp — get_yield_signal e get_yield_decision, ambas com um asset opcional ("ETH_STAKING", "USDC" ou "WETH"; o padrão é "USDC" para compatibilidade retroativa com integrações já publicadas). A maioria dos frameworks de agentes autônomos descobre/chama ferramentas via MCP em vez de clientes HTTP x402 feitos à mão. Usa o pacote oficial @x402/mcp; o pagamento é controlado por chamada de ferramenta (tools/list/initialize permanecem gratuitos, apenas a chamada de ferramenta exige pagamento). Há também um plugin elizaOS no registro oficial.
Formato da resposta
Cada taxa é marcada com de onde veio — onchain/api (Aave, Compound, Morpho — lidos diretamente do protocolo) ou defillama (Moonwell, Euler, Fluid — via API de yields da DefiLlama). Sem números estimados ou fabricados: uma fonte que falha ou retorna dados inválidos é omitida da resposta, nunca adivinhada.
Cada taxa também é comparada em uma base explícita (apyBasis: "supply-apy-total-incl-rewards"): juros base mais incentivos. Isso importa porque as fontes brutas discordam sobre o que "APY" significa — um liquidityRate/getSupplyRate on-chain é apenas base, enquanto o agregado da DefiLlama e o netApy da Morpho já incluem tokens de recompensa. Classificá-los lado a lado sem reconciliar isso compara coisas diferentes. Cada taxa detalha apyBaseBps/apyRewardBps quando a fonte os separa, e rewardBasis diz como o componente de incentivo foi obtido (reported, inferred, included-not-itemized, unavailable). Qualquer protocolo cujo incentivo não pôde ser estabelecido é listado em incompleteRewardData — seu APY é um piso, não um veredito.
{
"asset": "USDC",
"bestProtocol": "compound",
"gapBps": 150,
"rates": [
{ "protocol": "compound", "apyBps": 601, "apyBaseBps": 601, "apyRewardBps": 0, "rewardBasis": "reported", "tvlUsd": 8446455, "tvlBasis": "total-supplied", "weightedApyBps": 595, "source": "onchain", "asOf": "2026-07-30T..." },
{ "protocol": "moonwell", "apyBps": 434, "apyBaseBps": 403, "apyRewardBps": 31, "rewardBasis": "reported", "tvlUsd": 2643239, "tvlBasis": "aggregator-reported", "weightedApyBps": 382, "source": "defillama", "asOf": "..." }
],
"omittedProtocols": ["euler"],
"coverage": { "read": 5, "expected": 6 },
"apyBasis": "supply-apy-total-incl-rewards",
"incompleteRewardData": [],
"asOf": "2026-07-30T..."
}
Profundidade, e se o rendimento é uma campanha
Cada taxa também carrega tvlUsd com um tvlBasis dizendo o que esse número mede — total-supplied quando vem dos próprios livros do protocolo (Aave totalAToken, Comet totalSupply, Morpho totalAssetsUsd), aggregator-reported quando vem da DefiLlama, que reporta liquidez disponível para mercados de empréstimo. Não são a mesma quantidade e o campo diz qual você recebeu. Profundidade importa porque o topo de um mercado raso não é uma taxa executável para tamanho: no momento em que escrevo, o sinal de WETH lidera com um mercado de $716k cujo rendimento é 59% de campanha de incentivo.
As rotas de decisão agem sobre ambos: /decision/* retorna gainDependsOnIncentives e positionShareOfDestinationPct, os declara no reason legível por humanos e reduz a confiança quando sua posição seria uma grande parcela do destino. Uma resposta real:
MOVE, confiançamedium— "Mover aave → euler rende +106bps ajustado ao risco … Nota: todo o ganho depende da campanha de incentivo da euler (172bps dos seus 291bps) — ele desaparece se a campanha terminar. Nota: seus $200,000 seriam 27.9% do mercado de $716,897 da euler — grande o suficiente para que entrar dilua a taxa pela qual você está se movendo."
O rendimento é real? — /durability/*
Divide o APY de cada protocolo em juros base vs incentivo e reporta o piso pós-incentivo: o que você mantém se a campanha de recompensas parar. Em uma leitura ao vivo (2026-08-05), WETH na Base liderou com euler a 299bps — 57.9% disso é incentivo, piso de 126bps — enquanto os 153bps de aave eram inteiramente base. Sem incentivos, o ranking inverte. O endpoint de sinal sozinho teria apontado para a euler.
Duas regras impedem que isso se torne um gerador de falsos alarmes:
- Apenas fontes detalhadas são decompostas.
rewardBasis: "included-not-itemized"ou"unavailable"significa que o piso é desconhecido, e o protocolo é listado emundecomposable— nunca tratado como livre de incentivos. A ausência de um incentivo reportado não é evidência de ausência. - Sem afirmação de ranking quando o líder é opaco. Se o melhor protocolo atual não pode ser decomposto,
rankingChangesWithoutIncentivesénull, nãofalse. Você ainda recebebestVerifiableFloor— o maior rendimento comprovadamente independente de incentivos — que é uma afirmação totalmente medida de qualquer forma.
Apenas empréstimos na Base (USDC/WETH). Verificado ao vivo em 2026-08-05, todas as cinco fontes de staking líquido reportam apyReward: null na DefiLlama — 0 de 5 decomponíveis em cada chamada — então uma rota de durabilidade de staking de ETH cobraria por "não é possível estabelecer". O rendimento de staking ser livre de incentivos é plausível, mas um apyReward ausente não prova isso, e é a mesma inferência que este serviço se recusa a fazer para fluid/morpho no lado de empréstimos.
Deliberadamente não é uma previsão de data. A fonte óbvia para "quando essa campanha termina" é a API da Merkl (earliestCampaignEnd). Verificado ao vivo em 2026-08-05 contra api.merkl.xyz/v4/opportunities?chainId=8453&status=LIVE: Aave, Compound, Euler e Fluid têm zero campanhas LEND lá, e Morpho/Moonwell aparecem apenas como vaults MetaMorpho curados que não são os mercados que este serviço lê. status=PAST retorna timestamps nulos, então o histórico de renovação também não é mensurável. Cobrir 2 de 6 protocolos adivinhando correspondências de vaults — com a maioria das campanhas sendo semanais e com renovação automática — produziria um número de aparência confiante que está errado, que é o oposto do que este serviço vende.
Você consegue realmente sair? — /capacity/*
Um mercado de empréstimo com 99% de utilização paga lindamente e não deixa você sacar; a taxa alta é o sintoma. tvlUsd não consegue distinguir os dois — $100M fornecidos com $99M emprestados e $100M fornecidos com $10M emprestados são o mesmo número.
Utilização e liquidez livre vêm dos próprios livros do protocolo, na mesma chamada que já buscou a taxa (Aave: a tupla getReserveData; Compound: getUtilization() + totalSupply()), então isso custa zero RPC extra. Passe ?amountUsd= e cada protocolo reporta se esse tamanho pode sair agora (canExitNow), a razão de cobertura e qual parcela do mercado seria.
Morpho e os protocolos originados da DefiLlama não publicam emprestado-vs-fornecido, então são marcados como measured: false e nunca são retornados como bestProtocolExecutable. Não medido não é o mesmo que líquido. Os valores em USD são apenas USDC — converter um saldo de WETH exigiria um oráculo de preço dentro de um caminho de resposta pago; WETH ainda recebe utilização, que é adimensional.
Quão perto está o reajuste? — /sensitivity/*
Uma taxa de empréstimo não é um número, é uma função da utilização com um kink. Abaixo dele a taxa rasteja; acima dele, explode. Lido ao vivo em 2026-08-05:
utilization kink headroom borrow APY at 90% → 93%
compound USDC 89.82% 90% 0.18pp 4.08% → 15.95%
aave USDC 86.16% 90% 3.84pp 4.60% → 7.79%
O mercado de USDC da Compound estava a dezoito centésimos de ponto do joelho. O endpoint de sinal sozinho mostra um APY de fornecimento saudável de 3.29% e não diz nada sobre isso.
O kink e ambas as inclinações são lidos do próprio contrato de taxa de juros de cada protocolo — para a Compound, a curva reconstruída é verificada contra getBorrowRate(u), a função pura do próprio contrato, e correspondeu wei-por-wei em 50/85/90/93/99% de utilização; para a Aave, a forma é verificada contra o teto que o próprio contrato reporta (base + slope1 + slope2 == getMaxVariableBorrowRate). Se qualquer verificação falhar, o protocolo é descartado em vez de servido com um número derivado de uma fórmula que mudou.
Esta também é a primeira rota que fala com o tomador em vez do credor.
Apenas Aave e Compound. O AdaptiveCurveIRM da Morpho falha em três contagens independentes, verificado ao vivo: suas constantes de curva não são expostas on-chain (CURVE_STEEPNESS, TARGET_UTILIZATION, ADJUSTMENT_SPEED e INITIAL_RATE_AT_TARGET são todos internal constant, então usá-los significaria codificar números copiados de um repositório); o que é legível, rateAtTarget(id), é estado que deriva com o tempo, não uma curva estática, então "a taxa a 95%" não tem resposta fixa lá; e este serviço lê um vault (Gauntlet USDC Prime, $429M em 5 mercados Blue com colaterais diferentes) cujo curador realoca à vontade. Moonwell, Euler e Fluid vêm da DefiLlama sem nenhum acesso à curva. Todos são reportados como measured: false — nunca como estáveis.
Um risco em três invólucros — /exposure/*
GET /exposure/usdc-base-yield?positions=aave:200000,compound:50000,morpho:150000
O mercado está cheio de detectores de eventos — alertas de desancoragem, alertas de hack, alertas de liquidação — e a maioria deles é gratuita. Nenhum deles responde à pergunta que realmente custa dinheiro: estou exposto, e por qual caminho?
No colapso da Stream Finance, apenas 1 de ~320 vaults MetaMorpho detinha o ativo quebrado diretamente ($700k de dívida inadimplente), mas $93M de perda se tornaram $285M de contágio porque a exposição chegou indiretamente. O evento foi público em horas; o que machucou as pessoas foi não saber que estavam a dois saltos dele.
Uma leitura real em 2026-08-06 para o portfólio acima:
$400k across 3 venues — $200k attributable
collateral cbBTC 81.0% via compound+morpho ← shared
curator 0x9e33fa… 75.0% via morpho
collateral WETH 13.4% via compound+morpho ← shared
parameter kink=9000 100.0% via aave+compound ← shared
unattributed: aave $200k
Três plataformas, e 81% do que pode ser atribuído está atrás de um colateral. A linha kink diz outra coisa: Aave e Compound reajustam ambas a exatamente 90% de utilização, então dividir capital entre elas não compra nenhuma proteção contra um choque de utilização.
A atribuição difere por protocolo, porque as topologias de risco diferem, e o campo basis diz qual você recebeu:
- Morpho (
isolated-market) — cada mercado Blue é isolado com um único colateral, então a atribuição é exata. - Compound (
collateral-basket) — um ativo base contra uma cesta definida, ponderado pelo que é realmente depositado (totalsCollateral× o próprio price feed da Comet). Medido: cbBTC 43,1%, WETH 37,4%, tBTC 7,8%, cbETH 6,9%, wstETH 4,8%. - Aave — reportado como não atribuído, e não por falta de esforço: um fornecedor v3 está exposto a todo o conjunto de colaterais do pool. Atribuí-lo a um único ativo seria falso, e dividi-lo entre todos implicaria uma diversificação que não existe.
As porcentagens são do capital atribuível, não do total — sobre o total elas encolheriam e pareceriam baixa concentração quando a verdade é baixa visibilidade. coverage reporta ambos.
Isso mede exposição compartilhada estrutural — a afirmação factual "essas posições dependem da mesma coisa" — não correlação estatística. Dizer o quanto elas se movem juntas exigiria um histórico de preços que este serviço não possui, e seria uma afirmação mais fraca disfarçada de mais forte.
A detecção de colateral recursivo está deliberadamente ausente. Verificado ao vivo nos 77 mercados Morpho ativos na Base: zero ciclos e zero ativos que são tanto colateral quanto ativo de empréstimo. Pior, a recursão que matou a Stream não estava no gráfico de empréstimos — estava na emissão do sintético (xUSD respaldado por posições financiadas com o USDC emprestado). Um detector de ciclos teria reportado "tudo limpo" durante todo o colapso. Segurança falsa é pior que um alarme falso.
Por quanto tempo a resposta vale? — /persistence/*
GET /persistence/usdc-base-yield
Todo outro endpoint aqui — e todo feed de rendimento concorrente — responde o que paga melhor agora. Nenhum responde por quanto tempo isso permanece verdadeiro, que é o número que decide se mover capital vale o gás.
Este responde a partir das próprias atestações horárias deste serviço na Base. Ao longo de 24 dias e 439 atestações, os três ativos não são o mesmo produto de forma alguma:
| Ativo | Mudanças de liderança | Tempo mediano no topo | Vale a pena perseguir, por $10k, antes do gás |
|---|---|---|---|
| Empréstimo de WETH | 0 | > 518h (piso, censurado) | $6.50 |
| Staking líquido de ETH | 10 | 26h | $0.018 |
| Empréstimo de USDC | 167 | 2h | $0.011 |
Metade dessas 167 trocas de USDC são uma ida e volta entre os mesmos dois protocolos (compound <-> fluid). Seguir esse sinal literalmente custa mais em gás do que a vantagem vale — e até este endpoint existir, nada no catálogo dizia isso.
Também resolve, empiricamente, uma suposição que quase todo mundo faz: uma liderança maior não dura mais. Spearman -0,04 em 177 períodos de liderança concluídos, com as faixas 0-24bps e >=300bps ambas com mediana de 2h. O tamanho da lacuna não é um proxy utilizável para confiança, e este é o único lugar onde esse número é publicado — inclusive quando é desfavorável ao serviço que o publica.
As rotas /decision/* consomem isso internamente: o ganho esperado é projetado sobre o horizonte que você pediu ou a duração medida da liderança, o que for menor. Uma projeção de 30 dias em uma vantagem de 2h é exatamente como um MOVE que só paga gás é recomendado.
Limites honestos, declarados no payload em vez de em uma nota de rodapé: o intervalo de observação é de 1h, então lideranças mais curtas que isso são invisíveis; ativos cuja liderança ainda não mudou reportam um piso com uma flag de censura, nunca uma mediana; e cada número viaja com seu tamanho de amostra, com null sempre que a amostra é pequena demais. Cada entrada é um UID de atestação pública — recalcule o relatório inteiro a partir de base.easscan.org e você obtém os mesmos números sem confiar neste servidor.
Por quanto tempo um sinal é válido?
GET /accuracy.json (grátis) carrega duas medidas independentes, ambas derivadas das atestações públicas on-chain:
score— direcional: o protocolo sinalizado ainda era o líder (ou dentro de 25bps) quando avaliado contra o mercado agora.windowedScore— cada atestação julgada sobre sua própria janela de validade, ou seja, até a próxima atestação para aquele ativo substituí-la.medianWindowHoursé a resposta prática para "com que frequência devo verificar novamente?" e difere nitidamente por mercado: no registro de 2026-07-30, 13h para staking líquido de ETH e empréstimo de WETH, 1h para empréstimo de USDC na Base. USDC rotaciona rápido; isso é uma propriedade do mercado, não um defeito que o endpoint esconde.
O histórico agora cobre mais do que o sinal
Todo o argumento deste serviço é verificável, não prometido — e até 2026-08-06 o registro EAS cobria apenas o sinal. Os quatro produtos de análise foram vendidos apoiando-se na credibilidade que o sinal havia construído, não contribuíram nada de volta para ele e não podiam ser avaliados.
SENSITIVITY_SCHEMA é o primeiro a mudar isso, e a sensibilidade foi escolhida para ir primeiro por um motivo específico: é o único produto cujo registro se transforma em uma questão empírica depois. Com utilização e kink carimbados on-chain a cada leitura, o histórico eventualmente responde "mercados que ficaram a meio ponto do kink — com que frequência cruzaram, e quão rápido?" — e o número de headroom deixa de ser meramente descritivo.
Apenas entradas medidas podem ser atestadas (codificar uma não medida lança erro), e apenas mercados dentro de 5 pontos percentuais do kink são escritos: atestar tudo a cada leitura não tem teto de custo, e um mercado estacionado em 60% de utilização não produz informação que um mês depois não produziria.
Controlado por EAS_SENSITIVITY_SCHEMA_UID. Vazio significa que o gatilho simplesmente não roda — o mesmo interruptor por omissão que a migração do sinal v2 usou. Registrá-lo custa gás real e requer um CONFIRM tipado via npm run register-schema.
Verificabilidade
Documentação completa com cada artefato on-chain, o comando exato para verificar cada um e uma lista honesta do que a stack não resolve:
docs/verifiable-agent-trust.md.
Duas maneiras independentes de verificar se uma resposta não foi adulterada ou fabricada, nenhuma exigindo que você confie no uptime deste servidor no momento da verificação:
- Respostas assinadas — toda resposta REST/MCP é assinada (dados tipados EIP-712) pelo mesmo endereço
payToque o requisito de pagamento 402 nomeia. A struct (asset,bestProtocol,weightedApyBps,gapBps,asOf,contentHash) espelha o esquema EAS on-chain abaixo, mais umcontentHash(keccak256do corpo exato da resposta) vinculando-o à resposta completa. REST: cabeçalhosX-Signal-Signature/X-Signal-Signer/X-Signal-Eip712-Payload. MCP: um bloco de conteúdo irmão. Verifique com viem'sverifyTypedData— ou apenas chamegetSignalVerified()do pacoteyieldsignal-client, que faz ambas as verificações para você. - Atestações on-chain (EAS, mainnet da Base) — registros periódicos, públicos e permanentes de "no tempo T, o protocolo X pagou Y bps, Z à frente do segundo colocado", verificáveis de forma independente em easscan.org sem confiar neste servidor de forma alguma. Mesmo endereço de atestador que as respostas assinadas acima. Publicadas automaticamente sempre que o sinal muda materialmente (o melhor protocolo muda, ou a lacuna se move ≥25bps) ou fica obsoleto (>12h desde a última) — veja
src/attestation/autoAttest.tsePOST /internal/auto-attest(acionado por cron, não a cada chamada paga — isso não teria teto de custo).npm run attestainda existe para publicação manual, sob demanda. Histórico completo emGET /track-record(ou/track-record.json). - Descoberta de agente (ERC-8004, mainnet da Base) —
GET /agent-card.jsoné o arquivo de registro; agentId59272já cunhado emIdentityRegistry. Qualquer comprador REAL (uma carteira que não seja a do próprio serviço — o contrato bloqueia auto-feedback do proprietário/operador) pode deixar feedback verificável emReputationRegistryexecutandonpm run give-feedback— endereços/ABI emsrc/attestation/erc8004.ts.
Arquitetura
Projeto irmão do YieldPilot (um rebalanceador pessoal de Aave/Morpho/Compound), mas totalmente separado: credenciais CDP próprias, carteira receptora própria, nenhum código de runtime compartilhado. Veja CLAUDE.md e SECURITY.md para a documentação técnica completa e o modelo de ameaças.
src/expressApp.ts— o aplicativo Express + gate de pagamento x402 (createX402Server,@x402/express), reutilizado tanto pelo servidor de desenvolvimento local (src/server.ts) quanto pelo entrypoint serverless da Vercel (api/index.ts). Registra uma rota protegida por pagamento por ativo (RESOURCE_PATHS) além de uma verificação de liveness/healthnão paga.src/signal/— a lógica de comparação pura e determinística (sem I/O, totalmente testada por unidade).src/market-data/— a obtenção de dados em duas camadas (leituras diretas + DefiLlama), parametrizada por ativo (AssetId,USDC/WETH) viaBASE_ASSETSdoconfig/networks.ts.src/wallet/walletLock.ts— fixa o endereço da carteira receptora (viaEXPECTED_WALLET_ADDRESSem produção, já que serverless não tem disco persistente) para que uma rotação de credencial CDP seja detectada ruidosamente em vez de redirecionar pagamentos silenciosamente.src/mcp.ts— a ferramenta MCPget_yield_signal(parâmetro opcionalasset), controlada por chamada comcreatePaymentWrapperdo@x402/mcp(não o middleware Express de rota inteira, que colocaria paywall também emtools/list/initialize).src/market-data/cache.ts— TTL de 30s em cada leitor de taxa (direto + DefiLlama), uma instância de cache por ativo, para que uma rajada de chamadas pagas concorrentes não sobrecarregue endpoints públicos de RPC/API.src/notify/paymentLog.ts— registra pagador/tx/rede/valor para cada pagamento liquidado (onAfterSettle, tanto os servidores de pagamento REST quanto MCP) e alerta sobre um pagamento de uma carteira que não é a do proprietário (uma venda real).src/usage/— contadores de funil duráveis (usageStore.ts+usageMiddleware.ts), legíveis emGET /usage.json(autenticação necessária). Conta 402s servidos, tentativas pagas, liquidações, falhas e 404s por rota/ativo. As etapas do lado da venda (paid_attempt/served/settled/failed) são isentas do orçamento diário de eventos — o ruído de crawlers costumava esgotá-lo antes do meio-dia e apagar exatamente as linhas que respondem "isso vende?". Existe porque os logs de runtime da plataforma não são acessíveis de fora, então o único sinal auditável costumava ser a receita on-chain — que não consegue distinguir "ninguém chega" de "eles chegam e não pagam". O backend é qualquer Redis com API REST; a descoberta de credenciais corresponde por sufixo de env-var, então um store conectado através do dashboard da Vercel (que prefixa as variáveis que injeta) é detectado sem mudança de código. Sem store configurado, degrada para contadores em memória por instância e reporta"durable": false.src/cli/withdraw.ts— varre o USDC acumulado para a carteira pessoal do proprietário,CONFIRMmanual necessário, nunca automático.src/wallet/signerAccount.ts— resolve a mesma carteira receptora comsignMessage/signTypedData/sendTransactionexpostos (createX402Serverapenas expõe o endereço); usado para assinatura de respostas e atestação EAS.src/attestation/— definição de esquema EAS e codificação de calldata (pura, testada por unidade);publishAttestation.ts(lógica compartilhada de envio de tx),queryAttestations.ts(cliente GraphQL do EASScan + decodificador),autoAttest.ts(lógica de decisão pura + orquestração para o gatilho automático),trackRecord.ts(comparação então-vs-agora),erc8004.ts(endereços/ABI do registro ERC-8004).src/cli/registerSchema.ts/src/cli/attestSignal.ts/src/cli/registerAgent.ts/src/cli/giveFeedback.ts— registro de esquema único, publicação manual por atestação, cunhagem única de identidade ERC-8004 e feedback de reputação do lado do comprador, mesmo padrãoCONFIRMquewithdraw.ts.giveFeedback.tsé o único script que deliberadamente resolve uma carteira DIFERENTE dewallet/signerAccount.ts— o contrato rejeita feedback do próprio endereço do serviço.
Desenvolvimento local
npm install
npm test # automated tests (market-data readers, signal logic, retry, wallet lock, usage funnel)
npm run signal # live signal, real data, zero credentials needed (`npm run signal -- ETH_STAKING` / `-- WETH` for the other assets)
npm run dev # local x402 server (reads X402_ENVIRONMENT from .env)
npm run test:paid # spins up a test buyer wallet, funds it via the CDP faucet, pays for real (testnet only, REST endpoint)
npm run withdraw # sweep accumulated USDC — asks for typed "CONFIRM"
npm run register-schema # one-time EAS schema registration (mainnet, real gas) — asks for typed "CONFIRM"
npm run attest # publish one on-chain attestation of the current signal (mainnet, real gas) — asks for typed "CONFIRM"
npm run register-agent # one-time ERC-8004 identity mint (mainnet, real gas) — asks for typed "CONFIRM"
npm run give-feedback # a REAL buyer leaves feedback on ReputationRegistry (mainnet, real gas) — asks for typed "CONFIRM". Fails with "Self-feedback not allowed" if run from the service's own wallet.
Consulte .env.example para as variáveis necessárias. Gere seu próprio projeto/credenciais CDP dedicado em portal.cdp.coinbase.com — nunca reutilize o projeto de outra pessoa.
Fonte
github.com/Stakemate369/yieldsignal — código aberto, CI executa typecheck + suíte de testes completa em cada push/PR.
Por que Spark, Seamless e Silo não estão na lista de protocolos
Verificado em yields.llama.fi/pools em 2026-07-16, filtrando chain=Base + symbol=USDC: Spark só tem um pool de USDS (não USDC) na Base; Seamless e Silo não têm nenhum pool indexado na Base no momento. Em vez de inventar um número, esses três foram deixados de fora até que exista um mercado real de USDC para eles na Base — veja o comentário em src/market-data/types.ts.
Por que WETH, mas não WBTC/cbBTC
Verificado ao vivo em yields.llama.fi/pools em 2026-07-17: não há mercado canônico de "WBTC" na Base, apenas o cbBTC da Coinbase (um ativo diferente), e onde há mercado, o APY de fornecimento fica em ~0-0,2% em todos os seis protocolos — um sinal plano demais para valer a pena vender ("qual é o melhor" quase não importa quando todos estão empatados perto de zero). WETH, por outro lado, tem rendimento real e distinto em todos os seis protocolos (0,66%-3,7%), então foi o ativo adicionado no lugar.