New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@botparty/nextjs

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@botparty/nextjs

Next.js SDK for BotParty auth — middleware, server auth(), route handlers, SSR provider

latest
npmnpm
Version
0.0.83
Version published
Maintainers
1
Created
Source

@botparty/nextjs

Next.js SDK for BotParty auth — middleware, server auth(), auto route handlers, and SSR provider. Clerk-like DX for BotParty identity and payments.

Quick Start

npx @botparty/nextjs init

This interactive command will:

  • Scaffold a Next.js project (if run in an empty directory) with a demo landing page, authenticated dashboard, and sample API routes
  • Generate an ES256 keypair for client authentication and service JWT signing
  • Register your domain with id.botparty.club via DNS TXT verification (sends the public key to the server)
  • Write all env vars to .env
  • Create middleware and the catch-all route handler

Options:

npx @botparty/nextjs init --domain example.com   # skip domain prompt
npx @botparty/nextjs init --force                 # re-register and regenerate
npx @botparty/nextjs init --jwks                  # host /.well-known/jwks.json instead of registering inline key

Manual Install

npm install @botparty/nextjs

Environment Variables

All set automatically by npx @botparty/nextjs init:

BOTPARTY_AUTH_URL=https://id.botparty.club         # defaults to this if omitted
BOTPARTY_CLIENT_ID=bp_xxx
BOTPARTY_CLIENT_ASSERTION_KEY=<ES256 PEM private key>  # signs client assertions + service JWTs
BOTPARTY_DOMAIN=example.com                        # your verified domain (optional, defaults to VERCEL_PROJECT_PRODUCTION_URL)

The single BOTPARTY_CLIENT_ASSERTION_KEY does double duty:

  • OAuth token exchange: signs client_assertion JWTs (RFC 7523 private_key_jwt)
  • Payment gateway: signs X-BotParty-Service JWTs
  • Session cookies: AES encryption key derived from SHA-256("bp-session-key:" + key)

Setup (3 files)

1. Route Handler

// app/api/botparty/[...botparty]/route.ts
export { GET, POST } from '@botparty/nextjs/handlers';

Handles /login, /callback, /me, /sign-out, /wallet, /ledger automatically.

2. Middleware

// middleware.ts
import { botpartyMiddleware, createRouteMatcher } from '@botparty/nextjs/server';

const isPublic = createRouteMatcher(['/api/public(.*)', '/pricing', '/']);

export default botpartyMiddleware((auth, req) => {
  if (!isPublic(req)) auth.protect();
});

export const config = { matcher: ['/((?!_next|.*\\..*).*)'] };

3. Provider

// app/layout.tsx
import { BotPartyProvider } from '@botparty/nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <BotPartyProvider>{children}</BotPartyProvider>
      </body>
    </html>
  );
}

The provider is an async Server Component — it reads the session server-side and hydrates the client with zero waterfall.

Server Auth

Route Handlers & Server Components

import { auth } from '@botparty/nextjs/server';

export async function GET() {
  const session = await auth();

  if (!session.isAuthenticated) {
    return new Response('Unauthorized', { status: 401 });
  }

  session.userId;        // string | null
  session.email;         // string | null
  session.name;          // string | null
  session.picture;       // string | null
  session.namespaceId;   // string | null  (bot namespace)
  session.type;          // 'human' | 'bot' | null
  session.hasLinkedUser; // boolean
  session.getToken();    // raw token string

  // Helpers
  session.protect();           // redirects if not authenticated
  session.redirectToSignIn();  // explicit redirect
}

Middleware Auth Object

Inside botpartyMiddleware, the auth callback receives:

interface MiddlewareAuthObject {
  isAuthenticated: boolean;
  type: 'human' | 'bot' | null;
  userId: string | null;
  namespaceId: string | null;
  email: string | null;
  protect(): MiddlewareAuthObject;     // redirects to login if not authed
  redirectToSignIn(): never;
}

Creating Paid Endpoints

Use createPaymentGateway() to charge for API access via the x402 protocol. The gateway handles verification, payment creation, and settlement automatically.

Units: All amounts are integers in USDC atomic units (6 decimals). 1 USDC = 1,000,000 units.

Setup

import { createPaymentGateway } from '@botparty/nextjs/server';

const gateway = createPaymentGateway({ serviceName: 'My API' });

Domain and private key are read from env vars automatically (BOTPARTY_DOMAIN, BOTPARTY_CLIENT_ASSERTION_KEY). On Vercel, domain falls back to VERCEL_PROJECT_PRODUCTION_URL if BOTPARTY_DOMAIN is not set.

You can override any of these in the config object:

const gateway = createPaymentGateway({
  domain: 'custom.example.com',
  serviceName: 'My API',
  privateKey: process.env.MY_CUSTOM_KEY!,
});

Pay-per-call

Charge a flat fee per request:

// app/api/bots/pay-per-call/route.ts
export async function POST(req: Request) {
  const check = await gateway.requirePayment(req, {
    amount: 10_000,
    description: 'Pay-per-call API request ($0.01)',
  });

  if (!check.authorized) return check.response; // 402 with payTo link

  const result = { message: 'Paid request successful!' };

  await gateway.claim(check, {
    amount: 10_000,
    description: 'Pay-per-call API request',
  });

  return Response.json(result);
}

Dynamic payment (budget + actual cost)

Request a budget upfront, bill actual cost after processing:

