Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions typescript/.changeset/graph-advocate-action-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@coinbase/agentkit": minor
---

Add Graph Advocate action provider: paid trader-intelligence and agent-reputation actions (Hyperliquid score, Polymarket score, ERC-8004 reputation) that auto-pay over x402 from the agent's wallet on Base. Reuses the existing x402 signing stack, so no new dependencies.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Graph Advocate Action Provider

This directory provides an action provider for [Graph Advocate](https://graphadvocate.com), giving an AgentKit agent paid access to agent-priced onchain-intelligence endpoints. Each action calls a Graph Advocate endpoint gated by x402; the agent's own wallet auto-pays a small USDC fee on Base, and the action returns the JSON result.

Use it when an agent needs to **vet a counterparty wallet or agent** before trusting, paying, following, mirroring a copy-trade, or transacting.

## Actions

| Action | What it returns | Price (USDC on Base) |
|---|---|---|
| `get_hyperliquid_trader_score` | Hyperliquid perps trading skill (0-100): win rate, Sharpe-like return, liquidation rate, funding burn, classification | ~$0.02 |
| `get_polymarket_trader_score` | Polymarket trading skill (0-100): Sharpe-weighted score, win rate, sample size, PnL | ~$0.01 |
| `get_agent_reputation` | Onchain reputation (0-100) from ERC-8004 identity + USDC settlement velocity + recency | ~$0.02 |

All take `{ "wallet": "0x..." }`.

## Wallet Providers

Requires an `EvmWalletProvider` (payments settle in USDC on Base). The provider signs x402 payments exactly the way AgentKit's built-in `x402` provider does (`x402Client` + `wrapFetchWithPayment` + `registerExactEvmScheme`).

## Network Support

Base mainnet only (that is where the x402 payments settle).

## Configuration

```typescript
import { graphAdvocateActionProvider } from "@coinbase/agentkit";

const provider = graphAdvocateActionProvider({
// Per-call spend ceiling in whole USDC. An action priced above this is
// refused before any payment is signed. Defaults to
// GRAPH_ADVOCATE_MAX_PAYMENT_USDC env var, then 1.0.
maxPaymentUsdc: 0.10,
// Optional: override the base URL (e.g. a self-hosted instance).
// baseUrl: "https://graphadvocate.com",
});
```

## Example

```typescript
const agentKit = await AgentKit.from({
walletProvider,
actionProviders: [graphAdvocateActionProvider({ maxPaymentUsdc: 0.10 })],
});
```

Then the agent can, on its own:

```
User: Before I mirror 0x38e5…8a4a on Hyperliquid, is this a sharp trader?
Agent: (calls get_hyperliquid_trader_score) skill_score 71.4, classification "sharp",
win_rate 0.61, sharpe_like 0.84 — paid $0.02 USDC on Base.
```

## Notes

- Payment only settles on a `200`. Non-200 responses return `success: false` and do **not** charge.
- The per-call price is checked against `maxPaymentUsdc` before any signature, so a misconfiguration cannot overspend.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Base URL for the Graph Advocate agent (routing + agent-priced trader intelligence).
*/
export const GRAPH_ADVOCATE_BASE_URL = "https://graphadvocate.com";

/**
* Graph Advocate's x402-paid endpoints. Payments settle in USDC on Base.
* `priceUsdc` is the published per-call price, used to enforce the
* `maxPaymentUsdc` guard before a payment is ever signed.
*/
export const GRAPH_ADVOCATE_ENDPOINTS = {
hyperliquid_trader_score: { path: "/hyperliquid/score", priceUsdc: 0.02 },
polymarket_trader_score: { path: "/polymarket/pnl-quick", priceUsdc: 0.01 },
agent_reputation: { path: "/agent/score", priceUsdc: 0.02 },
} as const;

export type GraphAdvocateEndpointKey = keyof typeof GRAPH_ADVOCATE_ENDPOINTS;

/**
* Graph Advocate settles x402 payments in USDC on Base, so the provider only
* supports Base mainnet.
*/
export const GRAPH_ADVOCATE_SUPPORTED_NETWORKS = ["base-mainnet"];

/**
* Default per-call spend ceiling in whole USDC. Overridable via config or the
* GRAPH_ADVOCATE_MAX_PAYMENT_USDC env var.
*/
export const DEFAULT_MAX_PAYMENT_USDC = 1.0;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { graphAdvocateActionProvider, GraphAdvocateActionProvider } from "./graphAdvocateActionProvider";
import { Network } from "../../network";

describe("GraphAdvocateActionProvider", () => {
let provider: GraphAdvocateActionProvider;

beforeEach(() => {
provider = graphAdvocateActionProvider({ maxPaymentUsdc: 0.1 });
});

describe("supportsNetwork", () => {
it("supports base-mainnet", () => {
expect(provider.supportsNetwork({ networkId: "base-mainnet" } as Network)).toBe(true);
});

it("does not support other networks", () => {
expect(provider.supportsNetwork({ networkId: "ethereum-mainnet" } as Network)).toBe(false);
expect(provider.supportsNetwork({ networkId: "base-sepolia" } as Network)).toBe(false);
});
});

describe("payment cap guard", () => {
it("refuses an action priced above maxPaymentUsdc before signing", async () => {
// maxPaymentUsdc of 0.001 is below every endpoint price, so the action
// must return a 'Payment exceeds limit' error and never touch the wallet.
const capped = graphAdvocateActionProvider({ maxPaymentUsdc: 0.001 });
const result = await capped.getHyperliquidTraderScore(
{} as never,
{ wallet: "0x38e598961dd0456a7fb2e758bd433d3e59fb8a4a" },
);
const parsed = JSON.parse(result);
expect(parsed.error).toBe(true);
expect(parsed.message).toBe("Payment exceeds limit");
});
});

describe("wallet provider guard", () => {
it("rejects a non-EVM wallet provider", async () => {
const result = await provider.getAgentReputation(
{} as never, // not an EvmWalletProvider
{ wallet: "0x38e598961dd0456a7fb2e758bd433d3e59fb8a4a" },
);
const parsed = JSON.parse(result);
expect(parsed.error).toBe(true);
expect(parsed.message).toBe("Unsupported wallet provider");
});
});
});
Loading
Loading