Skip to content
⌘K

Build a game

SDK reference

Every call of @rare/sdk and @rare/sdk/server, with options, results and error codes.

Install and connect

client
import { Rare } from "@rare/sdk";

const rare = await Rare.connect({ game: "my-game" });
console.log(rare.transport); // "launcher-web", "launcher-native" or "web"

Rare.connect(options) finds a transport and returns a client. With no launcher it falls back to the web transport, which needs game. It throws no_transport only when you force a transport that is not there.

OptionTypeMeaning
gamestringYour game's slug. Native games get it from RARE_GAME if you leave it out. Required for the web transport.
transport"auto" (default), "launcher-web", "launcher-native" or "web"Force one transport. A forced transport that is not there throws no_transport.
network"mainnet" (default) or "testnet"Used by the web transport. On the device the launcher decides.
addressstringWeb transport: the player's address, if your page already knows it.
getAddressfunction returning a promise of an address or nullWeb transport: ask your page's wallet.
openUrlfunction taking a URLWeb transport: how to open rare.market. Default window.open.
apiBase, webBasestringWeb transport: defaults https://rare.market/api/v1 and https://rare.market.
envobjectEnvironment for native detection. Default process.env.
windowobjectDefault globalThis.window.
fetchfunctionDefault globalThis.fetch.
detectTimeoutMsnumberHow long to wait for the injected wallet. Default 300.

Every call takes an optional last argument { signal, timeoutMs }. An aborted signal throws aborted.

Amounts are in MIST. Inputs accept a bigint, a safe-integer number or a string of digits. Results that carry an amount (receivedMist, a notice's amountMist) are bigint. An ItemCard keeps the API's shape, where amounts are decimal strings.

Calls

me

TypeScript
const me = await rare.me();
// { address, username, network, canSign }

canSign is false when the account can only watch. On the web transport address is the one you passed and canSign is false.

inventory

TypeScript
const items = await rare.inventory(); // ItemCard[]

The player's items from this game only: its registered collections and classes. Each is an ItemCard as the Items API returns it (id, name, type, imageUrl, collection, listing, lastSaleMist, topOfferMist, owner, and more).

sell

TypeScript
const r = await rare.sell({ itemId, mode: "best-offer" });
// { status: "sold", digest, receivedMist }
InputMeaning
itemIdThe item to sell.
mode"best-offer" sells into the highest offer. "list" lists. Leave it out and the sheet asks.
priceMistWith "list", the asking price. Leave it out and the sheet asks.

status is sold, listed, cancelled or unavailable. The web transport answers pending.

buy

TypeScript
await rare.buy({ itemId });
await rare.buy({ collection: itemType, kind: 3, maxMist: 2_000_000_000n });

Pass an itemId, or a collection (a Move type or slug) to take the cheapest listing, optionally of one kind and under maxMist. status is bought, cancelled or unavailable, with digest and itemId when bought. The web transport answers pending.

claim

TypeScript
const r = await rare.claim(voucherToken);
// { status: "claimed", digest, objectId }

Submits a voucher your server signed: an item, an item state change or a trophy. The player confirms a one-line sheet and gas is paid where the game's budget allows. Pass the token string from the server. Both base64 and base64url are accepted. status is claimed, cancelled, rejected (the chain would refuse it: expired, wrong player, already used) or unavailable. The web transport answers pending.

open

TypeScript
await rare.open({ view: "trophies" });

view is item, collection, trophies, store or overlay, with an id for item and collection. Off the device the web transport opens the matching rare.market page. overlay only exists in Rare Launcher.

licence

TypeScript
const l = await rare.licence(); // { owned, edition?, lease? }

Rare Store ownership for this game. Only available in Rare Launcher.

Notices

TypeScript
const off = rare.on("notice", (n) => toast(n.title));
rare.on("error", (e) => console.warn(e));
off();       // stop this handler
rare.close(); // stop the stream

The first handler starts the stream and the last one to leave stops it. A notice has id, kind, title, body, itemId, amountMist, digest and the full raw object. Kinds for a game's items are offer_received, sold and bought. On the web transport the stream is /notify/stream for the player's address, which is also how a pending sheet reports its result.

Errors

Every error is a RareError with a code, and status and remoteCode when the other side sent them. Use isRareError(e) to narrow.

CodeMeaning
no_transportNo transport could be found, or a forced one is missing. Off the device, also a missing player address.
unsupportedThe call cannot run here, for example licence off the device.
unauthorizedThe Local API refused the token. Restart the game from the launcher.
forbiddenThe call reaches outside this game's items.
bad_requestBad input, caught before anything was sent or by the server.
not_foundThe item or route does not exist.
rate_limitedSlow down.
timeout, abortedThe call took too long, or you cancelled it.
networkRare could not be reached.
protocolThe other side answered with something that is not the documented shape.
voucher_invalidServer half: a voucher is malformed, expired or does not verify. It is a RareVoucherError.
serverAny other failure on the other side.

Server

server
import { gameKey, itemVoucher, stateVoucher, trophyVoucher, verifyVoucher, RareApi } from "@rare/sdk/server";

const key = gameKey(process.env.RARE_GAME_KEY!);
FunctionReturns
gameKey(secret)A GameKey with publicKey (32 bytes), publicKeyHex and sign. Accepts suiprivkey1..., 64 hex characters, 32 bytes of base64 or the bytes.
generateGameKey(){ key, secret }, for tests. Studio makes real keys.
itemVoucher(key, input)A signed item voucher. Input: classId, player, kind, optional attrs.
stateVoucher(key, input)A signed state voucher. Input: itemId, rev, attrs.
trophyVoucher(key, input)A signed trophy voucher. Input: registryId, gameId, player, trophyId.
verifyVoucher(token, publicKey, options)The parsed voucher, or throws RareVoucherError. Options: player, nowMs.
parseVoucher(token)The parsed voucher without checking the signature.
voucherMessage(voucher)The exact bytes that are signed.

Every signing function also takes ttlMs (default 10 minutes), nonce (default 64 random bits) and nowMs (for tests). Each returns a voucher with its fields, sig (64 bytes) and token, the string you send to the game client. See Voucher signing.

RareApi

TypeScript
const api = new RareApi({ apiKey: process.env.RARE_API_KEY });
const { items } = await api.items({ owner: player, game: "my-game" });
const owns = await api.owns(player, itemId, "my-game");
const game = await api.game("my-game");

A small client for server-side ownership checks. With game, items returns that game's items from the player's cross-game inventory. Without it, it pages every collectible the address holds. Options: apiKey, baseUrl, network, fetch, timeoutMs. Errors are RareError.

--
TPS:--