Skip to main content

SDK Overview

An Ekza SDK should make integration feel like product integration: list what my game approved, install a verified file, connect a player's account. No blockchain code is needed for that path.

Game SDKs​

PackageForWhat it gives a gameStatus
ekza-bevy-sdk (Rust)Bevy and any Rust engine (default-features = false drops Bevy)The unified catalogue, a store of approved avatars with offline copy, verified download and install, the slug contract, account connection, wallet pairing and tickets, a Bevy loaderWorking, 0.6
@ekza/stellar-sdk (TypeScript)Web games and appsOwned-avatar/passport plus a wallet-independent catalog entry for v2, Space approvals, verified VRM downloads and account contractsWallet path released; catalogue/account entry available on feature/space-account-migration, production rollout pending
@ekza/avatar-rendererReact / three.js surfacesOne shared GLB/VRM avatar componentWorking

Bevy SDK modules​

ModulePurpose
registryHTTP client: catalog_v2 (unified catalogue, narrowed to what a project approved), the older template catalogue and the free library
catalogOne normalized avatar shape for every feed
storeApproved avatars as store items (slug, exact rendition, free), persisted for offline starts; install verifies size, SHA-256 and the GLB envelope, then runs the game's own check before anything is placed on disk
accountConnect a game to a player's account with a short code and read their library; runs off the game loop and exposes a renderable state
passportThe wallet path: pairing, purchased library, one-use tickets, server-side consume
cache, validationVerified download cache and typed model validation issues
bevyResources and an asset loader (behind the bevy feature)

Secrets (device codes, tokens) stay in memory, never appear in URLs or logs, and the types that hold them have no Debug output.

No SDK for your engine yet​

Everything the SDK does is plain HTTP plus two checks. The contracts are documented in Game Integration: GET /v2/avatars, the download with size and SHA-256 verification, the slug derivation, and the account device flow.

Solana SDKs (optional layer)​

These are needed only when a product works with the on-chain layer directly. They live inside the protocol repositories:

PackageRepositoryPurpose
solana-stellar-sdksolana-stellar/sdkIDL, typed Anchor client, PDA helpers, account filters, and instruction helpers for universes, assets, and releases.
avatars-sdk/profilesolana-avatars/sdkProfile client for user_profile.
avatars-sdk/mintersolana-avatars/sdkAvatar collection and minting client for avatar_nft_minter.
EkzaSpaceClientsolana-ekza-space/sdkClient for Config, Space PDAs, minting, and Space settings.

Responsibilities of the Solana SDKs​

They should provide:

  • PDA derivation helpers;
  • typed account fetchers;
  • instruction builders;
  • metadata URI normalization;
  • ownership and license checks;
  • game-ready asset manifest loading;
  • simple integration primitives for inventory, marketplace, or avatar selection.

Space client example​

import {BN, Program, web3} from '@coral-xyz/anchor';
import {EkzaSpaceClient} from './sdk/ekzaSpaceClient';

const client = new EkzaSpaceClient(provider, program);

await client.initConfig({
totalSpaces: 1000,
priceLamports: new BN(0),
});

const {spacePda, mint} = await client.mintNextSpace(1, 'ipfs://bafy.../space.json');

await client.updateSpaceSettings(1, {
name: 'Creator Studio',
spaceConfigUri: 'ipfs://bafy.../space-config.json',
isOpen: true,
isEditableByOthers: false,
});

Stellar release flow​

The Stellar SDK should expose a higher-level release flow:

const universe = await stellar.createUniverse({
metadataUri: 'ipfs://bafy.../universe.json',
projectType: 'model3d',
collaborationPolicy: 'lineageEqual',
open: true,
});

const concept = await stellar.createAsset({
universe,
kind: 'image',
subtype: 'concept',
license: 'cc-by-4.0',
metadataUri: 'ipfs://bafy.../concept.json',
});

const finalModel = await stellar.createAsset({
universe,
kind: 'model3d',
subtype: 'final',
license: 'cc-by-4.0',
metadataUri: 'ipfs://bafy.../model.json',
parents: [concept],
});

// For `LineageEqual` and `Weighted`, finalize needs lineage proof accounts and
// must call the policy-specific finalize instruction.
const release = await stellar.finalizeLineageEqualRelease({
universe,
asset: finalModel,
assetCount: 1,
linkCount: 0,
remainingAccounts: [
concept,
], // pass lineage assets, links, and auto-created share accounts
});

The exact wrapper can evolve, but the application-facing concepts should stay stable: Universe, Asset, Release, Passport, License, Revenue Share.

On-chain asset resolution (planned shape)​

For products that resolve an on-chain release directly, a package should eventually provide the following. This is separate from the game path above, which already exists.

const passport = await ekza.resolveAssetPassport({
chain: 'solana',
release: releasePublicKey,
});

await ekza.assertLicense(passport, {
use: 'in-game-runtime',
gameId: 'omoba',
});

const asset = await ekza.loadGameAsset(passport);
scene.add(asset.model);

Local development​

Current commands:

cd solana-stellar
yarn --cwd sdk build
anchor test

cd solana-ekza-space
anchor build
anchor run litesvm

cd solana-avatars
anchor test

For frontend apps, local package dependencies can point to SDK directories:

{
"dependencies": {
"solana-stellar-sdk": "file:../solana-stellar/sdk",
"avatars-sdk": "file:../solana-avatars/sdk"
}
}