Skip to content

Quickstart

You need a partner key. They are invite-only — there is no signup page. Talk to us and we will issue one scoped to your collections and your domains.

bash
npm i @solanadeads/gravemint

Zero runtime dependencies, dual ESM + CJS, fully typed.

Read a drop

ts
import { GraveMintClient } from '@solanadeads/gravemint'

const gm = new GraveMintClient({ apiKey: 'gm_pub_…' })

const drop = await gm.v1.collection('deads')

drop.collection      // name, symbol, image, chain, socials
drop.stats           // totalSupply, mintedCount, availableCount, percentMinted
drop.phases.active   // the phase that is live right now, or null
drop.serverTime      // our clock — use it for countdowns, never Date.now()

Address a drop by its short id or on-chain address

Not by a database uuid — that is not a public identifier and is not accepted.

Render the price correctly

priceDisplay is already resolved. Branch on kind; never do arithmetic to reconstruct it.

ts
const p = drop.phases.active?.priceDisplay

switch (p?.kind) {
  case 'amount': return `${p.amount} ${p.currency}`
  case 'range':  return `from ${p.min} ${p.currency}`
  case 'hidden': return 'Price revealed when you qualify'
  default:       return 'See on GraveMint'   // 'unknown' — do NOT render 0
}

unknown and hidden are not zero

Rendering 0 as "Free" because a price could not be resolved is the exact failure this shape exists to prevent.

Mint

Three steps, and the middle one is the only part you own.

ts
// 1. we build it
const prepared = await gm.mint.prepare({
  collectionId: drop.collection.id,
  phaseId: drop.phases.active.id,
  walletAddress: wallet.publicKey.toBase58(),
  quantity: 1,
})

// 2. your signer signs it
const signed = await wallet.signTransaction(prepared.transactions[0].transaction)

// 3. we broadcast it
const result = await gm.mint.execute({
  sessionId: prepared.sessions[0].id,
  signedTransaction: signed,
})

You sign. We broadcast.

Never submit a mint transaction to the chain yourself. execute refuses a request carrying transactionHash with CLIENT_BROADCAST_NOT_ALLOWED, and there is no flag to disable that.

It is not bureaucracy: the server compares the signed bytes against the transaction it built — program ids, instruction data, resolved account keys, fee payer — and rejects anything that does not match. That check is what protects your collectors from a tampered transaction, and it is only possible because we are the one submitting.

When you cannot render a drop faithfully

Some mechanics are outside the core surface — packs, gallery mode, generative drops, claim codes. Rather than let you render a wrong panel, the API tells you:

ts
if (!drop.capabilities.supportedBySurface) {
  // drop.capabilities.requiresFeatures  -> e.g. ['claim_codes']
  // drop.capabilities.mintUrl           -> always correct
  return <a href={drop.capabilities.mintUrl}>Mint on GraveMint</a>
}

Showing a panel that quietly omits a mechanic is worse than sending the collector somewhere that handles it.

Next

SDK pages are generated from the published npm tarballs and cannot drift.