Sign In

@solinkify/gate

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solinkify/gate

Creator middleware (Next.js, Express, Cloudflare Workers) — blocks AI scrapers with HTTP 402 paywall, monetizes ethical AI agents on Solana.

npmnpm
Version
0.4.3
Version published
Weekly downloads
86
-85.88%
Maintainers
1
Weekly downloads
 
Created
Source

@solinkify/gate

A toll booth between AI scrapers and your content. Add one middleware — mainstream AI crawlers (ChatGPT / Claude / Perplexity) get an x402 v2 paywall (CAIP-2 networks, PAYMENT-REQUIRED wire header), while ethical AI agents auto-pay USDC on Solana to get in. Agentic payments for any stack.

  • 🛡️ AI bot detection via User-Agent (OpenAI, Anthropic, Perplexity, Google, and more)
  • 💸 Stablecoin (USDC) payments into an on-chain escrow — 99% goes to the creator
  • ⚡ Adapters for Next.js, Express/Node, Cloudflare Workers, Astro, SvelteKit, Hono, Nuxt, Remix, Fastify, Lambda@Edge, and any Fetch runtime (one core, many frameworks)

Install

npm install @solinkify/gate
# or: pnpm add @solinkify/gate

Peer dependency: Next.js ≥ 14 (optional — only for the Next.js adapter; Express & Workers don't need Next).

1. Register your endpoint (once)

Open solinkify.com/gate/setup → connect a wallet → register an endpoint (you get an endpointId + a price per request). This is what binds payments to your content on-chain.

2. Add the middleware (1-paste)

Create middleware.ts at the root of your Next.js project:

import { protectFromAI } from '@solinkify/gate';

export const middleware = protectFromAI({
  wallet: 'YOUR_CREATOR_WALLET',   // Solana wallet that receives 99%
  price: 0.001,                    // price per request (USDC)
  endpointId: 'my-blog',           // from step 1
});

export const config = {
  matcher: '/:path*',              // run on every route (scope with protectedPaths)
};

Done. Requests from AI scrapers → 402 + paywall message; regular visitors & browsers → pass through untouched.

Configuration (GateConfig)

OptionRequiredDefaultDescription
walletCreator's Solana wallet (receives 99%)
pricePrice per request (token units, e.g. 0.001 USDC)
endpointId⚠️''On-chain endpoint id (step 1) — required so payments bind to your endpoint
tokenMintUSDC mainnetSettlement SPL mint (override for devnet)
apiUrlhttps://api.solinkify.comVerification API
protectedPaths['/*']Paths to protect (glob: /articles/*)
excludePaths[]Paths always let through
detection'basic''basic' (block AI, SEO-safe) · 'strict' (also block search engines) · 'strict+' (aggressive: inspect browser UAs for headless/scraper signals)
blockDatacenterIpsfalsestrict+ only: block browser-UA requests from datacenter IPs (AWS/GCP/…). Opt-in (may hit legitimate VPN users).
allowBots[]Bot whitelist (e.g. ['Googlebot']) to protect SEO
verifyBotIpstrueVerify the client IP against the bot's official published ranges (Google/Bing). A "Googlebot" from a fake IP → blocked (closes the spoofing hole). Needs the adapter to supply an IP; when unverifiable → normal behaviour (safe).
trustProxytrueTrust x-forwarded-for/x-real-ip as the client IP. Correct behind Vercel/Cloudflare/nginx (which OVERWRITE the header). ⚠️ Set false if your app takes connections STRAIGHT from the internet — a direct client can forge XFF to bypass verify-IP/rate-limit/datacenter checks; with false only the socket IP is used.
customMessageCustom paywall message

Devnet vs mainnet (switch-ready)

Default = mainnet USDC. To test on devnet, override:

protectFromAI({
  wallet: 'YOUR_WALLET',
  price: 0.001,
  endpointId: 'my-blog',
  tokenMint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', // USDC devnet
});

Express / Node

import express from 'express';
import { protectFromAIExpress } from '@solinkify/gate/express';

const app = express();

app.use(protectFromAIExpress({
  wallet: 'YOUR_CREATOR_WALLET',
  price: 0.001,
  endpointId: 'my-blog',
}));

app.get('/articles/:id', (req, res) => {
  // req.solinkify = { verified, botName } is set for agents that paid
  res.send('Protected content');
});

Same GateConfig as Next.js. This adapter is zero-dependency (duck-typed req/res) — compatible with Express & Connect, no @types/express needed. If the middleware itself hits an unexpected error, the request fails open (passes) so your site never goes down because of the gate.

Astro / SvelteKit / Hono

// Astro — src/middleware.ts
import { createAstroGate } from '@solinkify/gate/astro';
export const onRequest = createAstroGate({ wallet, endpointId, price: 0.001 });

// SvelteKit — src/hooks.server.ts
import { createSvelteKitGate } from '@solinkify/gate/sveltekit';
export const handle = createSvelteKitGate({ wallet, endpointId, price: 0.001 });

// Hono (Workers/Deno/Bun/Node/edge)
import { createHonoGate } from '@solinkify/gate/hono';
app.use('/articles/*', createHonoGate({ wallet, endpointId, price: 0.001 }));

Nuxt / Remix

// Nuxt (Nitro) — server/middleware/solinkify.ts
import { createNuxtGate } from '@solinkify/gate/nuxt';
export default createNuxtGate({ wallet, endpointId, price: 0.001 });

// Remix / React Router — app/root.tsx
import { createRemixGate } from '@solinkify/gate/remix';
const gate = createRemixGate({ wallet, endpointId, price: 0.001 });
export async function loader({ request }) {
  await gate(request);         // throws a 402 Response for unpaid AI scrapers
  return json({ /* ... */ });
}

