@solinkify/gate-sdk
v0.2.2
Published
AI agent SDK — auto-pay HTTP 402 paywalls and access Solinkify Gate protected content on Solana.
Maintainers
Readme
@solinkify/gate-sdk
SDK for ethical AI agents: discover Solinkify Gate x402 (HTTP 402) paywalls, auto-pay via USDC escrow on Solana, and access the content — three modes:
| Mode | Tx per request | How |
|---|---|---|
| Pay-per-request | 1× lock (+release) | automatic via GateClient |
| Pre-paid balance | 0 | deposit once → the backend debits per request |
| Subscription | 0 | pay for a plan once → access until expiry |
Install
npm install @solinkify/gate-sdkQuick start: access paid content (1-paste)
import { Keypair } from '@solana/web3.js';
import { GateClient } from '@solinkify/gate-sdk';
const client = new GateClient({
wallet: Keypair.fromSecretKey(/* agent secret key */),
rpcUrl: 'https://api.devnet.solana.com',
maxPricePerRequest: 0.01, // budget cap per request (USDC)
});
const { response, via, paymentId } = await client.fetchProtected(url);
const content = await response.text();
// Pay-per-request: release the escrow once you have the content (99% → creator)
if (via === 'payment' && paymentId) await client.release(paymentId);fetchProtected handles the whole flow: request → 402 → check the pre-paid
balance first (if it covers the price, retry with no transaction —
via: 'prepaid') → otherwise lock an on-chain escrow → retry with the payment
proof (via: 'payment').
Every request self-identifies with an AI-agent User-Agent by default — that's what makes the gate answer 402 instead of serving a page meant for humans.
Pre-paid balance: deposit once, no per-request transactions
A global per-mint balance owned by the agent (an on-chain PDA, usable across every creator endpoint that settles in the same mint). The Solinkify backend debits exactly the endpoint's price per served request (fail-closed, on-chain split, an auditable event per debit). Withdraw the remainder anytime — only your wallet can.
import { depositPrepaid, getPrepaidBalance, withdrawPrepaid } from '@solinkify/gate-sdk';
const USDC_DEVNET = '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU';
const ctx = { wallet, rpcUrl: 'https://api.devnet.solana.com' };
await depositPrepaid(ctx, USDC_DEVNET, 1_000_000n); // 1 USDC = 1000 requests @0.001
const { balanceUnits } = await getPrepaidBalance(wallet.publicKey.toBase58(), 'USDC');
await withdrawPrepaid(ctx, USDC_DEVNET, balanceUnits); // withdraw anytimeAfter depositing, GateClient.fetchProtected uses it automatically
(preferPrepaid: true by default). Manual, without GateClient: send the
headers x-solinkify-payer: <wallet> + x-solinkify-prepaid: 1.
Subscription: pay once, access for the whole term
For endpoints where the creator attached a plan (price × duration):
import { subscribe } from '@solinkify/gate-sdk';
const { expiresAt, priceUnits } = await subscribe({
wallet, rpcUrl: 'https://api.devnet.solana.com',
creatorWallet: '<creator wallet>',
endpointId: 'premium',
});
// then access with headers:
// x-solinkify-payer: <your wallet>
// x-solinkify-subscription: 1Renewal = call subscribe again — the term extends from the current
expiry (nothing is forfeited). The payment split is enforced on-chain
(99% creator).
Discovery
Every gated site advertises its options — without triggering a 402:
const doc = await (await fetch('https://site.com/.well-known/solinkify')).json();
// doc.endpoints → endpoint list + prices
// doc.access_modes.prepaid.balance_url → balance check
// doc.access_modes.subscription.header → subscription headerThe 402 manifest carries the same access_modes.
That covers one host you already know about. To find hosts you do not, read the public registry of x402-priced endpoints:
import { discoverEndpoints } from '@solinkify/gate-sdk';
const found = await discoverEndpoints({ query: 'market data', maxPriceUsd: 0.01 });
// → url, priceUsd, currency, network, accessModes, payTo, verifiedAt
const { response } = await client.fetchProtected(found[0].url);Listing is decided by machine, never by agreement: the URL has to answer a real 402 with a valid x402 v2 manifest, that manifest has to pay the wallet that submitted it, and settlement has to use a whitelisted stablecoin. Verification is a snapshot, so the live 402 stays the authority on price.
Delivery records: keep evidence of what you received
Paying is provable on-chain. What came back is not, unless someone writes it down. After a paid fetch, file a signed statement of the exact bytes you got:
import { fileDeliveryReceipt, getDeliveryRecord } from '@solinkify/gate-sdk';
const { response, paymentId } = await client.fetchProtected(url);
const body = Buffer.from(await response.arrayBuffer());
await fileDeliveryReceipt({
wallet, paymentId, creatorWallet: manifest.payment.escrow_address, content: body,
});
const record = await getDeliveryRecord(paymentId);
// record.match === true → the gate filed the same hash you did
// record.match === false → the two sides disagree
// record.match === null → only one side filedYour side is signed with the wallet that funded the escrow, so it is bound to
you and re-verifiable by anyone. Gates that file their own side advertise
delivery_records: true in the 402 manifest.
This ends arguments about "you got nothing". It does not certify that the data was any good.
Pay-per-request: release & receipt
Once you have the content, release the escrow (the creator gets 99%):
import { releasePayment } from '@solinkify/gate-sdk';
await releasePayment({ wallet, rpcUrl, paymentId }); // automatic Jalur A/B routingIf the agent never releases, a timeout crank (1 hour) does it — the creator always gets paid. A successful verify returns a receipt (escrow PDA + endpoint/amount/mint binding) you can archive as proof of payment.
GateClient configuration
| Field | Default | Description |
|---|---|---|
| wallet | — | agent Keypair (required) |
| rpcUrl | — | Solana RPC (required) |
| maxPricePerRequest | 0.01 | USDC budget cap (or env GATE_MAX_SPEND_USDC; the legacy GATE_MAX_SPEND_SOL name still works) |
| preferPrepaid | true | use the pre-paid balance first when it covers the price |
| userAgent | solinkify-agent/0.2 (...) | self-identifying UA (an ethical agent MUST be recognizable so gates answer 402 instead of serving free content); a per-request header still wins |
| retries | 1 | payment retries (max 3, exponential backoff) |
| apiUrl | https://api.solinkify.com | Solinkify backend |
License
MIT © Solinkify
