x402-payments 0.1.0 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/README.md +169 -30
- data/examples/.env.example +46 -9
- data/examples/README.md +137 -25
- data/examples/generate_payment.rb +81 -21
- data/lib/x402/payments/chains.rb +86 -6
- data/lib/x402/payments/configuration.rb +40 -1
- data/lib/x402/payments/generator.rb +174 -66
- data/lib/x402/payments/networks.rb +65 -0
- data/lib/x402/payments/solana/generator.rb +288 -0
- data/lib/x402/payments/v1/headers.rb +11 -0
- data/lib/x402/payments/v1/payload_builder.rb +48 -0
- data/lib/x402/payments/v2/headers.rb +12 -0
- data/lib/x402/payments/v2/payload_builder.rb +73 -0
- data/lib/x402/payments/version.rb +1 -1
- data/lib/x402/payments.rb +102 -23
- metadata +26 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6dc411d32e832d03fd677129c82073d40d921a878389e034a4ad66a6ac6b8844
|
|
4
|
+
data.tar.gz: 81fb4038fa051babdf3314dbff9bfd1e7dfa81a41954eb520ce401d8cd22b4ab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b6be1da37e65cd6fd6d2bf603a6d0119bc9b6c0888b0365e1364aa66959cf182f5733765a964fd64818ef6c1bc9371d00357d0e00755b7714ba631fde982db47
|
|
7
|
+
data.tar.gz: 0d4db3d797a2b1ea19f0e330ddb91c4a56ad0494d57636501e05d2286fe19a86d8f69ddacdbf75d7ef37fb7daa47b8db8207878f73a9cb075318cf2b91b33e52
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-01-08
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Solana support** - Full support for Solana payments on `solana-devnet` and `solana` mainnet
|
|
10
|
+
- SPL Token `TransferChecked` transactions with partial signing
|
|
11
|
+
- Custom ATA (Associated Token Account) derivation with correct Ed25519 curve checking
|
|
12
|
+
- Facilitator fee payer model (uses x402.org facilitator by default)
|
|
13
|
+
- Inline `fee_payer:` override for different facilitators
|
|
14
|
+
- Configurable compute budget via `X402_SOLANA_COMPUTE_UNIT_LIMIT` and `X402_SOLANA_COMPUTE_UNIT_PRICE`
|
|
15
|
+
- **Protocol v1 and v2 support** - Both protocol versions fully supported
|
|
16
|
+
- v1: `X-PAYMENT` header, human-readable network names
|
|
17
|
+
- v2: `PAYMENT-SIGNATURE` header, CAIP-2 network identifiers
|
|
18
|
+
- Override protocol version per-request with `version:` parameter
|
|
19
|
+
- **Custom EVM chain registration** - `config.register_chain()` for adding custom EVM networks
|
|
20
|
+
- **Custom token registration** - `config.register_token()` for adding tokens beyond USDC
|
|
21
|
+
- **Networks module** - CAIP-2 network identifier conversion
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Default protocol version is v2
|
|
26
|
+
- Solana uses CAIP-2 format: `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` (devnet)
|
|
27
|
+
- Improved error messages for configuration issues
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- ATA derivation now uses correct Ed25519 curve equation (fixes `recipient_mismatch` errors)
|
|
32
|
+
|
|
33
|
+
## [0.1.0] - Initial Release
|
|
34
|
+
|
|
35
|
+
- Initial release with v1 protocol support
|
|
36
|
+
- EIP-712 signing for USDC payments
|
|
37
|
+
- Support for Base and Avalanche networks
|
data/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# X402::Payments
|
|
2
2
|
|
|
3
|
+
## Now supporting x402 v2!
|
|
4
|
+
|
|
3
5
|

