@0xopenseeddev/sdk
v0.1.0
Published
Programmatic SDK for spawning and managing OpenSeed seller nodes
Readme
@0xopenseeddev/sdk
Programmatic SDK for the OpenSeed network.
Spin up seller nodes, define AI offerings, and orchestrate a local peer network — all from JavaScript.
Installation
The SDK is a workspace package and is available automatically within the monorepo.
Import directly from source:
import { Network, SellerNode, Offering } from './packages/sdk/src/index.js';Or, if published externally:
npm install @0xopenseeddev/sdkQuick Start
import { Network, Offering } from '@0xopenseeddev/sdk';
const net = new Network({
apiKey: process.env.OPENROUTER_API_KEY,
registryUrl: 'http://localhost:9000'
});
net
.addSeller({
port: 8401,
peerId: 'my-node-001',
offerings: [
new Offering('inference')
.name('Llama 3 8B')
.description('Fast open-source model for everyday tasks.')
.services(['llama-3-8b'])
.pricing({ inputUsdPerMillion: 0.05, outputUsdPerMillion: 0.05 })
.upstreamModel('meta-llama/llama-3-8b-instruct:free')
]
});
await net.start();
// SIGINT / SIGTERM are handled automatically — Ctrl+C shuts everything down cleanly.API Reference
Offering
Fluent builder for a single capability advertised by a seller node.
new Offering(capability)| Argument | Type | Description |
|---|---|---|
| capability | 'inference' \| 'agent' \| 'tool' | Capability type |
Chain methods (all return this):
| Method | Argument | Description |
|---|---|---|
| .name(str) | string | Human-readable offering name |
| .description(str) | string | Short description shown to buyers |
| .services(ids) | string[] | Model/service IDs buyers request (e.g. ['gpt-4o-mini']) |
| .pricing(p) | object | Pricing in USD per 1M tokens (see below) |
| .upstreamModel(str) | string | Model name forwarded upstream (e.g. 'openai/gpt-4o-mini') |
Pricing object:
{
inputUsdPerMillion: 0.15, // required
cachedInputUsdPerMillion: 0.075, // optional, defaults to inputUsdPerMillion
outputUsdPerMillion: 0.60 // required
}
.toJSON()validates all required fields and throws if anything is missing.
Example:
new Offering('agent')
.name('Code Master')
.description('Best-in-class coding agent.')
.services(['claude-3-5-sonnet'])
.pricing({ inputUsdPerMillion: 3.00, cachedInputUsdPerMillion: 1.50, outputUsdPerMillion: 15.00 })
.upstreamModel('anthropic/claude-3-5-sonnet')SellerNode
Wraps a forked seller process. Extends EventEmitter.
new SellerNode(opts)Options:
| Option | Type | Required | Description |
|---|---|---|---|
| peerId | string | ✅ | Unique peer identifier |
| port | number | ✅ | HTTP port to listen on |
| offerings | Offering[] | ✅ | At least one Offering instance |
| endpoint | string | — | Public URL buyers connect to (default: http://localhost:<port>) |
| merchantAddress | string | — | On-chain address for payment receipts |
| registryUrl | string | — | Registry base URL (default: http://localhost:9000) |
| apiKey | string | — | Upstream AI provider key |
| upstreamBaseUrl | string | — | Upstream base URL (default: OpenRouter) |
| sellerPrivateKey | string | — | Seller private key for on-chain settlement |
| contractAddress | string | — | AntseedDeposits contract address |
| chainName | string | — | 'base' | 'base-sepolia' | 'localhost' |
| rpcUrl | string | — | RPC endpoint |
| sellerPath | string | — | Override path to seller entry point |
| env | object | — | Extra env vars passed to the child process |
Methods:
await node.start() // fork the process; resolves once forked
await node.stop() // send SIGTERM and wait for exit
node.info() // { peerId, port, endpoint, running, offerings[] }Events:
node.on('started', ({ peerId, port }) => { /* process is up and listening */ })
node.on('error', (err) => { /* fork failed */ })
node.on('exit', ({ peerId, code, signal }) => { /* process exited */ })Example:
import { SellerNode, Offering } from '@0xopenseeddev/sdk';
const node = new SellerNode({
peerId: 'my-node-001',
port: 8401,
apiKey: process.env.OPENROUTER_API_KEY,
offerings: [
new Offering('inference')
.name('GPT-4o Mini')
.services(['gpt-4o-mini'])
.pricing({ inputUsdPerMillion: 0.15, outputUsdPerMillion: 0.60 })
.upstreamModel('openai/gpt-4o-mini')
]
});
node.on('started', () => console.log('Node is ready!'));
node.on('exit', ({ code }) => console.log('Exited with code', code));
await node.start();
// Later:
await node.stop();Network
Orchestrates multiple SellerNode instances with shared defaults.
Extends EventEmitter.
new Network(defaults?)Defaults (applied to every node added via .addSeller()):
| Option | Type | Description |
|---|---|---|
| apiKey | string | Upstream AI provider key |
| upstreamBaseUrl | string | Upstream base URL |
| registryUrl | string | Registry base URL |
| merchantAddress | string | Shared merchant address |
| env | object | Extra env vars (merged with per-node env) |
Methods:
net.addSeller(opts) // same opts as SellerNode; returns Network (chainable)
await net.start() // start all nodes concurrently; hooks SIGINT/SIGTERM
await net.stop() // stop all running nodes concurrently
net.list() // array of node.info() for each node
net.size // number of nodesEvents:
net.on('node:started', ({ peerId, port }) => { })
net.on('node:error', ({ peerId, err }) => { })
net.on('node:exit', ({ peerId, code }) => { })Example — multi-node simulation:
import { Network, Offering } from '@0xopenseeddev/sdk';
const net = new Network({
apiKey: process.env.OPENROUTER_KEY,
registryUrl: 'http://localhost:9000',
merchantAddress: '0xYourAddress'
});
net
.addSeller({
port: 8401,
peerId: 'peer-llama-001',
offerings: [
new Offering('inference')
.name('Llama 3 8B')
.services(['llama-3-8b'])
.pricing({ inputUsdPerMillion: 0.05, outputUsdPerMillion: 0.05 })
.upstreamModel('meta-llama/llama-3-8b-instruct:free')
]
})
.addSeller({
port: 8402,
peerId: 'peer-gemini-002',
offerings: [
new Offering('inference')
.name('Gemini 2.5 Flash')
.services(['gemini-2.5-flash'])
.pricing({ inputUsdPerMillion: 0.27, outputUsdPerMillion: 0.27 })
.upstreamModel('google/gemini-2.5-flash')
]
});
await net.start();
// Ctrl+C → graceful shutdown of all nodesEnvironment Variables
All environment variables from the parent process are inherited by child nodes.
The SDK additionally injects the following:
| Variable | Source |
|---|---|
| PEER_ID | opts.peerId |
| SELLER_PORT | opts.port |
| SELLER_ENDPOINT | opts.endpoint |
| REGISTRY_URL | opts.registryUrl |
| OFFERINGS | serialised JSON of offerings |
| MERCHANT_ADDRESS | opts.merchantAddress |
| OPENAI_API_KEY / ANTHROPIC_API_KEY | opts.apiKey |
| UPSTREAM_BASE_URL | opts.upstreamBaseUrl |
| SELLER_PRIVATE_KEY | opts.sellerPrivateKey |
| CONTRACT_ADDRESS | opts.contractAddress |
| CHAIN_NAME | opts.chainName |
| RPC_URL | opts.rpcUrl |
Package Layout
packages/sdk/
├── src/
│ ├── index.js ← barrel export
│ ├── offering.js ← Offering builder
│ ├── seller.js ← SellerNode (fork wrapper)
│ └── network.js ← Network (multi-node orchestrator)
└── package.jsonSee Also
simulate.js— live example using the SDK to boot a 3-peer local networkpackages/seller— the seller node implementation the SDK forkspackages/cli— CLI that also uses the seller node programmatically