Fastify

import Fastify from 'fastify';
import { createFastifyGate } from '@solinkify/gate/fastify';

const app = Fastify();
app.addHook('onRequest', createFastifyGate({ wallet, endpointId, price: 0.001 }));

Any other Fetch runtime (Deno / Bun / edge) — guardFetch

Any handler with a Web Request can gate in ~5 lines:

import { resolveConfig } from '@solinkify/gate/core';
import { guardFetch } from '@solinkify/gate/fetch';
const gate = resolveConfig({ wallet, endpointId, price: 0.001 });

// Deno
Deno.serve((req) => guardFetch(req, gate, () => new Response('protected content')));

// Bun
Bun.serve({ fetch: (req) => guardFetch(req, gate, () => new Response('protected content')) });

// Vercel Edge / Netlify Edge Functions / Fastly Compute (JS) — same signature:
export default (req: Request) => guardFetch(req, gate, () => fetch(req));

AWS CloudFront (Lambda@Edge)

Gate ANY origin (S3 static site, ALB, legacy server) without touching its code — attach to the viewer-request event:

// index.mjs — Lambda@Edge (region us-east-1)
import { createLambdaEdgeGate } from '@solinkify/gate/lambda-edge';
export const handler = createLambdaEdgeGate({ wallet, endpointId, price: 0.001 });

Cloudflare Workers

import { createWorkerHandler } from '@solinkify/gate/worker';
export default { fetch: createWorkerHandler() };

Configure via environment variables (SOLINKIFY_WALLET, SOLINKIFY_PRICE, SOLINKIFY_ENDPOINT_ID, …). See src/worker.ts.

Build your own adapter (framework-agnostic core)

Every adapter is built on one dependency-free core:

import { resolveConfig, evaluateGate } from '@solinkify/gate/core';

const cfg = resolveConfig({ wallet, price: 0.001, endpointId: 'my-blog' });
const result = await evaluateGate(
  { pathname, userAgent, paymentId, payerPubkey },
  cfg,
);
// result.action === 'block' → send 402 (result.manifest + result.headers)
// result.action === 'next'  → pass through (result.verified carries metadata)

Tiered pricing & multi-stablecoin

Different prices per path (each tier binds to its own on-chain endpoint) + pick your stablecoin:

import { protectFromAI } from '@solinkify/gate';
import { stablecoinMint } from '@solinkify/gate';

export const middleware = protectFromAI({
  wallet: 'YOUR_WALLET',
  endpointId: 'standard',           // default for other paths
  price: 0.001,
  tokenMint: stablecoinMint('USDC'),     // or 'USDT'
  protectedPaths: ['/articles/*', '/premium/*'],
  tiers: [
    { pattern: '/premium/*', endpointId: 'premium', price: 0.01 }, // premium costs more
  ],
});

The first matching tier wins; no match → the top-level endpointId/price/tokenMint apply. Agents pay — and are verified — against that same tier's endpoint + price. Register each endpointId on-chain (one per tier). stablecoinMint(symbol, 'devnet'|'mainnet') saves you memorizing mint addresses.

Anti-abuse layers 4–5 (opt-in): JS challenge (PoW) + rate limiting

For scrapers whose UA is honest but NOT a known bot (curl, python, HTTP libraries) and for bulk scraping:

