@x402/paywall 0.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -0
- package/dist/cjs/evm/index.cjs +128 -0
- package/dist/cjs/evm/index.cjs.map +1 -0
- package/dist/cjs/evm/index.d.cts +8 -0
- package/dist/cjs/index.cjs +280 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +40 -0
- package/dist/cjs/svm/index.cjs +115 -0
- package/dist/cjs/svm/index.cjs.map +1 -0
- package/dist/cjs/svm/index.d.cts +8 -0
- package/dist/cjs/types-CHiWR9_p.d.cts +75 -0
- package/dist/esm/evm/index.d.ts +8 -0
- package/dist/esm/evm/index.js +126 -0
- package/dist/esm/evm/index.js.map +1 -0
- package/dist/esm/index.d.ts +40 -0
- package/dist/esm/index.js +275 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/svm/index.d.ts +8 -0
- package/dist/esm/svm/index.js +113 -0
- package/dist/esm/svm/index.js.map +1 -0
- package/dist/esm/types-CHiWR9_p.d.ts +75 -0
- package/package.json +110 -8
- package/index.js +0 -3
package/README.md
CHANGED
|
@@ -1 +1,204 @@
|
|
|
1
1
|
# @x402/paywall
|
|
2
|
+
|
|
3
|
+
Modular paywall UI for the x402 payment protocol with support for EVM and Solana networks.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Pre-built paywall UI out of the box
|
|
8
|
+
- Wallet connection (MetaMask, Coinbase Wallet, Phantom, etc.)
|
|
9
|
+
- USDC balance checking
|
|
10
|
+
- Multi-network support (EVM + Solana)
|
|
11
|
+
- Tree-shakeable - only bundle what you need
|
|
12
|
+
- Fully customizable via builder pattern
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @x402/paywall
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Bundle Sizes
|
|
21
|
+
|
|
22
|
+
Choose the import that matches your needs:
|
|
23
|
+
|
|
24
|
+
| Import | Size | Networks | Use Case |
|
|
25
|
+
|--------|------|----------|----------|
|
|
26
|
+
| `@x402/paywall` | 3.5MB | EVM + Solana | Multi-network apps |
|
|
27
|
+
| `@x402/paywall/evm` | 3.4MB | EVM only | Base, Ethereum, Polygon, etc. |
|
|
28
|
+
| `@x402/paywall/svm` | 1.0MB | Solana only | Solana apps |
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Option 1: EVM Only
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { createPaywall } from '@x402/paywall';
|
|
36
|
+
import { evmPaywall } from '@x402/paywall/evm';
|
|
37
|
+
|
|
38
|
+
const paywall = createPaywall()
|
|
39
|
+
.withNetwork(evmPaywall)
|
|
40
|
+
.withConfig({
|
|
41
|
+
appName: 'My App',
|
|
42
|
+
testnet: true
|
|
43
|
+
})
|
|
44
|
+
.build();
|
|
45
|
+
|
|
46
|
+
// Use with Express
|
|
47
|
+
app.use(paymentMiddleware(routes, facilitators, schemes, undefined, paywall));
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Option 2: Solana Only
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { createPaywall } from '@x402/paywall';
|
|
54
|
+
import { svmPaywall } from '@x402/paywall/svm';
|
|
55
|
+
|
|
56
|
+
const paywall = createPaywall()
|
|
57
|
+
.withNetwork(svmPaywall)
|
|
58
|
+
.withConfig({
|
|
59
|
+
appName: 'My Solana App',
|
|
60
|
+
testnet: true
|
|
61
|
+
})
|
|
62
|
+
.build();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Option 3: Multi-Network
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { createPaywall } from '@x402/paywall';
|
|
69
|
+
import { evmPaywall } from '@x402/paywall/evm';
|
|
70
|
+
import { svmPaywall } from '@x402/paywall/svm';
|
|
71
|
+
|
|
72
|
+
const paywall = createPaywall()
|
|
73
|
+
.withNetwork(evmPaywall) // First-match priority
|
|
74
|
+
.withNetwork(svmPaywall) // Fallback option
|
|
75
|
+
.withConfig({
|
|
76
|
+
appName: 'Multi-chain App',
|
|
77
|
+
testnet: true
|
|
78
|
+
})
|
|
79
|
+
.build();
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
### PaywallConfig Options
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
interface PaywallConfig {
|
|
88
|
+
appName?: string; // App name shown in wallet connection
|
|
89
|
+
appLogo?: string; // App logo URL
|
|
90
|
+
currentUrl?: string; // URL of protected resource
|
|
91
|
+
testnet?: boolean; // Use testnet (default: true)
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## How It Works
|
|
96
|
+
|
|
97
|
+
### First-Match Selection
|
|
98
|
+
|
|
99
|
+
When multiple networks are registered, the paywall uses **first-match selection**:
|
|
100
|
+
|
|
101
|
+
1. Iterates through `paymentRequired.accepts` array
|
|
102
|
+
2. Finds the first payment requirement that has a registered handler
|
|
103
|
+
3. Uses that handler to generate the HTML
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```typescript
|
|
107
|
+
// Server returns multiple options
|
|
108
|
+
{
|
|
109
|
+
"accepts": [
|
|
110
|
+
{ "network": "solana:5eykt...", ... }, // First
|
|
111
|
+
{ "network": "eip155:8453", ... } // Second
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// If both handlers registered, Solana is selected (it's first in accepts)
|
|
116
|
+
const paywall = createPaywall()
|
|
117
|
+
.withNetwork(evmPaywall)
|
|
118
|
+
.withNetwork(svmPaywall)
|
|
119
|
+
.build();
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Supported Networks
|
|
123
|
+
|
|
124
|
+
**EVM Networks** (via `evmPaywall`):
|
|
125
|
+
- CAIP-2: `eip155:*` (e.g., `eip155:8453` for Base, `eip155:84532` for Base Sepolia)
|
|
126
|
+
|
|
127
|
+
**Solana Networks** (via `svmPaywall`):
|
|
128
|
+
- CAIP-2: `solana:*` (e.g., `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` for mainnet)
|
|
129
|
+
|
|
130
|
+
## With HTTP Middleware
|
|
131
|
+
|
|
132
|
+
### Express
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import express from 'express';
|
|
136
|
+
import { paymentMiddleware } from '@x402/express';
|
|
137
|
+
import { createPaywall } from '@x402/paywall';
|
|
138
|
+
import { evmPaywall } from '@x402/paywall/evm';
|
|
139
|
+
|
|
140
|
+
const app = express();
|
|
141
|
+
|
|
142
|
+
const paywall = createPaywall()
|
|
143
|
+
.withNetwork(evmPaywall)
|
|
144
|
+
.withConfig({ appName: 'My API' })
|
|
145
|
+
.build();
|
|
146
|
+
|
|
147
|
+
app.use(paymentMiddleware(
|
|
148
|
+
{ "/api/premium": { price: "$0.10", network: "eip155:84532", payTo: "0x..." } },
|
|
149
|
+
facilitators,
|
|
150
|
+
schemes,
|
|
151
|
+
undefined,
|
|
152
|
+
paywall
|
|
153
|
+
));
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Automatic Detection
|
|
157
|
+
|
|
158
|
+
If you provide `paywallConfig` without a custom paywall, `@x402/core` automatically:
|
|
159
|
+
1. Tries to load `@x402/paywall` if installed
|
|
160
|
+
2. Falls back to basic HTML if not installed
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// Simple usage - auto-detects @x402/paywall
|
|
164
|
+
app.use(paymentMiddleware(routes, facilitators, schemes, {
|
|
165
|
+
appName: 'My App',
|
|
166
|
+
testnet: true
|
|
167
|
+
}));
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Custom Network Handlers
|
|
171
|
+
|
|
172
|
+
You can create custom handlers for new networks:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { createPaywall, type PaywallNetworkHandler } from '@x402/paywall';
|
|
176
|
+
|
|
177
|
+
const suiPaywall: PaywallNetworkHandler = {
|
|
178
|
+
supports: (req) => req.network.startsWith('sui:'),
|
|
179
|
+
generateHtml: (req, paymentRequired, config) => {
|
|
180
|
+
return `<!DOCTYPE html>...`; // Your custom Sui paywall
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const paywall = createPaywall()
|
|
185
|
+
.withNetwork(evmPaywall)
|
|
186
|
+
.withNetwork(svmPaywall)
|
|
187
|
+
.withNetwork(suiPaywall) // Custom handler
|
|
188
|
+
.build();
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
### Build
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
pnpm build:paywall # Generate HTML templates
|
|
197
|
+
pnpm build # Build TypeScript
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Test
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pnpm test # Run unit tests
|
|
204
|
+
```
|