AI TypeScript SDK (`@rivellum/ai-sdk`)
The AI-native TypeScript SDK for autonomous agent interactions on Rivellum. Purpose-built for AI agents, bots, and LLM-driven workflows that need to perform payments, manage escrow, stream funds, interact with the service marketplace, and coordinate multi-agent systems.
Installation
npm install @rivellum/ai-sdk
# or
pnpm add @rivellum/ai-sdk
Quick Start
import { RivellumAgent } from '@rivellum/ai-sdk';
const agent = new RivellumAgent({
nodeUrl: 'https://rpc.rivellum.network',
sessionKey: 'sk_your_session_key',
});
// Pay another agent
const result = await agent.pay({ to: '0xabc...64hex', amount: 1_000_000 });
// Purchase a service
const purchase = await agent.purchase({ serviceId: 'weather-api-us', maxPrice: 250_000 });
// Create an escrow
const escrow = await agent.escrow({
provider: '0xdef...64hex',
amount: 5_000_000,
description: 'GPU compute job',
ttlSecs: 3600,
});
RivellumAgent
Constructor
new RivellumAgent(options: RivellumAgentOptions)
| Parameter | Type | Required | Description |
|---|---|---|---|
options.nodeUrl | string | ❌ | Node RPC base URL. Defaults to http://localhost:8090. |
options.sessionKey | string | ❌ | Session key for authenticated requests (auto-injected into all POST bodies). |
options.timeoutMs | number | ❌ | Request timeout in ms. Default: 30000. |
Async context manager support:
async using agent = new RivellumAgent({ nodeUrl: 'https://rpc.rivellum.network' });
// or manually:
await agent.close();
Payment Methods
pay(opts)
async pay(opts: PayOptions): Promise<AiIntentResponse>
Sends a simple payment to another address.
Parameters:
interface PayOptions {
to: string; // Recipient address (hex, 64 chars)
amount: number; // Amount in base units
maxSlippageBps?: number; // Max slippage in basis points
idempotencyKey?: string; // Deduplicate retries
}
Returns: AiIntentResponse
interface AiIntentResponse {
accepted: boolean;
intent_id?: string;
status: string;
estimated_cost?: number;
error?: string;
}
const result = await agent.pay({
to: 'a1b2c3...64hex',
amount: 500_000,
idempotencyKey: 'pay-job-42',
});
if (result.accepted) {
console.log('Intent ID:', result.intent_id);
}
purchase(opts)
async purchase(opts: PurchaseOptions): Promise<AiIntentResponse>
Purchases a service from the marketplace. The node handles service discovery and payment routing.
interface PurchaseOptions {
serviceId: string; // Service identifier from marketplace
maxPrice: number; // Max price willing to pay (base units)
freshnessSecs?: number; // Max staleness of service data (seconds)
}
const result = await agent.purchase({
serviceId: 'flight-prices-global',
maxPrice: 100_000,
freshnessSecs: 60,
});
subscribe(opts)
async subscribe(opts: SubscribeOptions): Promise<AiIntentResponse>
Creates a recurring subscription to a service.
interface SubscribeOptions {
serviceId: string;
maxPricePerPeriod: number; // Max spend per billing period
periods: number; // Number of periods to subscribe for
}
await agent.subscribe({
serviceId: 'realtime-weather-feed',
maxPricePerPeriod: 50_000,
periods: 30, // 30 billing periods
});
intent(action)
async intent(action: Record<string, unknown>): Promise<AiIntentResponse>
Raw intent submission — pass any action dict for maximum flexibility. All standard fields (session key, etc.) are auto-injected.
await agent.intent({
type: 'transfer',
to: '0xabc...',
amount: 1000,
memo: 'custom action',
});
Escrow Methods
escrow(opts)
async escrow(opts: EscrowOptions): Promise<EscrowResponse>
Creates an on-chain escrow contract between the agent (buyer) and a provider.
interface EscrowOptions {
provider: string; // Provider address (hex)
amount: number; // Amount locked in escrow
description: string; // Job/contract description
ttlSecs: number; // Expiry in seconds from now
verification?: string; // Optional verification hash/proof schema
}
Returns: EscrowResponse
interface EscrowResponse {
escrow_id: string;
state: string; // 'active' | 'released' | 'disputed' | 'expired'
amount: number;
provider: string;
buyer: string;
created_at: number; // Unix timestamp (ms)
expires_at: number; // Unix timestamp (ms)
}
const escrow = await agent.escrow({
provider: 'a1b2...64hex',
amount: 2_000_000,
description: 'Fine-tune LLM on custom dataset',
ttlSecs: 86400, // 24 hours
});
console.log('Escrow ID:', escrow.escrow_id);
console.log('Expires:', new Date(escrow.expires_at));
releaseEscrow(escrowId, proof?)
async releaseEscrow(escrowId: string, proof?: string): Promise<AiIntentResponse>
Releases escrowed funds to the provider. Optionally provide a proof string to verify job completion.
await agent.releaseEscrow(escrow.escrow_id, completionProofHash);
disputeEscrow(escrowId, proof?)
async disputeEscrow(escrowId: string, proof?: string): Promise<AiIntentResponse>
Opens a dispute on an escrow. Funds are held until resolution.
await agent.disputeEscrow(escrow.escrow_id, 'job output does not match specification');
getEscrow(escrowId)
async getEscrow(escrowId: string): Promise<EscrowResponse>
Returns the current state of an escrow.
const status = await agent.getEscrow(escrow.escrow_id);
console.log('State:', status.state);
Service Marketplace Methods
searchMarket(opts?)
async searchMarket(opts?: MarketSearchOptions): Promise<MarketQueryResponse>
Searches the service marketplace.
interface MarketSearchOptions {
category?: string; // e.g. 'compute', 'data', 'models', 'inference'
maxPrice?: number; // Filter by max price
minReputation?: number; // Filter by min reputation score (0–100)
query?: string; // Free-text search
limit?: number;
}
Returns: MarketQueryResponse
interface MarketQueryResponse {
results: MarketResult[];
total: number;
}
interface MarketResult {
service_id: string;
name: string;
category: string;
price: string;
reputation: number; // 0–100
provider: string; // Provider address
description: string;
}
const results = await agent.searchMarket({
category: 'inference',
minReputation: 80,
query: 'GPT-4 compatible',
limit: 10,
});
for (const svc of results.results) {
console.log(`${svc.name} — ${svc.price} (rep: ${svc.reputation})`);
}
marketData(params?) / marketCompute(params?) / marketModels(params?)
async marketData(params?: Record<string, string | number>): Promise<MarketQueryResponse>
async marketCompute(params?: Record<string, string | number>): Promise<MarketQueryResponse>
async marketModels(params?: Record<string, string | number>): Promise<MarketQueryResponse>
Convenience methods to browse the data, compute, and model sub-marketplaces respectively.
const models = await agent.marketModels({ limit: 20 });
const compute = await agent.marketCompute({ min_vram_gb: 24 });
registerService(opts)
async registerService(opts: RegisterServiceOptions): Promise<RegisterServiceResponse>
Registers a service on the marketplace so other agents can discover and purchase it.
interface RegisterServiceOptions {
name: string;
category: string; // 'compute' | 'data' | 'models' | 'inference' | custom
description: string;
endpoint: string; // Public HTTPS endpoint for the service
pricingModel: string; // 'per_call' | 'per_token' | 'subscription' | 'auction'
price: number; // Price per unit (base units)
}
Returns: RegisterServiceResponse
interface RegisterServiceResponse {
service_id: string;
status: string;
}
const service = await agent.registerService({
name: 'Weather Oracle',
category: 'data',
description: 'Real-time weather data for 100+ cities',
endpoint: 'https://weather-oracle.example.com',
pricingModel: 'per_call',
price: 10_000,
});
console.log('Service ID:', service.service_id);
Agent Wallet Methods
createAgent(opts)
async createAgent(opts: CreateAgentOptions): Promise<CreateAgentResponse>
Creates a new agent wallet with a spending limit and optional permissions.
interface CreateAgentOptions {
owner: string; // Owner address (hex)
spendingLimit: number; // Total spending limit (base units)
permissions?: string[]; // e.g. ['pay', 'escrow', 'market']
expiresInSecs?: number; // Wallet expiry from now (seconds)
kind?: string; // Agent kind: 'bot', 'llm', 'oracle', etc.
name?: string; // Human-readable agent name
}
Returns: CreateAgentResponse
interface CreateAgentResponse {
agent_id: string;
wallet_address: string;
status: string;
}
getAgent(agentId)
async getAgent(agentId: string): Promise<AgentProfileResponse>
Returns the profile for an agent.
interface AgentProfileResponse {
agent_id: string;
kind: string;
name?: string;
wallet_address: string;
reputation_score: number;
total_spent: number;
active_escrows: number;
active_streams: number;
created_at: number;
}
getReputation(address)
async getReputation(address: string): Promise<ReputationResponse>
Returns the reputation profile for any address.
interface ReputationResponse {
address: string;
score: number; // 0–100
total_transactions: number;
success_rate: number; // 0.0–1.0
avg_latency_ms: number;
dispute_rate: number; // 0.0–1.0
}
createSession(agentId, opts)
async createSession(agentId: string, opts: CreateSessionOptions): Promise<CreateSessionResponse>
Creates a session key for an agent with a capped spending limit and expiry.
interface CreateSessionOptions {
maxSpend: number; // Max tokens this session can spend
expiresInSecs: number; // Session lifetime in seconds
allowedActions?: string[]; // Default: ['pay', 'purchase', 'subscribe']
rateLimitPerMinute?: number; // Max operations per minute
}
Returns: CreateSessionResponse
interface CreateSessionResponse {
session_key: string; // Pass as sessionKey in constructor for subsequent calls
expires_at: number; // Unix timestamp (ms)
max_spend: number;
status: string;
}
const session = await agent.createSession('agent-123', {
maxSpend: 500_000,
expiresInSecs: 3600,
allowedActions: ['pay', 'purchase'],
rateLimitPerMinute: 60,
});
// Use the session key in a new agent instance
const sessionAgent = new RivellumAgent({
nodeUrl: 'https://rpc.rivellum.network',
sessionKey: session.session_key,
});
getBudget(agentId)
async getBudget(agentId: string): Promise<AgentBudgetResponse>
Returns the current budget status for an agent.
interface AgentBudgetResponse {
agent_id: string;
wallet_address: string;
total_budget: number;
spent: number;
remaining: number;
active_streams: number;
active_escrows: number;
session_remaining?: number; // Remaining session-key budget
}
Payment Stream Methods
Streams enable continuous micropayment flows — ideal for metered services (API calls per-second, GPU billing, data streaming).
startStream(opts)
async startStream(opts: StreamStartOptions): Promise<StreamResponse>
interface StreamStartOptions {
receiver: string; // Receiving address (hex)
ratePerSecond: number; // Tokens streamed per second
maxBudget: number; // Total budget cap for the stream
serviceId?: string; // Optional associated service ID
}
Returns: StreamResponse
interface StreamResponse {
stream_id: string;
state: string; // 'active' | 'paused' | 'stopped' | 'exhausted'
rate_per_second: number;
total_streamed: number;
remaining_budget: number;
}
const stream = await agent.startStream({
receiver: 'provider...64hex',
ratePerSecond: 1_000,
maxBudget: 3_600_000, // 1 hour at 1000/sec
serviceId: 'gpu-inference',
});
console.log('Stream ID:', stream.stream_id);
stopStream(streamId)
async stopStream(streamId: string): Promise<StreamResponse>
Immediately halts a payment stream. Any unstreamed budget is returned.
getStream(streamId)
async getStream(streamId: string): Promise<StreamResponse>
Returns the current status of a stream.
Discovery Methods
topProviders(opts?)
async topProviders(opts?: {
limit?: number;
minScore?: number;
category?: string;
}): Promise<ProvidersResponse>
Returns the highest-reputation service providers.
interface ProvidersResponse {
providers: ReputationResponse[];
total: number;
}
const top = await agent.topProviders({ limit: 10, minScore: 90, category: 'compute' });
for (const p of top.providers) {
console.log(`${p.address}: score ${p.score}, txns ${p.total_transactions}`);
}
Common Patterns
Autonomous Agent Workflow
const agent = new RivellumAgent({
nodeUrl: 'https://rpc.rivellum.network',
sessionKey: process.env.SESSION_KEY,
});
// 1. Find a service
const results = await agent.searchMarket({ category: 'inference', minReputation: 85 });
const service = results.results[0];
// 2. Create escrow for the job
const job = await agent.escrow({
provider: service.provider,
amount: parseInt(service.price) * 100, // 100 API calls
description: `Batch inference: ${jobId}`,
ttlSecs: 3600,
});
// 3. Do the work, then release
const result = await callExternalService(service, job.escrow_id);
await agent.releaseEscrow(job.escrow_id, hashProof(result));
Start a GPU Compute Stream
const stream = await agent.startStream({
receiver: gpuProviderAddress,
ratePerSecond: 5_000, // 0.005 tokens/sec
maxBudget: 18_000_000, // 1 hour cap
serviceId: 'h100-cluster-01',
});
// On completion
await agent.stopStream(stream.stream_id);
const final = await agent.getStream(stream.stream_id);
console.log('Total streamed:', final.total_streamed);
Multi-Agent Budget Allocation
// Create a sub-agent with limited budget
const subAgent = await agent.createAgent({
owner: masterAddress,
spendingLimit: 100_000,
permissions: ['pay', 'purchase'],
kind: 'llm',
name: 'Research Assistant',
});
// Create a session key for the sub-agent
const session = await agent.createSession(subAgent.agent_id, {
maxSpend: 50_000,
expiresInSecs: 7200,
});
// Hand off to sub-agent process
const childAgent = new RivellumAgent({
nodeUrl: 'https://rpc.rivellum.network',
sessionKey: session.session_key,
});
Bounded Collection Types
The AI SDK exports Mist bounded collection type definitions for use with on-chain AI contracts.
import type { BoundedListSpec, BoundedMapSpec, BoundedSetSpec, BoundedQueueSpec } from '@rivellum/ai-sdk';
| Type | Description |
|---|---|
BoundedListSpec<T> | Ordered list with a fixed capacity cap |
BoundedSetSpec<T> | Unordered set with a capacity cap |
BoundedMapSpec<K,V> | Key-value map with a capacity cap |
BoundedSortedMapSpec<K,V> | Sorted map with a capacity cap |
BoundedQueueSpec<T> | FIFO queue with a capacity cap |
const leaderboard: BoundedSortedMapSpec<string, number> = {
keyType: 'address',
valueType: 'u64',
capacity: 100,
entries: [['0xabc...', 9500], ['0xdef...', 8700]],
};
Element types: 'u64', 'address', 'int', 'bool', 'string'
Intent Receipt Types
interface IntentReceipt {
intentKind: string;
status: 'accepted' | 'rejected' | 'matched' | 'partially_matched' | 'liquidated';
reasonCode: number;
feePaidMicros: number;
oracleCheck: 'accepted' | 'stale_rejected' | 'deviation_rejected' | 'circuit_breaker_rejected' | 'not_applicable';
riskCheck: 'passed' | 'failed' | 'not_applicable';
batchSummary: string;
builderCode?: number;
referralCode?: number;
}
Fee Preview
interface DeterministicFeeEnvelope {
minFeeMicros: number;
expectedFeeMicros: number;
worstCaseFeeMicros: number;
dominantCostDrivers: string[];
}
Differences from Core TS SDK
| Feature | Core TS SDK (@rivellum/sdk) | AI SDK (@rivellum/ai-sdk) |
|---|---|---|
| Target audience | All developers | AI agents, bots, LLMs |
| Auth | Node URL only | Session keys + node URL |
| Payments | Low-level envelope submission | High-level pay() / purchase() / subscribe() |
| Escrow | — | Full escrow lifecycle |
| Marketplace | — | Search, register, browse |
| Streaming | — | startStream() / stopStream() |
| Agent wallets | — | createAgent() / getBudget() |
| Reputation | — | getReputation() / topProviders() |
| Chain queries | All methods | — |