Skip to content

Commit 2d74f8a

Browse files
committed
Update README documentation and add payment policy functionality
- Restructure README: add centered headings and badges - Simplify installation instructions and quick start example - Add new "Payment Policies" section supporting chain selection, scheme preference, and amount limit - Add strategy factory functions: `preferNetwork`, `preferScheme`, `maxAmount` - Include two new policy usage examples: `chat-evm-policy.ts` and `chat-multichain-policy.ts` - Add `policies` parameter support to `X402OpenAI` constructor - Export policy-related types and functions
1 parent 9f92a74 commit 2d74f8a

File tree

10 files changed

+375
-121
lines changed

10 files changed

+375
-121
lines changed

README.md

Lines changed: 76 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
1+
<div align="center">
2+
13
# x402-openai
24

3-
> Drop-in OpenAI TypeScript client with transparent x402 payment support**EVM, Solana, and beyond**.
5+
**Drop-in OpenAI TypeScript client with transparent [x402](https://www.x402.org/) payment support.**
46

5-
[![TypeScript](https://img.shields.io/badge/typescript-5.0%2B-blue)](https://typescriptlang.org)
7+
[![npm](https://img.shields.io/npm/v/x402-openai)](https://www.npmjs.com/package/x402-openai)
8+
[![TypeScript 5.0+](https://img.shields.io/badge/typescript-5.0+-blue)](https://typescriptlang.org)
9+
[![CI](https://github.com/qntx/x402-openai-typescript/actions/workflows/ci.yml/badge.svg)](https://github.com/qntx/x402-openai-typescript/actions)
610
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
711

8-
## Install
12+
</div>
913

10-
```bash
11-
# EVM only
12-
bun add x402-openai openai @x402/fetch @x402/evm viem
14+
---
1315

14-
# Solana (SVM) only
15-
bun add x402-openai openai @x402/fetch @x402/svm @solana/kit @scure/base
16+
Wrap the standard `openai.OpenAI` client with a crypto wallet.
17+
When the server responds with **HTTP 402**, the library automatically signs and retries the request — zero code changes needed.
1618

17-
# Both chains
18-
bun add x402-openai openai @x402/fetch @x402/evm @x402/svm viem @solana/kit @scure/base
19+
## Installation
20+
21+
```bash
22+
bun add x402-openai @x402/evm viem # EVM (Ethereum / Base / …)
23+
bun add x402-openai @x402/svm @solana/kit @scure/base # Solana
24+
bun add x402-openai @x402/evm @x402/svm viem @solana/kit @scure/base # all chains
1925
```
2026

2127
## Quick Start
2228

23-
### EVM (Ethereum / Base / …)
24-
2529
```ts
2630
import { X402OpenAI } from "x402-openai";
2731
import { EvmWallet } from "x402-openai/wallets";
@@ -30,31 +34,35 @@ const client = new X402OpenAI({
3034
wallet: new EvmWallet({ privateKey: "0x…" }),
3135
});
3236

33-
// Use exactly like openai.OpenAI — everything just works!
34-
const completion = await client.chat.completions.create({
35-
model: "gpt-4o-mini",
37+
const res = await client.chat.completions.create({
38+
model: "openai/gpt-4o-mini",
3639
messages: [{ role: "user", content: "Hello!" }],
3740
});
38-
console.log(completion.choices[0]?.message.content);
41+
console.log(res.choices[0]?.message.content);
3942
```
4043

41-
### SVM (Solana)
44+
Swap `EvmWallet` for `SvmWallet` to pay on Solana — the API is identical.
4245

43-
```ts
44-
import { X402OpenAI } from "x402-openai";
45-
import { SvmWallet } from "x402-openai/wallets";
46+
## Usage
4647

47-
const client = new X402OpenAI({
48-
wallet: new SvmWallet({ privateKey: "base58…" }),
48+
### Streaming
49+
50+
```ts
51+
const stream = await client.chat.completions.create({
52+
model: "openai/gpt-4o-mini",
53+
messages: [{ role: "user", content: "Explain x402" }],
54+
stream: true,
4955
});
56+
57+
for await (const chunk of stream) {
58+
const content = chunk.choices[0]?.delta?.content;
59+
if (content) process.stdout.write(content);
60+
}
5061
```
5162

5263
### Multi-chain
5364

54-
Register multiple wallets — the x402 protocol automatically selects the right chain based on the server's payment requirements.
55-
5665
```ts
57-
import { X402OpenAI } from "x402-openai";
5866
import { EvmWallet, SvmWallet } from "x402-openai/wallets";
5967

6068
const client = new X402OpenAI({
@@ -65,116 +73,74 @@ const client = new X402OpenAI({
6573
});
6674
```
6775

68-
### EVM mnemonic phrase
76+
### BIP-39 Mnemonic (EVM)
6977

7078
```ts
71-
import { EvmWallet } from "x402-openai/wallets";
72-
7379
const wallet = new EvmWallet({ mnemonic: "word1 word2 … word12" });
74-
75-
// BIP-44 account #2
76-
const wallet2 = new EvmWallet({ mnemonic: "word1 word2 …", accountIndex: 2 });
77-
78-
// Custom derivation path
79-
const wallet3 = new EvmWallet({
80-
mnemonic: "word1 word2 …",
81-
derivationPath: "m/44'/60'/2'/0/0",
82-
});
80+
const wallet2 = new EvmWallet({ mnemonic: "", accountIndex: 2 }); // m/44'/60'/0'/0/2
81+
const wallet3 = new EvmWallet({ mnemonic: "", derivationPath: "m/44'/60'/2'/0/0" }); // custom path
8382
```
8483

85-
### Streaming
84+
The protocol selects the right chain automatically based on the server's payment requirements.
8685

87-
```ts
88-
const stream = await client.chat.completions.create({
89-
model: "gpt-4o-mini",
90-
messages: [{ role: "user", content: "Explain x402" }],
91-
stream: true,
92-
});
93-
94-
for await (const chunk of stream) {
95-
const content = chunk.choices[0]?.delta?.content;
96-
if (content) process.stdout.write(content);
97-
}
98-
```
86+
### Payment Policies
9987

100-
### Advanced: pre-built x402 client
88+
Use policies to control which chain or scheme is preferred when multiple payment options are available:
10189

10290
```ts
103-
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
104-
import { X402OpenAI } from "x402-openai";
105-
106-
const x402 = new x402Client();
107-
// ... register custom payment schemes ...
91+
import { X402OpenAI, preferNetwork, preferScheme, maxAmount } from "x402-openai";
92+
import { EvmWallet, SvmWallet } from "x402-openai/wallets";
10893

109-
const client = new X402OpenAI({ x402Client: x402 });
94+
const client = new X402OpenAI({
95+
wallets: [
96+
new EvmWallet({ privateKey: "0x…" }),
97+
new SvmWallet({ privateKey: "base58…" }),
98+
],
99+
policies: [
100+
preferNetwork("eip155:8453"), // Prefer Base mainnet
101+
preferScheme("exact"), // Prefer exact payment scheme
102+
maxAmount(1_000_000n), // Cap at 1 USDC (6 decimals)
103+
],
104+
});
110105
```
111106

112-
## API
107+
## API Reference
113108

114-
### `new X402OpenAI(options)`
109+
### `X402OpenAI`
115110

116111
Drop-in replacement for `openai.OpenAI`. Provide **exactly one** credential source:
117112

118-
| Parameter | Description |
119-
| ------------ | --------------------------------------------------- |
120-
| `wallet` | A single `Wallet` adapter (e.g. `EvmWallet`) |
121-
| `wallets` | List of `Wallet` adapters for multi-chain support |
122-
| `x402Client` | Pre-configured `x402Client` |
113+
| Parameter | Type | Description |
114+
| :----------- | :----------------- | :------------------------------------------------- |
115+
| `wallet` | `Wallet` | Single wallet adapter |
116+
| `wallets` | `Wallet[]` | Multiple adapters (multi-chain) |
117+
| `policies` | `PaymentPolicy[]` | Payment policies (chain/scheme preference, amount cap) |
118+
| `x402Client` | `x402Client` | Pre-configured x402 client (bypasses `policies`) |
123119

124-
Default `baseURL` is `https://llm.qntx.fun/v1`. All standard OpenAI constructor options (`baseURL`, `timeout`, `maxRetries`, …) are forwarded transparently.
120+
All standard OpenAI options (`baseURL`, `timeout`, `maxRetries`, …) are forwarded.
121+
Default `baseURL`: `https://llm.qntx.fun/v1`
125122

126-
### Wallet adapters
123+
### Wallet Adapters
127124

128-
| Class | Chain | Install extras |
129-
| -------------------------------- | ------------------------ | ----------------------------------------- |
130-
| `EvmWallet({ privateKey: … })` | EVM (Ethereum, Base, …) | `@x402/evm viem` |
131-
| `EvmWallet({ mnemonic: … })` | EVM (BIP-39) | `@x402/evm viem` |
132-
| `SvmWallet({ privateKey: … })` | Solana | `@x402/svm @solana/kit @scure/base` |
125+
| Class | Chain | Install extras |
126+
| :------------------------------- | :------------------ | :----------------------------------- |
127+
| `EvmWallet({ privateKey: … })` | EVM | `@x402/evm viem` |
128+
| `EvmWallet({ mnemonic: … })` | EVM (BIP-39) | `@x402/evm viem` |
129+
| `SvmWallet({ privateKey: … })` | Solana | `@x402/svm @solana/kit @scure/base` |
133130

134-
All wallets implement the `Wallet` interface. See [`src/wallets/base.ts`](src/wallets/base.ts) to add support for a new chain.
131+
Implement the [`Wallet`](src/wallets/base.ts) interface to add a new chain.
135132

136133
## Examples
137134

138-
```bash
139-
# EVM — private key
140-
EVM_PRIVATE_KEY="0x..." bun examples/chat-evm.ts
141-
142-
# EVM — mnemonic phrase
143-
MNEMONIC="word1 word2 ..." bun examples/chat-evm-mnemonic.ts
144-
145-
# SVM (Solana) — private key
146-
SOLANA_PRIVATE_KEY="base58..." bun examples/chat-svm.ts
147-
148-
# Streaming — EVM
149-
EVM_PRIVATE_KEY="0x..." bun examples/streaming-evm.ts
150-
151-
# Streaming — EVM mnemonic
152-
MNEMONIC="word1 word2 ..." bun examples/streaming-evm-mnemonic.ts
153-
154-
# Streaming — SVM
155-
SOLANA_PRIVATE_KEY="base58..." bun examples/streaming-svm.ts
156-
157-
# Multi-chain (EVM + SVM)
158-
EVM_PRIVATE_KEY="0x..." SOLANA_PRIVATE_KEY="base58..." bun examples/multichain.ts
159-
160-
# List models
161-
EVM_PRIVATE_KEY="0x..." bun examples/models.ts
162-
163-
# List models — mnemonic
164-
MNEMONIC="word1 word2 ..." bun examples/models-mnemonic.ts
165-
```
166-
167-
## Development
135+
See the [`examples/`](examples/) directory. Each script is self-contained:
168136

169137
```bash
170-
# Install dependencies
171-
bun install
172-
173-
# Run tests
174-
bun test
175-
176-
# Type check
177-
bun run typecheck
138+
EVM_PRIVATE_KEY="0x…" bun examples/chat-evm.ts
139+
SOLANA_PRIVATE_KEY="base58…" bun examples/chat-svm.ts
140+
EVM_PRIVATE_KEY="0x…" bun examples/streaming-evm.ts
141+
MNEMONIC="word1 word2 …" bun examples/chat-evm-mnemonic.ts
142+
EVM_PRIVATE_KEY="0x…" bun examples/chat-evm-policy.ts
143+
EVM_PRIVATE_KEY="0x…" SOLANA_PRIVATE_KEY="base58…" bun examples/chat-multichain-policy.ts
178144
```
179145

180146
## License

bun.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/chat-evm-policy.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* EVM chat completion with payment policy (prefer specific network).
3+
*
4+
* Demonstrates how to use policies to control which chain is used for payment
5+
* when multiple payment options are available.
6+
*
7+
* Usage: EVM_PRIVATE_KEY="0x..." bun examples/chat-evm-policy.ts
8+
*/
9+
10+
import { preferNetwork, X402OpenAI } from "../src/index.ts";
11+
import { EvmWallet } from "../src/wallets/index.ts";
12+
13+
const client = new X402OpenAI({
14+
wallet: new EvmWallet({
15+
privateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`,
16+
}),
17+
policies: [preferNetwork("eip155:8453")], // Prefer Base mainnet
18+
});
19+
20+
const response = await client.chat.completions.create({
21+
model: process.env.MODEL ?? "openai/gpt-4o-mini",
22+
messages: [{ role: "user", content: "What is the x402 payment protocol?" }],
23+
});
24+
25+
console.log(response.choices[0]?.message.content);

examples/chat-multichain-policy.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Multi-chain chat completion with payment policies.
3+
*
4+
* Registers both EVM and SVM wallets, then uses policies to prefer Base
5+
* mainnet and cap the maximum payment amount.
6+
*
7+
* Usage:
8+
* EVM_PRIVATE_KEY="0x..." SOLANA_PRIVATE_KEY="base58..." \
9+
* bun examples/chat-multichain-policy.ts
10+
*/
11+
12+
import {
13+
maxAmount,
14+
preferNetwork,
15+
preferScheme,
16+
X402OpenAI,
17+
} from "../src/index.ts";
18+
import { EvmWallet, SvmWallet } from "../src/wallets/index.ts";
19+
20+
const client = new X402OpenAI({
21+
wallets: [
22+
new EvmWallet({
23+
privateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`,
24+
}),
25+
new SvmWallet({ privateKey: process.env.SOLANA_PRIVATE_KEY ?? "" }),
26+
],
27+
policies: [
28+
preferNetwork("eip155:8453"), // Prefer Base mainnet
29+
preferScheme("exact"), // Prefer exact payment scheme
30+
maxAmount(1_000_000n), // Cap at 1 USDC (6 decimals)
31+
],
32+
});
33+
34+
const response = await client.chat.completions.create({
35+
model: process.env.MODEL ?? "openai/gpt-4o-mini",
36+
messages: [{ role: "user", content: "What is the x402 payment protocol?" }],
37+
});
38+
39+
console.log(response.choices[0]?.message.content);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "x402-openai",
3-
"version": "0.2.1",
3+
"version": "0.3.0",
44
"description": "Drop-in OpenAI TypeScript client with transparent x402 payment support.",
55
"type": "module",
66
"main": "./src/index.ts",

0 commit comments

Comments
 (0)