@solanadeads/gravemarket
v0.2.3
Published
Read-only TypeScript SDK for the Graveyard marketplace public API
Downloads
18
Maintainers
Readme
@solanadeads/gravemarket
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 |
| client.recommendations | similar |
| client.platform | tokenPrices, price, tokenPrice, fees, fee, chains, branding, analyticsConfig, status |
| client.affiliates | config, leaderboard |
| client.config | client |
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
