Agent SDK
Complete reference for the RecurAgent class. Use this when building an AI agent that needs to pay for services.
Installation
npm install @recur/sdk
RecurAgent
import { RecurAgent } from "@recur/sdk";
const agent = new RecurAgent(config: RecurAgentConfig);
RecurAgentConfig
| Option | Type | Required | Description |
|---|---|---|---|
wallet |
Keypair \| Signer |
Yes | Solana keypair or compatible signer |
network |
"mainnet-beta" \| "devnet" |
Yes | Solana network |
rpcUrl |
string |
No | Custom Solana RPC endpoint |
facilitatorUrl |
string |
No | Custom Facilitator URL (default: Recur’s hosted Facilitator) |
defaultToken |
string |
No | Default SPL token mint (default: USDC) |
Wallets
The wallet option accepts:
- A standard
Keypairfrom@solana/web3.js - Any object implementing the
Signerinterface:{ publicKey: PublicKey, signTransaction(tx): Promise<Transaction> }
This means you can pass signers from Privy, Dynamic, Turnkey, or any other embedded wallet provider.
// Standard keypair
import { Keypair } from "@solana/web3.js";
const agent = new RecurAgent({ wallet: keypair, network: "mainnet-beta" });
// Privy embedded wallet
const agent = new RecurAgent({ wallet: privySigner, network: "mainnet-beta" });
Methods
agent.pay()
Makes a one-time payment via the x402 flow. Handles the full request-402-pay-retry cycle.
const result = await agent.pay(options: PayOptions): Promise<PayResult>
PayOptions
| Option | Type | Required | Description |
|---|---|---|---|
url |
string |
Yes | The URL of the resource to pay for |
method |
string |
No | HTTP method (default: "GET") |
body |
object |
No | Request body for POST requests |
headers |
object |
No | Additional request headers |
maxAmount |
number |
No | Maximum amount to pay, in token base units. Rejects if the service requests more. |
token |
string |
No | SPL token mint to pay with (default: USDC) |
PayResult
| Field | Type | Description |
|---|---|---|
data |
any |
Parsed response body from the API |
status |
number |
HTTP status code |
headers |
object |
Response headers |
txSignature |
string |
Solana transaction signature |
amountPaid |
number |
Actual amount paid, in token base units |
const result = await agent.pay({
url: "https://api.example.com/v1/data",
maxAmount: 1_000_000, // reject if service asks for more than 1 USDC
});
console.log(result.data); // response body
console.log(result.txSignature); // on-chain proof
agent.subscribe()
Creates an on-chain subscription to a plan and delegates billing authority to the service provider.
const sub = await agent.subscribe(options: SubscribeOptions): Promise<Subscription>
SubscribeOptions
| Option | Type | Required | Description |
|---|---|---|---|
planId |
string |
Yes | On-chain plan address |
maxOveragePerCycle |
number |
No | Spend cap for metered overage per billing cycle |
token |
string |
No | Override the plan’s default token |
Returns: a Subscription object. See Subscriptions for the full structure.
const sub = await agent.subscribe({
planId: "7xKp...plan_address",
maxOveragePerCycle: 10_000_000, // authorize up to 10 USDC in overage
});
console.log(sub.id); // on-chain subscription address
console.log(sub.status); // "ACTIVE" or "TRIAL"
console.log(sub.nextBillingAt); // Unix timestamp
agent.cancelSubscription()
Cancels an active subscription. On-chain and immediate.
await agent.cancelSubscription(options: { subscriptionId: string }): Promise<void>
agent.listSubscriptions()
Returns all subscriptions for the agent’s wallet.
const subs = await agent.listSubscriptions(
options?: { status?: SubscriptionStatus }
): Promise<Subscription[]>
agent.createAllowance()
Creates a metered spend cap. See Allowances.
const allowance = await agent.createAllowance(options: AllowanceOptions): Promise<Allowance>
AllowanceOptions
| Option | Type | Required | Description |
|---|---|---|---|
grantee |
string |
Yes | Wallet address of the service being authorized |
maxAmount |
number |
Yes | Total spend cap, in token base units |
token |
string |
No | SPL token mint (default: USDC) |
expiresAt |
number |
No | Unix timestamp for expiry |
agent.revokeAllowance()
Revokes an allowance before it expires.
await agent.revokeAllowance(options: { allowanceId: string }): Promise<void>
agent.getAllowance()
Returns the current state of an allowance.
const status = await agent.getAllowance(
options: { allowanceId: string }
): Promise<Allowance>
Error handling
The SDK throws typed errors for all failure cases:
import {
InsufficientFundsError,
PaymentRejectedError,
AllowanceExhaustedError,
FacilitatorError,
} from "@recur/sdk/errors";
try {
await agent.pay({ url: "...", maxAmount: 1_000_000 });
} catch (e) {
if (e instanceof InsufficientFundsError) {
console.error("Wallet needs more USDC", e.required, e.available);
} else if (e instanceof PaymentRejectedError) {
console.error("Service rejected payment proof", e.reason);
} else if (e instanceof FacilitatorError) {
console.error("Facilitator error", e.statusCode, e.message);
}
}
| Error class | Cause |
|---|---|
InsufficientFundsError |
Wallet balance below required amount |
PaymentRejectedError |
Service rejected the payment proof |
MaxAmountExceededError |
Service requested more than maxAmount |
AllowanceExhaustedError |
Spend cap reached |
SubscriptionNotActiveError |
Subscription is paused or cancelled |
FacilitatorError |
Facilitator returned an error |
SolanaTransactionError |
On-chain transaction failed |