// app/api/bots/dynamic-payment/route.ts
export async function POST(req: Request) {
  const check = await gateway.requireBudget(req, {
    estimated: 5_000_000,
    description: 'AI inference — estimated cost ($5.00)',
  });

  if (!check.authorized) return check.response; // 402

  const actualCost = await doExpensiveWork();

  await gateway.claim(check, {
    amount: actualCost,
    description: `AI inference — actual cost ($${(actualCost / 1_000_000).toFixed(6)})`,
  });

  return Response.json({ message: 'Done!', charged: actualCost });
}

Payment flow summary

  • Caller hits endpoint
  • requirePayment() checks for an approved payment via the facilitator
  • If not approved: returns 402 with PAYMENT-REQUIRED header and a JSON body containing a payTo link to a /humans/{flowId} multi-step approval flow
  • Human visits the payTo link, completes login + top-up + approval
  • Caller retries the same request (no special headers needed)
  • requirePayment() finds the approved payment, returns authorized: true
  • After processing, claim() settles the payment via the facilitator

Calling Other Services

Your service has a domain identity — the ES256 key in BOTPARTY_CLIENT_ASSERTION_KEY that botparty init registered with the IdP. To call another BotParty service, use botpartyFetch, which attaches the right Authorization header. Pick a mode explicitly:

import { botpartyFetch } from '@botparty/nextjs/server';

// 1. domain — act AS your service (signed domain JWT). The peer's auth() sees
//    type:'bot', namespaceId=<your domain>. Use for backend / machine calls.
const res = await botpartyFetch('https://peer.botparty.club/api/v1/thing', {
  botpartyAuth: { as: 'domain' },
});

// 2. user — act ON BEHALF OF the signed-in user (forwards their access token).
//    The peer sees the end user, not your service.
const res2 = await botpartyFetch('https://peer.botparty.club/api/v1/thing', {
  botpartyAuth: { as: 'user' },
});

// 3. apiKey — use a stable bpk_ key (CI / standalone backend identities).
const res3 = await botpartyFetch('https://peer.botparty.club/api/v1/thing', {
  botpartyAuth: { as: 'apiKey' }, // reads BOTPARTY_STABLE_API_KEY
});

How the peer verifies it: the receiving service's auth() resolves the Authorization: Bearer token — a domain JWT is verified against the issuer's IdP namespace JWKS (no shared secret, no extra hosting), a user access token against the IdP, and a bpk_ key via introspection.

Lower-level helpers are also exported: signDomainToken(opts) returns just the JWT, and botpartyAuthHeaders(mode, targetUrl?) returns just the { Authorization } header for use with non-fetch clients (axios, the AI SDK provider config, etc.).

LLM inference is the exception. llm.botparty.club/v1/* routes straight to LiteLLM, which needs an sk- virtual key — not a domain JWT. Mint one once with npx @botparty/nextjs add-service llm (it authenticates to the management API with your domain identity and writes LLM_API_KEY to .env). See docs/SERVICE-TO-SERVICE.md.

Client Components

All hooks and components from @botparty/react are re-exported:

import {
  useAuth, useUser, useWallet, useLedger,
  SignedIn, SignedOut, HasLinkedUser,
  UserButton, NamespaceBadge,
  WalletBalance, TransactionList, TopUpButton, SpendingControls,
} from '@botparty/nextjs';

Example Page

import { SignedIn, SignedOut, UserButton, WalletBalance } from '@botparty/nextjs';

export default function Dashboard() {
  return (
    <div>
      <SignedIn>
        <UserButton />
        <WalletBalance />
      </SignedIn>
      <SignedOut>
        <a href="/api/botparty/auth/login">Sign in</a>
      </SignedOut>
    </div>
  );
}

Session Strategy

  • Fast path: Encrypted cookies (__botparty_session 15min, __botparty_refresh 30d) encrypted with key derived from BOTPARTY_CLIENT_ASSERTION_KEY
  • Bearer tokens: ES256 access tokens verified against id.botparty.club/.well-known/jwks.json
  • Namespace JWTs: Verified against per-namespace JWKS endpoints
  • Silent refresh: Middleware auto-refreshes expired session cookies from the refresh token

Demo Project

When you run npx @botparty/nextjs init in an empty directory, it scaffolds a complete demo with:

  • Landing page (/) -- sign in button, feature cards
  • Dashboard (/dashboard) -- protected route showing all SDK components:
    • <UserButton>, <NamespaceBadge>, <WalletBalance>, <TransactionList>
    • <TopUpButton>, <SpendingControls>
    • API tester panel with buttons to call each sample route
    • Terminal commands for testing with botparty curl
  • Sample API routes:
    • GET /api/bots/open -- accepts any authenticated bot
    • GET /api/bots/user-required -- requires namespace linked to human account
    • POST /api/bots/pay-per-call -- $0.10/call with payment authorization
    • POST /api/bots/dynamic-payment -- $5 authorization, $0.20/call

Exports

PathContents
@botparty/nextjsBotPartyProvider, all React hooks + components
@botparty/nextjs/serverauth(), currentUser(), botpartyMiddleware, createRouteMatcher, session utils, botpartyFetch, botpartyAuthHeaders, signDomainToken
@botparty/nextjs/handlersGET, POST catch-all route handlers

Keywords

botparty

FAQs

Package last updated on 05 Jun 2026

Related posts