Install
$ agentstack add skill-adwilkinson-usdctofiat-peerlytics-starters-query-peerlytics-data ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Query Peerlytics Data
Overview
Guide the user to query ZKP2P protocol data using @peerlytics/sdk. The SDK provides real-time access to P2P exchange rates, orderbooks, maker portfolios, protocol activity, and vault analytics on Base.
Upstream status (2026-09-02)
The Peerlytics REST API is down. peerlytics.xyz/api/v1/* returns 404 for every documented route — authenticated and not — and /developers, /llms.txt and /api/openapi are 404 too, so no new API key can be issued. Every SDK call below will fail against the live host until that is resolved (#15).
Tell the user this before writing code against it. The shapes, filters and error semantics documented here are still accurate and worth building against; the host is not answering.
When to use
- User asks about USDC exchange rates or P2P liquidity
- User wants protocol analytics (volume, deposits, spreads)
- User asks about maker performance or deposit data
- User wants to build a dashboard or monitor with ZKP2P data
- User mentions Peerlytics, ZKP2P, or protocol analytics
Installation
npm install @peerlytics/sdk
Authentication
Two options:
API key (recommended): 1,000 free requests/month.
import { Peerlytics } from "@peerlytics/sdk";
const client = new Peerlytics({ apiKey: "pk_live_..." });
// The portal that issues keys (peerlytics.xyz/developers) is 404 — see Upstream status.
x402 (keyless): Pay per request with USDC on Base. No account needed. This routes to the same 404 endpoints, so it is not a workaround for the outage. Pass auth: { mode: "x402", signer } and the SDK handles the 402 challenge, payment payload, paid retry, and settlement callback.
Response shapes & filters
The SDK (≥ 1.0) targets the Stripe-style v2 wire format (snake_case + Unix seconds + { data, ... } envelopes) but exposes an idiomatic camelCase TS surface — the legacy success: true envelope flag is gone, the SDK unwraps data for you. A few gotchas worth knowing up front:
- List endpoints return objects, not raw arrays.
getActivity,getDeposits,getIntents, andgetMarketSummaryall return a paginated envelope like{ events, count, hasMore, limit, offset, filters }. Iterate over.events/.deposits/.intents/.markets, not the top-level result.
getDepositsandgetIntentstake optional filters. Since SDK 4 an empty call returns a bounded page (limit50 by default, hard-capped at 200) instead of throwing. Narrow it when you can:getDeposits:depositor,delegate,platform,currencygetIntents:owner,recipient,verifier,depositId,status
- Currency resolution on deposits. Deposit responses expose both the raw bytes32 hash and the resolved ISO code: use
market.currency/deposit.currencies[].currency(e.g."GBP"), notmarket.currencyCode/deposit.currencies[].currencyCode(e.g.0xc4ae21...). CallgetCurrencies()if you need to build your own hash→code map.
- Timestamps may be Unix seconds.
ApiKeyInfo.createdAt,ApiKeyInfo.lastUsedAt, andfreeCreditsResetAtare typednumber | string— v2 servers emit Unix seconds (integer), the v1-compat path still emits ISO strings. Convert withNumber(value) * 1000when you need a JSDate.
getTimeseriesreturnsbuckets: TimeseriesBucket[] | null. Single global series populatesbuckets;groupByrequests populateseriesinstead. Always default withdata.buckets ?? []before iterating.
getProtocolSummaryis overloaded. Calling with no args returns the legacyInvestorAnalyticsSummary(mtd,allTime, ...). Pass{ from, to, range, compare }to get the windowed{ window, summary, composition, comparison }payload.
Core patterns
Protocol overview
const summary = await client.getProtocolSummary();
// { mtd: { settledVolumeUsd, activeLiquidityUsd, activeDeposits, ... }, allTime: { ... } }
Exchange rates
const rates = await client.getMarketSummary({ currency: "EUR" });
// Rate stats per platform/currency pair: best rate, average, sample size
Live orderbook
const orderbook = await client.getOrderbook({ currency: "GBP" });
// Orderbook grouped by rate level: rate, totalLiquidity, depositCount
const takerView = await client.getOrderbook({
currency: "GBP",
taker: "0xBuyerWallet",
includeGated: true,
});
// Adds the restricted deposits this wallet can actually fill; count them with
// filters.applied.accessibleRestrictedDepositCount, and read the permitted
// payment-method hashes from takerAccess.paymentMethodsByDeposit.
// SDK 4 returns the access result, not the policy that produced it.
// Without `taker`, the book contains only publicly takeable liquidity.
// Each payment pair carries isPublic plus the disputeProtectionOptedOut /
// disputeProtectionRequiresStake pair. Protection is default-on, so branch on
// the opt-*out* flag; both are null only on a taker-authorized legacy fallback
// that lacks tuple projection.
Maker portfolio
const maker = await client.getMaker("0xMakerAddress");
// Deposits, profit, APR, allocation breakdown, active currencies.
// summary.manualReleaseShare is volume released without a payment proof,
// as a share of released volume — null (never 0) when there is no release
// volume to divide by, so "no data" stays distinguishable from "never".
Deposit detail
const deposit = await client.getDeposit("42");
// Full deposit with intents, payment methods, currencies, status
Live activity
const { events, count, hasMore } = await client.getActivity({
type: "intent_fulfilled",
limit: 20,
});
// getActivity returns { events, count, hasMore, limit, offset, filters }
// — iterate over `events`, not the top-level result.
for (const event of events) {
console.log(event.type, event.amountUsd, event.currency);
}
Vault analytics
const vaults = await client.getVaultsOverview();
// All vaults with AUM, fees, fill count, daily snapshots
Full method reference
Analytics:
getProtocolSummary()— protocol MTD/QTD/YTD/all-time volume, liquidity, depositsgetLeaderboard({ limit?, offset? })— top makers/takers by volume, APR, profit; takers also rankedbyTrustScoregetProtocolOverview(range)— full analytics overview for mtd, 3mtd, ytd, all
Market:
getMarketSummary({ currency?, platform?, includeRates?, limit?, offset? })— rate stats per pairgetOrderbook({ currency?, platform?, minSize?, taker?, includeGated? })— live orderbook by rate level. Unscoped it returns only publicly takeable liquidity;takeradds the restricted deposits that wallet can fill and counts them infilters.applied.accessibleRestrictedDepositCount, andincludeGated: truereturns that viewer's permitted payment-method hashes intakerAccess.paymentMethodsByDeposit
Explorer:
getDeposit(id, { limit?, offset? })— deposit detail with intentsgetDeposits({ depositor?, delegate?, platform?, currency?, status?, accepting?, limit?, offset? })— query deposits. All filters optional; an empty call returns a bounded page (default 50, max 200). Returns{ deposits, count, hasMore, ... }.getIntent(hash)— intent detailgetIntents({ owner?, recipient?, verifier?, depositId?, status?, limit?, offset? })— query intents. All filters optional; an empty call returns a bounded page (default 50, max 200). Returns{ intents, count, hasMore, ... }.getAddress(address, { limit?, offset? })— address profile with statsgetMaker(address)— maker portfolio with allocations, profit, and manual-release exposure (summary.manualReleaseShare)getTaker(address)— taker portfolio: fills, success rate,cancelledVolumeUsd, currency/platform mix. SDK 4 removed the wallet-class label; rank takers bytrustScorefromgetLeaderboard()getIntegrator(code, { windowDays? })— ERC-8021 integrator rollup.windowDaysis currently materialized for 90 only (omit or pass 90).getIntegratorIntents(code, opts?)/getIntegratorReferralFees(code, opts?)— convenience wrappers overgetIntegrator()returningrecentIntents/recentReferralFees.getPlatform(platform, { windowDays? })— platform rollup: currencies, makers, takers, recent intents. Same 90-day rule asgetIntegrator.getDelegate(address)— delegate rollup: rate managers, delegated deposits, PnLgetVerifier(address, { limit?, offset? })— verifier stats and breakdowngetVault(id, { days? })— vault detail with snapshotssearch(query, { type?, role?, limit?, offset? })— multi-type search
Activity:
getActivity({ type?, depositId?, address?, rateManagerId?, since?, limit?, offset? })— live protocol events. Returns{ events, count, hasMore, ... }— iterate over.events, not the top-level result.streamActivity({ type?, rateManagerId?, since?, intervalMs?, limit? }, { signal? })— SSE real-time event stream (returns ReadableStream)
History:
getMakerHistory(address, { from?, to?, range?, limit?, offset? })— maker historical stats with optional date window + pagination cursorgetTakerHistory(address, { from?, to?, range?, limit?, offset? })— taker history, same window semantics asgetMakerHistory
Metadata:
getCurrencies()— supported fiat currenciesgetPlatforms()— supported payment platforms
Vaults:
getVaultsOverview()— all vaults with AUM, fees, snapshotsgetVault(id, { days? })— vault detail with snapshots
Account & keys (SDK ≥ 1.0 takes the opaque id from listKeys(), not the raw key):
listKeys()— list API keys; each entry exposesid(sha256 of the raw key) for use belowcreateKey(label?)— create key (hits dedicatedPOST /account/keys)rotateKey(idOrKey)— rotate key; accepts either the opaqueidor the raw keydeleteKey(id)— delete key byidfromlistKeys()(raw key is no longer accepted)getCredits()— credit balance, free-tier window, and purchase historycreateCheckout(pkg)— purchase credits ("starter" | "growth" | "scale")
Error handling
import { PeerlyticsError, RateLimitError, NotFoundError, ValidationError } from "@peerlytics/sdk";
try {
const data = await client.getMaker(address);
} catch (err) {
if (err instanceof NotFoundError) console.log("Address not found");
if (err instanceof RateLimitError) console.log(`Rate limited, retry in ${err.retryAfter}s`);
if (err instanceof ValidationError) console.log(`Bad request: ${err.code} — ${err.message}`);
if (err instanceof PeerlyticsError) console.log(`HTTP ${err.status}: ${err.message}`);
}
ValidationError covers both server-returned 400s (e.g. invalid_range, unknown_platform) and client-side checks (invalid_address for a malformed address, unsupported_window for a windowDays other than 90).
Links
- npm: https://www.npmjs.com/package/@peerlytics/sdk
- llms.txt: https://github.com/ADWilkinson/usdctofiat-peerlytics-starters/blob/main/peerlytics/llms.txt
- Explorer: https://peerlytics.xyz/explorer
- Starters: https://github.com/ADWilkinson/usdctofiat-peerlytics-starters
The developer portal, OpenAPI spec and hosted llms.txt are 404 — see Upstream status.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ADWilkinson
- Source: ADWilkinson/usdctofiat-peerlytics-starters
- License: MIT
- Homepage: https://offramp-sdk.vercel.app
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.