@onyx-aleo/sdk
v1.0.0
Published
Official JavaScript/TypeScript SDK for ONYX — privacy-preserving luxury goods authentication on Aleo
Downloads
6
Maintainers
Readme
@onyx-aleo/sdk
Official JavaScript / TypeScript SDK for ONYX — privacy-preserving luxury goods authentication built on the Aleo blockchain.
Installation
npm install @onyx-aleo/sdk
# or
yarn add @onyx-aleo/sdk
# or
pnpm add @onyx-aleo/sdkRequirements: Node.js ≥ 18 (uses the Web Crypto API and native fetch)
Quick Start
import { OnyxClient } from "@onyx-aleo/sdk";
const onyx = new OnyxClient({
baseUrl: "https://api.onyx-aleo.xyz",
apiKey: "your-jwt-token", // optional for public endpoints
});
// Verify a luxury item's NFC tag
const result = await onyx.artifacts.verify("bhp256(serial_hash, tag_nonce)");
console.log(result.brand?.displayName); // "Hermès"
console.log(result.artifact?.stolen); // false
// Browse the marketplace
const { listings } = await onyx.listings.list({
currency: "USDC",
sort: "newest",
limit: 20,
});Authentication
ONYX uses wallet-signature authentication. The SDK ships a helper for each step:
// 1. Request a challenge nonce
const { nonce, message } = await onyx.auth.challenge("aleo1youraddress...");
// 2. Sign the message with your Aleo wallet (Leo Wallet / Puzzle)
const signature = await window.leoWallet.signMessage(message);
// 3. Exchange signature for a JWT
const { token } = await onyx.auth.login("aleo1youraddress...", signature, nonce);
// 4. Create an authenticated client
const authed = new OnyxClient({
baseUrl: "https://api.onyx-aleo.xyz",
apiKey: token,
});API Reference
OnyxClient
| Namespace | Purpose |
|---|---|
| onyx.auth | Obtain an authentication token |
| onyx.brands | Register a brand, view stats |
| onyx.artifacts | Mint, transfer, verify luxury items |
| onyx.listings | Browse and create marketplace listings |
| onyx.sales | Manage atomic purchase flows |
| onyx.webhooks | Register and manage webhook endpoints |
Brands
// Register your brand (authenticated)
const brand = await onyx.brands.register({ displayName: "MyBrand" });
// Your brand profile
const me = await onyx.brands.me();
console.log(me.artifactCount);
// All registered brands (public)
const brands = await onyx.brands.list();Artifacts
// Mint a new item (brand authentication required)
const artifact = await onyx.artifacts.mint({
tagHash: "bhp256...",
modelId: "bag-001",
serialHash: "bhp256...",
initialOwner: "aleo1owner...",
txId: "at1abc...",
});
// Transfer ownership
await onyx.artifacts.transfer({
tagHash: "bhp256...",
toAddress: "aleo1new_owner...",
txId: "at1xyz...",
});
// Verify any item — no auth needed
const { valid, brand, artifact, listing } = await onyx.artifacts.verify("bhp256...");Listings & Marketplace
// Browse listings
const { listings, total } = await onyx.listings.list({
brand: "aleo1brand...",
currency: "USDC",
minPrice: 1000,
maxPrice: 50000,
sort: "price_asc",
page: 1,
limit: 20,
});
// Single listing
const listing = await onyx.listings.get("listing-id");
// Create a listing (authenticated seller)
const newListing = await onyx.listings.create({
tagCommitment: "...",
tagHash: "bhp256...",
modelId: "bag-001",
title: "Hermès Birkin 30 — Togo Noir",
description: "2023, pristine condition, full provenance chain on Aleo.",
condition: "like_new",
price: 18500,
currency: "USDC",
imageUrl: "https://your-cdn.com/image.jpg",
});Sales
// Initiate a purchase (buyer authentication)
const sale = await onyx.sales.create({
listingId: "listing-id",
tagCommitment: "...",
});
// Poll sale status
const status = await onyx.sales.getByListingId("listing-id");
console.log(status.status); // "pending" | "paid" | "completed"Webhooks
Registering a Webhook
const wh = await onyx.webhooks.register({
url: "https://yourserver.com/onyx-webhook",
events: ["artifact.minted", "sale.completed", "artifact.stolen"],
secret: process.env.WEBHOOK_SECRET!, // store this securely
});
console.log(wh.id);Handling Incoming Events
import {
verifyWebhookSignature,
parseWebhookPayload,
type WebhookPayload,
} from "@onyx-aleo/sdk";
// Express example
app.post("/onyx-webhook", express.raw({ type: "application/json" }), async (req, res) => {
const sig = req.headers["x-onyx-signature"] as string;
const valid = await verifyWebhookSignature(req.body, sig, process.env.WEBHOOK_SECRET!);
if (!valid) return res.status(401).send("Invalid signature");
const payload = parseWebhookPayload(JSON.parse(req.body.toString()));
switch (payload.event) {
case "artifact.minted":
console.log("New item registered:", payload.data);
break;
case "sale.completed":
console.log("Sale completed:", payload.data);
break;
case "artifact.stolen":
console.log("Stolen report:", payload.data);
break;
}
res.sendStatus(200);
});Webhook Events
| Event | Description |
|---|---|
| artifact.minted | A new item was registered by a brand |
| artifact.transferred | Ownership transferred |
| artifact.stolen | Item flagged as stolen |
| listing.created | A listing was published |
| listing.cancelled | A listing was cancelled |
| sale.created | A buyer initiated a purchase |
| sale.completed | Atomic swap completed on-chain |
| sale.cancelled | Sale cancelled or refunded |
Signature Format
The X-Onyx-Signature header uses the format sha256=<hex-hmac> where the HMAC is computed over the raw request body using HMAC-SHA256 and your webhook secret.
Error Handling
import { OnyxClient, OnyxError } from "@onyx-aleo/sdk";
try {
const artifact = await onyx.artifacts.verify("invalid-hash");
} catch (err) {
if (err instanceof OnyxError) {
console.error(err.message); // Human-readable message
console.error(err.status); // HTTP status code
console.error(err.code); // Machine-readable code, e.g. "NOT_FOUND"
}
}TypeScript
All types are exported from the package root:
import type {
Brand,
Artifact,
Listing,
Sale,
VerifyResult,
WebhookPayload,
WebhookEvent,
OnyxClientConfig,
} from "@onyx-aleo/sdk";License
MIT — see LICENSE.
Built with zero-knowledge proofs on Aleo. ONYX: trust without disclosure.
