# With Bun
Source: https://armory.sh/accept-payments/bun
Accept Armory payments in Bun
Accept crypto payments in your Bun HTTP server with the Armory middleware.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-bun
# yarn
yarn add @armory-sh/middleware-bun
# pnpm
pnpm add @armory-sh/middleware-bun
# bun
bun add @armory-sh/middleware-bun
```
## Quick Start
```typescript theme={null}
import { createBunMiddleware } from '@armory-sh/middleware-bun';
const middleware = createBunMiddleware({
payTo: '0xYourWalletAddress...',
amount: '1.0'
});
Bun.serve({
port: 3000,
fetch: async (req) => {
const result = await middleware(req);
// If middleware returns a response, payment failed/required
if (result) return result;
// Payment verified — handle your request
return new Response(JSON.stringify({ data: 'protected content' }));
}
});
```
***
## How It Works
The middleware returns:
* `null` if payment is valid (your handler proceeds)
* A `Response` object if payment is missing/invalid (returned to client)
***
## Settlement Modes
Control how payments are settled after verification:
```typescript theme={null}
const middleware = createBunMiddleware({
payTo: '0x...',
amount: '1.0',
settlementMode: 'verify' // | 'settle' | 'async'
});
```
| Mode | Description |
| -------- | --------------------------------------------- |
| `verify` | Verify only, don't settle (great for testing) |
| `settle` | Verify and settle on-chain before responding |
| `async` | Return immediately, settle in background |
***
## Configuration
```typescript theme={null}
const middleware = createBunMiddleware({
payTo: '0x...',
amount: '1.0',
settlementMode: 'verify'
});
```
## Route Configuration
For per-route behavior, use `createRouteAwareBunMiddleware`:
```typescript theme={null}
import { createRouteAwareBunMiddleware } from '@armory-sh/middleware-bun';
const middleware = createRouteAwareBunMiddleware({
routes: ['/api/basic', '/api/premium/*'],
payTo: '0xYourAddress...',
amount: '$1.00',
network: 'base',
perRoute: {
'/api/premium/*': {
amount: '$5.00'
}
}
});
```
***
## Tips
Use `settlementMode: 'verify'` during development to skip on-chain settlement while still testing payment verification.
The `amount` can be a human-readable string like `"1.0"` — no manual decimal calculation needed.
With `settlementMode: 'settle'`, responses will be delayed until the on-chain transaction completes. Use `async` for better UX.
***
## More Information
See [`@armory-sh/middleware-bun`](/packages/middleware-bun) for full configuration options.
# With Elysia
Source: https://armory.sh/accept-payments/elysia
Accept Armory payments in Elysia
Accept crypto payments in your Elysia API with the Armory middleware plugin.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-elysia
# yarn
yarn add @armory-sh/middleware-elysia
# pnpm
pnpm add @armory-sh/middleware-elysia
# bun
bun add @armory-sh/middleware-elysia
```
## Quick Start
```typescript theme={null}
import { Elysia } from 'elysia';
import { paymentMiddleware } from '@armory-sh/middleware-elysia';
const app = new Elysia()
.use(paymentMiddleware({
requirements: {
to: '0xYourWalletAddress...',
amount: 1000000n, // 1 USDC (6 decimals)
expiry: Date.now() + 3600 * 1000,
chainId: 'eip155:8453',
assetId: 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
}
}))
.get('/api/data', ({ store }) => {
return { message: 'Payment successful!' };
})
.listen(3000);
```
***
## Accessing Payment Info
Payment information is stored in the Elysia store:
```typescript theme={null}
app.get('/api/premium', ({ store }) => {
const payment = store.payment;
return {
message: `Hello ${payment.payerAddress}`,
paid: payment.payload.amount
};
});
```
***
## With Schema Validation
Combine payment middleware with Elysia's schema validation:
```typescript theme={null}
import { t } from 'elysia';
app.post(
'/api/purchase',
({ store, body }) => {
const { itemId, quantity } = body;
const { payerAddress } = store.payment;
// Process purchase for verified payer
return { purchased: true, for: payerAddress };
},
{
body: t.Object({
itemId: t.String(),
quantity: t.Optional(t.Number()),
}),
}
);
```
***
## Type Safety
For full TypeScript support, type your Elysia instance:
```typescript theme={null}
import type { PaymentContext } from '@armory-sh/middleware-elysia';
const app = new Elysia<{ store: PaymentContext }>()
.use(paymentMiddleware({ ... }))
.get('/api/data', ({ store }) => {
// store.payment is fully typed
console.log(store.payment.payerAddress);
});
```
## Route Configuration
For per-route requirements, use `routeAwarePaymentMiddleware`:
```typescript theme={null}
import { routeAwarePaymentMiddleware } from '@armory-sh/middleware-elysia';
app.use(routeAwarePaymentMiddleware({
'/api/basic': { requirements: basicRequirements },
'/api/premium': { requirements: premiumRequirements },
}));
```
***
## Tips
USDC on Base uses 6 decimals. 1 USDC = `1000000n` as a bigint.
Elysia's store is shared across all middleware. Payment info is available in any route after the middleware runs.
***
## More Information
See [`@armory-sh/middleware-elysia`](/packages/middleware-elysia) for full configuration options.
# With Express
Source: https://armory.sh/accept-payments/express
Accept Armory payments in Express
Accept crypto payments in your Express API with the Armory middleware.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-express
# yarn
yarn add @armory-sh/middleware-express
# pnpm
pnpm add @armory-sh/middleware-express
# bun
bun add @armory-sh/middleware-express
```
## Quick Start
```typescript theme={null}
import express from 'express';
import { paymentMiddleware } from '@armory-sh/middleware-express';
const app = express();
// Protect all routes with payment
app.use(paymentMiddleware({
requirements: {
to: '0xYourWalletAddress...',
amount: 1000000n, // 1 USDC (6 decimals)
expiry: Date.now() + 3600 * 1000,
chainId: 'eip155:8453',
assetId: 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
}
}));
app.get('/api/data', (req, res) => {
res.json({ message: 'Payment successful!' });
});
app.listen(3000);
```
***
## Accessing Payment Info
The middleware attaches payment information to every request:
```typescript theme={null}
app.get('/api/user', (req, res) => {
const { payerAddress, payload, version } = req.payment;
res.json({
message: `Hello ${payerAddress}`,
paid: payload.amount
});
});
```
***
## Protecting Specific Routes
You can apply the middleware to specific routes only:
```typescript theme={null}
// Public route — no payment required
app.get('/api/public', (req, res) => {
res.json({ message: 'Anyone can access this' });
});
// Protected route — payment required
app.get('/api/premium',
paymentMiddleware({ /* config */ }),
(req, res) => {
res.json({ message: 'Paid content' });
}
);
```
## Route Configuration
For per-route pricing or requirements, use `routeAwarePaymentMiddleware`:
```typescript theme={null}
import { routeAwarePaymentMiddleware } from '@armory-sh/middleware-express';
app.use('/api', routeAwarePaymentMiddleware({
'/api/basic': { requirements: basicRequirements },
'/api/premium': { requirements: premiumRequirements },
}));
```
***
## Tips
Want to accept payments on Base using USDC? Use token address `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` with 6 decimals.
Express middleware runs sequentially — place `paymentMiddleware` before any routes that require payment protection.
***
## More Information
See [`@armory-sh/middleware-express`](/packages/middleware-express) for full configuration options.
# With Hono
Source: https://armory.sh/accept-payments/hono
Accept Armory payments in Hono
Accept crypto payments in your Hono API with the Armory middleware.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-hono
# yarn
yarn add @armory-sh/middleware-hono
# pnpm
pnpm add @armory-sh/middleware-hono
# bun
bun add @armory-sh/middleware-hono
```
## Quick Start
```typescript theme={null}
import { Hono } from 'hono';
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-hono';
const app = new Hono();
// Protect all routes
app.use('*', acceptPaymentsViaArmory({
payTo: '0xYourWalletAddress...',
amount: '1.0'
}));
app.get('/api/data', (c) => {
return c.json({ message: 'Payment successful!' });
});
app.listen(3000);
```
***
## Accessing Payment Info
Payment information is stored in the Hono context:
```typescript theme={null}
app.get('/api/user', (c) => {
const payment = c.get('payment');
const { payerAddress, payload } = payment;
return c.json({
message: `Hello ${payerAddress}`,
paid: payload.amount
});
});
```
***
## Protecting Specific Routes
Use path patterns to protect specific route groups:
```typescript theme={null}
// Public routes — no payment
app.get('/', (c) => c.json({ message: 'Welcome' }));
// All /api/* routes require payment
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0x...',
amount: '1.0'
}));
app.get('/api/data', (c) => c.json({ data: '...' }));
```
***
## Multi-Network Support
Accept payments across multiple networks:
```typescript theme={null}
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0x...',
amount: '1.0',
accept: {
networks: ['base', 'ethereum', 'polygon'],
tokens: ['usdc', 'usdt']
}
}));
```
## Route Configuration
For route-specific configuration, use `routeAwarePaymentMiddleware`:
```typescript theme={null}
import { routeAwarePaymentMiddleware } from '@armory-sh/middleware-hono';
app.use('/api/*', routeAwarePaymentMiddleware({
routes: ['/api/basic', '/api/premium/*'],
payTo: '0xYourAddress...',
amount: '$1.00',
network: 'base',
perRoute: {
'/api/premium/*': {
amount: '$5.00'
}
}
}));
```
***
## Tips
The `amount` parameter accepts human-readable strings like `"1.0"` for 1 token — no need to calculate decimals manually.
Hono's middleware matching is pattern-based. Use `/api/*` to protect all API routes, or `/premium/*` for paid content only.
***
## More Information
See [`@armory-sh/middleware-hono`](/packages/middleware-hono) for full configuration options.
# With Next.js
Source: https://armory.sh/accept-payments/next
Accept x402 payments in your Next.js App Router application
Accept x402 payments in your Next.js App Router application using the `@armory-sh/middleware-next` package.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-next
# yarn
yarn add @armory-sh/middleware-next
# pnpm
pnpm add @armory-sh/middleware-next
# bun
bun add @armory-sh/middleware-next
```
## Basic Setup
Create a `middleware.ts` file in your Next.js app root:
```typescript theme={null}
// middleware.ts
import { paymentProxy, x402ResourceServer } from "@armory-sh/middleware-next";
// Create a verification client
const verificationClient = {
async verify(headers: Headers) {
const response = await fetch("https://your-verifier.com/verify", {
method: "POST",
headers: Object.fromEntries(headers.entries()),
});
return response.json();
},
};
// Create the resource server
const resourceServer = new x402ResourceServer(verificationClient);
// Configure payment proxy with per-route settings
export const proxy = paymentProxy(
{
"/api/protected": {
accepts: {
scheme: "exact",
price: "1000000", // $1.00 in atomic units (6 decimals)
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Access to protected API",
},
},
resourceServer
);
// Configure which routes the middleware should run on
export const config = { matcher: ["/api/protected/:path*"] };
```
## Route Patterns
Next.js middleware uses the same `matcher` config as standard Next.js middleware:
```typescript theme={null}
// Single route
export const config = { matcher: ["/api/protected"] };
// Wildcard (matches all sub-paths)
export const config = { matcher: ["/api/protected/:path*"] };
// Multiple routes
export const config = {
matcher: ["/api/users/:path*", "/api/posts/:path*"]
};
```
## Per-Route Configuration
Configure different payment requirements for different routes:
```typescript theme={null}
export const proxy = paymentProxy(
{
"/api/basic": {
accepts: {
scheme: "exact",
price: "1000000", // $1.00
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Basic tier access",
},
"/api/premium": {
accepts: {
scheme: "exact",
price: "5000000", // $5.00
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Premium tier access",
},
"/api/vip": {
accepts: {
scheme: "exact",
price: "10000000", // $10.00
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "VIP tier access",
},
},
resourceServer
);
```
## Wildcard Routes
Use wildcards to match multiple routes with a single configuration:
```typescript theme={null}
export const proxy = paymentProxy(
{
"/api/premium/*": {
accepts: {
scheme: "exact",
price: "5000000", // $5.00
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Premium API access",
},
},
resourceServer
);
export const config = { matcher: ["/api/:path*"] };
```
## Resource Server
The `x402ResourceServer` manages payment schemes and requirements:
```typescript theme={null}
import type { PaymentScheme } from "@armory-sh/middleware-next";
import type { PaymentRequirementsV2 } from "@armory-sh/base";
// Create custom payment schemes
const exactScheme: PaymentScheme = {
name: "exact",
getRequirements: (): PaymentRequirementsV2 => ({
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" as `0x${string}`,
payTo: "0xYourAddress..." as `0x${string}`,
maxTimeoutSeconds: 300,
extra: {},
}),
};
// Register schemes for different chains
const resourceServer = new x402ResourceServer(verificationClient)
.register("eip155:8453", exactScheme) // Base
.register("eip155:1", exactScheme); // Ethereum
```
## Response Format
When payment is verified, the middleware returns a JSON response:
```json theme={null}
{
"verified": true,
"payerAddress": "0x..."
}
```
When payment is required, it returns a 402 response with payment requirements:
```json theme={null}
{
"error": "Payment required",
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"amount": "1000000",
"asset": "0x8335...",
"payTo": "0xYour..."
}
]
}
```
## Complete Example
```typescript theme={null}
// middleware.ts
import { paymentProxy, x402ResourceServer } from "@armory-sh/middleware-next";
const verificationClient = {
async verify(headers: Headers) {
const response = await fetch("https://verifier.example.com/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
...Object.fromEntries(headers.entries()),
},
body: JSON.stringify({
headers: Object.fromEntries(headers.entries()),
}),
});
return response.json();
},
};
const resourceServer = new x402ResourceServer(verificationClient);
export const proxy = paymentProxy(
{
"/api/data/basic": {
accepts: {
scheme: "exact",
price: "1000000",
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Basic data access",
},
"/api/data/premium": {
accepts: {
scheme: "exact",
price: "5000000",
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Premium data access",
},
"/api/analytics/*": {
accepts: {
scheme: "exact",
price: "10000000",
network: "eip155:8453",
payTo: "0xYourAddress...",
},
description: "Analytics access (all endpoints)",
},
},
resourceServer
);
export const config = {
matcher: ["/api/data/:path*", "/api/analytics/:path*"],
};
```
## API Routes
Your API routes can check for payment verification:
```typescript theme={null}
// app/api/data/premium/route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(request: NextRequest) {
// Payment verification is handled by middleware
// If we reach here, payment was verified
const payerAddress = request.headers.get("X-Payer-Address");
return NextResponse.json({
data: "premium data",
accessedBy: payerAddress,
});
}
```
## Error Handling
The middleware automatically handles common errors:
* **404**: Route not found (no matching payment configuration)
* **402**: Payment required (no payment header provided)
* **400**: Invalid payment payload
* **500**: Configuration error
## Types
```typescript theme={null}
import type {
PaymentScheme,
RoutePaymentConfig,
} from "@armory-sh/middleware-next";
```
# Custom Networks
Source: https://armory.sh/advanced/custom-networks
Configure Armory for custom EVM chains and networks
# Custom Networks
Use Armory on any EVM-compatible chain by configuring network settings.
## Network Configuration
A network configuration includes:
```typescript theme={null}
{
name: string; // Display name
chainId: number; // EIP-155 chain ID
usdcAddress: `0x${string}`; // USDC contract address
rpcUrl: string; // RPC endpoint
caip2Id: string; // CAIP-2 network ID
caipAssetId: string; // CAIP-2 asset ID
}
```
## Add a Custom Network
### For Middleware
Configure RPC URLs for your custom network:
#### Bun
```typescript theme={null}
import { createBunMiddleware } from '@armory-sh/middleware-bun';
import { USDC_BASE } from '@armory-sh/base';
const middleware = createBunMiddleware({
payTo: '0x...',
amount: '2000000',
token: USDC_BASE,
rpcUrls: {
8453: 'https://mainnet.base.org',
// Add your custom network
123456: 'https://your-custom-rpc.com',
}
});
const app = Bun.serve({
fetch: async (req) => {
const result = await middleware(req);
if (result) return result;
return new Response(JSON.stringify({ data: 'protected content' }));
}
});
```
#### Express
```typescript theme={null}
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-express';
app.use(acceptPaymentsViaArmory({
payTo: '0x...',
amount: '2000000',
rpcUrls: {
8453: 'https://mainnet.base.org',
123456: 'https://your-custom-rpc.com',
}
}));
```
### For Client
Clients automatically derive network from the token's `chainId`:
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-viem';
import { privateKeyToAccount } from 'viem/accounts';
const CUSTOM_TOKEN = {
symbol: 'USDC',
name: 'USD Coin',
version: '2',
contractAddress: '0x...',
chainId: 123456, // Your custom chain ID
decimals: 6,
};
const client = createArmoryClient({
wallet: { type: 'account', account },
token: CUSTOM_TOKEN,
rpcUrl: 'https://your-custom-rpc.com', // Optional: custom RPC
});
```
## CAIP IDs
Armory uses [CAIP](https://chainagnostic.org/)-style IDs for network identification:
### CAIP-2 (Network)
Format: `eip155:`
```typescript theme={null}
const caip2Id = `eip155:${chainId}`;
// Examples:
'eip155:1' // Ethereum
'eip155:8453' // Base
'eip155:123456' // Custom
```
### CAIP-2 Asset (Token)
Format: `eip155:/erc20:`
```typescript theme={null}
const caipAssetId = `eip155:${chainId}/erc20:${contractAddress}`;
// Example:
'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
```
## Example: Arbitrum Sepolia
```typescript theme={null}
import { createBunMiddleware } from '@armory-sh/middleware-bun';
// Custom token on Arbitrum Sepolia
const USDC_ARB_SEPOLIA = {
symbol: 'USDC',
name: 'USD Coin',
version: '2',
contractAddress: '0x75faf114eafb1Acbe221d265a875F4Ea013E0bA1',
chainId: 421614,
decimals: 6,
};
const middleware = createBunMiddleware({
payTo: '0x...',
amount: '2000000',
token: USDC_ARB_SEPOLIA,
rpcUrls: {
421614: 'https://sepolia-rollup.arbitrum.one/rpc',
}
});
const app = Bun.serve({
fetch: async (req) => {
const result = await middleware(req);
if (result) return result;
return new Response(JSON.stringify({ data: 'protected content' }));
}
});
```
## Testnet Configuration
```typescript theme={null}
// Testnet token
const USDC_SEPOLIA = {
symbol: 'USDC',
name: 'USD Coin',
version: '2',
contractAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
chainId: 11155111, // Sepolia
decimals: 6,
};
const client = createArmoryClient({
wallet: { type: 'account', account },
token: USDC_SEPOLIA,
rpcUrl: 'https://rpc.sepolia.org',
});
```
## Multi-Network Support
Accept payments across multiple networks:
```typescript theme={null}
app.use(acceptPaymentsViaArmory({
payTo: '0x...',
amount: '2000000',
accept: {
networks: ['base', 'ethereum', 123456], // Mix names and chain IDs
tokens: [USDC_BASE, CUSTOM_TOKEN],
}
}));
```
## Network Discovery
Get network info from chain ID:
```typescript theme={null}
import { getNetworkByChainId } from '@armory-sh/base';
const network = getNetworkByChainId(8453);
console.log(network);
// {
// name: "Base Mainnet",
// chainId: 8453,
// usdcAddress: "0x8335...",
// rpcUrl: "https://mainnet.base.org",
// caip2Id: "eip155:8453",
// caipAssetId: "eip155:8453/erc20:0x8335..."
// }
```
# Custom Tokens
Source: https://armory.sh/advanced/custom-tokens
Use custom tokens with Armory middleware and clients
# Custom Tokens
Use any EIP-3009 compatible token with Armory — not just the pre-configured ones.
## Define a Custom Token
Create a token object matching your contract:
```typescript theme={null}
import type { CustomToken } from '@armory-sh/base';
const MY_TOKEN: CustomToken = {
symbol: 'MYTKN',
name: 'My Token',
version: '1',
contractAddress: '0x1234567890123456789012345678901234567890',
chainId: 8453, // Base
decimals: 18,
};
```
## Use with Middleware
Pass your custom token directly to the middleware:
### Bun
```typescript theme={null}
import { createBunMiddleware } from '@armory-sh/middleware-bun';
const middleware = createBunMiddleware({
payTo: '0xYourWalletAddress...',
amount: '1000000000000000000', // 1 token (18 decimals)
token: MY_TOKEN,
});
const app = Bun.serve({
fetch: async (req) => {
const result = await middleware(req);
if (result) return result;
return new Response(JSON.stringify({ data: 'protected content' }));
}
});
```
### Express
```typescript theme={null}
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-express';
app.use(acceptPaymentsViaArmory({
payTo: '0xYourWalletAddress...',
amount: '1000000000000000000',
token: MY_TOKEN,
}));
```
### Hono
```typescript theme={null}
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-hono';
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0xYourWalletAddress...',
amount: '1000000000000000000',
token: MY_TOKEN,
}));
```
### Elysia
```typescript theme={null}
import { paymentMiddleware } from '@armory-sh/middleware-elysia';
const app = new Elysia()
.use(paymentMiddleware({
requirements: {
to: '0xYourWalletAddress...',
amount: '1000000000000000000',
chainId: 'eip155:8453',
assetId: 'eip155:8453/erc20:0x1234567890123456789012345678901234567890',
}
}));
```
## Use with Client
Pass your custom token when creating a client:
### Viem
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-viem';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const client = createArmoryClient({
wallet: { type: 'account', account },
token: MY_TOKEN,
});
```
### Ethers
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-ethers';
import { Wallet } from 'ethers';
const wallet = new Wallet('0x...');
const client = createArmoryClient({
wallet: { type: 'wallet', wallet },
token: MY_TOKEN,
});
```
### Web3.js
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-web3';
import { Web3 } from 'web3';
const web3 = new Web3('...');
const account = web3.eth.accounts.privateKeyToAccount('0x...');
const client = createArmoryClient({
wallet: { type: 'web3', account, web3 },
token: MY_TOKEN,
});
```
## Register Token (Optional)
If you want your token to be discoverable via the token registry:
```typescript theme={null}
import { registerToken, getToken } from '@armory-sh/base';
registerToken(MY_TOKEN);
// Now available via:
const token = getToken(8453, '0x1234...');
```
## Multi-Token Setup
Accept multiple custom tokens:
```typescript theme={null}
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-hono';
const TOKEN_1 = { symbol: 'TKN1', contractAddress: '0x...', chainId: 8453, decimals: 18 };
const TOKEN_2 = { symbol: 'TKN2', contractAddress: '0x...', chainId: 8453, decimals: 6 };
// Middleware accepts either token
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0x...',
amount: '1000000',
accept: {
tokens: [TOKEN_1, TOKEN_2],
}
}));
```
## Token Requirements
Your token must implement [EIP-3009](https://eips.ethereum.org/EIPS/eip-3009):
```solidity theme={null}
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external;
```
Most major stablecoins (USDC, USDT, DAI, PYUSD) already support this.
# Changelog
Source: https://armory.sh/changelog
Changelog for all Armory packages
Subscribe via RSS: `/changelog/rss.xml`.
### Patch Changes
* Deterministic facilitator routing precedence across network/token combinations:
* `facilitatorUrlByToken[network][token]`
* `facilitatorUrlByChain[network]`
* `facilitatorUrl`
* Fixed middleware token-map resolution bug that could select the wrong facilitator URL on shared chains.
* Added fail-open extension capability filtering for challenge headers: unsupported extension keys are automatically omitted per facilitator `/supported` response (with cache).
* Added facilitator-aware pricing selection support for middleware config resolvers (`network + token + facilitator` before fallback tiers).
* Added regression coverage for facilitator precedence and extension capability filtering.
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
### Patch Changes
* 281eeb8: Fix Versions
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
### Patch Changes
* Fix Amount
### Patch Changes
* Clenaup Flows
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
### Patch Changes
* Add Simple Middleware Back
### Patch Changes
* ALpah Test
### Patch Changes
* Test Link
### Patch Changes
* Completed E2E Flows w/ v2
### Minor Changes
* **Added**: Export token constants (`TOKENS`, `USDC_BASE`, `EURC_BASE`, etc.) from `@armory-sh/tokens` package
* **Added**: Token helper functions (`getToken`, `getAllTokens`, `getTokensBySymbol`, `getUSDCTokens`, etc.)
* Token constants are now available directly from `@armory-sh/base` for convenience
### Patch Changes
* v2 Only, Cleanup
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
### Patch Changes
* :wq!
### Patch Changes
* Automated release
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Cleanup
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
### Patch Changes
* Add Simple Middleware Back
### Patch Changes
* ALpah Test
### Patch Changes
* Test Link
### Patch Changes
* Completed E2E Flows w/ v2
### Patch Changes
* v2 Only, Cleanup
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
### Patch Changes
* :wq!
### Patch Changes
* Cleanup
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/extensions\@0.1.1
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* Fix Structure
### Patch Changes
* d5977fa: Fix Compatiblity
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
### Patch Changes
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* Fix Structure
### Patch Changes
* d5977fa: Fix Compatiblity
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
### Patch Changes
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/extensions\@0.1.1
* @armory-sh/base\@0.2.20
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
### Patch Changes
* Fix Structure
### Patch Changes
* d5977fa: Fix Compatiblity
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
### Patch Changes
* Automated release
### Patch Changes
* Automated release
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
# @armory-sh/base
Source: https://armory.sh/changelogs/base
Release history for @armory-sh/base
# @armory-sh/base
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.2.28
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
## Version 0.2.25
### Patch Changes
* 281eeb8: Fix Versions
## Version 0.2.24
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
## Version 0.2.23
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
## Version 0.2.22
### Patch Changes
* Fix Amount
## Version 0.2.21
### Patch Changes
* Clenaup Flows
## Version 0.2.20
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
## Version 0.2.19
### Patch Changes
* Add Simple Middleware Back
## Version 0.2.18
### Patch Changes
* ALpah Test
## Version 0.2.17
### Patch Changes
* Test Link
## Version 0.2.16
### Patch Changes
* Completed E2E Flows w/ v2
## Version 0.2.15
### Minor Changes
* **Added**: Export token constants (`TOKENS`, `USDC_BASE`, `EURC_BASE`, etc.) from `@armory-sh/tokens` package
* **Added**: Token helper functions (`getToken`, `getAllTokens`, `getTokensBySymbol`, `getUSDCTokens`, etc.)
* Token constants are now available directly from `@armory-sh/base` for convenience
## Version 0.2.14
### Patch Changes
* v2 Only, Cleanup
## Version 0.2.13
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
## Version 0.2.12
### Patch Changes
* :wq!
## Version 0.2.11
### Patch Changes
* Automated release
## Version 0.2.10
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Automated release
## Version 0.2.9
### Patch Changes
* Automated release
## Version 0.2.8
### Patch Changes
* Automated release
## Version 0.2.7
### Patch Changes
* Automated release
## Version 0.2.6
### Patch Changes
* Automated release
## Version 0.2.5
### Patch Changes
* Automated release
## Version 0.2.4
### Patch Changes
* Cleanup
## Version 0.2.3
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
# CLI
Source: https://armory.sh/changelogs/cli
Release history for CLI
# CLI
Full package changelog.
## Version 0.3.8
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
## Version 0.3.5
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
## Version 0.3.4
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
## Version 0.3.3
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
## Version 0.3.2
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
## Version 0.3.1
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
## Version 0.2.11
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
## Version 0.2.10
### Patch Changes
* Add Simple Middleware Back
## Version 0.2.9
### Patch Changes
* ALpah Test
## Version 0.2.8
### Patch Changes
* Test Link
## Version 0.2.7
### Patch Changes
* Completed E2E Flows w/ v2
## Version 0.2.6
### Patch Changes
* v2 Only, Cleanup
## Version 0.2.5
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
## Version 0.2.4
### Patch Changes
* :wq!
## Version 0.2.3
### Patch Changes
* Cleanup
## Version 0.2.2
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
# @armory-sh/client-ethers
Source: https://armory.sh/changelogs/client-ethers
Release history for @armory-sh/client-ethers
# @armory-sh/client-ethers
Full package changelog.
## Version 0.2.27
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.2.24
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.2.23
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.2.22
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.2.21
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.2.20
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.2.19
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.2.18
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.2.17
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.2.16
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.2.15
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.2.14
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.2.13
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.2.12
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
## Version 0.2.11
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
## Version 0.2.10
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
## Version 0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
## Version 0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
## Version 0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
## Version 0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
## Version 0.2.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
## Version 0.2.4
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
## Version 0.2.3
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
# @armory-sh/client-hooks
Source: https://armory.sh/changelogs/client-hooks
Release history for @armory-sh/client-hooks
# @armory-sh/client-hooks
Full package changelog.
## Version 0.1.1
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
# @armory-sh/client-viem
Source: https://armory.sh/changelogs/client-viem
Release history for @armory-sh/client-viem
# @armory-sh/client-viem
Full package changelog.
## Version 0.2.27
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
## Version 0.2.24
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
## Version 0.2.23
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
## Version 0.2.22
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
## Version 0.2.21
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
## Version 0.2.20
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
## Version 0.2.19
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/extensions\@0.1.1
* @armory-sh/base\@0.2.20
## Version 0.2.18
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.2.17
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.2.16
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.2.15
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.2.14
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.2.13
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.2.12
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
## Version 0.2.11
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
## Version 0.2.10
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* 0e32676: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
## Version 0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
## Version 0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
## Version 0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
## Version 0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
## Version 0.2.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
## Version 0.2.4
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
## Version 0.2.3
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
# @armory-sh/client-web3
Source: https://armory.sh/changelogs/client-web3
Release history for @armory-sh/client-web3
# @armory-sh/client-web3
Full package changelog.
## Version 0.2.24
### Patch Changes
* 993834f: Fix v2 Headers
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.2.21
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.2.20
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.2.19
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.2.18
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.2.17
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.2.16
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.2.15
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.2.14
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.2.13
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.2.12
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.2.11
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.2.10
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.2.9
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
## Version 0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
## Version 0.2.7
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
## Version 0.2.6
### Patch Changes
* Automated release
## Version 0.2.6
### Patch Changes
* Automated release
## Version 0.2.6
### Patch Changes
* Automated release
## Version 0.2.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
## Version 0.2.8
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
## Version 0.2.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
## Version 0.2.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
## Version 0.2.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
## Version 0.2.4
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
## Version 0.2.3
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
# @armory-sh/extensions
Source: https://armory.sh/changelogs/extensions
Release history for @armory-sh/extensions
# @armory-sh/extensions
Full package changelog.
## Version 0.1.9
### Patch Changes
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.1.6
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.1.5
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.1.4
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.1.3
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.1.2
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.1.1
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
# @armory-sh/middleware-bun
Source: https://armory.sh/changelogs/middleware-bun
Release history for @armory-sh/middleware-bun
# @armory-sh/middleware-bun
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.3.26
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.3.23
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.3.22
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.3.21
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.3.20
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.3.19
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.3.18
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.3.17
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.3.16
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.3.15
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.3.14
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.3.13
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.3.12
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.3.11
### Patch Changes
* Fix Structure
## Version 0.3.10
### Patch Changes
* d5977fa: Fix Compatiblity
## Version 0.3.9
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
## Version 0.3.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
## Version 0.3.8
### Patch Changes
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
## Version 0.3.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
## Version 0.3.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
## Version 0.3.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
## Version 0.3.4
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
## Version 0.3.3
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
## Version 0.3.2
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
## Version 0.3.1
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
# @armory-sh/middleware-elysia
Source: https://armory.sh/changelogs/middleware-elysia
Release history for @armory-sh/middleware-elysia
# @armory-sh/middleware-elysia
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.3.26
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.3.23
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.3.22
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.3.21
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.3.20
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.3.19
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.3.18
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.3.17
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.3.16
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.3.15
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.3.14
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.3.13
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.3.12
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.3.11
### Patch Changes
* Fix Structure
## Version 0.3.10
### Patch Changes
* d5977fa: Fix Compatiblity
## Version 0.3.9
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
## Version 0.3.9
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
## Version 0.3.8
### Patch Changes
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
## Version 0.3.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
## Version 0.3.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
## Version 0.3.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
## Version 0.3.4
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
## Version 0.3.3
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
## Version 0.3.2
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
## Version 0.3.1
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
# @armory-sh/middleware-express
Source: https://armory.sh/changelogs/middleware-express
Release history for @armory-sh/middleware-express
# @armory-sh/middleware-express
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.4.16
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.4.12
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.4.11
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.4.10
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.4.9
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.4.8
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.4.7
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.4.6
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.4.5
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.4.4
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.4.3
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.4.2
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.4.1
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
# @armory-sh/middleware-express-v4
Source: https://armory.sh/changelogs/middleware-express-v4
Release history for @armory-sh/middleware-express-v4
# @armory-sh/middleware-express-v4
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.1.10
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.1.6
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.1.5
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.1.4
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.1.3
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.1.2
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.1.1
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
## Version 0.3.19
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.3.18
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.3.17
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.3.16
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.3.15
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.3.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
# @armory-sh/middleware-hono
Source: https://armory.sh/changelogs/middleware-hono
Release history for @armory-sh/middleware-hono
# @armory-sh/middleware-hono
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.3.28
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
* @armory-sh/extensions\@0.1.9
## Version 0.3.25
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/extensions\@0.1.6
* @armory-sh/base\@0.2.25
## Version 0.3.24
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/extensions\@0.1.5
* @armory-sh/base\@0.2.24
## Version 0.3.23
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/extensions\@0.1.4
* @armory-sh/base\@0.2.23
## Version 0.3.22
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/extensions\@0.1.3
* @armory-sh/base\@0.2.22
## Version 0.3.21
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/extensions\@0.1.2
* @armory-sh/base\@0.2.21
## Version 0.3.20
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/extensions\@0.1.1
* @armory-sh/base\@0.2.20
## Version 0.3.19
### Patch Changes
* Add Simple Middleware Back
* Updated dependencies
* @armory-sh/base\@0.2.19
## Version 0.3.18
### Patch Changes
* ALpah Test
* Updated dependencies
* @armory-sh/base\@0.2.18
## Version 0.3.17
### Patch Changes
* Test Link
* Updated dependencies
* @armory-sh/base\@0.2.17
## Version 0.3.16
### Patch Changes
* Completed E2E Flows w/ v2
* Updated dependencies
* @armory-sh/base\@0.2.16
## Version 0.3.15
### Patch Changes
* v2 Only, Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.14
## Version 0.3.14
### Patch Changes
* Add Deep Test Suite, Enhance Compatibility
* Updated dependencies
* @armory-sh/base\@0.2.13
## Version 0.3.13
### Patch Changes
* Fix Structure
## Version 0.3.12
### Patch Changes
* d5977fa: Fix Compatiblity
## Version 0.3.11
### Patch Changes
* :wq!
* Updated dependencies
* @armory-sh/base\@0.2.12
* @armory-sh/facilitator\@0.2.12
## Version 0.3.11
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.11
* @armory-sh/facilitator\@0.2.11
## Version 0.3.10
### Patch Changes
* 0b7c70b: Automated release
* 77ddc6c: Automated release
* Updated dependencies \[0b7c70b]
* Updated dependencies \[77ddc6c]
* Updated dependencies \[0e32676]
* Updated dependencies
* @armory-sh/base\@0.2.10
* @armory-sh/facilitator\@0.2.10
## Version 0.3.9
### Patch Changes
* Automated release
## Version 0.3.8
### Patch Changes
* Automated release
## Version 0.3.7
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.9
* @armory-sh/facilitator\@0.2.9
## Version 0.3.6
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.8
* @armory-sh/facilitator\@0.2.8
## Version 0.3.5
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.7
* @armory-sh/facilitator\@0.2.7
## Version 0.3.4
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.6
* @armory-sh/facilitator\@0.2.6
## Version 0.3.3
### Patch Changes
* Automated release
* Updated dependencies
* @armory-sh/base\@0.2.5
* @armory-sh/facilitator\@0.2.5
## Version 0.3.2
### Patch Changes
* Cleanup
* Updated dependencies
* @armory-sh/base\@0.2.4
* @armory-sh/facilitator\@0.2.4
## Version 0.3.1
### Patch Changes
* Cleanup Code, Add Bespoke Middleware
* Updated dependencies
* @armory-sh/base\@0.2.3
* @armory-sh/facilitator\@0.2.3
# @armory-sh/middleware-next
Source: https://armory.sh/changelogs/middleware-next
Release history for @armory-sh/middleware-next
# @armory-sh/middleware-next
Full package changelog.
## Unreleased
### Patch Changes
* Added deterministic facilitator routing precedence for mix-and-match network/token/facilitator setups.
* Fixed per-token facilitator resolution on shared chains to avoid wrong facilitator selection.
* Added facilitator capability-based extension filtering in payment challenge headers (fail-open: unsupported keys are auto-ignored).
* Added facilitator-aware pricing selection for middleware config flows (`network + token + facilitator` before fallback).
## Version 0.1.9
### Patch Changes
* 3ba536a: Streamline Client, Multitoken Middleware
* Improve dynamic requirement handling across middleware and clients, and surface detailed payment verification errors.
* Fix requirement selection/verification to use the accepted requirement dynamically (not first-item assumptions)
* Support explicit `requirements` config paths consistently in middleware wrappers
* Surface server verification details (for example `insufficient_funds`) in client retry failure errors
* Add regression tests for non-primary requirement selection and client selector behavior
* Clarify hooks vs extensions semantics in docs/READMEs and normalize docs page titles
* e90cb54: Update Package Dodcs
* 261eed7: Multichain Validation
* e03c05c: Add Client Hooks, Fix Test Suite
* Updated dependencies \[993834f]
* Updated dependencies \[3ba536a]
* Updated dependencies
* Updated dependencies \[e90cb54]
* Updated dependencies \[261eed7]
* Updated dependencies \[e03c05c]
* @armory-sh/base\@0.2.28
## Version 0.1.6
### Patch Changes
* 281eeb8: Fix Versions
* Updated dependencies \[281eeb8]
* @armory-sh/base\@0.2.25
## Version 0.1.5
### Patch Changes
* 4033813: Package Cleanup, Minor Docs
* Updated dependencies \[4033813]
* @armory-sh/base\@0.2.24
## Version 0.1.4
### Patch Changes
* 99b2ede: Fix USDC Names
* e6a88ff: Fix Dependency Resolution
* 6697eec: Fix Nonce Type
* 9ba2f62: Fix
* a938742: Fixing Amount
* Updated dependencies \[99b2ede]
* Updated dependencies \[e6a88ff]
* Updated dependencies \[6697eec]
* Updated dependencies \[9ba2f62]
* Updated dependencies \[a938742]
* @armory-sh/base\@0.2.23
## Version 0.1.3
### Patch Changes
* Fix Amount
* Updated dependencies
* @armory-sh/base\@0.2.22
## Version 0.1.2
### Patch Changes
* Clenaup Flows
* Updated dependencies
* @armory-sh/base\@0.2.21
## Version 0.1.1
### Patch Changes
* Next.js Middleware, Extensiosn Package, Client Robustness, Route Filtering Added
* Updated dependencies
* @armory-sh/base\@0.2.20
# CLI
Source: https://armory.sh/cli
Command-line tooling for Armory workflows
The CLI docs live in the dedicated [CLI section](/make-payments/cli-overview).
## Start Here
* [Overview](/make-payments/cli-overview)
* [Create](/make-payments/cli-create)
* [Verify](/make-payments/cli-verify)
* [Examples](/make-payments/cli-examples)
# Chain Preference Hook
Source: https://armory.sh/client-hooks/chain
Prefer specific networks when multiple payment options are available
```typescript theme={null}
import { PaymentPreference } from '@armory-sh/client-hooks';
const hook = PaymentPreference.chain(['base', 'ethereum', 'skale-base']);
```
Use this hook first when you want deterministic network preference.
# Cheapest Hook
Source: https://armory.sh/client-hooks/cheapest
Select the lowest-amount compatible payment option
```typescript theme={null}
import { PaymentPreference } from '@armory-sh/client-hooks';
const hook = PaymentPreference.cheapest();
```
This hook refines selection within the already-selected chain and token scope.
# Combine Hooks
Source: https://armory.sh/client-hooks/combine
Compose multiple hooks and hook arrays into one list
```typescript theme={null}
import { combineHooks, Logger, PaymentPreference } from '@armory-sh/client-hooks';
const hooks = combineHooks(
PaymentPreference.chain(['base']),
[PaymentPreference.token(['USDC'])],
PaymentPreference.cheapest(),
Logger.console(),
null
);
```
# Custom Hooks
Source: https://armory.sh/client-hooks/custom-hooks
Create custom Armory hooks for advanced flow control
Use custom hooks to implement project-specific behavior in payment lifecycle phases.
```typescript theme={null}
import type { ClientHook } from '@armory-sh/client-hooks';
const customHook: ClientHook = {
name: 'require-premium-route',
onPaymentRequired: async (context) => {
const url = typeof context.url === 'string' ? context.url : context.url.toString();
if (!url.includes('/premium')) {
return;
}
},
onError: async (context) => {
console.error('[hook-error]', context.phase, context.error);
}
};
```
For custom x402 extension payload fields, use `createCustomHook` from `@armory-sh/extensions`.
# Logger Hook
Source: https://armory.sh/client-hooks/logger
Emit payment lifecycle logs during client execution
```typescript theme={null}
import { Logger } from '@armory-sh/client-hooks';
const hook = Logger.console({
prefix: '[x402]',
enabled: true
});
```
# Armory Hooks Overview
Source: https://armory.sh/client-hooks/overview
Understand Armory's client hook lifecycle and execution model
Armory hooks are lifecycle callbacks that run during payment execution.
Hooks are not x402 protocol fields. They are local runtime behavior for selection, mutation, logging, and error handling.
## Lifecycle
1. `onPaymentRequired`
2. `selectRequirement`
3. `beforeSignPayment`
4. `afterPaymentResponse`
5. `onError`
## Execution Model
* Hooks execute in array order
* Selection narrows progressively as hooks run
* Hook failures are fail-closed by default
## Next Pages
* [Chain Preference](/client-hooks/chain)
* [Token Preference](/client-hooks/token)
* [Cheapest Selection](/client-hooks/cheapest)
* [Logger](/client-hooks/logger)
* [combineHooks](/client-hooks/combine)
* [Custom Hooks](/client-hooks/custom-hooks)
# Token Preference Hook
Source: https://armory.sh/client-hooks/token
Prefer specific assets when multiple token options are available
```typescript theme={null}
import { PaymentPreference } from '@armory-sh/client-hooks';
const hook = PaymentPreference.token(['USDC', 'USDT', 'WBTC']);
```
Run this after chain preference if you want network-first, token-second selection.
# Overview
Source: https://armory.sh/extensions
What x402 extensions are and how Armory uses them
x402 extensions are protocol-level metadata attached to challenges and payment payloads via the `extensions` object.
Use extensions when a server requires additional fields beyond core payment data, such as authentication, idempotency, or discovery metadata.
## Built-in Extensions
* Sign-In-With-X (`siwx`) for wallet-authenticated access
* Payment Identifier (`paymentIdentifier`) for idempotency
* Bazaar (`bazaar`) for discovery metadata
## Extension Flow
1. Server declares required extensions in `PAYMENT-REQUIRED`
2. Client hooks inspect required extension metadata
3. Client adds extension payload fields before signing
4. Server verifies and processes extension data
## Next Pages
* [Sign-In-With-X](/extensions/siwx)
* [Payment Identifier](/extensions/payment-identifier)
* [Bazaar](/extensions/bazaar)
* [Custom Extensions](/extensions/custom)
# Bazaar
Source: https://armory.sh/extensions/bazaar
Declare discovery extension metadata for x402 resources
## Server Declaration
```typescript theme={null}
import { declareDiscoveryExtension } from '@armory-sh/extensions';
const extension = declareDiscoveryExtension({
required: true
});
```
Bazaar is primarily server-driven and used for discovery metadata in x402 resource ecosystems.
# Custom Extensions
Source: https://armory.sh/extensions/custom
Build your own extension behavior with custom hooks
```typescript theme={null}
import { createCustomHook } from '@armory-sh/extensions';
const customHook = createCustomHook({
key: 'my-extension',
handler: async (context) => {
if (!context.payload) {
return;
}
context.payload.extensions = {
...(context.payload.extensions ?? {}),
'my-extension': { enabled: true }
};
},
priority: 75
});
```
## Best Practices
* Add extension data only if the server requested it
* Keep extension payloads small and deterministic
* Version extension data when schema changes
# Payment Identifier
Source: https://armory.sh/extensions/payment-identifier
Use payment IDs for idempotency across payment requests
## Client Hook
```typescript theme={null}
import { createPaymentIdHook } from '@armory-sh/extensions';
const autoIdHook = createPaymentIdHook();
const fixedIdHook = createPaymentIdHook({
paymentId: 'invoice-2026-00042'
});
```
## Server Declaration
```typescript theme={null}
import { declarePaymentIdentifierExtension } from '@armory-sh/extensions';
const extension = declarePaymentIdentifierExtension({
required: true
});
```
## Utility
```typescript theme={null}
import { generatePaymentId } from '@armory-sh/extensions';
const id = generatePaymentId();
```
# Sign-In-With-X
Source: https://armory.sh/extensions/siwx
Add SIWX authentication to x402 payment flows
## Client Hook
```typescript theme={null}
import { createSIWxHook } from '@armory-sh/extensions';
const hook = createSIWxHook({
domain: 'api.example.com',
statement: 'Sign in to access protected routes',
expirationSeconds: 3600
});
```
## Server Declaration
```typescript theme={null}
import { declareSIWxExtension } from '@armory-sh/extensions';
const extension = declareSIWxExtension({
domain: 'api.example.com',
statement: 'Sign in to access this API',
network: 'eip155:8453',
expirationSeconds: 3600
});
```
## Validation
```typescript theme={null}
import { parseSIWxHeader, validateSIWxMessage, verifySIWxSignature } from '@armory-sh/extensions';
const payload = parseSIWxHeader(header);
const messageResult = validateSIWxMessage(payload, 'https://api.example.com/data');
if (messageResult.valid) {
const signatureResult = await verifySIWxSignature(payload, {
evmVerifier: async () => true
});
}
```
# Introduction
Source: https://armory.sh/index
Introduction to Armory and how to get started with x402 v2 payments
Armory is a TypeScript toolkit for x402 v2 payments that lets APIs require wallet-based payment over standard HTTP flows.
Armory targets x402 v2 wire compatibility so Armory clients and middleware can interoperate with Coinbase x402 SDK implementations.
## What You Can Build
* Paid API endpoints using middleware in Express, Hono, Bun, Elysia, and Next.js.
* Wallet-based API clients using Viem, Ethers.js, and Web3.js.
* Multi-network and multi-token payment flows with shared base logic.
## How Armory Works
1. A protected endpoint returns `402` with `PAYMENT-REQUIRED`.
2. The client selects one option from `accepts[]` and signs a payment payload.
3. The retried request sends `PAYMENT-SIGNATURE`.
4. The server verifies/settles and returns data with `PAYMENT-RESPONSE`.
## Start Here
* [Key Concepts](/key-concepts)
* [Accept Payments](/accept-payments/express)
* [Make Payments](/make-payments/viem)
* [CLI](/cli)
## Core Packages
* `@armory-sh/base`: shared protocol types, encoding, and payment flow logic.
* Middleware packages: route protection and payment verification.
* Client packages: wallet integration and payment retries.
* `@armory-sh/extensions`: optional protocol extensions.
* `@armory-sh/client-hooks`: optional selection/logging hooks.
## Supported Networks and Tokens
Armory supports Ethereum, Base, SKALE, and testnets listed in the protocol docs, with major payment tokens including USDC.
## Next Step
Go to [Key Concepts](/key-concepts) to understand the model before implementing server or client code.
# Key Concepts
Source: https://armory.sh/key-concepts
Core x402 v2 concepts and how Armory applies them
This page explains the core x402 v2 model and how Armory maps it into practical server and client libraries.
## What Armory Is
Armory is a TypeScript toolkit for implementing x402 v2 payments over HTTP.
* Server middleware packages enforce payment requirements and verify payloads.
* Client packages create and send payment payloads from wallets.
* Shared protocol logic and types live in `@armory-sh/base`.
## x402 v2 in One Flow
1. Client requests a protected resource.
2. Server returns `402` with `PAYMENT-REQUIRED` and an `accepts[]` list.
3. Client selects one requirement, signs payment authorization, and retries with `PAYMENT-SIGNATURE`.
4. Server verifies and settles, then returns data with `PAYMENT-RESPONSE`.
## Three Actors
* Resource server: protects routes and requires payment.
* Client: picks a requirement and signs authorization with a wallet.
* Facilitator: verifies and settles payments.
## Core Objects
* `PaymentRequirements`: server-offered requirement options in `accepts[]`.
* `PaymentPayload`: client-signed payment payload tied to one accepted requirement.
* `SettlementResponse`: settlement result returned from verification/settlement.
* `VerifyResponse`: verification result from facilitator.
## HTTP Header Contract
* `PAYMENT-REQUIRED`: challenge with `accepts[]` and resource metadata.
* `PAYMENT-SIGNATURE`: client payment payload.
* `PAYMENT-RESPONSE`: settlement response.
## Versioning Rule
Armory is v2-only. Requests and responses should use x402 v2 fields and wire format.
## Scheme and Signing
For EVM exact payments, Armory uses EIP-3009 (`transferWithAuthorization`) and EIP-712 signatures.
* Payer signs authorization off-chain.
* Settlement executes token transfer on-chain.
* Nonce and validity windows prevent replay.
## Identifiers You Will See
* Network: CAIP-2 format, for example `eip155:8453`.
* Token/asset: token contract or CAIP asset form.
* Chain/token inputs can often be provided as names, IDs, or CAIP forms.
## How to Apply This in Armory
* Accept payments: start with a middleware package under `/accept-payments/*`.
* Make payments: start with a client package under `/make-payments/*`.
* Extend behavior: use extension docs and client hooks for selection/logging.
## References
* [x402 Spec v2](https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md)
* [HTTP Transport v2](https://github.com/coinbase/x402/tree/main/specs/transports-v2/http.md)
* [A2A Transport v2](https://github.com/coinbase/x402/tree/main/specs/transports-v2/a2a.md)
# Create
Source: https://armory.sh/make-payments/cli-create
Scaffold server and client payment projects
`armory create` scaffolds starter projects for payment-enabled servers and clients.
## Syntax
```bash theme={null}
armory create
```
## Templates
Server templates:
* `bun-server`
* `elysia-server`
* `express-server`
* `hono-server`
* `next-server`
Client templates:
* `viem-client`
* `ethers-client`
* `web3-client`
## Example: Bun Merchant + Viem Client
```bash theme={null}
armory create bun-server merchant-api
cd merchant-api
bun install
bun run dev
cd ..
armory create viem-client buyer-app
cd buyer-app
bun install
PRIVATE_KEY=0xYOUR_PRIVATE_KEY bun run dev
```
## Example: Next.js Protected Routes
```bash theme={null}
armory create next-server paywalled-next
cd paywalled-next
bun install
bun run dev
```
After scaffold, configure `payTo`, token, and chain in the generated middleware config.
# Examples
Source: https://armory.sh/make-payments/cli-examples
Practical Armory CLI workflows for payment setup and verification
# CLI Examples
## Merchant API + Viem Buyer
```bash theme={null}
armory create bun-server merchant-api
cd merchant-api
bun install
bun run dev
cd ..
armory create viem-client buyer-app
cd buyer-app
bun install
PRIVATE_KEY=0xYOUR_PRIVATE_KEY bun run dev
```
## Validate a Target Payment Pair
```bash theme={null}
armory validate network base
armory validate token usdc
```
## Inspect Endpoint Requirements
```bash theme={null}
armory verify http://localhost:3000/api/premium
```
## Explore Supported Config
```bash theme={null}
armory networks
armory tokens
armory extensions
```
# Extensions
Source: https://armory.sh/make-payments/cli-extensions
Inspect supported x402 extensions
`armory extensions` prints the known extension set from the Armory ecosystem.
## Usage
```bash theme={null}
armory extensions
# shorthand
armory ext
```
## Example: Check for Required Extension in CI
```bash theme={null}
REQUIRED=payment-identifier
if armory extensions | rg -q "$REQUIRED"; then
echo "extension available"
else
echo "missing extension: $REQUIRED" && exit 1
fi
```
## Next
See extension implementation guides:
* [Extensions Overview](/extensions)
* [Payment Identifier](/extensions/payment-identifier)
# Networks
Source: https://armory.sh/make-payments/cli-networks
Query supported chains and IDs
`armory networks` lists supported chain names, chain IDs, and CAIP identifiers.
## Common Usage
```bash theme={null}
# all networks
armory networks
# filtered
armory networks --mainnet
armory networks --testnet
```
## Scripted Validation Example
```bash theme={null}
NETWORK=base
if armory networks | rg -qi "$NETWORK"; then
echo "supported: $NETWORK"
else
echo "unsupported: $NETWORK"
fi
```
## Build Input Values for Clients
```bash theme={null}
# validate the network format your app will pass
armory validate network base
armory validate network 8453
armory validate network eip155:8453
```
# Overview
Source: https://armory.sh/make-payments/cli-overview
Use Armory CLI to build and validate payment flows
Use `armory-cli` to scaffold projects and inspect supported x402 payment configuration.
## Install
```bash theme={null}
bunx armory-cli --help
# or
bun add -g armory-cli
```
## Command Map
* `armory create` to scaffold payment-enabled apps
* `armory networks` to list supported chains
* `armory tokens` to list supported tokens
* `armory validate` to validate chain/token identifiers
* `armory extensions` to inspect available extension helpers
* `armory verify` to inspect endpoint payment headers
## End-to-End CLI Workflow
```bash theme={null}
# 1) Create a server
armory create bun-server merchant-api
cd merchant-api
bun install
bun run dev
# 2) Validate target network/token for the client flow
armory validate network base
armory validate token usdc
# 3) Inspect payment requirements from the protected endpoint
armory verify http://localhost:3000/api/premium
# 4) Scaffold a client to pay the endpoint
cd ..
armory create viem-client buyer-client
cd buyer-client
bun install
PRIVATE_KEY=0xYOUR_KEY bun run dev
```
## Next Steps
* [CLI Create](/make-payments/cli-create)
* [CLI Verify](/make-payments/cli-verify)
* [CLI Examples](/make-payments/cli-examples)
# Tokens
Source: https://armory.sh/make-payments/cli-tokens
Query supported tokens by network and identifier
`armory tokens` lists supported payment tokens and addresses.
## Common Usage
```bash theme={null}
# all tokens
armory tokens
# by chain name
armory tokens base
# by chain id
armory tokens 8453
```
## Example: Pick a Valid Token Contract
```bash theme={null}
armory tokens base
armory validate token usdc
armory validate token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
```
## Example: Gate CI on Required Token Availability
```bash theme={null}
if armory tokens base | rg -q "USDC"; then
echo "USDC on Base available"
else
echo "USDC on Base missing" && exit 1
fi
```
# Validate
Source: https://armory.sh/make-payments/cli-validate
Validate network and token identifiers before runtime
`armory validate` checks whether your identifier is recognized.
## Network Validation
```bash theme={null}
armory validate network base
armory validate network 8453
armory validate network eip155:8453
```
## Token Validation
```bash theme={null}
armory validate token usdc
armory validate token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
```
## Practical Preflight Script
```bash theme={null}
set -e
armory validate network "$TARGET_CHAIN"
armory validate token "$TARGET_TOKEN"
echo "inputs valid"
```
Use this before startup to fail fast on misconfigured chain/token values.
# Verify
Source: https://armory.sh/make-payments/cli-verify
Inspect endpoint payment requirements and response headers
`armory verify` checks endpoint responses for payment headers and requirement metadata.
## Usage
```bash theme={null}
armory verify https://api.example.com/premium
# alias
armory inspect https://api.example.com/premium
```
## Local Debug Workflow
```bash theme={null}
# terminal 1
cd merchant-api
bun run dev
# terminal 2
armory verify http://localhost:3000/api/premium
```
## Example Output Interpretation
* `402` with `PAYMENT-REQUIRED`: endpoint is paywalled
* `200`: endpoint is open or payment already satisfied
* malformed/missing payment headers: check middleware wiring and route matching
## Troubleshooting
* Verify the route is protected in middleware config.
* Validate `chainId` and `assetId` used by your requirement payload.
* Confirm facilitator URL is reachable from your server runtime.
# With Ethers.js
Source: https://armory.sh/make-payments/ethers
Make payments with Ethers.js
# Make Payments with Ethers.js
Make payments to Armory-protected APIs using Ethers.js wallets.
`hooks` are lifecycle callbacks. `extensions` are protocol fields on x402 payloads/challenges. They work together but are separate.
When payment verification fails on retry (`402`), Armory surfaces server detail (for example `insufficient_funds`) in the error path.
## Basic Payment
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-ethers';
import { ethers } from 'ethers';
const signer = new ethers.Wallet('0x...');
const result = await armoryPay(
{ signer },
'https://api.example.com/data',
'base',
'usdc'
);
console.log(result.data);
```
## Armory object workflow
```typescript theme={null}
import { createArmory } from '@armory-sh/client-ethers';
import { ethers } from 'ethers';
const signer = new ethers.Wallet('0x...');
const armory = createArmory({
wallet: signer,
chains: 'base',
tokens: 'usdc',
debug: true,
});
const premium = await armory.post('https://api.example.com/premium', { tier: 'pro' });
const info = await armory.call('https://api.example.com/data');
console.log(premium.data, info.data);
```
`createArmory` exposes `.get`, `.post`, `.put`, `.delete`, `.patch`, `.pay`, and `.call`. When a 402 response arrives, it selects from `accepts[]`. Without hooks it uses the first compatible option; add `@armory-sh/client-hooks` to apply chain/token/cheapest preferences.
Use `.pay(url, { method: 'PATCH', body })` when you need to override the method and `.call(url)` if you just want the default GET request with payment.
## With Provider
```typescript theme={null}
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider('https://...');
const signer = new ethers.Wallet('0x...', provider);
const result = await armoryPay(
{ signer },
'https://api.example.com/data',
'base',
'usdc'
);
```
# With Viem.js
Source: https://armory.sh/make-payments/viem
Make payments with Viem
# Make Payments with Viem
Make payments to Armory-protected APIs using Viem wallets.
`hooks` are lifecycle callbacks. `extensions` are protocol fields on x402 payloads/challenges. They work together but are separate.
When payment verification fails on retry (`402`), Armory surfaces server detail (for example `insufficient_funds`) in the thrown error.
## Basic Payment
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-viem';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const result = await armoryPay(
{ account },
'https://api.example.com/data',
'base',
'usdc'
);
console.log(result.data);
```
## Prefer the Armory object (method-based API)
For multi-call flows the new `createArmory` object bundles the payment client with method helpers and automatic server option selection.
```typescript theme={null}
import { createArmory } from '@armory-sh/client-viem';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const armory = createArmory({
wallet: { account },
// Restrict the object to Base + USDC if you want to avoid extra lookups
chains: 'base',
tokens: 'usdc',
debug: true,
});
const premium = await armory.post('https://api.example.com/premium', { signal: 'upgrade' });
const info = await armory.call('https://api.example.com/data');
console.log(premium.data, info.data);
```
`createArmory` handles 402 responses from `PAYMENT-REQUIRED` and selects from `accepts[]`. Without hooks it uses the first compatible option. Add `@armory-sh/client-hooks` to apply chain/token/cheapest preference logic. The object exposes `.get`, `.post`, `.put`, `.delete`, `.patch`, `.pay`, and a `.call` shorthand for GET requests.
Use `armory.pay(url, { method: 'PATCH', body })` when you need to override the HTTP method; call `.call` for a simple GET.
## With Custom Amount
```typescript theme={null}
const result = await armoryPay(
{ account },
'https://api.example.com/premium',
'base',
'usdc',
{ amount: '5.0' }
);
```
## Using Public Client
```typescript theme={null}
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';
const publicClient = createPublicClient({
chain: base,
transport: http()
});
const result = await armoryPay(
{ account, publicClient },
'https://api.example.com/data',
'base',
'usdc'
);
```
## With Extension Hooks
For servers that require protocol extensions (like Sign-In-With-X):
```typescript theme={null}
import { createX402Client } from '@armory-sh/client-viem';
import { createSIWxHook, createPaymentIdHook } from '@armory-sh/extensions';
import { PaymentPreference, Logger } from '@armory-sh/client-hooks';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [
// Extension hooks
createSIWxHook({
domain: 'example.com',
statement: 'Sign in to access premium content'
}),
createPaymentIdHook(),
// Optional preference hooks
PaymentPreference.chain(['base', 'polygon', 'skale']),
PaymentPreference.token(['USDT', 'USDC', 'WBTC']),
PaymentPreference.cheapest(),
Logger.console(),
]
});
// Hooks automatically add extensions when server requests them
const response = await client.fetch('https://api.example.com/protected');
const data = await response.json();
```
## Multiple Requests
Reuse the client for multiple requests:
```typescript theme={null}
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [createSIWxHook()]
});
// First request - may trigger SIWX signing
const response1 = await client.fetch('https://api.example.com/data1');
// Subsequent requests - hooks execute as needed
const response2 = await client.fetch('https://api.example.com/data2');
```
## Custom Extensions
Create custom hooks for your own extensions:
```typescript theme={null}
import { createCustomHook } from '@armory-sh/extensions';
const myExtensionHook = createCustomHook({
key: 'my-extension',
handler: async (context) => {
if (context.payload) {
context.payload.extensions = {
...(context.payload.extensions ?? {}),
'my-extension': { timestamp: Date.now() }
};
}
},
priority: 75
});
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [myExtensionHook]
});
```
# With Web3.js
Source: https://armory.sh/make-payments/web3
Make payments with Web3.js
# Make Payments with Web3.js
Make payments to Armory-protected APIs using Web3.js wallets.
`hooks` are lifecycle callbacks. `extensions` are protocol fields on x402 payloads/challenges. They work together but are separate.
When payment verification fails on retry (`402`), Armory surfaces server detail (for example `insufficient_funds`) in the thrown error.
## Basic Payment
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-web3';
import { Web3 } from 'web3';
const web3 = new Web3('https://...');
const account = web3.eth.accounts.wallet.add('0x...')[0];
const result = await armoryPay(
{ web3, account },
'https://api.example.com/data',
'base',
'usdc'
);
console.log(result.data);
```
## Armory object workflow
```typescript theme={null}
import { createArmory } from '@armory-sh/client-web3';
import { Web3 } from 'web3';
const web3 = new Web3('https://...');
const account = web3.eth.accounts.wallet.add('0x...')[0];
const armory = createArmory({
wallet: { web3, account },
chains: 'base',
tokens: 'usdc',
debug: true,
});
const premium = await armory.patch('https://api.example.com/premium', { tier: 'pro' });
const info = await armory.call('https://api.example.com/data');
console.log(premium.data, info.data);
```
The `createArmory` object exposes `.get`, `.post`, `.put`, `.delete`, `.patch`, `.pay`, and `.call`. When the API responds with a 402, it selects from `accepts[]`. Without hooks it uses the first compatible option; add `@armory-sh/client-hooks` to apply chain/token/cheapest preferences.
Use `.pay(url, { method: 'PATCH', body })` when you need to override the HTTP method and `.call(url)` for the default GET.
## With Browser Wallet
```typescript theme={null}
const web3 = new Web3(window.ethereum);
const accounts = await web3.eth.requestAccounts();
const result = await armoryPay(
{ web3, account: accounts[0] },
'https://api.example.com/data',
'base',
'usdc'
);
```
# @armory-sh/base
Source: https://armory.sh/packages/base
Core protocol types, encoding, EIP-712, and network configs
Core protocol types, EIP-712 signing, encoding, network configs, and token registry.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/base
# yarn
yarn add @armory-sh/base
# pnpm
pnpm add @armory-sh/base
# bun
bun add @armory-sh/base
```
## Key Exports
```typescript theme={null}
import {
// Types
type PaymentPayload,
type PaymentPayloadV1,
type PaymentPayloadV2,
type SettlementResponse,
// Encoding/Decoding
encodePaymentV2,
decodePaymentV2,
decodePayment,
// EIP-712
createEIP712Domain,
createTransferWithAuthorization,
EIP712_TYPES,
// Networks
getNetworkConfig,
getNetworkByChainId,
// Token Registry
registerToken,
getCustomToken,
type CustomToken,
} from '@armory-sh/base';
```
## EIP-712 Typed Data
Armory uses EIP-712 typed data for EIP-3009 `TransferWithAuthorization` signatures. The types are defined as:
```typescript theme={null}
const EIP712_TYPES = {
TransferWithAuthorization: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "value", type: "uint256" },
{ name: "validAfter", type: "uint256" },
{ name: "validBefore", type: "uint256" },
{ name: "nonce", type: "bytes32" }, // Must be 64-character hex string
]
};
```
**Important**: The `nonce` field MUST be a `bytes32` hex string (e.g., `0x0000000000000000000000000000000000000000000000000000000000000001`), not a number or BigInt. This matches the [x402 specification](https://github.com/coinbase/x402) for signature compatibility with Coinbase SDKs.
### Creating Authorization Messages
```typescript theme={null}
import {
createEIP712Domain,
createTransferWithAuthorization,
validateTransferWithAuthorization
} from '@armory-sh/base';
const domain = createEIP712Domain(8453, '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913');
const auth = createTransferWithAuthorization({
from: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
to: '0xRecipientAddress...',
value: 1000000n, // 1 USDC (6 decimals)
validAfter: 0n,
validBefore: BigInt(Math.floor(Date.now() / 1000) + 3600),
nonce: '0x0000000000000000000000000000000000000000000000000000000000000001',
});
validateTransferWithAuthorization(auth); // Throws on invalid data
```
## Network Configuration
```typescript theme={null}
import { getNetworkConfig } from '@armory-sh/base';
const base = getNetworkConfig(8453);
// { name: 'base', chainId: 8453, caip2Id: 'eip155:8453', ... }
```
## Custom Tokens
```typescript theme={null}
import { registerToken, type CustomToken } from '@armory-sh/base';
const myToken: CustomToken = {
symbol: 'MYTOKEN',
name: 'My Custom Token',
version: '1',
contractAddress: '0x...',
chainId: 8453,
decimals: 18,
};
registerToken(myToken);
```
# @armory-sh/client-ethers
Source: https://armory.sh/packages/client-ethers
Ethers.js v6 payment client
Make payments using Ethers.js v6 wallets.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/client-ethers
# yarn
yarn add @armory-sh/client-ethers
# pnpm
pnpm add @armory-sh/client-ethers
# bun
bun add @armory-sh/client-ethers
```
## armoryPay
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-ethers';
import { ethers } from 'ethers';
const signer = new ethers.Wallet('0x...');
const result = await armoryPay(
{ signer },
'https://api.example.com/data',
'base',
'usdc'
);
if (result.success) {
console.log(result.data);
} else {
console.error(result.code, result.message);
}
```
## createArmoryClient
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-ethers';
const armory = createArmoryClient({
provider,
signer,
});
const result = await armory.pay({
to: '0x...',
amount: '1000000000',
token: TOKENS.USDC_BASE,
});
```
## Configuration Options
```typescript theme={null}
import { createX402Client } from '@armory-sh/client-ethers';
const client = createX402Client({
signer,
// Protocol version (default: "auto")
protocolVersion: 2,
// Authorization expiry in seconds (default: 3600)
defaultExpiry: 7200,
// Custom nonce generator - MUST return bytes32 hex string
nonceGenerator: () => `0x${Date.now().toString(16).padStart(64, '0')}` as `0x${string}`,
});
```
**Nonce Format**: The `nonceGenerator` must return a `bytes32` hex string (64 hex characters after `0x`). This is required for EIP-712 signature compatibility with the x402 specification.
# @armory-sh/client-hooks
Source: https://armory.sh/packages/client-hooks
Optional hook presets for x402 clients
Optional preset hooks for Armory clients.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/client-hooks
# yarn
yarn add @armory-sh/client-hooks
# pnpm
pnpm add @armory-sh/client-hooks
# bun
bun add @armory-sh/client-hooks
```
## API Reference
### PaymentPreference
Chain and token selection hooks.
#### PaymentPreference.chain(preferredChains)
Prefer specific networks when multiple options are available.
```typescript theme={null}
import { PaymentPreference } from '@armory-sh/client-hooks';
const hook = PaymentPreference.chain(['base', 'ethereum', 'skale-base']);
```
**Parameter:**
* `preferredChains` - Array of network keys (string or string\[])
**Supported network keys:**
* `ethereum` - Ethereum Mainnet
* `base` - Base Mainnet
* `base-sepolia` - Base Sepolia Testnet
* `skale-base` - SKALE Base
* `skale-base-sepolia` - SKALE Base Sepolia
* `ethereum-sepolia` - Ethereum Sepolia Testnet
#### PaymentPreference.token(preferredTokens)
Prefer specific tokens when multiple options are available.
```typescript theme={null}
const hook = PaymentPreference.token(['USDT', 'USDC', 'WBTC']);
```
**Parameter:**
* `preferredTokens` - Array of token symbols (string or string\[])
#### PaymentPreference.cheapest()
Select the option with the lowest amount within the selected network and asset.
```typescript theme={null}
const hook = PaymentPreference.cheapest();
```
### Logger
Payment event logging.
#### Logger.console(options?)
Log payment events to the console.
```typescript theme={null}
import { Logger } from '@armory-sh/client-hooks';
const hook = Logger.console({
prefix: '[x402]',
enabled: true
});
```
**Options:**
| Option | Type | Default | Description |
| --------- | --------- | ---------- | -------------- |
| `prefix` | `string` | `"[x402]"` | Log prefix |
| `enabled` | `boolean` | `true` | Enable logging |
### Utilities
#### combineHooks(...hooks)
Combine multiple hook arrays into a single array.
```typescript theme={null}
import { combineHooks } from '@armory-sh/client-hooks';
const hooks = combineHooks(
PaymentPreference.chain(['base']),
[PaymentPreference.token(['USDC'])], // Can pass arrays
null, // Nulls/undefined are filtered
);
```
### Types
```typescript theme={null}
import type {
PaymentRequiredContext,
PaymentPayloadContext,
ClientHookErrorContext,
ClientHook,
} from '@armory-sh/client-hooks';
```
#### PaymentRequiredContext
Context passed when payment is required.
```typescript theme={null}
interface PaymentRequiredContext {
url: RequestInfo | URL;
requestInit: RequestInit | undefined;
accepts: PaymentRequirementsV2[];
requirements: PaymentRequirementsV2;
selectedRequirement?: PaymentRequirementsV2;
serverExtensions: Extensions | undefined;
fromAddress: Address;
nonce: `0x${string}`;
validBefore: number;
}
```
#### PaymentPayloadContext
Context passed before signing payment.
```typescript theme={null}
interface PaymentPayloadContext {
payload: PaymentPayloadV2;
requirements: PaymentRequirementsV2;
wallet: TWallet;
paymentContext: PaymentRequiredContext;
}
```
#### ClientHookErrorContext
Context passed when a hook errors.
```typescript theme={null}
interface ClientHookErrorContext {
error: unknown;
phase: 'onPaymentRequired' | 'selectRequirement' | 'beforeSignPayment' | 'afterPaymentResponse';
}
```
#### ClientHook
Hook interface.
```typescript theme={null}
interface ClientHook {
name?: string;
onPaymentRequired?: (context: PaymentRequiredContext) => void | Promise;
selectRequirement?: (
context: PaymentRequiredContext
) => PaymentRequirementsV2 | undefined | Promise;
beforeSignPayment?: (
context: PaymentPayloadContext
) => void | Promise;
afterPaymentResponse?: (
context: PaymentPayloadContext & { response: Response }
) => void | Promise;
onError?: (context: ClientHookErrorContext) => void | Promise;
}
```
## Usage
```typescript theme={null}
import { createX402Client } from '@armory-sh/client-viem';
import { PaymentPreference, Logger } from '@armory-sh/client-hooks';
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [
PaymentPreference.chain(['base', 'ethereum', 'skale-base']),
PaymentPreference.token(['USDT', 'USDC', 'WBTC']),
PaymentPreference.cheapest(),
Logger.console(),
],
});
```
## Selection Behavior
* Hook selection narrows progressively in array order
* Chain preference runs first, then token preference can narrow within selected chain
* Cheapest refines within the selected network and asset
* If no hook selects, clients fall back to the first compatible `accepts[]` option from `PAYMENT-REQUIRED`
## Notes
* This package is optional. Core clients work without it.
* Hooks are fail-closed by default: if a hook throws, payment flow throws.
# @armory-sh/client-viem
Source: https://armory.sh/packages/client-viem
Viem-based payment client
Make payments using Viem wallets.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/client-viem
# yarn
yarn add @armory-sh/client-viem
# pnpm
pnpm add @armory-sh/client-viem
# bun
bun add @armory-sh/client-viem
```
## armoryPay
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-viem';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const result = await armoryPay(
{ account },
'https://api.example.com/data',
'base',
'usdc'
);
if (result.success) {
console.log(result.data);
} else {
console.error(result.code, result.message);
}
```
## With Custom Amount
```typescript theme={null}
await armoryPay(
{ account },
'https://api.example.com/premium',
'base',
'usdc',
{ amount: '5.0' }
);
```
## createArmoryClient
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-viem';
const armory = createArmoryClient({
walletClient,
publicClient,
});
const result = await armory.pay({
to: '0x...',
amount: 1000000000n,
token: TOKENS.USDC_BASE,
});
```
## Configuration Options
```typescript theme={null}
import { createX402Client } from '@armory-sh/client-viem';
const client = createX402Client({
wallet: { type: 'account', account },
// Protocol version (default: 2)
version: 2,
// Authorization expiry in seconds (default: 3600)
defaultExpiry: 7200,
// Custom nonce generator - MUST return bytes32 hex string
nonceGenerator: () => `0x${Date.now().toString(16).padStart(64, '0')}` as `0x${string}`,
// Enable debug logging
debug: true,
});
```
**Nonce Format**: The `nonceGenerator` must return a `bytes32` hex string (64 hex characters after `0x`). This is required for EIP-712 signature compatibility with the x402 specification.
## Extension Hooks
The client supports an extension hook system for handling protocol extensions like Sign-In-With-X and Payment Identifier.
### Using Hooks
```typescript theme={null}
import { createX402Client } from '@armory-sh/client-viem';
import { createSIWxHook, createPaymentIdHook } from '@armory-sh/extensions';
import { PaymentPreference, Logger } from '@armory-sh/client-hooks';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount('0x...');
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [
createSIWxHook({
domain: 'example.com',
statement: 'Sign in to access premium content'
}),
createPaymentIdHook(),
PaymentPreference.chain(['base', 'polygon', 'skale']),
PaymentPreference.token(['USDT', 'USDC', 'WBTC']),
PaymentPreference.cheapest(),
Logger.console(),
]
});
// Hooks automatically add extensions when server requests them
const response = await client.fetch('https://api.example.com/protected');
```
### Hook Order
Hooks execute in array order.
### Custom Hooks
Create custom hooks for your own extensions:
```typescript theme={null}
import { createCustomHook } from '@armory-sh/extensions';
const myHook = createCustomHook({
key: 'my-extension',
handler: async (context) => {
// context.payload - the payment payload (when available)
// context.paymentContext - the original payment required context
// context.serverExtensions - extensions requested by server
if (context.payload) {
context.payload.extensions = {
...(context.payload.extensions ?? {}),
'my-extension': { customData: 'value' }
};
}
},
priority: 75
});
const client = createX402Client({
wallet: { type: 'account', account },
hooks: [myHook]
});
```
### Hook Execution Points
Hooks can execute at:
1. `onPaymentRequired`
2. `selectRequirement`
3. `beforeSignPayment`
4. `afterPaymentResponse`
5. `onError`
## Exports
| Export | Description |
| --------------------- | ------------------------------------ |
| `createX402Client` | Create a full x402 client |
| `createX402Transport` | Create a fetch function for payments |
| `armoryPay` | One-line payment function |
| `executeHooks` | Execute extension hooks |
| `mergeExtensions` | Merge extension objects |
# @armory-sh/client-web3
Source: https://armory.sh/packages/client-web3
Web3.js payment client
Make payments using Web3.js wallets.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/client-web3
# yarn
yarn add @armory-sh/client-web3
# pnpm
pnpm add @armory-sh/client-web3
# bun
bun add @armory-sh/client-web3
```
## armoryPay
```typescript theme={null}
import { armoryPay } from '@armory-sh/client-web3';
import { Web3 } from 'web3';
const web3 = new Web3('https://...');
const account = web3.eth.accounts.wallet.add('0x...')[0];
const result = await armoryPay(
{ web3, account },
'https://api.example.com/data',
'base',
'usdc'
);
if (result.success) {
console.log(result.data);
} else {
console.error(result.code, result.message);
}
```
## createArmoryClient
```typescript theme={null}
import { createArmoryClient } from '@armory-sh/client-web3';
const armory = createArmoryClient({
web3,
account,
});
const result = await armory.pay({
to: '0x...',
amount: '1000000000',
token: TOKENS.USDC_BASE,
});
```
# @armory-sh/extensions
Source: https://armory.sh/packages/extensions
x402 protocol extensions
Protocol extensions for the x402 payment standard.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/extensions
# yarn
yarn add @armory-sh/extensions
# pnpm
pnpm add @armory-sh/extensions
# bun
bun add @armory-sh/extensions
```
## Available Extensions
| Extension | Purpose |
| ------------------ | --------------------------------------- |
| Sign-In-With-X | Wallet authentication for repeat access |
| Payment Identifier | Idempotency for payment requests |
| Bazaar | Resource discovery |
## API Reference
### Hook Creators (Client-Side)
Hooks allow you to automatically handle server extension requirements.
#### createSIWxHook
Creates a hook that handles Sign-In-With-X authentication:
```typescript theme={null}
import { createSIWxHook } from '@armory-sh/extensions';
const hook = createSIWxHook({
domain: 'example.com',
statement: 'Sign in to access premium content',
expirationSeconds: 3600
});
```
**Config Options:**
| Option | Type | Description |
| ------------------- | -------- | ------------------------- |
| `domain` | `string` | Domain requesting sign-in |
| `statement` | `string` | Human-readable statement |
| `expirationSeconds` | `number` | Seconds until expiration |
#### createPaymentIdHook
Creates a hook that adds payment idempotency:
```typescript theme={null}
import { createPaymentIdHook } from '@armory-sh/extensions';
// Auto-generate payment ID
const hook = createPaymentIdHook();
// Or specify a custom ID
const hook = createPaymentIdHook({
paymentId: 'my-custom-id-123'
});
```
**Config Options:**
| Option | Type | Description |
| ----------- | -------- | ------------------------- |
| `paymentId` | `string` | Custom payment identifier |
#### createCustomHook
Create custom extension hooks:
```typescript theme={null}
import { createCustomHook } from '@armory-sh/extensions';
const customHook = createCustomHook({
key: 'my-extension',
handler: async (context) => {
// Modify the payment payload
if (context.payload) {
context.payload.extensions = {
...(context.payload.extensions ?? {}),
'my-extension': { data: 'value' }
};
}
},
priority: 75 // Higher priority runs first
});
```
### Server Extension Declaration
For server-side middleware, declare extensions that clients should provide:
#### declareSIWxExtension
```typescript theme={null}
import { declareSIWxExtension } from '@armory-sh/extensions';
const extension = declareSIWxExtension({
domain: 'api.example.com',
statement: 'Sign in to access this API',
network: 'eip155:8453',
expirationSeconds: 3600
});
```
#### declarePaymentIdentifierExtension
```typescript theme={null}
import { declarePaymentIdentifierExtension } from '@armory-sh/extensions';
// Require payment ID from clients
const extension = declarePaymentIdentifierExtension({
required: true
});
```
#### declareDiscoveryExtension
```typescript theme={null}
import { declareDiscoveryExtension } from '@armory-sh/extensions';
const extension = declareDiscoveryExtension({
required: true
});
```
### Verification
Verify client-provided extension data:
#### validateSIWxMessage
```typescript theme={null}
import { validateSIWxMessage, parseSIWxHeader } from '@armory-sh/extensions';
const payload = parseSIWxHeader(header);
const result = validateSIWxMessage(
payload,
'https://api.example.com/resource',
{ maxAge: 3600 }
);
if (result.valid) {
console.log('Valid SIWX message');
} else {
console.error('Invalid:', result.error);
}
```
#### verifySIWxSignature
```typescript theme={null}
import { verifySIWxSignature } from '@armory-sh/extensions';
const result = await verifySIWxSignature(payload, {
evmVerifier: async (message, signature, address) => {
// Custom signature verification
return true;
}
});
```
### Utilities
#### generatePaymentId
Generate a random payment identifier:
```typescript theme={null}
import { generatePaymentId } from '@armory-sh/extensions';
const id = generatePaymentId();
```
#### extractExtension
Extract extension data from a payload:
```typescript theme={null}
import { extractExtension } from '@armory-sh/extensions';
const siwxData = extractExtension(payload.extensions, 'siwx');
```
### Constants
```typescript theme={null}
import {
SIGN_IN_WITH_X,
PAYMENT_IDENTIFIER,
BAZAAR,
} from '@armory-sh/extensions';
```
### Types
```typescript theme={null}
import type {
SIWxHookConfig,
PaymentIdHookConfig,
CustomHookConfig,
SIWxExtensionConfig,
PaymentIdentifierConfig,
BazaarDiscoveryConfig,
SIWxPayload,
SIWxExtensionInfo,
PaymentIdentifierExtensionInfo,
BazaarExtensionInfo,
Extension,
} from '@armory-sh/extensions';
```
## Exports Summary
| Export | Description |
| ----------------------------------- | -------------------------------------- |
| `createSIWxHook` | Hook for Sign-In-With-X |
| `createPaymentIdHook` | Hook for payment idempotency |
| `createCustomHook` | Create custom hooks |
| `declareSIWxExtension` | Declare SIWX extension for server |
| `declarePaymentIdentifierExtension` | Declare payment ID extension |
| `declareDiscoveryExtension` | Declare Bazaar discovery extension |
| `validateSIWxMessage` | Validate SIWX payload |
| `verifySIWxSignature` | Verify SIWX signature |
| `parseSIWxHeader` | Parse SIWX header |
| `encodeSIWxHeader` | Encode SIWX header |
| `createSIWxMessage` | Create SIWX message |
| `createSIWxPayload` | Create SIWX payload |
| `generatePaymentId` | Generate random payment ID |
| `extractExtension` | Extract extension data |
| `isSIWxExtension` | Check if extension is SIWX |
| `isPaymentIdentifierExtension` | Check if extension is Payment ID |
| `isDiscoveryExtension` | Check if extension is Bazaar discovery |
# @armory-sh/middleware-bun
Source: https://armory.sh/packages/middleware-bun
Payment middleware for Bun servers
Accept crypto payments in your Bun HTTP server with a single function call.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-bun
# yarn
yarn add @armory-sh/middleware-bun
# pnpm
pnpm add @armory-sh/middleware-bun
# bun
bun add @armory-sh/middleware-bun
```
## Quick Start
```typescript theme={null}
import { createBunMiddleware } from '@armory-sh/middleware-bun';
const middleware = createBunMiddleware({
payTo: '0xYourWalletAddress...',
amount: '1.0'
});
Bun.serve({
port: 3000,
fetch: async (req) => {
const result = await middleware(req);
// If middleware returns a response, payment failed/required
if (result) return result;
// Payment verified — handle your request
return new Response(JSON.stringify({ data: 'protected content' }));
}
});
```
***
## How It Works
The middleware intercepts incoming requests and:
1. Checks for payment headers (`X-Payment` or `X402-PAYMENT`)
2. Verifies the payment signature and amount
3. Returns `null` if valid (allowing your handler to proceed)
4. Returns a `Response` with 402 status if payment is missing or invalid
***
## Configuration
### Required Options
```typescript theme={null}
{
payTo: string, // Your wallet address
amount: string | bigint // Amount to charge
}
```
### Settlement Modes
Control how payments are settled after verification:
```typescript theme={null}
const middleware = createBunMiddleware({
payTo: '0x...',
amount: '1.0',
settlementMode: 'verify' // | 'settle' | 'async'
});
```
| Mode | Description |
| -------- | -------------------------------------------- |
| `verify` | Verify only, don't settle (good for testing) |
| `settle` | Verify and settle on-chain before responding |
| `async` | Return immediately, settle in background |
### Verification Backend
Use your deployed verification backend in production.
***
## Response Format
On successful payment verification, the middleware returns a `Response` with:
**Headers:**
* `X-Payment-Verified: true`
* `X-Payer-Address: 0x...`
**Body:**
```json theme={null}
{
"verified": true,
"payerAddress": "0x...",
"version": 2
}
```
***
## Error Responses
### 402 Payment Required
No payment header was provided.
```json theme={null}
{
"error": "Payment required"
}
```
### 402 Verification Failed
Payment signature or amount was invalid.
```json theme={null}
{
"error": "Payment verification failed: ..."
}
```
### 400 Settlement Failed
Settlement mode was `settle` but on-chain transaction failed.
```json theme={null}
{
"error": "Settlement failed"
}
```
***
## Tips
For development and testing, use `settlementMode: 'verify'` to skip on-chain settlement while still verifying payment signatures.
The `amount` can be specified as a human-readable string like `"1.0"` for 1 token, or as a `bigint` for precise control over decimals.
Always validate the `payTo` address matches your wallet. The middleware does not check if the address is valid or belongs to you.
## Advanced Mix-and-Match Config (Current API)
Use `paymentMiddleware` for per-token/per-network facilitator routing and extension-aware challenge headers:
```typescript theme={null}
import { paymentMiddleware } from "@armory-sh/middleware-bun";
const middleware = paymentMiddleware({
payTo: "0x1234567890123456789012345678901234567890",
chains: ["base", "skale-base"],
tokens: ["usdc", "usdt", "weth", "wbtc"],
amount: "1.0",
facilitatorUrl: "https://fallback-facilitator.example",
facilitatorUrlByChain: {
base: "https://payai.example",
},
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": {
usdc: "https://payai.example",
usdt: "https://kobaru.example",
weth: "https://kobaru.example",
wbtc: "https://kobaru.example",
},
},
extensions: {
bazaar: { info: { input: { sku: "pro-plan" } }, schema: { type: "object" } },
"sign-in-with-x": { info: { domain: "api.example.com" }, schema: { type: "object" } },
},
});
```
For fully custom amount-per-combination behavior, pass explicit `requirements`:
```typescript theme={null}
paymentMiddleware({
requirements: [
{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
{
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
],
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": { usdt: "https://kobaru.example" },
},
});
```
Unsupported extension keys are auto-ignored (fail-open) per facilitator `/supported` capability response.
# @armory-sh/middleware-elysia
Source: https://armory.sh/packages/middleware-elysia
Payment middleware for Elysia
Accept crypto payments in your Elysia API with a single middleware plugin.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-elysia
# yarn
yarn add @armory-sh/middleware-elysia
# pnpm
pnpm add @armory-sh/middleware-elysia
# bun
bun add @armory-sh/middleware-elysia
```
## Quick Start
```typescript theme={null}
import { Elysia } from 'elysia';
import { paymentMiddleware } from '@armory-sh/middleware-elysia';
const app = new Elysia()
.use(paymentMiddleware({
requirements: {
to: '0xYourWalletAddress...',
amount: 1000000n, // 1 USDC (6 decimals)
expiry: Date.now() + 3600 * 1000,
chainId: 'eip155:8453',
assetId: 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
}
}))
.get('/api/protected', ({ store }) => {
return { message: `Hello ${store.payment.payerAddress}!` };
})
.listen(3000);
```
***
## How It Works
The middleware plugin:
1. Checks for payment headers (`X-Payment` or `X402-PAYMENT`)
2. Verifies the payment signature and amount
3. Stores payment info in the Elysia store
4. Proceeds to your handler if valid, or returns 402 if invalid
***
## Configuration
### Payment Requirements
```typescript theme={null}
{
requirements: {
to: string, // Your wallet address
amount: bigint, // Amount in smallest unit
expiry: number, // Expiry timestamp (milliseconds)
chainId: string, // CAIP-2 chain ID
assetId: string // CAIP-19 asset ID
}
}
```
### Verification Options
Provide your verification backend configuration in middleware options for production deployments.
### Advanced Mix-and-Match Config (Current API)
```typescript theme={null}
import { Elysia } from "elysia";
import { paymentMiddleware } from "@armory-sh/middleware-elysia";
const app = new Elysia().use(
paymentMiddleware({
payTo: "0x1234567890123456789012345678901234567890",
chains: ["base", "skale-base"],
tokens: ["usdc", "usdt", "weth", "wbtc"],
amount: "1.0",
facilitatorUrl: "https://fallback-facilitator.example",
facilitatorUrlByChain: {
base: "https://payai.example",
},
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": {
usdc: "https://payai.example",
usdt: "https://kobaru.example",
weth: "https://kobaru.example",
wbtc: "https://kobaru.example",
},
},
extensions: {
bazaar: { info: { input: { sku: "pro-plan" } }, schema: { type: "object" } },
"sign-in-with-x": { info: { domain: "api.example.com" }, schema: { type: "object" } },
},
}),
);
```
For full custom amount-per-combination control, use explicit `requirements`:
```typescript theme={null}
paymentMiddleware({
requirements: [
{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
{
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
],
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": { usdt: "https://kobaru.example" },
},
});
```
`extensions` are fail-open filtered based on facilitator capability; unsupported keys are omitted from challenge headers automatically.
***
## Accessing Payment Info
Payment information is stored in the Elysia store:
```typescript theme={null}
app.get('/api/user', ({ store }) => {
const payment = store.payment;
return {
payer: payment.payerAddress,
paid: payment.payload.amount,
token: payment.payload.token
};
});
```
**Available Properties:**
| Property | Type | Description |
| -------------- | ---------------- | --------------------------- |
| `payload` | `PaymentPayload` | Decoded payment payload |
| `payerAddress` | `string` | Wallet address of the payer |
| `version` | `1 \| 2` | Payment protocol version |
| `verified` | `boolean` | Whether verification passed |
***
## Type Safety
For full TypeScript support, type your Elysia instance:
```typescript theme={null}
import type { PaymentContext } from '@armory-sh/middleware-elysia';
const app = new Elysia<{ store: PaymentContext }>()
.use(paymentMiddleware({ ... }))
.get('/api/data', ({ store }) => {
// store.payment is fully typed
console.log(store.payment.payerAddress);
});
```
***
## Response Headers
On successful verification:
```
X-Payment-Verified: true
X-Payer-Address: 0x...
X-Payment-Response: {"status":"verified","payerAddress":"0x...","version":2}
```
***
## Error Responses
### 402 Payment Required
No payment header was provided.
```json theme={null}
{
"error": "Payment required",
"requirements": { ... }
}
```
### 400 Invalid Payload
Payment header exists but couldn't be decoded.
```json theme={null}
{
"error": "Invalid payment payload",
"message": "..."
}
```
### 400 Version Mismatch
Payment version doesn't match requirements.
```json theme={null}
{
"error": "Payment version mismatch",
"expected": 2,
"received": 1
}
```
### 402 Verification Failed
Payment signature or amount was invalid.
```json theme={null}
{
"error": "Verification failed: ..."
}
```
***
## Tips
Elysia's store is shared across all middleware and routes. Payment info will be available in any route handler after the middleware runs.
# @armory-sh/middleware-express
Source: https://armory.sh/packages/middleware-express
Payment middleware for Express
Accept crypto payments in your Express API with a single middleware function.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-express
# yarn
yarn add @armory-sh/middleware-express
# pnpm
pnpm add @armory-sh/middleware-express
# bun
bun add @armory-sh/middleware-express
```
## Quick Start
This page covers Express v5+ with `@armory-sh/middleware-express`.
For Express v4, use the separate package page: [`@armory-sh/middleware-express-v4`](/packages/middleware-express-v4).
```typescript theme={null}
import express from 'express';
import { paymentMiddleware } from '@armory-sh/middleware-express';
const app = express();
app.use(paymentMiddleware({
requirements: {
to: '0xYourWalletAddress...',
amount: 1000000n, // 1 USDC (6 decimals)
expiry: Date.now() + 3600 * 1000,
chainId: 'eip155:8453',
assetId: 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913'
}
}));
app.get('/api/protected', (req, res) => {
// Payment info is attached to the request
console.log(req.payment);
res.json({ message: 'Payment verified!' });
});
app.listen(3000);
```
***
## How It Works
The middleware intercepts requests and:
1. Checks for payment headers (`X-Payment` or `X402-PAYMENT`)
2. Verifies the payment signature and amount
3. Attaches payment info to `req.payment`
4. Calls `next()` if valid, or returns 402 if invalid
***
## Configuration
### Payment Requirements
```typescript theme={null}
{
requirements: {
to: string, // Your wallet address
amount: bigint, // Amount in smallest unit (wei for native, token decimals for ERC20)
expiry: number, // Expiry timestamp (milliseconds)
chainId: string, // CAIP-2 chain ID (e.g., 'eip155:8453')
assetId: string // CAIP-19 asset ID
}
}
```
### Common Token Addresses
| Network | Token | Address |
| -------- | ----- | -------------------------------------------- |
| Base | USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| Ethereum | USDC | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` |
| Base | USDT | `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb` |
### Verification Options
See runtime verification configuration in your deployment environment and middleware setup.
### Advanced Mix-and-Match Config (Current API)
```typescript theme={null}
import express from "express";
import { paymentMiddleware } from "@armory-sh/middleware-express";
const app = express();
app.use(
"/api/premium/*",
paymentMiddleware({
payTo: "0x1234567890123456789012345678901234567890",
chains: ["base", "skale-base"],
tokens: ["usdc", "usdt", "weth", "wbtc"],
amount: "1.0",
facilitatorUrl: "https://fallback-facilitator.example",
facilitatorUrlByChain: {
base: "https://payai.example",
},
facilitatorUrlByToken: {
base: {
usdc: "https://payai.example",
},
"skale-base": {
usdc: "https://payai.example",
usdt: "https://kobaru.example",
weth: "https://kobaru.example",
wbtc: "https://kobaru.example",
},
},
extensions: {
bazaar: { info: { input: { sku: "pro-plan" } }, schema: { type: "object" } },
"sign-in-with-x": { info: { domain: "api.example.com" }, schema: { type: "object" } },
},
}),
);
```
You can mix and match network, token, facilitator, and amount by providing explicit requirements:
```typescript theme={null}
app.use(
"/api/checkout",
paymentMiddleware({
requirements: [
{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
{
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
],
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": { usdt: "https://kobaru.example" },
},
}),
);
```
`extensions` are fail-open filtered per facilitator capability (`/supported`): unsupported keys are automatically omitted from the challenge header.
***
## Accessing Payment Info
The middleware augments the Express request with payment information:
```typescript theme={null}
app.get('/api/user', (req, res) => {
const { payerAddress, payload, version, verified } = req.payment;
res.json({
welcome: `Hello ${payerAddress}`,
youPaid: payload.amount,
token: payload.token
});
});
```
**Available Properties:**
| Property | Type | Description |
| -------------- | ---------------- | --------------------------- |
| `payload` | `PaymentPayload` | Decoded payment payload |
| `payerAddress` | `string` | Wallet address of the payer |
| `version` | `1 \| 2` | Payment protocol version |
| `verified` | `boolean` | Whether verification passed |
***
## Response Headers
On successful verification, the middleware adds:
```
X-Payment-Response: {"status":"verified","payerAddress":"0x...","version":2}
```
***
## Error Responses
### 402 Payment Required
No payment header was provided.
```json theme={null}
{
"error": "Payment required",
"requirements": { ... }
}
```
### 400 Invalid Payload
Payment header exists but couldn't be decoded.
```json theme={null}
{
"error": "Invalid payment payload",
"message": "..."
}
```
### 402 Verification Failed
Payment signature or amount was invalid.
```json theme={null}
{
"error": "Verification failed: ..."
}
```
***
## Tips
Express middleware runs in order — place `paymentMiddleware` before any routes that require payment.
# @armory-sh/middleware-express-v4
Source: https://armory.sh/packages/middleware-express-v4
Payment middleware for Express v4
Accept crypto payments in your Express v4 API with a single middleware function.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-express-v4
# yarn
yarn add @armory-sh/middleware-express-v4
# pnpm
pnpm add @armory-sh/middleware-express-v4
# bun
bun add @armory-sh/middleware-express-v4
```
## Quick Start
```typescript theme={null}
import express from 'express';
import { paymentMiddleware } from '@armory-sh/middleware-express-v4';
const app = express();
app.use(paymentMiddleware({
requirements: {
scheme: 'exact',
network: 'eip155:8453',
amount: '1000000',
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
payTo: '0xYourWalletAddress...',
maxTimeoutSeconds: 3600,
extra: {}
}
}));
app.get('/api/protected', (req, res) => {
console.log(req.payment);
res.json({ message: 'Payment verified!' });
});
app.listen(3000);
```
***
## Express v4 vs v5
This package is specifically for **Express v4**. The API differs slightly from the v5 package:
| Feature | Express v4 Package | Express v5 Package |
| ------------ | ---------------------------------- | ------------------------------- |
| Package | `@armory-sh/middleware-express-v4` | `@armory-sh/middleware-express` |
| Requirements | Uses `scheme`, `network`, `asset` | Uses `chainId`, `assetId` |
| Amount | String (`"1000000"`) | BigInt (`1000000n`) |
For full documentation on configuration options, accessing payment info, and error responses, see the [Express middleware documentation](/packages/middleware-express).
***
## Route-Aware Middleware
Configure different payment requirements for different routes:
```typescript theme={null}
import { routeAwarePaymentMiddleware } from '@armory-sh/middleware-express-v4';
app.use(routeAwarePaymentMiddleware({
'/api/basic': {
requirements: {
scheme: 'exact',
network: 'eip155:8453',
amount: '1000000',
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
payTo: '0xYourAddress...',
maxTimeoutSeconds: 300,
extra: {}
}
},
'/api/premium': {
requirements: {
scheme: 'exact',
network: 'eip155:8453',
amount: '5000000',
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
payTo: '0xYourAddress...',
maxTimeoutSeconds: 300,
extra: {}
}
}
}));
```
## Advanced Mix-and-Match Example
For fully custom combinations, define explicit requirements and route-specific facilitator URLs:
```typescript theme={null}
import { routeAwarePaymentMiddleware } from "@armory-sh/middleware-express-v4";
app.use(
routeAwarePaymentMiddleware({
"/api/basic": {
requirements: {
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
facilitatorUrl: "https://payai.example",
},
"/api/skale-premium": {
requirements: {
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
facilitatorUrl: "https://kobaru.example",
},
}),
);
```
For v4, the cleanest way to mix facilitator+amount by token/network is to define separate requirements per route, each with its own `facilitatorUrl`.
***
## Migration to Express v5
When upgrading to Express v5, switch to `@armory-sh/middleware-express`:
```bash theme={null}
# npm
npm uninstall @armory-sh/middleware-express-v4
npm install @armory-sh/middleware-express
# yarn
yarn remove @armory-sh/middleware-express-v4
yarn add @armory-sh/middleware-express
# pnpm
pnpm remove @armory-sh/middleware-express-v4
pnpm add @armory-sh/middleware-express
# bun
bun remove @armory-sh/middleware-express-v4
bun add @armory-sh/middleware-express
```
Then update your code to use the v5 API format (BigInt amounts, `chainId`/`assetId` instead of `network`/`asset`).
# @armory-sh/middleware-hono
Source: https://armory.sh/packages/middleware-hono
Payment middleware for Hono
Accept crypto payments in your Hono API with a single middleware function.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-hono
# yarn
yarn add @armory-sh/middleware-hono
# pnpm
pnpm add @armory-sh/middleware-hono
# bun
bun add @armory-sh/middleware-hono
```
## Quick Start
```typescript theme={null}
import { Hono } from 'hono';
import { acceptPaymentsViaArmory } from '@armory-sh/middleware-hono';
const app = new Hono();
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0xYourWalletAddress...',
amount: '1.0'
}));
app.get('/api/protected', (c) => {
const payment = c.get('payment');
return c.json({ message: `Hello ${payment.payerAddress}!` });
});
app.listen(3000);
```
***
## How It Works
The middleware intercepts requests and:
1. Checks for payment headers (`X-Payment` or `X402-PAYMENT`)
2. Verifies the payment signature and amount
3. Stores payment info in the Hono context
4. Calls `next()` if valid, or returns 402 if invalid
***
## Configuration
### Minimal Setup
```typescript theme={null}
acceptPaymentsViaArmory({
payTo: '0xYourWallet...', // Your wallet address
amount: '1.0' // Amount in tokens (e.g., 1 USDC)
});
```
### All Options
```typescript theme={null}
{
payTo: string, // Your wallet address
amount: string | bigint, // Amount to charge
token?: string, // Token symbol (default: USDC)
network?: string, // Network name (default: base)
defaultVersion?: 1 | 2 // Payment version (default: 2)
}
```
***
## Accessing Payment Info
Payment information is stored in the Hono context:
```typescript theme={null}
app.get('/api/user', (c) => {
const payment = c.get('payment');
return c.json({
payer: payment.payerAddress,
paid: payment.payload.amount,
token: payment.payload.token
});
});
```
**Available Properties:**
| Property | Type | Description |
| -------------- | ---------------- | --------------------------------------------- |
| `payload` | `PaymentPayload` | Decoded payment payload |
| `payerAddress` | `string` | Wallet address of the payer |
| `version` | `1 \| 2` | Payment protocol version |
| `verified` | `true` | Always true when request reaches your handler |
***
## Response Headers
On successful verification:
```
X-Payment-Verified: true
X-Payer-Address: 0x...
X-Payment-Response: {"status":"verified","payerAddress":"0x...","version":2}
```
***
## Error Responses
### 402 Payment Required
```json theme={null}
{
"error": "Payment required",
"requirements": { ... }
}
```
### 402 Verification Failed
```json theme={null}
{
"error": "Payment verification failed: ..."
}
```
***
## Multi-Network Support
Accept payments across multiple networks and tokens:
```typescript theme={null}
app.use('/api/*', acceptPaymentsViaArmory({
payTo: '0x...',
amount: '1.0',
accept: {
networks: ['base', 'ethereum', 'polygon'],
tokens: ['usdc', 'usdt']
}
}));
```
## Advanced Mix-and-Match Config (Current API)
```typescript theme={null}
import { Hono } from "hono";
import { paymentMiddleware } from "@armory-sh/middleware-hono";
const app = new Hono();
app.use(
"/api/*",
paymentMiddleware({
payTo: "0x1234567890123456789012345678901234567890",
chains: ["base", "skale-base"],
tokens: ["usdc", "usdt", "weth", "wbtc"],
amount: "1.0",
facilitatorUrl: "https://fallback-facilitator.example",
facilitatorUrlByChain: {
base: "https://payai.example",
},
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": {
usdc: "https://payai.example",
usdt: "https://kobaru.example",
weth: "https://kobaru.example",
wbtc: "https://kobaru.example",
},
},
extensions: {
bazaar: { info: { input: { sku: "pro-plan" } }, schema: { type: "object" } },
"sign-in-with-x": { info: { domain: "api.example.com" }, schema: { type: "object" } },
},
}),
);
```
If you need fully custom amount-per-requirement combinations, use explicit `requirements`:
```typescript theme={null}
paymentMiddleware({
requirements: [
{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
{
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
],
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": { usdt: "https://kobaru.example" },
},
});
```
Extension keys are fail-open filtered by facilitator capability: unsupported keys are automatically omitted from `PAYMENT-REQUIRED`.
***
## Tips
The `amount` parameter accepts human-readable strings like `"1.0"` for 1 token, or use `bigint` for precise decimal control.
Hono middleware applies to routes that match the path pattern. Use `/api/*` to protect all API routes, or specific paths like `/premium/*` for paid content.
The middleware will return 402 before your handler runs if payment is missing or invalid. Only verified requests reach your route handlers.
# @armory-sh/middleware-next
Source: https://armory.sh/packages/middleware-next
x402 payment middleware for Next.js App Router.
## Installation
```bash theme={null}
# npm
npm install @armory-sh/middleware-next
# yarn
yarn add @armory-sh/middleware-next
# pnpm
pnpm add @armory-sh/middleware-next
# bun
bun add @armory-sh/middleware-next
```
## Features
* Per-route payment configuration
* Route pattern matching (exact, wildcard, parameterized)
* Resource server for payment scheme management
* Built-in verification integration
* Full TypeScript support
## Quick Start
```typescript theme={null}
// middleware.ts
import { paymentProxy, x402ResourceServer } from "@armory-sh/middleware-next";
const verificationClient = {
async verify(headers: Headers) {
return { success: true, payerAddress: "0x..." };
},
};
const resourceServer = new x402ResourceServer(verificationClient);
export const proxy = paymentProxy(
{
"/api/protected": {
accepts: {
scheme: "exact",
price: "1000000",
network: "eip155:8453",
payTo: "0xYourAddress...",
},
},
},
resourceServer
);
export const config = { matcher: ["/api/protected/:path*"] };
```
## API
### `paymentProxy(routes, resourceServer)`
Creates a payment proxy handler for Next.js middleware.
**Parameters:**
* `routes`: Record mapping route patterns to payment config
* `resourceServer`: x402ResourceServer instance
**Returns:** Next.js middleware function
### `x402ResourceServer`
Registers and manages payment schemes.
**Methods:**
* `register(chainId, scheme)`: Register a payment scheme
* `getRequirements(chainId)`: Get requirements for a chain
* `getAllRequirements()`: Get all registered requirements
### Types
```typescript theme={null}
interface VerificationClient {
verify(headers: Headers): Promise<{
success: boolean;
payerAddress?: string;
error?: string
}>;
settle?(headers: Headers): Promise<{
success: boolean;
txHash?: string;
error?: string
}>;
}
interface PaymentScheme {
name: string;
getRequirements(): PaymentRequirementsV2;
}
interface RoutePaymentConfig {
accepts: {
scheme: string;
price: string;
network: string;
payTo: string;
};
description?: string;
}
```
## Route Patterns
Supports three types of route patterns:
* **Exact**: `/api/users` - matches only `/api/users`
* **Wildcard**: `/api/*` - matches `/api/users`, `/api/posts/123`
* **Parameterized**: `/api/users/:id` - matches `/api/users/123`
## Examples
See the [Next.js Middleware guide](../../accept-payments/next) for complete examples.
## Advanced Mix-and-Match Config (Current API)
If you are using `paymentMiddleware` directly, you can route by chain/token/facilitator and attach extensions:
```typescript theme={null}
import { paymentMiddleware } from "@armory-sh/middleware-next";
const middleware = paymentMiddleware({
payTo: "0x1234567890123456789012345678901234567890",
chains: ["base", "skale-base"],
tokens: ["usdc", "usdt", "weth", "wbtc"],
amount: "1.0",
facilitatorUrl: "https://fallback-facilitator.example",
facilitatorUrlByChain: {
base: "https://payai.example",
},
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": {
usdc: "https://payai.example",
usdt: "https://kobaru.example",
weth: "https://kobaru.example",
wbtc: "https://kobaru.example",
},
},
extensions: {
bazaar: { info: { input: { sku: "pro-plan" } }, schema: { type: "object" } },
"sign-in-with-x": { info: { domain: "api.example.com" }, schema: { type: "object" } },
},
});
```
For mixed amounts per route/combination, use explicit `requirements` arrays:
```typescript theme={null}
paymentMiddleware({
requirements: [
{
scheme: "exact",
network: "eip155:8453",
amount: "1000000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
{
scheme: "exact",
network: "eip155:1187947933",
amount: "2500000",
asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
payTo: "0x1234567890123456789012345678901234567890",
maxTimeoutSeconds: 300,
},
],
facilitatorUrlByToken: {
base: { usdc: "https://payai.example" },
"skale-base": { usdt: "https://kobaru.example" },
},
});
```
Unsupported extension keys are fail-open filtered out per facilitator capability response.