Build with $AMPS
The developer toolkit for integrating $AMPS token payments into your apps. Especially built for AI agents that charge tokens per API call.
npm install @amplifyworld/sdk
*Beyond viem as peer dependency
Installation
Install the SDK and its peer dependency:
# npm
npm install @amplifyworld/sdk viem
# pnpm
pnpm add @amplifyworld/sdk viem
# yarn
yarn add @amplifyworld/sdk viem
viem is the modern TypeScript interface for Ethereum with first-class type safety, tree-shaking, and tiny bundle size. It's used by Coinbase, Uniswap, and most major DeFi projects.
Quick Start
Get up and running in under 10 lines:
import { createAmpsClient } from '@amplifyworld/sdk'
// Create a client (read-only, uses public Base RPC)
const amps = createAmpsClient()
// Check any wallet balance
const balance = await amps.getBalance('0x...')
console.log(`Balance: ${balance.formatted} AMPS`)
// Get on-chain token info
const info = await amps.getTokenInfo()
console.log(`Total Supply: ${info.totalSupply} ${info.symbol}`)
Client
createAmpsClient() is your single entry point. It supports three modes:
Read-Only
Check balances, watch events. No wallet needed.
const amps = createAmpsClient()
Server-Side
Sign transactions with a private key (for backends/agents).
const amps = createAmpsClient({
privateKey: process.env.KEY
})
Browser Wallet
Use MetaMask, Coinbase Wallet, or any EIP-1193 provider.
const amps = createAmpsClient({
walletClient: yourWalletClient
})
const amps = createAmpsClient({
// Custom RPC (recommended for production)
rpcUrl: 'https://base-mainnet.g.alchemy.com/v2/YOUR_KEY',
// Private key for server-side signing
privateKey: '0x...',
})
Balances
const balance = await amps.getBalance('0x...')
console.log(balance.formatted) // "1,500.25"
console.log(balance.value) // "1500.25"
console.log(balance.raw) // 1500250000000000000000n
console.log(balance.symbol) // "AMPS"
// Raw BigInt for computations
const raw = await amps.getRawBalance('0x...')
| Property | Type | Description |
|---|---|---|
formatted | string | Display-ready with commas (e.g. "1,500.25") |
value | string | Raw decimal string (e.g. "1500.25") |
raw | bigint | Wei-level precision for math |
symbol | string | Always "AMPS" |
Transfers
Send $AMPS to any address. Amounts can be human-readable strings or BigInt.
// Transfer 100 AMPS
const result = await amps.transfer('0xRecipient...', '100')
console.log(`Tx: ${result.hash}`)
console.log(`Status: ${result.receipt.status}`) // "success"
// Transfer with BigInt precision
import { parseAmps } from '@amplifyworld/sdk'
await amps.transfer('0x...', parseAmps('99.99'))
The SDK automatically checks your balance before sending. If insufficient, it throws InsufficientBalanceError without wasting gas.
Approvals
Approve third parties (like AI services) to spend $AMPS on your behalf.
// Approve a service to spend up to 1000 AMPS
await amps.approve('0xServiceWallet...', '1000')
// Check current allowance
const allowance = await amps.getAllowance('0xOwner...', '0xSpender...')
console.log(`Approved: ${allowance.formatted} AMPS`)
// Transfer from approved account (for service providers)
await amps.transferFrom('0xUser...', '0xService...', '0.5')
Events
Subscribe to real-time $AMPS transfer and approval events.
// Watch all incoming transfers to your address
const unwatch = amps.watchTransfers((event) => {
console.log(`Received ${event.amount} AMPS from ${event.from}`)
console.log(`Tx: ${event.txHash}`)
}, { to: myAddress })
// Watch approvals for your service
const unwatchApprovals = amps.watchApprovals((event) => {
console.log(`${event.owner} approved ${event.amount} AMPS`)
}, { spender: myServiceAddress })
// Stop watching
unwatch()
unwatchApprovals()
Payment Gateway
The killer feature — charge users in $AMPS per AI API call. Define your pricing table, and the gateway handles allowance checks, on-chain transfers, and receipts.
import { createAmpsGateway } from '@amplifyworld/sdk'
const gateway = createAmpsGateway({
privateKey: process.env.SERVICE_WALLET_KEY,
pricing: {
'chat.completion': '0.5', // 0.5 AMPS per chat
'image.generate': '2.0', // 2 AMPS per image
'code.analyze': '1.0', // 1 AMPS per analysis
},
})
// Charge a user
const receipt = await gateway.charge({
payer: '0xUserAddress...',
service: 'chat.completion',
})
console.log(receipt.txHash) // '0x...'
console.log(receipt.amount) // '0.5'
console.log(receipt.service) // 'chat.completion'
Sessions
Track approval-based spending within time windows — perfect for AI agents making multiple calls.
const session = await gateway.sessions.create({
userAddress: '0xUser...',
serviceAddress: gateway.serviceAddress,
maxSpend: '100', // Cap at 100 AMPS
ttlSeconds: 3600, // 1 hour
})
// Before each charge, check the session
if (gateway.sessions.canSpend(session.id, '0.5')) {
await gateway.charge({ ... })
gateway.sessions.recordSpend(session.id, '0.5')
}
console.log(session.remaining) // '99.5'
Receipts
Verify that a payment actually happened on-chain. Useful for "proof of payment" flows.
import { verifyReceipt, createAmpsClient } from '@amplifyworld/sdk'
const amps = createAmpsClient()
const receipt = await verifyReceipt(amps.publicClient, '0xTxHash...', {
expectedRecipient: '0xYourWallet...',
expectedMinAmount: '1.0',
})
console.log(receipt.payer) // '0x...'
console.log(receipt.amount) // '1.5'
console.log(receipt.timestamp) // '2026-04-21T16:30:00.000Z'
Dynamic Pricing
Use functions instead of fixed prices to implement usage-based billing.
const gateway = createAmpsGateway({
privateKey: '0x...',
pricing: {
// Fixed price
'chat.message': '0.5',
// Price based on token count
'chat.long': (meta) => {
const tokens = (meta?.tokens as number) ?? 500
return String(tokens * 0.001) // 0.001 AMPS per token
},
// Price based on image resolution
'image.generate': async (meta) => {
const size = (meta?.size as string) ?? '512x512'
const prices = { '256x256': '1', '512x512': '2', '1024x1024': '5' }
return prices[size] ?? '2'
},
},
})
// Charge with metadata
await gateway.charge({
payer: '0x...',
service: 'chat.long',
metadata: { tokens: 2500 }, // Will cost 2.5 AMPS
})
Express Paywall
Drop-in middleware that gates Express routes behind $AMPS payments.
import express from 'express'
import { ampsPaywall } from '@amplifyworld/sdk/middleware'
const app = express()
app.post('/api/generate', ampsPaywall({
price: '1.0',
recipient: '0xYourWallet...',
}), async (req, res) => {
// Only runs after on-chain payment verification
const result = await generateImage(req.body.prompt)
res.json({ result, receipt: req.ampsReceipt })
})
x402 Pattern
The middleware implements the x402 protocol pattern — when no payment is provided,
it returns 402 Payment Required with machine-readable payment instructions:
{
"error": "Payment Required",
"message": "This endpoint requires 1.0 AMPS payment",
"payment": {
"token": "AMPS",
"chain": "base",
"chainId": 8453,
"amount": "1.0",
"recipient": "0xYourWallet...",
"contract": "0x1A074F116786248FC79B130E6379293C7EF604a4"
}
}
AI agents can automatically parse this response, execute the payment, and retry with the tx hash:
// 1. First request → gets 402
const res = await fetch('/api/generate', { method: 'POST' })
if (res.status === 402) {
const { payment } = await res.json()
// 2. Pay with AMPS SDK
const tx = await amps.transfer(payment.recipient, payment.amount)
// 3. Retry with payment proof
const paid = await fetch('/api/generate', {
method: 'POST',
headers: { 'X-AMPS-Tx-Hash': tx.hash },
})
}
Error Handling
All errors extend AmpsError with structured error codes:
| Error Class | Code | Thrown When |
|---|---|---|
WalletRequiredError | WALLET_REQUIRED | Write operation without wallet |
InsufficientBalanceError | INSUFFICIENT_BALANCE | Transfer exceeds balance |
InsufficientAllowanceError | INSUFFICIENT_ALLOWANCE | transferFrom exceeds approval |
ServiceNotFoundError | SERVICE_NOT_FOUND | Unknown service in gateway |
SessionExpiredError | SESSION_EXPIRED | Session timed out or exhausted |
PaymentVerificationError | PAYMENT_VERIFICATION_FAILED | Tx not found or mismatch |
import { InsufficientBalanceError } from '@amplifyworld/sdk'
try {
await amps.transfer('0x...', '1000000')
} catch (e) {
if (e instanceof InsufficientBalanceError) {
console.log(`Need ${e.required}, have ${e.available}`)
}
}
Utilities
import { parseAmps, formatAmps, formatAmpsDisplay } from '@amplifyworld/sdk'
parseAmps('100') // 100000000000000000000n
parseAmps('0.5') // 500000000000000000n
formatAmps(100000000000000000000n) // "100"
formatAmpsDisplay(1500250000000000000000n) // "1,500.25"
Constants
import {
AMPS_CONTRACT_ADDRESS, // '0x1A074F116786248FC79B130E6379293C7EF604a4'
AMPS_CHAIN, // Base chain config (viem Chain object)
AMPS_TOKEN, // { name, symbol, decimals, chainId, explorer }
DEFAULT_RPC_URL, // 'https://mainnet.base.org'
ERC20_ABI, // Human-readable ERC-20 ABI
} from '@amplifyworld/sdk'