HELIX 3 Docs
Guides

Sell an item for LIX

Add a server-authoritative, idempotent in-world purchase. The client requests; the server charges LIX and grants the item atomically.

This wires a real in-world purchase. The rule that shapes everything: the client requests, the server settles. LIX is deducted server-side and the grant is idempotent so retries can't double-charge.

The flow

Client requests a purchase. It never touches the wallet directly.

Server validates (price, eligibility, stock), then consumes/charges and grants atomically with an idempotency key.

Wallet & inventory update; the client reacts to the settled result.

Simple catalog purchase

For items priced in the platform catalog, one call does it — settlement is handled for you:

const result = await Helix.marketplace.purchaseItem('premium_sword_001');
if (result.status === 'completed') equip('premium_sword_001');
else showToast(result.reason);
const result = await Helix.marketplace.purchaseItem('premium_sword_001');
if (result.status === 'completed') equip('premium_sword_001');
local result = Helix.marketplace.purchaseItem("premium_sword_001")
if result.status == "completed" then equip("premium_sword_001") end

Custom server-authoritative sale

When you need custom pricing or bundles, the client asks and your HelixInstance server settles:

src/client.ts
const res = await Helix.network.request('buy', { sku: 'starter-bundle' });
if (res.ok) showInventory();
else showToast(res.reason);
src/server.ts
export default class Shop extends HelixInstance {
  async onRequest(player, event, payload) {
    if (event !== 'buy') return;

    const sku = CATALOG[payload.sku];
    if (!sku) return { ok: false, reason: 'Unknown item' };

    const { lix } = await Helix.wallet.getBalance(player.id);
    if (lix < sku.priceLix) return { ok: false, reason: 'Not enough LIX' };

    // atomic: charge LIX + grant item, idempotent on requestId
    const result = await Helix.inventory.purchase({
      buyer: player.id,
      itemId: sku.itemId,
      priceLix: sku.priceLix,
      idempotencyKey: this.requestId,
    });

    return result.ok
      ? { ok: true }
      : { ok: false, reason: result.error };
  }
}

Idempotency is not optional

Networks retry. Without an idempotencyKey, a retried purchase can charge twice. The SDK provides a stable key per request — pass it through. The grant and the charge are one atomic operation.

What the platform handles for you

  • Settlement & fees. Commission and payouts are applied by the platform — you don't compute them.
  • Anti-fraud & limits. Server-side checks live in the economy service.
  • The provider stays hidden. You call Helix.wallet / Helix.marketplace / Helix.inventory; payment internals are never in your code.

On this page