@lxg2it/satbill
v0.1.0
Published
TypeScript client for the satbill Bitcoin billing engine
Maintainers
Readme
@lxg2it/satbill
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.
Install
npm install @lxg2it/satbillQuick start
import { 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: '[email protected]' });
// 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');Works with @lxg2it/ai
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;
}API reference
createBillingClient(options)
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) |
Accounts
| 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 |
Plans & Subscriptions
| 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 |
Access gating
| 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';
};Wallet
| Method | Description |
|---|---|
| getWalletStatus() | Check on-chain sync status |
| triggerWalletSync() | Trigger a manual sync |
Errors
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);
}
}Running satbill locally
git clone https://github.com/lxg2it/satbill
cd satbill
cargo run --bin satbill-serverSee the satbill README for full setup including Bitcoin Signet demo.
License
MIT
