
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@nexflow-smf/smf
Advanced tools
NexFlow Smart Meta-Facilitator SDK for x402 payments - zero dependencies
Zero-dependency SDK for NexFlow Smart Meta-Facilitator (SMF).
Route x402 payments to the best facilitator, verify payment intents, and settle batches—all with a single line of code.
fetchnpm install @nexflow-smf/smf
# or
yarn add @nexflow-smf/smf
# or
pnpm add @nexflow-smf/smf
import { NexFlowSMFClient } from '@nexflow-smf/smf';
const smf = new NexFlowSMFClient({
baseUrl: 'https://api.nexflowapp.app',
apiKey: process.env.NEXFLOW_API_KEY!,
});
// Route a payment to the best facilitator
const route = await smf.route({
amount_wei: '1000000',
token_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
chain_id: 'eip155:8453', // Base
payment_id: 'order-12345', // Idempotency key
});
console.log(`Facilitator: ${route.facilitator_id}`);
console.log(`Platform fee: ${route.expected_fee_wei} wei`);
console.log(`Confidence: ${route.confidence}`);
console.log(`Quote expires: ${route.quote_expires_at}`);
new NexFlowSMFClient(options)Create a new client instance.
const smf = new NexFlowSMFClient({
baseUrl: 'https://api.nexflowapp.app', // Required
apiKey: 'nf_live_xxx', // Required
timeoutMs: 30000, // Optional (default: 30s)
rateLimitThreshold: 0.8, // Optional (default: 0.8)
});
smf.route(request, options?)Route a payment to the best available facilitator.
const route = await smf.route({
amount_wei: '1000000',
token_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
chain_id: 'eip155:8453',
recipient: '0xabcd...', // Optional
payment_id: 'order-123', // Optional (also used as idempotency key)
metadata: { orderId: 123 }, // Optional
});
// Response
{
facilitator_id: 'cdp',
path: 'scored',
expected_fee_wei: '2500', // 0.25% platform fee
estimated_latency_ms: 150,
confidence: 0.95,
quote_expires_at: '2026-01-03T...',
quote_id: 'order-123',
}
smf.verify(request, options?)Verify an x402 payment intent.
const verification = await smf.verify({
payment_intent: 'x402:1:base:0xabc...:1000000:USDC:sig',
recipient_address: '0xabcd...',
amount_wei: '1000000', // Optional
facilitator_id: 'cdp', // Optional hint
});
// Response
{
valid: true,
facilitator: 'cdp',
estimated_settlement_ms: 500,
}
// Or if invalid
{
valid: false,
reason: 'Recipient mismatch: expected 0x..., got 0x...',
facilitator: 'none',
estimated_settlement_ms: 0,
}
smf.settle(request, options?)Settle a batch of payments.
// Queue for next batch window
const settlement = await smf.settle({
batch_id: 'batch-xyz',
facilitator_id: 'cdp',
});
// Force immediate settlement
const immediate = await smf.settle({
batch_id: 'batch-xyz',
facilitator_id: 'cdp',
force: true,
});
// Response
{
status: 'submitted', // 'pending' | 'submitted' | 'confirmed' | 'failed'
transaction_hash: '0xabc...', // When submitted/confirmed
settled_at: '2026-01-03T...', // When confirmed
error: 'Insufficient funds', // When failed
}
smf.health()Get system health status.
const health = await smf.health();
// Response
{
status: 'healthy', // 'healthy' | 'degraded' | 'down'
summary: { total: 5, healthy: 4, degraded: 1, down: 0 },
facilitators: [
{
facilitatorId: 'cdp',
name: 'Coinbase Developer Platform',
status: 'healthy',
metrics: { successRate: 0.99, p95LatencyMs: 150, ... },
},
// ...
],
timestamp: '2026-01-03T...',
}
smf.facilitators()Get list of available facilitators.
const facilitators = await smf.facilitators();
// Response
[
{
id: 'cdp',
label: 'Coinbase Developer Platform',
url: 'https://cdp.coinbase.com',
supportedNetworks: ['base', 'ethereum'],
tokens: ['USDC', 'ETH'],
priority: 1,
feeBps: 25,
enabled: true,
status: 'healthy',
},
// ...
]
smf.getRateLimit()Get rate limit information from the last request.
await smf.route({ ... });
const rateLimit = smf.getRateLimit();
if (rateLimit) {
console.log(`${rateLimit.remaining}/${rateLimit.limit} requests remaining`);
console.log(`Resets at: ${rateLimit.resetAt}`);
}
All errors are wrapped in NexFlowSMFError with structured information.
import { NexFlowSMFClient, NexFlowSMFError } from '@nexflow-smf/smf';
try {
await smf.route({ ... });
} catch (error) {
if (error instanceof NexFlowSMFError) {
console.log(error.statusCode); // 400, 401, 429, 500, etc.
console.log(error.code); // 'INVALID_REQUEST', 'RATE_LIMITED', etc.
console.log(error.message); // Human-readable message
console.log(error.details); // Additional context from API
console.log(error.retryable); // true for 429, 5xx, timeout, network errors
if (error.retryable) {
// Implement retry logic
}
}
}
| Code | Description |
|---|---|
MISSING_API_KEY | Authorization header not provided |
INVALID_API_KEY | API key is invalid or expired |
INVALID_REQUEST | Request body validation failed |
INVALID_AMOUNT | Amount must be a positive integer string |
INVALID_CHAIN_ID | Chain ID format is invalid |
MALFORMED_PAYMENT | Payment intent cannot be parsed |
RECIPIENT_MISMATCH | Recipient doesn't match payment intent |
BATCH_NOT_FOUND | Batch ID doesn't exist |
RATE_LIMITED | Rate limit exceeded (retryable) |
TIMEOUT | Request timed out (retryable) |
NETWORK_ERROR | Network request failed (retryable) |
INTERNAL_ERROR | Server error (retryable) |
All POST requests use idempotency keys to prevent accidental duplicate operations.
// Auto-generated idempotency key
const route1 = await smf.route({
amount_wei: '1000000',
token_address: '0xabc...',
chain_id: 'eip155:8453',
});
// Use payment_id as idempotency key
const route2 = await smf.route({
amount_wei: '1000000',
token_address: '0xabc...',
chain_id: 'eip155:8453',
payment_id: 'order-123', // Will be used as idempotency key
});
// Explicit idempotency key
const route3 = await smf.route(
{ amount_wei: '1000000', token_address: '0xabc...', chain_id: 'eip155:8453' },
{ idempotencyKey: 'my-custom-key' }
);
Idempotency keys are cached server-side for 5 minutes. Retrying with the same key within that window returns the cached response.
The SDK exposes rate limit information after each request.
// Check rate limit after request
const route = await smf.route({ ... });
const rateLimit = smf.getRateLimit();
// Check if approaching limit
if (smf.isApproachingRateLimit()) {
console.warn('Consider slowing down requests');
}
The SDK automatically logs a warning when utilization exceeds 80% (configurable via rateLimitThreshold).
The SDK exports validation helpers for input validation.
import {
isValidChainId,
isValidAddress,
isValidWei,
isValidPaymentIntent,
generateIdempotencyKey,
} from '@nexflow-smf/smf';
isValidChainId('eip155:8453'); // true
isValidAddress('0xabc...'); // true
isValidWei('1000000'); // true
isValidPaymentIntent('x402:...'); // true
const key = generateIdempotencyKey(); // '1735939200000-abc123xyz'
Full type definitions are included. Import types as needed:
import type {
SMFRouteRequest,
SMFRouteResponse,
SMFVerifyRequest,
SMFVerifyResponse,
SMFSettleRequest,
SMFSettleResponse,
SMFHealthResponse,
SMFFacilitatorInfo,
RateLimitInfo,
SMFErrorCode,
} from '@nexflow-smf/smf';
fetch)fetch support (browsers, Deno, Bun, etc.)MIT © NexFlow
FAQs
NexFlow Smart Meta-Facilitator SDK for x402 payments - zero dependencies
The npm package @nexflow-smf/smf receives a total of 17 weekly downloads. As such, @nexflow-smf/smf popularity was classified as not popular.
We found that @nexflow-smf/smf demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.