protectFromAI({
  wallet, endpointId, price: 0.001,
  challenge: true,               // Layer 4: JS proof-of-work interstitial
  challengeSecret: process.env.GATE_CHALLENGE_SECRET, // REQUIRED for multi-instance
  rateLimit: { max: 120, windowSecs: 60 },            // Layer 5: per-IP rate anomaly
});
  • challenge — all non-bot traffic must pass a PoW page once per hour (HMAC clearance cookie, bound to IP + expiry). Real browsers clear it in ±1 second; non-browsers never do. Known AI bots STILL get the 402 (they're the monetization target); robots.txt/sitemap/discovery are never challenged. ⚠️ Aggressive — humans see a brief splash on first visit.
  • rateLimit — above the threshold → 402 paywall. Fails open: a rate backend outage never blocks humans.

Pre-paid balance & subscriptions (no per-request transaction)

Besides pay-per-request, agents get two access modes that need no transaction per request — both work automatically, zero extra middleware config:

  • Pre-paid — the agent deposits stablecoin once into its own on-chain balance, then sends x-solinkify-payer + x-solinkify-prepaid headers. The Solinkify backend debits exactly your endpoint's price per request (fail-closed, on-chain split, 99% still yours) — it shows up in your dashboard like any payment.
  • Subscription — you attach a plan per endpoint (price × duration) from the dashboardManage Endpoints panel. The agent pays once (subscribe, 99% straight to you) then accesses with the x-solinkify-subscription header until the plan expires.

The 402 manifest and /.well-known/solinkify advertise both via the access_modes field, so ethical agents discover them on their own. Agent side: see @solinkify/gate-sdk (depositPrepaid, subscribe, and a GateClient that automatically uses the prepaid balance when it covers the price).

Edit prices, enable/disable endpoints, and manage subscription plans — all from the Manage Endpoints panel, no CLI required.

Delivery records (opt-in): prove what was served

x402 proves a payment happened and says nothing about what came back. Turn this on and the gate hashes the body it served for a paid request and files that hash against the payment id. The paying agent files its own hash of what it received, and anyone holding the payment id can ask whether the two agree.

protectFromAI({
  wallet: 'YOUR_WALLET',
  price: 0.001,
  deliveryRecords: true,     // off by default
  deliveryMaxBytes: 8 * 1024 * 1024, // skip bodies larger than this
});

Paid responses come back with x-solinkify-content-sha256, and the 402 manifest and /.well-known/solinkify both advertise delivery_records: true so agents know to expect one. Read the result:

curl https://api.solinkify.com/api/gate/delivery/<payment_id>
# → { creator: {...}, agent: {...}, match: true }

What it proves. That neither side can serve one thing and later claim another. match: false is evidence; match: null means only one side filed. It is NOT proof the content was correct: a creator that serves garbage can record the hash of that garbage.

Cost. Hashing needs the whole body, so responses are buffered up to deliveryMaxBytes (larger ones stream as usual and are skipped). Filing is fire-and-forget and never delays or fails the response.

Where it works. Adapters that can see the response body: guardFetch, Astro, SvelteKit, Hono, Cloudflare Workers, Express, Fastify, Python (WSGI + ASGI), and the reverse proxy. Next.js middleware, Nuxt, Lambda@Edge and the WordPress plugin never touch the body, so the flag is ignored there and only the agent side can be filed.

SEO-safe by default (+ robots.txt)

The two-tier detector protects your SEO:

  • All AI gets blocked (402): GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot, Gemini/Vertex, Meta AI, CCBot, Bytespider, DeepSeek, and more — plus AI-search & agent tooling (Firecrawl, etc.).
  • Traditional search engines always pass (default basic mode): Googlebot, bingbot, Baidu, Yandex, PetalBot → ranking & indexing untouched.
  • /robots.txt & /sitemap*.xml are always crawlable (never 402'd).

⚠️ detection: 'strict' also blocks Googlebot/bingbot → hurts SEO. The SDK emits a console.warn; if you truly need strict, whitelist search engines: allowBots: ['Googlebot', 'Bingbot'].

Google/Apple AI can't be blocked via User-Agent (Googlebot & Applebot serve search + AI from the same UA). Opt out of their AI training via robots.txt (Google-Extended, Applebot-Extended) — without hurting search. The generator is included:

// app/robots.ts (Next.js)
import { generateRobotsTxt } from '@solinkify/gate/robots';

export function GET() {
  return new Response(
    generateRobotsTxt({ sitemap: 'https://example.com/sitemap.xml' }),
    { headers: { 'Content-Type': 'text/plain' } },
  );
}

Result: every robots.txt-respecting AI crawler gets Disallow, while User-agent: * stays Allow: /. Layered defense = the 402 gate (UA) + robots.txt (declarative).

How it works (the 402 flow)

  • An AI scraper sends a request → the middleware detects the bot User-Agent.
  • It answers HTTP 402 + a payment manifest (escrow_address, payment_id, endpoint_id, token_mint).
  • Mainstream AI shows a "content is protected" message (it can't pay — intended).
  • An ethical AI agent (using @solinkify/gate-sdk) → auto-pays into escrow → retries with proof → gets the content. Agents with a pre-paid balance / active subscription skip the payment step entirely (see above).
  • Escrow release: 99% creator, the rest is the protocol fee (enforced on-chain).

Track earnings

Real-time at solinkify.com/gate/earnings.

License

MIT © Solinkify

Keywords

solana

FAQs

Package last updated on 29 Jul 2026

Did you know?

Socket

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.

Install

Related posts