Skip to content

Commit 3e40422

Browse files
Morganyyuclaude
andcommitted
Initial commit: @vybenetwork/x402-client
Client SDK for the Vybe x402 API. Pay-per-call HTTP and prepaid-credit WebSocket access to Vybe's Solana analytics API over the x402 payment protocol on Solana mainnet. Security: - UntrustedPaymentError refuses to sign 402 challenges that mismatch the discovered payTo/network or exceed maxUsdPerCall (default $0.10) - No source maps in published artifact Build/publish: - Tag-driven npm release workflow (publish.yml) with provenance via OIDC - 91 unit tests, 12-file tarball (~87 kB) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 parents  commit 3e40422

32 files changed

Lines changed: 7982 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
node-version: [20, 22]
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: ${{ matrix.node-version }}
20+
cache: npm
21+
- run: npm ci
22+
- run: npm run typecheck
23+
- run: npm test
24+
- run: npm run build

.github/workflows/publish.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Publish to npm
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
id-token: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 22
19+
registry-url: "https://registry.npmjs.org"
20+
cache: npm
21+
- run: npm ci
22+
- run: npm run typecheck
23+
- run: npm test
24+
- run: npm run build
25+
- run: npm publish --provenance --access public
26+
env:
27+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules/
2+
dist/
3+
.env
4+
.env.local
5+
*.log
6+
.DS_Store
7+
coverage/
8+
.vitest-cache/

