| name | routstr-sdk-integration |
| description | Guide for integrating the @routstr/sdk npm package to route OpenAI-compatible API requests with automatic payment handling |
Routstr SDK Integration
Integrate the @routstr/sdk npm package to route OpenAI-compatible API requests to the cheapest provider with automatic payment handling.
Setup Steps
-
Install the package
npm install @routstr/sdk
-
Set up storage (choose based on environment)
import {
createSdkStore,
createSqliteDriver,
createLocalStorageDriver,
createMemoryDriver,
} from "@routstr/sdk";
const { store, hydrate } = createSdkStore({ driver: createSqliteDriver() });
const { store, hydrate } = createSdkStore({
driver: createLocalStorageDriver(),
});
const { store, hydrate } = createSdkStore({ driver: createMemoryDriver() });
-
Bootstrap providers (run once at startup)
import {
ModelManager,
MintDiscovery,
createDiscoveryAdapterFromStore,
createProviderRegistryFromStore,
} from "@routstr/sdk";
const discoveryAdapter = createDiscoveryAdapterFromStore(store);
const providerRegistry = createProviderRegistryFromStore(store);
const modelManager = new ModelManager(discoveryAdapter);
const providers = await modelManager.bootstrapProviders(false);
await modelManager.fetchModels(providers);
const mintDiscovery = new MintDiscovery(discoveryAdapter);
await mintDiscovery.discoverMints(providers);
-
Implement WalletAdapter
const walletAdapter = {
async getBalances(): Promise<Record<string, number>> {
},
getMintUnits(): Record<string, "sat" | "msat"> {
},
getActiveMintUrl(): string | null {
},
async sendToken(
mintUrl: string,
amount: number,
p2pkPubkey?: string
): Promise<string> {
},
async receiveToken(token: string): Promise<{
success: boolean;
amount: number;
unit: "sat" | "msat";
message?: string;
}> {
},
};
Using the SDK
Directly consuming AI inference
import { RoutstrClient } from "@routstr/sdk";
const client = new RoutstrClient(
walletAdapter,
storageAdapter,
providerRegistry,
"min",
"xcashu"
);
await client.fetchAIResponse(
{
messageHistory: [{ role: "user", content: userPrompt }],
selectedModel: model,
baseUrl: providerUrl,
mintUrl: activeMintUrl,
},
{
onStreamingUpdate: (content) => process.stdout.write(content),
onBalanceUpdate: (balance) => console.error(`[Balance: ${balance} sats]`),
onTransactionUpdate: (tx) => console.error(`[Spent: ${tx.amount} sats]`),
}
);
Building an HTTP Proxy
import { createServer } from "http";
import { routeRequests } from "@routstr/sdk";
const server = createServer(async (req, res) => {
const body = await readBody(req);
const { model } = JSON.parse(body);
const response = await routeRequests({
modelId: model,
requestBody: JSON.parse(body),
path: "/v1/chat/completions",
mode: "xcashu",
walletAdapter,
storageAdapter,
providerRegistry,
discoveryAdapter,
modelManager,
});
res.statusCode = response.status;
response.headers.forEach((value, key) => res.setHeader(key, value));
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
res.write(value);
}
res.end();
});
Authentication Modes
| Mode | Description | Best For | Trade offs |
|---|
xcashu | Cashu token spending with automatic refunds | Pay-per-use with better privacy, one-off requests | Higher latency (requires creating Cashu tokens / ecash). More transaction fees. |
apikeys | Balance is temporarily kept with a routstr node, can be refunded anytime | Agentic sessions that benefit from faster inference. Session based accounts. | Balance held by provider for longer. Less privacy (requests are linked during a session). |
Common Patterns
Force a specific provider
await routeRequests({
forcedProvider: "https://specific.provider.com/",
});
Add custom providers
const modelManager = new ModelManager(discoveryAdapter, {
includeProviderUrls: ["https://my-private-provider.com/"],
});
Check available providers for a model
import { ProviderManager } from "@routstr/sdk";
const providerManager = new ProviderManager(providerRegistry);
const ranking = providerManager.getProviderPriceRankingForModel("gpt-4o");
Package Reference