Rivellum

Rivellum Portal

Download Wallet (Chrome)
Checking...
testnet

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)
ParameterTypeRequiredDescription
options.nodeUrlstringNode RPC base URL. Defaults to http://localhost:8090.
options.sessionKeystringSession key for authenticated requests (auto-injected into all POST bodies).
options.timeoutMsnumberRequest 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';
TypeDescription
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

FeatureCore TS SDK (@rivellum/sdk)AI SDK (@rivellum/ai-sdk)
Target audienceAll developersAI agents, bots, LLMs
AuthNode URL onlySession keys + node URL
PaymentsLow-level envelope submissionHigh-level pay() / purchase() / subscribe()
EscrowFull escrow lifecycle
MarketplaceSearch, register, browse
StreamingstartStream() / stopStream()
Agent walletscreateAgent() / getBudget()
ReputationgetReputation() / topProviders()
Chain queriesAll methods