@qntx/openai
v1.0.1
Published
Drop-in OpenAI TypeScript client with transparent x402 payment support.
Maintainers
Readme
@qntx/openai
Drop-in OpenAI TypeScript client with transparent x402 payment support.
Wrap the standard openai.OpenAI client with per-chain private keys.
When the server responds with HTTP 402, the library automatically signs and retries the request — zero code changes needed.
Supplying evm or svm registers both exact and upto. aptos, avm, stellar, hedera, near, xrpl, tvm, keeta, and concordium register exact only. Default spend controls from @x402/core cap each payment at $1 of a recognized default asset.
Installation
bun add @qntx/openai @x402/evm viem # EVM (Ethereum / Base / …)
bun add @qntx/openai @x402/svm @solana/kit @scure/base # Solana
bun add @qntx/openai @x402/aptos # Aptos
bun add @qntx/openai @x402/avm # Algorand (AVM)
bun add @qntx/openai @x402/stellar # Stellar
bun add @qntx/openai @x402/hedera # Hedera
bun add @qntx/openai @x402/near # NEAR
bun add @qntx/openai @x402/xrpl xrpl # XRPL
bun add @qntx/openai @x402/tvm @ton/crypto # TVM (TON)
bun add @qntx/openai @x402/keeta @keetanetwork/keetanet-client # Keeta
bun add @qntx/openai @x402/concordium @concordium/web-sdk # ConcordiumQuick Start
import { X402OpenAI } from "@qntx/openai";
const client = new X402OpenAI({
evm: "0x…",
});
const res = await client.chat.completions.create({
model: "openai/gpt-4o-mini",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(res.choices[0]?.message.content);Pass svm: "base58…" instead of evm to pay on Solana — the rest of the API is identical. The same constructor accepts aptos, avm, stellar, hedera, near, xrpl, tvm, keeta, and concordium.
Usage
Streaming
const stream = await client.chat.completions.create({
model: "openai/gpt-4o-mini",
messages: [{ role: "user", content: "Explain x402" }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) process.stdout.write(content);
}Multi-chain
const client = new X402OpenAI({
evm: "0x…",
svm: "base58…",
aptos: "0x…",
avm: "base64…",
stellar: "S…",
hedera: { accountId: "0.0.N", privateKey: "0x…" },
near: { accountId: "alice.near", secretKey: "ed25519:…" },
xrpl: "sEd…",
tvm: "hex-or-base64…",
keeta: process.env.KEETA_SEED,
concordium: { privateKey: "hex…", address: "base58…" },
});The protocol selects the right chain automatically based on the server's payment requirements.
Key formats
| Option | Key material |
| :----------- | :---------------------------------------------------------- |
| evm | 0x hex secp256k1 |
| svm | base58 64-byte secret |
| aptos | hex or AIP-80 Ed25519 (ed25519-priv-0x…) |
| avm | base64 64-byte secret (32-byte seed + 32-byte pubkey) |
| stellar | Stellar S… secret seed |
| hedera | ECDSA hex/DER plus 0.0.N account id |
| near | ed25519:… / secp256k1:… plus account id |
| xrpl | XRPL family seed (not BIP-39) |
| tvm | hex/base64 32-byte seed or 64-byte secret |
| keeta | generateRandomSeed({ asString: true }) output, not BIP-39 |
| concordium | hex Ed25519 plus base58 address |
Bare evm / svm / aptos / avm / stellar / tvm strings become { privateKey }. Bare xrpl / keeta strings become { seed }. hedera, near, and concordium have no string overload. Empty strings throw. Keeta 12/24-word BIP-39 strings throw.
Aptos, AVM, Stellar
These families register exact only (upto is not implemented in @x402/* for them).
- Aptos (
aptos:*):createClientSignerfrom@x402/aptos. OptionalrpcUrl. Optional 402extra.feePayerenables a sponsored tx. - AVM (
algorand:*):toClientAvmSignerfrom@x402/avm. OptionalalgodUrl/algodToken. Do not pass a prebuilt Algorand client here — use thex402Clienthatch. Optional 402extra.feePayerfor a gasless group. - Stellar (
stellar:*):createEd25519Signerfrom@x402/stellar. Defaultnetworkisstellar:pubnet(the official factory defaults tostellar:testnet). Passnetwork: "stellar:testnet"for testnet. OptionalrpcUrlis a Soroban RPC endpoint (required for pubnet payments). The 402 must setextra.areFeesSponsored === trueor the scheme throws.
Hedera, NEAR, XRPL
These families also register exact only, on a concrete CAIP-2 (not a wildcard). Default networks are mainnet.
- Hedera (
hedera:mainnetby default, orhedera:testnet):{ accountId, privateKey, network?, nodeUrl? }. No string overload. The 402 must setextra.feePayer. Native HBAR (asset: "0.0.0") is not a default asset — passspendControls.allowedAssetsto allow it. - NEAR (
near:mainnetby default, ornear:testnet):{ accountId, secretKey, network?, rpcUrl? }. No string overload. OptionalrpcUrlis mapped to{ [network]: rpcUrl }. - XRPL (
xrpl:0by default, orxrpl:1): family seed, or{ seed, network?, wsUrl? }. OptionalwsUrlis mapped to{ [network]: wsUrl }. The 402 must setextra.areFeesSponsored === false(the payer pays the XRPL fee). Default asset is RLUSD; native XRP is not allowed unless you opt in:
new X402OpenAI({
xrpl: { seed, network: "xrpl:0" },
spendControls: {
allowedAssets: [{ network: "xrpl:*", asset: "XRP" }],
},
});TVM, Keeta, Concordium
These families also register exact only. TVM uses a concrete CAIP-2; Keeta and Concordium use wildcards.
- TVM (
tvm:-239by default, ortvm:-3): hex/base64 32-byte seed or 64-byte secret, or{ privateKey, network?, provider?, apiKey?, providerBaseUrl? }. The 402 must setextra.areFeesSponsored === true. Do not registertvm:*— the signer is bound to one network. - Keeta (
keeta:*):generateRandomSeed({ asString: true })output, or{ seed }. Not a BIP-39 mnemonic (12/24-word strings throw). This package never callsseedFromPassphrase. - Concordium (
ccd:*):{ privateKey, address, grpcUrl?, useTls? }. No string overload (addressis required). OfficialuseTlsdefault istrue. The 402 must setextra.feePayer. Default asset is USDR; native CCD is not allowed unless you opt in:
new X402OpenAI({
concordium: { privateKey, address },
spendControls: {
allowedAssets: [{ network: "ccd:*", asset: "CCD" }],
},
});Long-lived TVM and Keeta clients hold HTTP / UserClient handles. Call await client.close() (or await using) when finished. close() before the first request is a no-op. Fetch after close() throws X402OpenAI is closed and does not rebuild.
Spend controls
new x402Client() already allows only default (USD-pegged) assets and caps each payment at $1. This package does not change that default.
Pass spendControls to raise the cap, allow extra assets, or disable controls:
const client = new X402OpenAI({
evm: "0x…",
spendControls: { maxAmountPerPayment: "$5" },
});- Omit
spendControlsto keep the official$1+ default-asset allowlist. spendControls: falsedisables allowlist and caps.- Gateway prices above
$1require the caller to raisemaxAmountPerPayment.
exact and upto
evm registers ExactEvmScheme and UptoEvmScheme on eip155:*. svm registers ExactSvmScheme and UptoSvmScheme on solana:*. No extra flag; the gateway is not probed.
- EVM
upto: Permit2 (permitWitnessTransferFrom). The 402 must includeextra.facilitatorAddress. Pass{ rpcUrl }onevmto enable official EIP-2612 / ERC-20 approval sponsoring. - SVM
upto: payment-channelopenthat escrows the full authorized ceiling until settle/close. The 402 must includeextra.feePayerandextra.receiverAuthorizer. - The 402
amountis the authorized maximum. The client signs that max; it does not sign a smaller amount. The server chooses the actual charge (<=max) at settle. If the ceiling exceeds spend controls, payment creation throws.
import { preferScheme, X402OpenAI } from "@qntx/openai";
const client = new X402OpenAI({
evm: "0x…",
policies: [preferScheme("upto")],
});Payment Policies
Use policies to prefer a chain or scheme when multiple options remain after spend controls. Policies do not cap spend.
import { X402OpenAI, preferNetwork, preferScheme } from "@qntx/openai";
const client = new X402OpenAI({
evm: "0x…",
svm: "base58…",
policies: [
preferNetwork("eip155:8453"), // Prefer Base mainnet
preferScheme("upto"),
],
});If nothing matches, all remaining options pass through.
API Reference
X402OpenAI
Drop-in replacement for openai.OpenAI. Provide at least one of evm, svm, aptos, avm, stellar, hedera, near, xrpl, tvm, keeta, concordium, or x402Client:
| Parameter | Type | Description |
| :---------------------------- | :--------------------------------- | :----------------------------------------------------------------------------------------------------- |
| evm | `0x${string}` or EvmConfig | EVM secp256k1 private key (0x hex). Registers exact and upto. |
| svm | string or SvmConfig | Solana base58 secret key. Registers exact and upto. |
| aptos | string or AptosConfig | Aptos hex or AIP-80 Ed25519 key. Registers exact. |
| avm | string or AvmConfig | Algorand base64 64-byte secret. Registers exact. |
| stellar | string or StellarConfig | Stellar S… secret. Registers exact. Default network stellar:pubnet. |
| hedera | HederaConfig | Hedera account id + ECDSA key. Registers exact on hedera:mainnet by default. |
| near | NearConfig | NEAR account id + secret key. Registers exact on near:mainnet by default. |
| xrpl | string or XrplConfig | XRPL family seed. Registers exact on xrpl:0 by default. |
| tvm | string or TvmConfig | TON seed/secret. Registers exact on tvm:-239 by default. |
| keeta | string or KeetaConfig | Keeta seed (not BIP-39). Registers exact on keeta:*. |
| concordium | ConcordiumConfig | Concordium key + address. Registers exact on ccd:*. |
| spendControls | SpendControls or false | Official spend controls. Omit for $1 + default assets. |
| policies | PaymentPolicy[] | Preference policies (preferNetwork / preferScheme). |
| paymentRequirementsSelector | SelectPaymentRequirements | Picks among remaining requirements after spend controls and policies. |
| x402Client | x402Client | Pre-configured x402 client (exclusive with keys, spendControls, policies, paymentRequirementsSelector) |
| Type | Fields | Notes |
| :-------------------------------------- | :--------------------------------------------------------------- | :--------------------------------- |
| EvmConfig, SvmConfig, AptosConfig | { privateKey, rpcUrl? } | |
| AvmConfig | { privateKey, algodUrl?, algodToken? } | |
| StellarConfig | { privateKey, network?, rpcUrl? } | rpcUrl is required on pubnet |
| HederaConfig | { accountId, privateKey, network?, nodeUrl? } | |
| NearConfig | { accountId, secretKey, network?, rpcUrl? } | rpcUrl → { [network]: rpcUrl } |
| XrplConfig | { seed, network?, wsUrl? } | wsUrl → { [network]: wsUrl } |
| TvmConfig | { privateKey, network?, provider?, apiKey?, providerBaseUrl? } | |
| KeetaConfig | { seed } | |
| ConcordiumConfig | { privateKey, address, grpcUrl?, useTls? } | |
Empty keys throw.
close(): Promise<void> (also [Symbol.asyncDispose]) releases Keeta/TVM handles. Close before the first request is a no-op. Fetch after close throws X402OpenAI is closed and does not rebuild.
SpendControls is Exclude<NonNullable<x402ClientConfig["spendControls"]>, false> from @x402/fetch.
All standard OpenAI options (baseURL, timeout, maxRetries, …) are forwarded. Default baseURL: https://llm.qntx.org/v1.
| Option | Chain | Install extras |
| :----------- | :--------- | :------------------------------------------ |
| evm | EVM | @x402/evm viem |
| svm | Solana | @x402/svm @solana/kit @scure/base |
| aptos | Aptos | @x402/aptos |
| avm | Algorand | @x402/avm |
| stellar | Stellar | @x402/stellar |
| hedera | Hedera | @x402/hedera |
| near | NEAR | @x402/near |
| xrpl | XRPL | @x402/xrpl xrpl |
| tvm | TVM | @x402/tvm @ton/crypto |
| keeta | Keeta | @x402/keeta @keetanetwork/keetanet-client |
| concordium | Concordium | @x402/concordium @concordium/web-sdk |
License
This project is licensed under the MIT License.
A QuantX open-source project.
Code is law. We write both.
