GraveMarket SDK
@solanadeads/gravemarket · version 0.2.4 · install with npm i @solanadeads/gravemarket
This page is generated from the published tarball — it is byte-for-byte the README inside node_modules/@solanadeads/gravemarket at v0.2.4. It is not a summary and it cannot drift.
Read-only TypeScript SDK for the GraveMarket marketplace public API. Wraps public GET endpoints and returns fully typed responses.
- Zero runtime dependencies. Native
fetch. Works in Node 18+, browsers, Cloudflare Workers, Deno, and Bun. - Typed. Full
.d.tsfor every method and response. - Cursor pagination. Async iterator helpers for every paged endpoint.
Install
npm install @solanadeads/gravemarket
# or
pnpm add @solanadeads/gravemarketRequires Node 18+ (uses native fetch and AbortController).
Quick start
import { GravemarketClient } from '@solanadeads/gravemarket';
const client = new GravemarketClient();
// Browse collections — reference by slug or contract address
const page = await client.collections.list({ limit: 25, chain: 'solana-mainnet' });
const first = page.data[0];
console.log(first.name, first.slug, first.contract_address, first.floor_price);
// Fetch an NFT — by mint address (Solana) or `contract:tokenId` (EVM)
const item = await client.items.get('<mint-address>');
// Just the rarity rank/score/tier
const rarity = await client.items.rarity('<mint-address>');
// { rank: 12, score: 184.2, tier: 'legendary', total_supply: 5000 }Legacy
Graveyard*-prefixed exports (e.g.GraveyardClient,GraveyardApiError) remain available as aliases for backward compatibility with existing integrations.
Options
new GravemarketClient({
apiKey: 'gm_...', // recommended — get one at https://gravemarket.io/developers
baseUrl: 'https://api.solanadeads.com', // default
timeoutMs: 30_000, // default 30s
fetch: customFetch, // optional — defaults to globalThis.fetch
headers: { 'X-My-Header': '1' }, // optional default headers
});API keys
The SDK works anonymously by default, but applying for an API key is recommended — anonymous access will be disabled in the future. Generate one at gravemarket.io/developers and pass it via the apiKey option. The SDK sends it as the X-API-Key header on every request.
When the API responds with HTTP 429, the SDK throws a GravemarketRateLimitError exposing retryAfterMs, limit, and remaining:
import { GravemarketRateLimitError } from '@solanadeads/gravemarket';
try {
await client.collections.list();
} catch (err) {
if (err instanceof GravemarketRateLimitError) {
await new Promise((r) => setTimeout(r, err.retryAfterMs ?? 1000));
// retry
}
}Namespaces
| Namespace | Methods |
|---|---|
client.collections | meta, launches, sparklines, list, get, items, activity, stats, traits, holders, offers, traitFloors, traitPricingSummary, crossChain, analytics, floor, listAll, activityAll |
client.items | get, activity, offers, listings, traits, neighbors, priceHistory, rarity |
client.orders | aggregatedListings, bestPrice, aggregatedFloor, offersSummary, onchainStatus |
client.activity | list, listAll |
client.search | query, traits |
client.analytics | platform, collection, compare, heatmap, flow |
client.smartMoney | feed, leaderboard, inflows |
client.walletAnalytics | pnl, pnlLots |
client.trust | collections, wallet |
client.recommendations | similar |
client.platform | tokenPrices, price, tokenPrice, fees, fee, chains, branding, analyticsConfig, status |
client.affiliates | config, leaderboard |
client.config | client |
Smart Money
Track what the top wallets are doing right now.
// Live whale activity feed (cursor-paginated)
const { feed, next_cursor } = await client.smartMoney.feed({ chain: 'solana-mainnet', limit: 25 });
for (const row of feed) {
console.log(row.side, row.collection?.name, row.price_usd, row.from_address);
}
// Top whales by metric over period
const { rankings } = await client.smartMoney.leaderboard({ metric: 'realized_pnl', period: '30d' });
// Collections with the most net whale inflow
const { inflows } = await client.smartMoney.inflows({ period: '7d' });Wallet PnL
Per-wallet profit/loss with FIFO lot tracking.
const summary = await client.walletAnalytics.pnl(wallet, { period: '30d' });
console.log(summary.realized_pnl_usd, summary.unrealized_pnl_usd, summary.win_rate_pct);
// Paginate the underlying lots (open + closed)
const lots = await client.walletAnalytics.pnlLots(wallet, { closed_only: true, limit: 100 });Trust
Wash-trade fingerprints for collections and wallets.
// Top trustworthy / suspicious collections
const cleanest = await client.trust.collections({ sort: 'cleanest', period: '7d', limit: 20 });
const sus = await client.trust.collections({ sort: 'most_suspicious', period: '30d' });
// Wallet wash-rate (returns null pct for wallets under 10 trades)
const t = await client.trust.wallet(wallet);
console.log(t.wash_pct_30d, t.in_cluster);Adjusted volume toggle
Platform / collection analytics accept volume: 'reported' | 'adjusted' (default adjusted). Adjusted volume excludes sales flagged by the wash-trade detector.
const reported = await client.analytics.platform({ period: '7d', volume: 'reported' });
const adjusted = await client.analytics.platform({ period: '7d' }); // adjusted by defaultCollection-level analytics
// Daily series + stats snapshot + holder history for a collection
const a = await client.analytics.collection('apes-collection', { period: '30d' });
// Side-by-side comparison of up to 4 collections
const cmp = await client.analytics.compare({ collection_ids: 'a,b,c', period: '7d' });
// 7×24 liquidity heatmap (UTC) per chain × window
const h = await client.analytics.heatmap({ chain: 'solana-mainnet', metric: 'volume', days: 30 });
// Net flow / buyer-seller mix / hold-time histogram for a collection
const f = await client.analytics.flow('apes-collection-uuid', { period: '7d' });Identifying entities
Reference entities by their public identifiers:
| Entity | Identifier |
|---|---|
| Collection | slug or contract_address |
| Item (NFT) | token_address (Solana mint), or contract_address:token_id (EVM) |
| Wallet | wallet_address |
| Affiliate | affiliate_code |
| Trait | trait_type + trait_value |
Pagination
Cursor-paginated endpoints return { data, cursor, hasMore }. Several namespaces expose *All methods returning async iterators:
for await (const batch of client.collections.listAll({ chain: 'solana-mainnet' })) {
for (const c of batch) console.log(c.slug, c.floor_price);
}Or use paginate() directly:
import { paginate } from '@solanadeads/gravemarket';
for await (const batch of paginate((cursor) =>
client.activity.list({ cursor, type: 'sale', limit: 100 }),
)) {
// ...
}Error handling
import { GravemarketApiError, GravemarketTimeoutError } from '@solanadeads/gravemarket';
try {
await client.items.get('does-not-exist');
} catch (err) {
if (err instanceof GravemarketTimeoutError) {
// request timed out
} else if (err instanceof GravemarketApiError) {
console.error(err.code, err.status, err.message);
} else {
throw err;
}
}The SDK auto-unwraps the { success, data } envelope. If the server returns success: false, a GravemarketApiError is thrown with the server's code and message.
License
MIT
