The @insureco/wallet TypeScript client for iec-wallet. Check balances, charge gas, credit tokens, query the ledger, and validate deploy reserves — with full type safety and built-in retry logic.
npm install @insureco/wallet
// Production
import { WalletClient, WalletError, deriveWalletId } from '@insureco/wallet'
// Testing
import { MockWalletClient } from '@insureco/wallet/testing'
Zero external dependencies — uses only native Node.js fetch, crypto, and AbortSignal.
import { WalletClient } from '@insureco/wallet'
// From explicit config
const wallet = new WalletClient({
baseUrl: process.env.IEC_WALLET_URL || 'http://localhost:3002',
serviceKey: process.env.INTERNAL_SERVICE_KEY,
})
// Or from environment variables
const wallet = WalletClient.fromEnv()
// Ensure a wallet exists (idempotent)
const { wallet: w } = await wallet.ensureWallet({
ownerId: 'my-org',
ownerType: 'organization',
ownerName: 'My Organization',
})
// w.id === 'wallet-my-org'
// w.totalBalance === 50000 (org gets 50K intro tokens)
// Check balance
const balance = await wallet.getBalance('wallet-my-org')
// { walletId, totalBalance, balances: [{ tokenType, balance }] }
// Credit tokens
await wallet.credit('wallet-my-org', {
amount: 10000,
tokenType: 'purchased',
reason: 'Token purchase',
referenceId: 'purchase-123',
})
// Query ledger
const ledger = await wallet.getLedger('wallet-my-org', {
page: 1,
limit: 20,
serviceId: 'my-api', // optional filter
})
| Gas Type | What It Pays For | Uses Intro Tokens? |
|---|---|---|
hosting | Pod uptime (charged hourly) | Yes |
transaction | API calls through Janus | No — automatically skipped |
// Hosting gas (uses intro tokens)
await wallet.debit('wallet-my-org', {
amount: 5,
reason: 'hosting_gas',
gasType: 'hosting',
serviceId: 'my-api',
})
// Transaction gas (purchased/earned only)
await wallet.debit('wallet-my-org', {
amount: 1,
reason: 'api_call',
gasType: 'transaction',
serviceId: 'my-api',
})
const { sufficient, balance, required } = await wallet.checkReserve({
walletId: 'wallet-my-org',
podTier: 'nano', // nano | small | medium | large | xlarge
months: 3,
})
if (!sufficient) {
throw new Error(`Insufficient reserve: ${balance} < ${required}`)
}
import { MockWalletClient } from '@insureco/wallet/testing'
const mockWallet = new MockWalletClient()
// Pre-seed a wallet balance
mockWallet.seed('wallet-test-org', 50000)
// Inject into your service
const service = new MyService({ wallet: mockWallet })
await service.processPayment('wallet-test-org', 100)
// Assert
expect(mockWallet.getBalance('wallet-test-org').totalBalance).toBe(49900)
expect(mockWallet.transactions).toHaveLength(1)
import { WalletError } from '@insureco/wallet'
try {
await wallet.debit('wallet-my-org', { amount: 100, gasType: 'hosting' })
} catch (err) {
if (err instanceof WalletError) {
if (err.code === 'INSUFFICIENT_BALANCE') {
// handle low balance
}
}
}
| Variable | Required | Description |
|---|---|---|
IEC_WALLET_URL | Yes* | Base URL of the wallet service |
WALLET_URL | Fallback | Alternative if IEC_WALLET_URL is not set |
INTERNAL_SERVICE_KEY | No | Service-to-service auth key |
Declare iec-wallet in internalDependencies to have IEC_WALLET_URL auto-injected:
spec:
internalDependencies:
- service: iec-wallet # injects IEC_WALLET_URL
Last updated: February 28, 2026