SDK Overview
The White Rabbit SDK provides two clients for building on-chain automation:
| Client | Key type | What it does |
|---|---|---|
WorkspaceClient | ws_... workspace key | Execute any component standalone |
WorkflowClient | ws_... workspace key + workflowId | Trigger and inspect workflow runs |
Install
npm install caller-sdk
WorkspaceClient — execute components
import { WorkspaceClient, ComponentModule } from 'caller-sdk';
const workspace = new WorkspaceClient({ apiKey: process.env.WR_API_KEY! });
.promise() — wait for result
Submits the component and opens an SSE stream. Resolves with typed output on completion — no polling needed.
const result = await workspace
.call(ComponentModule.GET_EVM_ACCOUNT_BALANCE, {
jsonRpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
tokenAddress: '0x0000000000000000000000000000000000000000',
account: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
})
.promise();
console.log(result.balance); // "1000000000000000000"
.execute() — fire and track
Returns immediately with an execution record. Use this with webhook callbacks or when you'll poll/stream the result separately.
const execution = await workspace
.call(ComponentModule.WAIT_FOR_EVM_TRANSACTION, {
jsonRpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
transactionHash: '0xabc123...',
})
.execute({
callbackUrl: 'https://your-app.com/webhooks/wr',
callbackSecret: process.env.WR_CALLBACK_SECRET,
});
console.log(execution.id); // track via /executions/:id
console.log(execution.status); // "CREATED" — running asynchronously
Without waitForMs, .execute() always returns status: "CREATED". The component runs in the background. Use .promise() for direct results, or set callbackUrl for webhook delivery.
WorkflowClient — run workflows
import { WorkflowClient } from 'caller-sdk';
const workflow = new WorkflowClient({
apiKey: process.env.WR_API_KEY!,
workflowId: process.env.WR_WORKFLOW_ID!,
});
Trigger and wait
const { runId } = await workflow.trigger();
const run = await workflow.waitForRun(runId);
console.log(run.status); // "COMPLETED"
console.log(run.totalUsage); // credits consumed
Stream live progress
const sub = workflow.stream(runId, {
onUpdate(event) {
console.log(event.status, event.output.pendingStageCount);
},
});
// sub.close() to unsubscribe early
ComponentModule enum
All workspace.call() calls take a ComponentModule enum value — not a raw string. This ensures type-safe inputs and outputs:
import { ComponentModule } from 'caller-sdk';
// ✓ Correct — fully typed inputs and outputs
workspace.call(ComponentModule.RANDOM_UUID, {}).promise();
// ✗ Avoid — bypasses type safety
workspace.call('RANDOM_UUID' as ComponentModule, {}).promise();
Browse the full enum → Component Library
Response shape
interface ExecuteComponentResponse {
id: string;
module: string;
status: 'CREATED' | 'EXECUTING' | 'COMPLETED' | 'FAILED';
completed: boolean;
output: unknown | null; // typed by ComponentModule when using .promise()
error: unknown | null;
totalUsage: number;
callback: {
url: string | null;
signed: boolean;
signatureAlgorithm: 'hmac-sha256-v1' | null;
headerNames: string[];
deliveredAt: string | null;
lastAttemptAt: string | null;
attemptCount: number;
lastError: unknown | null;
};
createdAt: string;
updatedAt: string;
}
Error handling
Input validation happens synchronously before any network call — no await needed to catch it:
import { WorkspaceClient, ComponentModule, CallerSDKError } from 'caller-sdk';
const workspace = new WorkspaceClient({ apiKey: process.env.WR_API_KEY! });
try {
// Throws synchronously if inputs don't match the schema
const result = await workspace
.call(ComponentModule.BROADCAST_EVM_TRANSACTION, {
jsonRpcUrl: 'https://rpc.example.com',
signedTransaction: '0x...',
})
.promise();
} catch (err) {
if (err instanceof CallerSDKError) {
console.error(err.message); // Human-readable
console.error(err.details); // Zod errors or API error body
}
}
HTTP error codes:
| Code | Meaning |
|---|---|
400 | Validation error — check message field |
401 | Missing or invalid API key |
402 | Insufficient credits |
429 | Rate limit exceeded — check Retry-After header |
502 | Upstream microservice unavailable |
Next steps
- Getting Started → — installation and first component
- Execute Component → — full delivery mode reference
- Execute Workflow → — trigger, stream, inspect
- Authentication → — key types and callback verification