SDK Reference
A JavaScript/TypeScript SDK for licensing user-generated content. Streamlines digital asset licensing with smart license templates, automated agreement creation, and seamless royalty management.
Getting Started
To quickly get up and running with the Spaceport SDK, check out our Quick Start Guide.
Modules
Core
client.SpaceportSDK
Guides
API Authentication
The SDK supports API key authentication for backend services and server-side applications. When an API key is provided, it will be automatically included in all HTTP requests to v1 API endpoints.
Creating Assets and Listings
Here’s a complete example of creating an asset and listing it for licensing:
import { SpaceportSDK, Network } from "@spaceport/sdk";
import { privateKeyToAccount } from "viem/accounts";
import { parseEther } from "viem";
import * as fs from "fs";
import * as path from "path";
async function createAssetAndListing() {
// Initialize SDK with wallet
const account = privateKeyToAccount(`0x${process.env.LICENSOR_PRIVATE_KEY}`);
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// 1. Get or create user
let currentUser;
try {
currentUser = await sdk.users.getCurrentUser();
} catch (error) {
currentUser = await sdk.users.create({
email: "[email protected]",
firstName: "Alice",
lastName: "Creator",
});
}
// 2. Create asset record in Directus
const logoPath = path.join(__dirname, "../media/spaceport_logo.png");
const logoBuffer = fs.readFileSync(logoPath);
const logoFile = new File([logoBuffer], "spaceport_logo.png", {
type: "image/png",
});
const assetResult = await sdk.assets.create({
name: "My Digital Asset",
title: "My Digital Asset",
userId: currentUser.id,
organizationId: currentUser.organizationId,
storageAccess: "public",
description: "A unique digital creation",
tags: ["art", "digital", "nft"],
mediaFile: logoFile,
thumbnailFile: logoFile,
});
// 3. Set up bond token approvals
const requiredAllowance = parseEther("100"); // Adjust based on your needs
await sdk.bondToken.approveAllForAmount(requiredAllowance);
// 4. Get existing smart license
const smartLicenses = await sdk.smartLicenses.getAll({ status: "published" });
const smartLicenseHash = smartLicenses[0]?.smartLicenseHash;
// 5. Create listing
const listingResult = await sdk.listings.create({
licensorAddress: account.address,
price: parseEther("10"), // 10 tokens
smartLicenseHash: smartLicenseHash,
duration: BigInt(365 * 24 * 60 * 60), // 1 year
licenseRoyalties: 200n, // 2%
resellRoyalties: 500n, // 5%
availableAgreements: 100,
listingType: "AutoReview",
assetIds: [assetResult.assetId],
userId: currentUser.id,
organizationId: currentUser.organizationId,
title: "My Digital Asset License",
description: "License for my unique digital creation",
category: "digital-art",
});
// 6. Monitor job status
if (listingResult.jobId) {
const jobStatus = await sdk.utils.pollJobStatus(listingResult.jobId, {
timeout: 300000, // 5 minutes
interval: 3000, // 3 seconds
});
console.log("Listing creation status:", jobStatus.status);
}
}
Job Monitoring
The SDK provides utilities for monitoring asynchronous job operations with configurable timeouts and intervals:
import { SpaceportSDK } from "@spaceport/sdk";
async function monitorJobs() {
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// Monitor a job with custom timeout and polling interval
const jobStatus = await sdk.utils.pollJobStatus(jobId, {
timeout: 300000, // 5 minutes timeout
interval: 3000, // Poll every 3 seconds
});
// Handle different job statuses
if (jobStatus.status === "completed") {
console.log("Job completed successfully!");
// Handle different data structures returned by jobs
let results: any[] = [];
if (Array.isArray(jobStatus.data)) {
results = jobStatus.data;
} else if (jobStatus.data?.value && Array.isArray(jobStatus.data.value)) {
results = jobStatus.data.value;
}
console.log(`Processed ${results.length} items`);
} else if (jobStatus.status === "failed") {
console.error(`Job failed: ${jobStatus.error || "Unknown error"}`);
}
// Monitor multiple jobs in parallel
const jobIds = ["job1", "job2", "job3"];
const jobStatuses = await Promise.all(
jobIds.map((id) => sdk.utils.pollJobStatus(id))
);
}
Product Creation
The SDK provides product management functionality to create products from signed agreement assets:
import { SpaceportSDK } from "@spaceport/sdk";
async function productManagementExamples() {
// Initialize SDK with a wallet and API key
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// Get current user
const currentUser = await sdk.users.getCurrentUser();
// Generate delegated attestation signatures for product creation
const delegatedAttestationParams =
await sdk.products.generateDelegatedAttestationSignatures(2); // For 2 products
// Create products from agreement assets
const productResult = await sdk.products.create({
robloxAssetId: "123456789", // Roblox asset ID
agreementId: "e5a654c3-a5c9-4651-9c93-d0e947154a1a", // Agreement ID from your database
productDetails: [
{
assetId: "asset-uuid-1", // Asset ID from the agreement
title: "My Awesome Product",
description: "A product created from a signed agreement",
},
{
assetId: "asset-uuid-2", // Another asset ID from the agreement
title: "Another Great Product",
description: "Second product from the same agreement",
},
],
delegatedAttestationParams, // Signatures generated above
});
console.log("Product creation result:", productResult);
if (productResult.success) {
console.log("🎉 Products created successfully!");
}
}
Querying Data
The SDK provides a query module for accessing licensing information and agreement history. The query module automatically connects to the appropriate data source based on your network configuration:
import { SpaceportSDK, SpaceportChainType, QueryClient } from "@spaceport/sdk";
async function queryExamples() {
// Option 1: Access the query module via the SDK instance
// This automatically uses the environment from the SDK configuration
const sdk = SpaceportSDK.create({ chain: "devnet" });
console.log(`Using environment: ${sdk.query.getEnvironment()}`); // 'devnet'
// Query active listings
const activeListings = await sdk.query.listings.getActiveListings({
first: 10,
});
console.log(`Found ${activeListings.totalCount} active listings`);
// Option 2: Use the QueryClient directly with a specific environment
// This is useful for standalone queries or when you need to query multiple environments
const queryClient = new QueryClient("testnet");
const testnetListings = await queryClient.listings.getActiveListings({
first: 5,
});
// Common query examples
// Get listings by licensor
const licensorAddress = "0x1234...";
const licensorListings = await sdk.query.listings.getListingsByLicensor(
licensorAddress
);
// Get agreements for a licensee
const licenseeAddress = "0xabcd...";
const licenseeAgreements = await sdk.query.agreements.getAgreementsByLicensee(
licenseeAddress
);
// Get agreements for a licensor
const licensorAgreements = await sdk.query.agreements.getAgreementsByLicensor(
licensorAddress
);
// Get a specific listing by ID
const listingId = "0x1234..."; // Listing identifier
const listing = await sdk.query.listings.getListingById(listingId);
// Get active agreements
const activeAgreements = await sdk.query.agreements.getBindingAgreements();
// Get smart licenses
const smartLicenses = await sdk.query.smartLicenses.getSmartLicenses({
first: 5,
});
// Get a specific smart license by its hash
const smartLicenseHash = "0xabcd...";
const smartLicense = await sdk.query.smartLicenses.getSmartLicenseByHash(
smartLicenseHash
);
// Execute custom queries using the underlying GraphQL client
const client = sdk.query.getGraphQLClient();
const customQuery = `
query {
listingObjects(where: { price_gt: "1000000000000000000" }) {
id
price
licensor
nftId
}
}
`;
const result = await client.query(customQuery).toPromise();
}
Royalty Management
The SDK provides invoice generation functionality to create mock invoice data for testing and development:
import { SpaceportSDK } from "@spaceport/sdk";
async function generateInvoiceData() {
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// Generate mock invoice data for testing
const assetPlatformId = `roblox-${Math.floor(Math.random() * 1000000000)}`;
const csvResult = await sdk.invoices.generateMockInvoiceData({
count: 8, // Number of invoices per quarter
startYear: 2025, // Starting year for invoice data
quarters: 4, // Number of quarters to generate
assetPlatformId: assetPlatformId, // Platform-specific asset ID
});
// Create a File object from the CSV content
const csvFile = new File([csvResult.csvContent], "mock-invoices.csv", {
type: "text/csv",
});
console.log(
`Generated ${csvResult.totalInvoices} invoices across ${csvResult.quarterRanges.length} quarters`
);
// Access quarter ranges for period-based operations
csvResult.quarterRanges.forEach((quarter, index) => {
console.log(
`Q${
index + 1
}: ${quarter.start.toISOString()} - ${quarter.end.toISOString()}`
);
});
return { csvFile, csvResult };
}
Signing License Agreements
Here’s how to sign a license agreement:
import { SpaceportSDK } from "@spaceport/sdk";
import { privateKeyToAccount } from "viem/accounts";
import * as fs from "fs";
import * as path from "path";
async function signAgreement() {
// Initialize SDK with licensee wallet
const account = privateKeyToAccount(`0x${process.env.LICENSEE_PRIVATE_KEY}`);
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// 1. Get or create user
let currentUser;
try {
currentUser = await sdk.users.getCurrentUser();
} catch (error) {
currentUser = await sdk.users.create({
email: "[email protected]",
firstName: "Bob",
lastName: "Licensee",
});
}
// 2. Get available listings
const listings = await sdk.listings.getAll({ status: "published" });
const firstListing = listings[0];
// 3. Get smart license details
const smartLicense = await sdk.smartLicenses.getByHash(
firstListing.smart_license_hash,
"published"
);
// 4. Prepare signing details
const { requiredDetails, requiredFilesMetadata } =
sdk.agreements.getRequiredSigningDetails(smartLicense);
// Load required PDF file
const pdfPath = path.join(__dirname, "../media/pdf-sample_0.pdf");
const pdfBuffer = await fs.promises.readFile(pdfPath);
const pdfFile = new File([pdfBuffer], "originalGameConcept.pdf", {
type: "application/pdf",
});
// Fill in required details
const licenseeSigningDetails = {
details: {
licenseeName: "Acme Corporation",
licenseeOrgAddress: "123 Business St, Metropolis, NY 10001",
licenseeAppointeeName: "Jane Smith",
licenseeAppointeeEmail: "[email protected]",
licenseeJurisdiction: "Delaware, USA",
licenseeNotificationName: "Legal Department",
licenseeNotificationEmail: "[email protected]",
// Add other required fields...
},
files: {
originalGameConcept: pdfFile,
},
};
// 5. Create and sign agreement
const result = await sdk.agreements.createAndSign({
coreListingId: firstListing.id,
onChainListingIds: firstListing.assets.map(
(asset) => asset.on_chain_listing_id
),
licenseeSigningDetails,
storageAccess: "public",
});
// 6. Monitor job status
if (result.jobId) {
const jobStatus = await sdk.utils.pollJobStatus(result.jobId, {
timeout: 300000,
interval: 3000,
});
console.log("Agreement signing status:", jobStatus.status);
}
}
User Management
The SDK provides user management functionality to create and retrieve users associated with wallet addresses:
import { SpaceportSDK } from "@spaceport/sdk";
async function userManagementExamples() {
// Initialize SDK with a wallet
const account = privateKeyToAccount(`0x${process.env.YOUR_PRIVATE_KEY}`);
const sdk = SpaceportSDK.createWithAccount(account, {
chain: "devnet",
apiKey: process.env.SDK_API_KEY,
});
// Create a new user (wallet address is automatically included from SDK)
const newUser = await sdk.users.create({
email: "[email protected]",
firstName: "John",
lastName: "Doe",
});
console.log(`User created: ${newUser.userId}`);
// Get the current user (based on the wallet address used to initialize the SDK)
try {
const currentUser = await sdk.users.getCurrentUser();
console.log(
`Current user: ${currentUser.email} (${currentUser.walletAddress})`
);
} catch (error) {
console.log("No user found for current wallet address");
}
// Get a user by specific wallet address
const walletAddress = "0x1234567890123456789012345678901234567890";
try {
const user = await sdk.users.getByWalletAddress(walletAddress);
console.log(`User found: ${user.email}`);
console.log(`Organization ID: ${user.organizationId}`);
console.log(`Core login enabled: ${user.allowCoreLogin}`);
} catch (error) {
console.log(`No user found with wallet address: ${walletAddress}`);
}
}
Query
query/client.QueryClient
Query Client for interacting with The Graph API
This client provides methods for querying indexed blockchain data
Query/modules
query/modules/agreements.AgreementsQueryModule
Module for querying agreement data from The Graph
query/modules/listings.ListingsQueryModule
Module for querying listing data from The Graph
query/modules/smartLicenses.SmartLicensesQueryModule
Module for querying smart license data from The Graph
Resources
resources/agreements.AgreementClient
The AgreementClient provides methods for interacting with licensing agreements on the Spaceport platform.
Agreements represent the legally binding contract formed when a licensee accepts a licensor’s listing terms.
This client handles actions like creating (signing), and accepting agreements, as well as querying agreement data.
resources/assets.AssetClient
The AssetClient is used to manage digital assets within the Spaceport ecosystem.
Assets are the core digital items, such as 3D models, audio files, or other creative works,
that can be licensed and monetized. This client handles creating and managing the metadata
and files associated with these assets.
resources/bondToken.BondTokenClient
The BondTokenClient provides an interface for interacting with the platform’s utility token, the Bond Token.
This token is used for payments, staking, and other economic activities within the Spaceport and Cultura ecosystem.
This client simplifies operations like checking balances, approving transfers, and minting new tokens.
resources/invoices.InvoiceClient
The InvoiceClient handles operations related to invoices, which are records of sales or usage of licensed assets.
Invoices are typically imported from external platforms (e.g., Roblox sales data) and are used as the basis
for calculating and distributing royalties to rights holders. This client can import, fetch, and even generate
mock invoice data for testing.
resources/listings.ListingClient
The ListingClient is used to manage listings on the Spaceport marketplace.
A listing is an offer made by a licensor to license one or more assets under specific terms,
such as price, duration, and royalties. This client handles creating and querying these listings.
resources/products.ProductClient
The ProductClient manages the lifecycle of products, which represent the instantiation of a licensed asset
on an external platform (e.g., a specific t-shirt on Roblox created from a licensed design).
Products link the Spaceport asset and agreement to its real-world counterpart,
enabling tracking and royalty calculations.
resources/royalties.RoyaltyClient
The RoyaltyClient handles the complex process of royalty management.
Royalties are the payments due to licensors based on the revenue generated by licensed products.
This client provides methods to register sales data (via invoices), calculate royalties,
and manage their payment and acceptance both on-chain and off-chain.
resources/smartLicenses.SmartLicenseClient
The SmartLicenseClient is used to manage Smart License templates on the blockchain.
A Smart License is a reusable, on-chain template that defines the terms and conditions of a license,
such as required licensee information or specific usage rights. These templates are then attached to listings
to standardize and automate the licensing process.
resources/users.UserClient
The UserClient manages user profiles within the Spaceport ecosystem.
A user account is typically associated with a wallet address and holds information
about the user’s identity and activities on the platform. This client handles
user creation and retrieval.