AGENTS.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Vybe x402 Client — Agent Instructions
2+
3+
> Machine-readable instructions for AI agents to make pay-per-call requests to Vybe's Solana analytics API via the x402 protocol.
4+
5+
## Quick Reference
6+
7+
| Requirement | Value |
8+
|-------------|-------|
9+
| Package | `@vybenetwork/x402-client` (npm; pre-release, pin a specific version while in beta) |
10+
| Cost per call | $0.001–$0.010 USDC (depends on endpoint, see discovery) |
11+
| Per-call safety cap | $0.10 USDC default (refuses to sign 402s above this; tune via `maxUsdPerCall`) |
12+
| Network | Solana Mainnet |
13+
| API URL | `https://x402-api.vybenetwork.xyz` (distinct from `api.vybenetwork.xyz`, which is the API-key subscription endpoint) |
14+
| Discovery | `GET https://x402-api.vybenetwork.xyz/` (network, payTo, per-route pricing) |
15+
| Vybe API reference | https://docs.vybenetwork.com/reference |
16+
17+
## Prerequisites
18+
19+
1. Node.js 20+ runtime. The SDK is also browser-compatible for HTTP (see README "Browser" section), but **do not run it in a browser with a raw private key**`loadKeypair` takes the full keypair, which would be exposed to any user, extension, or DevTools tab with page access. Server-side Node is the realistic target today; production browser usage needs wallet-adapter signing (not yet supported).
20+
2. A **dedicated** funded Solana wallet (do not reuse a wallet you also use for trading or other activity — the SDK signs USDC transfers per call, so mixed-purpose wallets create fragile bookkeeping and risk unintended charges):
21+
- **USDC** (mainnet, mint `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`) — pays per call. $0.50 covers ~500 default calls.
22+
- **SOL is NOT required** for the client wallet. The x402 API pays Solana gas on every transfer. The wallet only needs USDC and an associated USDC token account (created the first time anyone sends USDC to it).
23+
3. A Solana RPC URL. The SDK signs each payment client-side, which makes 2 RPC calls per paid request (`fetchMint` + `getLatestBlockhash`).
24+
- Public mainnet RPC works for sequential demo use (~5 RPS ceiling).
25+
- For any concurrency, use a paid tier. [Helius](https://www.helius.dev/) free tier gives 10 RPS, no card.
26+
- Helius offers an agent-friendly CLI signup: see https://dashboard.helius.dev/agents.md — pays 1 USDC, returns an API key in JSON.
27+
28+
## Complete Flow
29+
30+
### Step 1: Install
31+
32+
```bash
33+
npm install @vybenetwork/x402-client
34+
```
35+
36+
### Step 2: Load Keypair
37+
38+
```ts
39+
import { VybeClient, loadKeypair } from "@vybenetwork/x402-client";
40+
41+
const client = new VybeClient({
42+
wallet: await loadKeypair(process.env.CLIENT_PRIVATE_KEY!), // base58 (Phantom export) OR base64 — auto-detected
43+
rpcUrl: process.env.SOLANA_RPC_URL, // strongly recommended
44+
budget: { maxUsd: 1.00, onExceed: "reject" }, // optional cumulative-spend cap
45+
});
46+
```
47+
48+
`loadKeypair` accepts a base58 string (Phantom-style export), a base64 string, or — in Node — a file path via `loadKeypair.fromFile(path)`. The wallet's public address is exposed as `client.wallet.address`; private key never leaves the SDK.
49+
50+
### Step 3: Make a Paid Call
51+
52+
```ts
53+
const tokenInfo = await client.get("/v4/tokens/<mintAddress>");
54+
```
55+
56+
Method maps:
57+
- `client.get(path)` — GET, parsed body returned.
58+
- `client.request(path, init)` — any HTTP method (POST batch endpoints use `request` with `method: "POST"` and JSON body).
59+
60+
The SDK auto-handles the 402 challenge: first request returns 402 with payment requirements, SDK signs a USDC transfer matching those terms, retries with the signed payment header, returns the body. Single `await`.
61+
62+
### Step 4 (optional): Stream via WebSocket
63+
64+
For event streams, pay once for a session of prepaid credits, then connect a WebSocket. Auto-topup when low. See README "WebSocket streaming" section.
65+
66+
## Endpoint Discovery
67+
68+
Two ways:
69+
70+
1. **Vybe API reference** — full endpoint catalog at https://docs.vybenetwork.com/reference. Every endpoint listed there is callable through the x402 API at the same path (`/v4/tokens/{mintAddress}`, `/v4/account/{ownerAddress}/pnl`, etc.) — just swap the base URL.
71+
2. **Vybe MCP** — Vybe ships an MCP server with searchable endpoint metadata: https://docs.vybenetwork.com/docs/mcp. Useful if your agent runtime supports MCP. The MCP also exposes a `pay-with-x402` custom tool that returns step-by-step instructions for paying via this SDK — calling that tool first is a fast on-ramp for agents that just need to know "how do I pay for these endpoints?".
72+
73+
## Pricing
74+
75+
Discovery endpoint returns the current price table:
76+
77+
```bash
78+
curl https://x402-api.vybenetwork.xyz/
79+
```
80+
81+
Price tiers (heavier endpoints cost more — `GET /` is authoritative):
82+
83+
| Price | Example endpoints |
84+
|-------|-------------------|
85+
| $0.001 | token info, balances, known-accounts |
86+
| $0.003 | candles, ohlcv |
87+
| $0.005 | pnl, top-traders |
88+
| $0.008 | top-holders, transfers, trades |
89+
| $0.010 | batch POSTs (token-balances, etc.) |
90+
91+
## Error Handling
92+
93+
The SDK throws typed errors. Match on `instanceof`:
94+
95+
```ts
96+
import {
97+
VybeClient,
98+
PaymentRequiredError,
99+
ApiError,
100+
NetworkError,
101+
BudgetExceededError,
102+
InsufficientCreditsError,
103+
ServiceUnavailableError,
104+
UntrustedPaymentError,
105+
} from "@vybenetwork/x402-client";
106+
107+
try {
108+
const data = await client.get("/v4/tokens/...");
109+
} catch (err) {
110+
if (err instanceof BudgetExceededError) { /* cumulative cap hit; stop */ }
111+
else if (err instanceof PaymentRequiredError) { /* 402 after retry — verify failed */ }
112+
else if (err instanceof ApiError) { /* API 4xx/5xx — err.status, err.body */ }
113+
else if (err instanceof NetworkError) { /* transport — likely RPC 429 in err.cause */ }
114+
else throw err;
115+
}
116+
```
117+
118+
| Error | Meaning | Action |
119+
|-------|---------|--------|
120+
| `PaymentRequiredError` | 402 returned after signed retry | Inspect `err.payment`. Usually means RPC blockhash expired in flight; retry. |
121+
| `ApiError` (status 429) | Per-wallet rate limit (600/min/payer) | Backoff 1s, retry. Use multiple wallets to scale. |
122+
| `ApiError` (status 4xx) | User error — bad path, bad params | Check `err.body`. Pay-on-success: 4xx still bills. |
123+
| `ApiError` (status 5xx) | API failure | No charge — payment is abandoned server-side. Retry with backoff. |
124+
| `NetworkError` | Transport error (DNS, RPC 429, fetch failure) | Inspect `err.cause`. Most common cause: client RPC throttled — use a paid tier. |
125+
| `BudgetExceededError` | Cumulative spend cap hit | Stop or raise the cap. |
126+
| `UntrustedPaymentError` | SDK refused to sign — payTo / network mismatch, or amount > `maxUsdPerCall` | No funds at risk (thrown before signing). Inspect `err.reason`. Raise `maxUsdPerCall` only after auditing the new pricing. |
127+
128+
## Inspecting Spend
129+
130+
```ts
131+
client.budgetState();
132+
// → { spentUsd: 0.027, capUsd: 1.00, remainingUsd: 0.973 }
133+
```
134+
135+
## See Also
136+
137+
- README: https://github.com/vybenetwork/x402-client#readme
138+
- x402 protocol: https://x402.org
139+
- Vybe API reference: https://docs.vybenetwork.com/reference
140+
- Vybe MCP: https://docs.vybenetwork.com/docs/mcp
141+
- Helius (RPC): https://www.helius.dev/ — agent signup: https://dashboard.helius.dev/agents.md

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Vybe Network
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)