|
|
4
6
|
|
|
5
7
|
Ruby gem for generating signed payment HTTP headers and links using the [x402 protocol](https://www.x402.org/).
|
|
6
8
|
|
|
7
|
-
Supports USDC payments on Base, Avalanche, and other EVM networks with EIP-712 signing.
|
|
9
|
+
Supports USDC and other token payments on Base, Avalanche, Solana, and other EVM networks with EIP-712 signing.
|
|
8
10
|
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
@@ -52,31 +54,168 @@ gem install x402-payments
|
|
|
52
54
|
|
|
53
55
|
## Configuration
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
57
|
+
Configure the gem using environment variables. See `examples/.env.example` for a template.
|
|
58
|
+
|
|
59
|
+
### Environment Variables
|
|
60
|
+
|
|
61
|
+
| Variable | Required | Description |
|
|
62
|
+
| -------------------------------- | ------------ | ------------------------------------------------ |
|
|
63
|
+
| `X402_PRIVATE_KEY` | Yes (EVM) | EVM private key for signing |
|
|
64
|
+
| `X402_PAY_TO` | Yes (EVM) | EVM recipient wallet address |
|
|
65
|
+
| `X402_SOL_PRIVATE_KEY` | Yes (Solana) | Solana private key (base58 or JSON array) |
|
|
66
|
+
| `X402_SOL_PAY_TO` | Yes (Solana) | Solana recipient wallet address |
|
|
67
|
+
| `X402_CHAIN` | No | Network to use (default: `base-sepolia`) |
|
|
68
|
+
| `X402_CURRENCY` | No | Token symbol (default: `USDC`) |
|
|
69
|
+
| `X402_PROTOCOL_VERSION` | No | Protocol version 1 or 2 (default: `2`) |
|
|
70
|
+
| `X402_MAX_TIMEOUT_SECONDS` | No | Payment validity timeout (default: `600`) |
|
|
71
|
+
| `X402_SOLANA_FEE_PAYER` | No | Solana fee payer (default: x402.org facilitator) |
|
|
72
|
+
| `X402_SOLANA_COMPUTE_UNIT_LIMIT` | No | Solana compute unit limit (default: `200000`) |
|
|
73
|
+
| `X402_SOLANA_COMPUTE_UNIT_PRICE` | No | Priority fee in micro-lamports (default: `1000`) |
|
|
74
|
+
| `X402_SOLANA_RPC_URL` | No | Custom Solana mainnet RPC URL |
|
|
75
|
+
| `X402_SOLANA_DEVNET_RPC_URL` | No | Custom Solana devnet RPC URL |
|
|
76
|
+
| `X402_BASE_RPC_URL` | No | Custom Base mainnet RPC URL |
|
|
77
|
+
| `X402_BASE_SEPOLIA_RPC_URL` | No | Custom Base Sepolia RPC URL |
|
|
78
|
+
| `X402_AVALANCHE_RPC_URL` | No | Custom Avalanche mainnet RPC URL |
|
|
79
|
+
| `X402_AVALANCHE_FUJI_RPC_URL` | No | Custom Avalanche Fuji RPC URL |
|
|
72
80
|
|
|
73
81
|
### Supported Networks
|
|
74
82
|
|
|
83
|
+
**EVM Networks:**
|
|
84
|
+
|
|
75
85
|
- `base-sepolia` (testnet) - Default
|
|
76
86
|
- `base` (mainnet)
|
|
77
87
|
- `avalanche-fuji` (testnet)
|
|
78
88
|
- `avalanche` (mainnet)
|
|
79
89
|
|
|
90
|
+
**Solana Networks:**
|
|
91
|
+
|
|
92
|
+
- `solana-devnet` (testnet)
|
|
93
|
+
- `solana` (mainnet)
|
|
94
|
+
|
|
95
|
+
### Custom Chains and Tokens
|
|
96
|
+
|
|
97
|
+
You can register custom EVM chains and tokens beyond the built-in options.
|
|
98
|
+
|
|
99
|
+
#### Register a Custom Chain
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
X402::Payments.configure do |config|
|
|
103
|
+
config.default_pay_to = ENV['X402_PAY_TO']
|
|
104
|
+
config.private_key = ENV['X402_PRIVATE_KEY']
|
|
105
|
+
|
|
106
|
+
# Register Polygon Amoy testnet
|
|
107
|
+
config.register_chain(
|
|
108
|
+
name: "polygon-amoy",
|
|
109
|
+
chain_id: 80002,
|
|
110
|
+
standard: "eip155"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Register the token for that chain
|
|
114
|
+
config.register_token(
|
|
115
|
+
chain: "polygon-amoy",
|
|
116
|
+
symbol: "USDC",
|
|
117
|
+
address: "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582",
|
|
118
|
+
decimals: 6,
|
|
119
|
+
name: "USD Coin",
|
|
120
|
+
version: "2"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Set the RPC URL for the custom chain
|
|
124
|
+
config.rpc_urls["polygon-amoy"] = "https://bitter-attentive-pool.matic-amoy.quiknode.pro"
|
|
125
|
+
|
|
126
|
+
config.chain = "polygon-amoy"
|
|
127
|
+
config.currency = "USDC"
|
|
128
|
+
end
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
You can also set RPC URLs via environment variables using the pattern `X402_<CHAIN>_RPC_URL`:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
export X402_POLYGON_AMOY_RPC_URL="https://bitter-attentive-pool.matic-amoy.quiknode.pro"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Register a Custom Token on a Built-in Chain
|
|
138
|
+
|
|
139
|
+
```ruby
|
|
140
|
+
X402::Payments.configure do |config|
|
|
141
|
+
config.default_pay_to = ENV['X402_PAY_TO']
|
|
142
|
+
config.private_key = ENV['X402_PRIVATE_KEY']
|
|
143
|
+
|
|
144
|
+
# Accept WETH on Base instead of USDC
|
|
145
|
+
config.register_token(
|
|
146
|
+
chain: "base",
|
|
147
|
+
symbol: "WETH",
|
|
148
|
+
address: "0x4200000000000000000000000000000000000006",
|
|
149
|
+
decimals: 18,
|
|
150
|
+
name: "Wrapped Ether",
|
|
151
|
+
version: "1"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
config.chain = "base"
|
|
155
|
+
config.currency = "WETH"
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Token Registration Parameters
|
|
160
|
+
|
|
161
|
+
| Parameter | Required | Description |
|
|
162
|
+
| ---------- | -------- | ---------------------------------------------- |
|
|
163
|
+
| `chain` | Yes | Chain name (built-in or custom registered) |
|
|
164
|
+
| `symbol` | Yes | Token symbol (e.g., "USDC", "WETH") |
|
|
165
|
+
| `address` | Yes | Token contract address |
|
|
166
|
+
| `decimals` | Yes | Token decimals (e.g., 6 for USDC, 18 for WETH) |
|
|
167
|
+
| `name` | Yes | Token name for EIP-712 domain |
|
|
168
|
+
| `version` | No | EIP-712 version (default: "1") |
|
|
169
|
+
|
|
170
|
+
### Solana Configuration
|
|
171
|
+
|
|
172
|
+
For Solana payments, ensure you've set the Solana-specific environment variables (see Configuration section above), then set your chain:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
export X402_CHAIN="solana-devnet" # or "solana" for mainnet
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
You can also override the fee payer per-request:
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
X402::Payments.generate_header(
|
|
182
|
+
amount: 0.001,
|
|
183
|
+
resource: "http://example.com/api",
|
|
184
|
+
network: "solana-devnet",
|
|
185
|
+
fee_payer: "CustomFacilitatorFeePayer" # use different facilitator
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
> **Note**: Both sender and receiver must have a USDC [Associated Token Account (ATA)](https://spl.solana.com/associated-token-account). The sender must have USDC in their wallet (receiving USDC creates the ATA automatically).
|
|
190
|
+
|
|
191
|
+
## Protocol Versions
|
|
192
|
+
|
|
193
|
+
x402-payments supports both v1 and v2 of the x402 protocol. **v2 is the default**.
|
|
194
|
+
|
|
195
|
+
### v2 (Default)
|
|
196
|
+
|
|
197
|
+
```ruby
|
|
198
|
+
X402::Payments.configure do |config|
|
|
199
|
+
config.private_key = ENV['X402_PRIVATE_KEY']
|
|
200
|
+
config.default_pay_to = ENV['X402_PAY_TO']
|
|
201
|
+
config.protocol_version = 2 # Default, can be omitted
|
|
202
|
+
end
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
v2 uses CAIP-2 network identifiers (`eip155:84532`) and the `PAYMENT-SIGNATURE` header.
|
|
206
|
+
|
|
207
|
+
### v1 (Legacy)
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
X402::Payments.configure do |config|
|
|
211
|
+
config.private_key = ENV['X402_PRIVATE_KEY']
|
|
212
|
+
config.default_pay_to = ENV['X402_PAY_TO']
|
|
213
|
+
config.protocol_version = 1
|
|
214
|
+
end
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
v1 uses simple network names (`base-sepolia`) and the `X-PAYMENT` header.
|
|
218
|
+
|
|
80
219
|
## Usage
|
|
81
220
|
|
|
82
221
|
### Basic Usage
|
|
@@ -92,8 +231,8 @@ header = X402::Payments.generate_header(
|
|
|
92
231
|
pay_to: "0xRecipientAddress" # Optional: override recipient (defaults to config)
|
|
93
232
|
)
|
|
94
233
|
|
|
95
|
-
# Use the header in an HTTP request
|
|
96
|
-
# curl -H "
|
|
234
|
+
# Use the header in an HTTP request (v2 uses PAYMENT-SIGNATURE, v1 uses X-PAYMENT)
|
|
235
|
+
# curl -H "PAYMENT-SIGNATURE: #{header}" http://localhost:3000/api/weather
|
|
97
236
|
```
|
|
98
237
|
|
|
99
238
|
**Note**: The `pay_to` parameter allows you to specify a different recipient wallet address per payment. If not provided, it uses the configured `default_pay_to`.
|
|
@@ -146,27 +285,27 @@ end
|
|
|
146
285
|
header = X402::Payments.generate_header(
|
|
147
286
|
amount: 0.001,
|
|
148
287
|
resource: "http://localhost:3000/api/data",
|
|
288
|
+
# version: 1, # Override configured protocol version (1 or 2)
|
|
149
289
|
# network: "avalanche", # Override default network
|
|
150
|
-
# private_key: "0xDifferentKey",
|
|
151
|
-
# pay_to: "0xRecipientWalletAddress",
|
|
152
|
-
# extra: { # Override EIP-712 domain
|
|
153
|
-
# name: "Custom Token",
|
|
154
|
-
# version: "1"
|
|
155
|
-
# }
|
|
290
|
+
# private_key: "0xDifferentKey", # Override default key
|
|
291
|
+
# pay_to: "0xRecipientWalletAddress", # Override recipient address
|
|
156
292
|
)
|
|
157
293
|
|
|
158
294
|
puts "Payment Header:"
|
|
159
295
|
puts header
|
|
160
296
|
|
|
161
|
-
|
|
297
|
+
# v2 (default) uses PAYMENT-SIGNATURE, v1 uses X-PAYMENT
|
|
298
|
+
HTTParty.get("http://localhost:3000/api/data", headers: { "PAYMENT-SIGNATURE" => header })
|
|
162
299
|
```
|
|
163
300
|
|
|
164
301
|
## How It Works
|
|
165
302
|
|
|
166
303
|
1. **Payment Requirements**: The gem creates a payment requirement specifying the amount (in USDC atomic units), network, and resource
|
|
167
|
-
2. **
|
|
168
|
-
|
|
169
|
-
|
|
304
|
+
2. **Transaction Signing**:
|
|
305
|
+
- **EVM**: Uses EIP-3009 `TransferWithAuthorization` to create a signature that authorizes the payment
|
|
306
|
+
- **Solana**: Creates a partially-signed `TransferChecked` transaction (facilitator adds fee payer signature)
|
|
307
|
+
3. **Header Encoding**: Encodes the signed payment data as a base64 string for the HTTP header (`PAYMENT-SIGNATURE` for v2, `X-PAYMENT` for v1)
|
|
308
|
+
4. **Server Validation**: The server validates the signature/transaction and settles the payment on-chain via the [facilitator](https://x402.org/facilitator)
|
|
170
309
|
|
|
171
310
|
## Example Script
|
|
172
311
|
|
data/examples/.env.example
CHANGED
|
@@ -1,14 +1,51 @@
|
|
|
1
|
+
# ===========================================
|
|
1
2
|
# X402 Payments Configuration
|
|
2
|
-
#
|
|
3
|
+
# ===========================================
|
|
4
|
+
# Copy this file to .env and fill in your values
|
|
3
5
|
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
+
# -------------------------------------------
|
|
7
|
+
# EVM Configuration (Required for EVM chains)
|
|
8
|
+
# -------------------------------------------
|
|
9
|
+
X402_PRIVATE_KEY=0xYourEvmPrivateKey
|
|
10
|
+
X402_PAY_TO=0xEvmPayToAddress
|
|
6
11
|
|
|
7
|
-
#
|
|
8
|
-
|
|
12
|
+
# -------------------------------------------
|
|
13
|
+
# Solana Configuration (Required for Solana)
|
|
14
|
+
# -------------------------------------------
|
|
15
|
+
X402_SOL_PRIVATE_KEY=YourSolPrivateKey
|
|
16
|
+
X402_SOL_PAY_TO=SolPayToWalletAddress
|
|
9
17
|
|
|
10
|
-
# Optional:
|
|
11
|
-
|
|
18
|
+
# Optional: Override default x402.org facilitator
|
|
19
|
+
X402_SOLANA_FEE_PAYER=CKPKJWNdJEqa81x7CkZ14BVPiY6y16Sxs7owznqtWYp5
|
|
12
20
|
|
|
13
|
-
# Optional:
|
|
14
|
-
|
|
21
|
+
# Optional: Solana compute budget for priority fees
|
|
22
|
+
# X402_SOLANA_COMPUTE_UNIT_LIMIT=200000
|
|
23
|
+
# X402_SOLANA_COMPUTE_UNIT_PRICE=1000
|
|
24
|
+
|
|
25
|
+
# -------------------------------------------
|
|
26
|
+
# General Configuration (Optional)
|
|
27
|
+
# -------------------------------------------
|
|
28
|
+
# X402_CHAIN=base-sepolia
|
|
29
|
+
# X402_CURRENCY=USDC
|
|
30
|
+
# X402_PROTOCOL_VERSION=2
|
|
31
|
+
# X402_MAX_TIMEOUT_SECONDS=600
|
|
32
|
+
|
|
33
|
+
# -------------------------------------------
|
|
34
|
+
# Custom RPC URLs (Optional)
|
|
35
|
+
# -------------------------------------------
|
|
36
|
+
# Override default RPC endpoints for any chain
|
|
37
|
+
# Pattern: X402_<CHAIN_NAME>_RPC_URL (dashes become underscores)
|
|
38
|
+
|
|
39
|
+
# EVM chains
|
|
40
|
+
# X402_BASE_RPC_URL=https://your-base-rpc.com
|
|
41
|
+
# X402_BASE_SEPOLIA_RPC_URL=https://your-base-sepolia-rpc.com
|
|
42
|
+
# X402_AVALANCHE_RPC_URL=https://your-avalanche-rpc.com
|
|
43
|
+
# X402_AVALANCHE_FUJI_RPC_URL=https://your-avalanche-fuji-rpc.com
|
|
44
|
+
|
|
45
|
+
# Solana chains
|
|
46
|
+
# X402_SOLANA_RPC_URL=https://your-solana-mainnet-rpc.com
|
|
47
|
+
# X402_SOLANA_DEVNET_RPC_URL=https://your-solana-devnet-rpc.com
|
|
48
|
+
|
|
49
|
+
# Custom chains (example)
|
|
50
|
+
# X402_POLYGON_AMOY_RPC_URL=https://your-rpc-amoy-rpc.com
|
|
51
|
+
# X402_POLYGON_RPC_URL=https://your-polygon-rpc.com
|
data/examples/README.md
CHANGED
|
@@ -4,7 +4,7 @@ This directory contains example scripts demonstrating how to use the x402-paymen
|
|
|
4
4
|
|
|
5
5
|
## generate_payment.rb
|
|
6
6
|
|
|
7
|
-
Generates a signed payment header and curl command for testing x402 payments.
|
|
7
|
+
Generates a signed payment header and curl command for testing x402 payments on EVM chains and Solana.
|
|
8
8
|
|
|
9
9
|
### Setup
|
|
10
10
|
|
|
@@ -20,44 +20,123 @@ cp .env.example .env
|
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
# From the gem root directory
|
|
23
|
-
cd /
|
|
23
|
+
cd /path/to/x402-payments
|
|
24
24
|
|
|
25
25
|
# Load environment variables and run
|
|
26
26
|
export $(cat examples/.env | xargs)
|
|
27
27
|
ruby examples/generate_payment.rb
|
|
28
28
|
|
|
29
|
-
# Or set variables inline
|
|
29
|
+
# Or set variables inline (EVM)
|
|
30
30
|
X402_PRIVATE_KEY="0xYourPrivateKey" \
|
|
31
31
|
X402_PAY_TO="0xYourRecipientAddress" \
|
|
32
|
-
X402_CHAIN="base-sepolia" \
|
|
33
32
|
ruby examples/generate_payment.rb
|
|
33
|
+
|
|
34
|
+
# Or set variables inline (Solana)
|
|
35
|
+
X402_SOL_PRIVATE_KEY="YourBase58PrivateKey" \
|
|
36
|
+
X402_SOL_PAY_TO="YourSolanaWalletAddress" \
|
|
37
|
+
ruby examples/generate_payment.rb -c solana-devnet
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Command Line Options
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ruby examples/generate_payment.rb [options]
|
|
44
|
+
|
|
45
|
+
Options:
|
|
46
|
+
-v, --version VERSION Protocol version (1 or 2, default: 2)
|
|
47
|
+
-c, --chain CHAIN Chain name (e.g., base-sepolia, solana-devnet)
|
|
48
|
+
-h, --help Show help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Examples
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# EVM: Use v2 protocol on Base Sepolia (default)
|
|
55
|
+
ruby examples/generate_payment.rb -v 2
|
|
56
|
+
|
|
57
|
+
# EVM: Use Polygon Amoy testnet (custom chain)
|
|
58
|
+
ruby examples/generate_payment.rb -c polygon-amoy -v 2
|
|
59
|
+
|
|
60
|
+
# EVM: Use built-in Base Sepolia with v1
|
|
61
|
+
ruby examples/generate_payment.rb -c base-sepolia -v 1
|
|
62
|
+
|
|
63
|
+
# Solana: Use Solana devnet
|
|
64
|
+
ruby examples/generate_payment.rb -c solana-devnet -v 2
|
|
65
|
+
|
|
66
|
+
# Solana: Use Solana mainnet
|
|
67
|
+
ruby examples/generate_payment.rb -c solana -v 2
|
|
34
68
|
```
|
|
35
69
|
|
|
36
70
|
### Environment Variables
|
|
37
71
|
|
|
38
|
-
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
72
|
+
**EVM chains:**
|
|
73
|
+
- `X402_PRIVATE_KEY` - EVM private key for signing (required for EVM)
|
|
74
|
+
- `X402_PAY_TO` - EVM recipient wallet address (required for EVM)
|
|
75
|
+
|
|
76
|
+
**Solana chains:**
|
|
77
|
+
- `X402_SOL_PRIVATE_KEY` - Solana private key in base58 or JSON array format (required for Solana)
|
|
78
|
+
- `X402_SOL_PAY_TO` - Solana recipient wallet address (required for Solana)
|
|
79
|
+
- `X402_SOLANA_FEE_PAYER` - Facilitator fee payer (optional, defaults to x402.org facilitator)
|
|
80
|
+
- `X402_SOLANA_COMPUTE_UNIT_LIMIT` - Compute unit limit (optional, default: 200000)
|
|
81
|
+
- `X402_SOLANA_COMPUTE_UNIT_PRICE` - Priority fee in micro-lamports (optional, default: 1000)
|
|
82
|
+
|
|
83
|
+
**General:**
|
|
84
|
+
- `X402_CHAIN` - Network to use (default: `base-sepolia`, can be overridden with `-c`)
|
|
85
|
+
|
|
86
|
+
### Supported Chains
|
|
87
|
+
|
|
88
|
+
**EVM chains (built-in):**
|
|
89
|
+
- `base-sepolia` (testnet) - default
|
|
90
|
+
- `base` (mainnet)
|
|
91
|
+
- `avalanche-fuji` (testnet)
|
|
92
|
+
- `avalanche` (mainnet)
|
|
93
|
+
|
|
94
|
+
**Solana chains (built-in):**
|
|
95
|
+
- `solana-devnet` (testnet)
|
|
96
|
+
- `solana` (mainnet)
|
|
41
97
|
|
|
42
|
-
|
|
98
|
+
**Custom EVM chains (pre-configured in example):**
|
|
99
|
+
- `polygon-amoy` (Polygon testnet, chain ID: 80002)
|
|
100
|
+
- `polygon` (Polygon mainnet, chain ID: 137)
|
|
101
|
+
|
|
102
|
+
### Example Output (EVM)
|
|
43
103
|
|
|
44
104
|
```
|
|
45
|
-
=== X402 Payment Generator ===
|
|
46
|
-
Default Pay To: 0xYourRecipientAddress
|
|
105
|
+
=== X402 Payment Generator (V2) ===
|
|
47
106
|
Chain: base-sepolia
|
|
107
|
+
CAIP-2: eip155:84532
|
|
108
|
+
Protocol Version: 2
|
|
109
|
+
|
|
110
|
+
Resource: http://localhost:3000/api/v2/weather/paywalled_info
|
|
111
|
+
Amount: $0.001 USD
|
|
48
112
|
|
|
49
|
-
|
|
50
|
-
Resource: http://localhost:3000/api/weather/current
|
|
51
|
-
Amount: $0.001 USD
|
|
113
|
+
Header Name: PAYMENT-SIGNATURE
|
|
52
114
|
|
|
53
|
-
Payment Header
|
|
54
|
-
|
|
115
|
+
Payment Header:
|
|
116
|
+
eyJ4NDAyVmVyc2lvbiI6Miwic...
|
|
55
117
|
|
|
56
118
|
Curl Command:
|
|
57
|
-
curl -
|
|
119
|
+
curl -s -H "PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Miwic..." http://localhost:3000/api/v2/weather/paywalled_info | jq .
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Example Output (Solana)
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
=== X402 Payment Generator (V2) ===
|
|
126
|
+
Chain: solana-devnet (Solana)
|
|
127
|
+
CAIP-2: solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
|
|
128
|
+
Protocol Version: 2
|
|
129
|
+
|
|
130
|
+
Resource: http://localhost:3000/api/v2/weather/paywalled_info_sol
|
|
131
|
+
Amount: $0.001 USD
|
|
132
|
+
|
|
133
|
+
Header Name: PAYMENT-SIGNATURE
|
|
58
134
|
|
|
59
|
-
|
|
60
|
-
|
|
135
|
+
Payment Header:
|
|
136
|
+
eyJ4NDAyVmVyc2lvbiI6Miwic...
|
|
137
|
+
|
|
138
|
+
Curl Command:
|
|
139
|
+
curl -s -H "PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Miwic..." http://localhost:3000/api/v2/weather/paywalled_info_sol | jq .
|
|
61
140
|
```
|
|
62
141
|
|
|
63
142
|
You can copy and paste the curl command to test your x402-enabled API endpoint.
|
|
@@ -68,21 +147,54 @@ You can modify `generate_payment.rb` to:
|
|
|
68
147
|
|
|
69
148
|
- Change the amount (e.g., `amount = 0.005` for $0.005)
|
|
70
149
|
- Target different resources (e.g., `resource_url = "https://api.example.com/data"`)
|
|
71
|
-
- Use different networks (set `X402_CHAIN` environment variable)
|
|
150
|
+
- Use different networks (set `X402_CHAIN` environment variable or `-c` flag)
|
|
72
151
|
- Add custom descriptions
|
|
152
|
+
- Override the fee payer for Solana transactions
|
|
73
153
|
|
|
74
|
-
### Example: Generate Payment
|
|
154
|
+
### Example: Generate EVM Payment Programmatically
|
|
75
155
|
|
|
76
156
|
```ruby
|
|
77
|
-
|
|
157
|
+
require 'x402/payments'
|
|
78
158
|
|
|
79
|
-
|
|
80
|
-
|
|
159
|
+
X402::Payments.configure do |config|
|
|
160
|
+
config.private_key = ENV['X402_PRIVATE_KEY']
|
|
161
|
+
config.default_pay_to = ENV['X402_PAY_TO']
|
|
162
|
+
config.chain = 'base-sepolia'
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
link = X402::Payments.generate_link(
|
|
81
166
|
amount: 0.005,
|
|
82
167
|
resource: "http://localhost:3000/api/premium/data",
|
|
83
168
|
description: "Premium API access"
|
|
84
169
|
)
|
|
85
170
|
|
|
86
|
-
puts
|
|
87
|
-
puts custom_link[:curl_command]
|
|
171
|
+
puts link[:curl_command]
|
|
88
172
|
```
|
|
173
|
+
|
|
174
|
+
### Example: Generate Solana Payment Programmatically
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
require 'x402/payments'
|
|
178
|
+
|
|
179
|
+
X402::Payments.configure do |config|
|
|
180
|
+
config.private_key = ENV['X402_SOL_PRIVATE_KEY']
|
|
181
|
+
config.default_pay_to = ENV['X402_SOL_PAY_TO']
|
|
182
|
+
config.chain = 'solana-devnet'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
link = X402::Payments.generate_link(
|
|
186
|
+
amount: 0.001,
|
|
187
|
+
resource: "http://localhost:3000/api/sol/data",
|
|
188
|
+
description: "Solana payment",
|
|
189
|
+
# fee_payer: "CustomFeePayerAddress" # Optional: override default facilitator
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
puts link[:curl_command]
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Solana Notes
|
|
196
|
+
|
|
197
|
+
- Both sender and receiver must have a USDC Associated Token Account (ATA)
|
|
198
|
+
- The sender must have USDC in their wallet
|
|
199
|
+
- Transactions are partially signed by the sender; the facilitator adds the fee payer signature
|
|
200
|
+
- Default facilitator is x402.org (`CKPKJWNdJEqa81x7CkZ14BVPiY6y16Sxs7owznqtWYp5`)
|