TypeScript client for the satbill Bitcoin billing engine.
satbill is a Rust service providing subscription and metered billing infrastructure backed by on-chain Bitcoin. This package gives you a type-safe TypeScript interface to its REST API.
npm install @lxg2it/satbillimport { createBillingClient } from '@lxg2it/satbill';
const billing = createBillingClient({
baseUrl: process.env.SATBILL_URL ?? 'http://localhost:8080',
apiKey: process.env.SATBILL_API_KEY,
});
// Create an account
const account = await billing.createAccount({ name: 'Alice', email: 'alice@example.com' });
// Check if a user has access before serving a request
const access = await billing.checkAccess(account.id, 'api.basic');
if (!access.granted) {
throw new Error(`Access denied: ${access.reason}`);
}
// Charge for metered usage (1 sat per 1000 tokens)
await billing.charge(account.id, Math.ceil(tokensUsed / 1000), 'api.usage');import { createModelRouter } from '@lxg2it/ai';
import { createBillingClient } from '@lxg2it/satbill';
const router = createModelRouter({ apiKey: process.env.MODEL_ROUTER_KEY });
const billing = createBillingClient({ baseUrl: process.env.SATBILL_URL });
// Middleware pattern: gate AI requests behind a balance check
async function handleAiRequest(accountId: string, prompt: string) {
const access = await billing.checkAccess(accountId, 'api.basic');
if (!access.granted) return { error: 'Payment required', status: 402 };
const result = await router.complete({ prompt, tier: 'economy' });
// Charge after successful completion
await billing.charge(accountId, result.usage.totalTokens, 'completion');
return result;
}Factory function. Options:
| Field | Type | Description |
|---|---|---|
baseUrl |
string |
URL of the satbill server |
apiKey |
string? |
Bearer token for auth |
fetch |
FetchFunction? |
Custom fetch (for testing / Node <18) |
| Method | Description |
|---|---|
createAccount(req) |
Create a new billing account |
getAccount(id) |
Get account details |
getBalance(id) |
Get satoshi balance (available / pending / reserved) |
deposit(id, req) |
Add funds to an account |
withdraw(id, req) |
Remove funds from an account |
charge(id, sats, description) |
Deduct satoshis (metered billing) |
getTransactions(id, limit?) |
Transaction history |
getDepositAddress(id) |
Get on-chain deposit address |
| Method | Description |
|---|---|
createPlan(req) |
Create a billing plan |
listPlans() |
List all plans |
subscribe(req) |
Subscribe an account to a plan |
cancelSubscription(id) |
Cancel a subscription |
| Method | Description |
|---|---|
checkAccess(accountId, feature) |
Check if an account has access to a feature |
Returns AccessGranted or AccessDenied:
type AccessGranted = { granted: true; features: string[] };
type AccessDenied = {
granted: false;
reason:
| 'NoActiveSubscription'
| 'SubscriptionExpired'
| 'FeatureNotIncluded'
| 'InsufficientBalance'
| 'AccountSuspended';
};| Method | Description |
|---|---|
getWalletStatus() |
Check on-chain sync status |
triggerWalletSync() |
Trigger a manual sync |
All methods throw SatbillError on failure:
import { SatbillError } from '@lxg2it/satbill';
try {
await billing.checkAccess(id, 'api.basic');
} catch (e) {
if (e instanceof SatbillError) {
console.log(e.code, e.status, e.message);
}
}git clone https://github.com/lxg2it/satbill
cd satbill
cargo run --bin satbill-serverSee the satbill README for full setup including Bitcoin Signet demo.
MIT