-
Notifications
You must be signed in to change notification settings - Fork 50
add x402 express.js template #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
v1xingyue
wants to merge
3
commits into
solana-foundation:main
Choose a base branch
from
Solana-ZH:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Server Configuration | ||
| # Solana address to receive payments (must be a valid base58 Solana address) | ||
| PAY_TO_ADDRESS=Dy6mBH4YeqJCRZohd39iSFaf4jyLaxPeBakbZwt1jToL | ||
|
|
||
| # Payment Configuration (also configurable in src/config.ts) | ||
| # Solana network (mainnet-beta, devnet, etc.) | ||
| NETWORK=mainnet-beta | ||
|
|
||
| # Token asset for payments (USDC, SOL, etc.) | ||
| ASSET=USDC | ||
|
|
||
| # Payment amount per request (as string) | ||
| AMOUNT=100 | ||
|
|
||
| # Client Configuration | ||
| # Your Solana keypair as a JSON array (get from wallet's secret key) | ||
| # Example: [123,45,67,...] (array of numbers 0-255) | ||
| SECRET_KEY= | ||
|
|
||
| # Optional: Proxy URL for client requests | ||
| # PROXY_URL=http://proxy.example.com:8080 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| node_modules | ||
| .env | ||
| .vercel |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,256 @@ | ||
| # X402 Express Server and Client | ||
|
|
||
| This project demonstrates how to use X402 payment system with Express.js, allowing API endpoints to charge for access using Solana USDC payments. | ||
|
|
||
| ## What is X402? | ||
|
|
||
| X402 is a payment protocol that enables API endpoints to automatically charge clients for access. Payments are processed on the Solana blockchain using USDC. | ||
|
|
||
| ## Project Structure | ||
|
|
||
| - **Server** (`src/index.ts`): Express.js server with X402-protected API routes | ||
| - **Client** (`src/client.ts`): Example client that automatically pays when calling protected endpoints | ||
| - **Routes** (`src/routes/index.ts`): API routes with X402 payment middleware | ||
| - **Config** (`src/config.ts`): Centralized configuration for payment settings (network, asset, amount, payment address) | ||
|
|
||
| ## Server | ||
|
|
||
| The server sets up Express.js with a protected API endpoint that requires payment: | ||
|
|
||
| ### Protected Route | ||
|
|
||
| The `/api/protected` endpoint requires a payment of **100 USDC** to access. It uses X402 middleware to automatically verify and process payments. | ||
|
|
||
| ```bash | ||
| # Start the server (configure for your deployment platform) | ||
| # For Vercel: | ||
| vercel dev | ||
|
|
||
| # Without Vercel: | ||
| npm run server | ||
| ``` | ||
|
|
||
| ### Configuration | ||
|
|
||
| Payment configuration is centralized in `src/config.ts`. The following environment variables can be set to customize the payment settings: | ||
|
|
||
| - `PAY_TO_ADDRESS`: Solana address to receive payments (defaults to a test address) | ||
| - `NETWORK`: Solana network (defaults to `"mainnet-beta"`) | ||
| - `ASSET`: Token asset to use for payments (defaults to `"USDC"`) | ||
| - `AMOUNT`: Payment amount per request (defaults to `"100"`) | ||
|
|
||
| All configuration values can be overridden via environment variables or edited directly in `src/config.ts`. | ||
|
|
||
| ## Client | ||
|
|
||
| The client demonstrates how to automatically pay for API access using X402: | ||
|
|
||
| ### Setup | ||
|
|
||
| 1. Install dependencies: | ||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| 2. Configure environment variables in `.env`: | ||
| ``` | ||
| SECRET_KEY=[your Solana keypair JSON array] | ||
| PROXY_URL=[optional proxy URL] | ||
| ``` | ||
|
|
||
| ### Usage | ||
|
|
||
| Run the client to call the protected endpoint: | ||
| ```bash | ||
| npm run client | ||
| ``` | ||
|
|
||
| The client will: | ||
| 1. Load your Solana keypair | ||
| 2. Create a payment handler with X402 | ||
| 3. Wrap `fetch` to automatically handle payments | ||
| 4. Call the protected endpoint (payment happens automatically) | ||
|
|
||
| ### How It Works | ||
|
|
||
| - The client uses `@faremeter/payment-solana` to create a payment handler | ||
| - `wrap(fetch, { handlers: [handler] })` automatically adds payment to requests | ||
| - When calling a protected endpoint, the payment is processed on Solana before the request completes | ||
|
|
||
| ## X402 Usage | ||
|
|
||
| X402 middleware is configured using centralized settings in `src/config.ts`: | ||
|
|
||
| - **Network**: Solana mainnet-beta (configurable via `NETWORK` env var or `src/config.ts`) | ||
| - **Asset**: USDC (configurable via `ASSET` env var or `src/config.ts`) | ||
| - **Amount**: 100 USDC per request (configurable via `AMOUNT` env var or `src/config.ts`) | ||
| - **Payment Address**: Set via `PAY_TO_ADDRESS` env var or `src/config.ts` | ||
| - **Facilitator**: Handles payment verification at `https://facilitator.corbits.io` | ||
|
|
||
| The middleware automatically: | ||
| - Validates incoming payment signatures | ||
| - Verifies payment amounts | ||
| - Grants access only after successful payment | ||
|
|
||
| ## Deployment | ||
|
|
||
| ### Deploy to Vercel | ||
|
|
||
| Deploy your own instance of this project to Vercel with one click: | ||
|
|
||
| [](https://vercel.com/new/clone?repository-url=https://github.com/v1xingyue/x402-express) | ||
|
|
||
| > **Note:** Replace `your-username/x402-express` with your repository URL if deploying from your own fork. | ||
|
|
||
| ### Manual Deployment Steps | ||
|
|
||
| 1. **Fork or clone this repository** | ||
| 2. **Connect to Vercel:** | ||
| - Go to [Vercel](https://vercel.com) | ||
| - Import your repository | ||
| - Configure the project settings | ||
|
|
||
| 3. **Set environment variables in Vercel:** | ||
| - Go to Project Settings → Environment Variables | ||
| - Add `PAY_TO_ADDRESS` with your Solana address to receive payments | ||
| - Optionally set `NETWORK`, `ASSET`, and `AMOUNT` to customize payment settings | ||
| - The client-side variables (`SECRET_KEY`, `PROXY_URL`) are only needed for local client development | ||
|
|
||
| 4. **Deploy:** | ||
| - Vercel will automatically detect Express.js and deploy | ||
| - Your API will be available at `https://your-project.vercel.app` | ||
|
|
||
| 5. **Update client URL:** | ||
| - Update the API URL in `src/client.ts` to point to your deployed server | ||
| - Replace `https://x402-express.vercel.app` with your Vercel deployment URL | ||
|
|
||
| ## Development | ||
|
|
||
| ### Getting Started | ||
|
|
||
| 1. **Clone and install dependencies:** | ||
| ```bash | ||
| git clone <repository-url> | ||
| cd x402-express | ||
| npm install | ||
| ``` | ||
|
|
||
| 2. **Set up environment variables:** | ||
| ```bash | ||
| cp .env.example .env | ||
| ``` | ||
|
|
||
| 3. **Configure your `.env` file:** | ||
| - **SECRET_KEY**: Convert your Solana wallet's secret key to a JSON array format | ||
| ```bash | ||
| # If you have a keypair file, you can extract it: | ||
| # The format should be: [123,45,67,...] (array of 64 numbers) | ||
| ``` | ||
| - **PAY_TO_ADDRESS**: Your Solana address to receive payments (get USDC test tokens from [Circle Faucet](https://faucet.circle.com/)) | ||
| - **NETWORK** (optional): Solana network - defaults to `"mainnet-beta"` (also configurable in `src/config.ts`) | ||
| - **ASSET** (optional): Token asset for payments - defaults to `"USDC"` (also configurable in `src/config.ts`) | ||
| - **AMOUNT** (optional): Payment amount per request - defaults to `"100"` (also configurable in `src/config.ts`) | ||
| - **PROXY_URL** (optional): Set if you need to use a proxy for requests | ||
|
|
||
| 4. **Run the server:** | ||
| ```bash | ||
| # For local development with Vercel: | ||
| vercel dev | ||
|
|
||
| # Or configure for your preferred deployment platform | ||
| ``` | ||
|
|
||
| 5. **Test the client:** | ||
| ```bash | ||
| npm run client | ||
| ``` | ||
|
|
||
| ### Adding More Protected Routes | ||
|
|
||
| To add additional protected routes with X402 payment, follow this pattern in `src/routes/index.ts`: | ||
|
|
||
| ```typescript | ||
| import { payToAddress, network, asset, amount } from "../config.js"; | ||
|
|
||
| // Option 1: Use default config values | ||
| const defaultExtract = solana.x402Exact({ | ||
| network: network as Network, | ||
| asset: asset as Asset, | ||
| amount: amount, | ||
| payTo: payToAddress, | ||
| }); | ||
|
|
||
| // Option 2: Create custom payment requirement | ||
| const customExtract = solana.x402Exact({ | ||
| network: "mainnet-beta", | ||
| asset: "USDC", | ||
| amount: "50", // Amount in USDC (adjust as needed) | ||
| payTo: payToAddress, | ||
| }); | ||
|
|
||
| // Create protected route | ||
| router.get( | ||
| "/custom-endpoint", | ||
| await middleware.createMiddleware({ | ||
| facilitatorURL: "https://facilitator.corbits.io", | ||
| accepts: [customExtract], | ||
| }), | ||
| (_, res) => { | ||
| return res.json({ message: "Custom protected endpoint" }); | ||
| } | ||
| ); | ||
| ``` | ||
|
|
||
| ### Customizing Payment Settings | ||
|
|
||
| Payment configuration is centralized in `src/config.ts`. You can customize: | ||
|
|
||
| 1. **Via Environment Variables** (recommended for deployments): | ||
| ```bash | ||
| NETWORK=mainnet-beta | ||
| ASSET=USDC | ||
| AMOUNT=100 | ||
| PAY_TO_ADDRESS=YourSolanaAddressHere | ||
| ``` | ||
|
|
||
| 2. **Directly in `src/config.ts`**: | ||
| ```typescript | ||
| export const amount = process.env.AMOUNT || "100"; // Change default here | ||
| export const asset = process.env.ASSET || "USDC"; // Change asset here | ||
| export const network = process.env.NETWORK || "mainnet-beta"; // Change network here | ||
| ``` | ||
|
|
||
| - **Amount**: Default is `"100"` USDC. Amounts are specified as strings (e.g., `"50"`, `"1000"`) | ||
| - **Asset**: Currently set to `"USDC"`. Can be changed to other supported SPL tokens | ||
| - **Network**: Currently `"mainnet-beta"`. Can be changed to `"devnet"` for testing | ||
|
|
||
| ### Development Workflow | ||
|
|
||
| 1. **Local Development:** | ||
| - Make changes to server routes in `src/routes/index.ts` | ||
| - Update client code in `src/client.ts` | ||
| - Test locally with `vercel dev` | ||
|
|
||
| 2. **Adding New Features:** | ||
| - Create new route files in `src/routes/` if needed | ||
| - Import and use them in `src/routes/index.ts` | ||
| - Update client to call new endpoints | ||
|
|
||
| 3. **Testing Payments:** | ||
| - Use test USDC from [Circle Faucet](https://faucet.circle.com/) | ||
| - Monitor transactions on Solana explorer | ||
| - Check facilitator logs for payment verification | ||
|
|
||
| ### Tips | ||
|
|
||
| - Keep your `SECRET_KEY` secure and never commit it to version control | ||
| - Use different addresses for development and production | ||
| - Monitor your Solana wallet balance to ensure sufficient USDC for testing | ||
| - The facilitator handles payment verification, so your server doesn't need direct blockchain access | ||
|
|
||
|
|
||
| ## 🤝 Contribution | ||
|
|
||
| Contributed by [cevin](https://github.com/v1xingyue) from [Solar](https://www.solar.team/). | ||
|
|
||
| Feel free to raise issues or submit PRs for future improvements. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"/> | ||
| <title>About - X402 Express Server</title> | ||
| <link rel="stylesheet" href="/style.css" /> | ||
| </head> | ||
| <body> | ||
| <nav> | ||
| <a href="/">Home</a> | ||
| <a href="/about">About</a> | ||
| <a href="/api">API</a> | ||
| <a href="/healthz">Health</a> | ||
| </nav> | ||
|
|
||
| <div> | ||
| <h1>About X402 Express</h1> | ||
|
|
||
| <h2>Project Overview</h2> | ||
| <p>This project demonstrates how to use X402 payment system with Express.js, allowing API endpoints to charge for access using Solana USDC payments.</p> | ||
|
|
||
| <h2>Project Structure</h2> | ||
| <ul> | ||
| <li><strong>Server</strong> (<code>src/index.ts</code>): Express.js server with X402-protected API routes</li> | ||
| <li><strong>Client</strong> (<code>src/client.ts</code>): Example client that automatically pays when calling protected endpoints</li> | ||
| <li><strong>Routes</strong> (<code>src/routes/index.ts</code>): API routes with X402 payment middleware</li> | ||
| <li><strong>Config</strong> (<code>src/config.ts</code>): Centralized configuration for payment settings (network, asset, amount, payment address)</li> | ||
| </ul> | ||
|
|
||
| <h2>Protected Route</h2> | ||
| <p>The <code>/api/protected</code> endpoint requires a payment of <strong>100 USDC</strong> to access. It uses X402 middleware to automatically verify and process payments.</p> | ||
|
|
||
| <h2>Configuration</h2> | ||
| <p>Payment configuration is centralized in <code>src/config.ts</code>. The following environment variables can be set to customize the payment settings:</p> | ||
| <ul> | ||
| <li><code>PAY_TO_ADDRESS</code>: Solana address to receive payments (defaults to a test address)</li> | ||
| <li><code>NETWORK</code>: Solana network (defaults to <code>"mainnet-beta"</code>)</li> | ||
| <li><code>ASSET</code>: Token asset to use for payments (defaults to <code>"USDC"</code>)</li> | ||
| <li><code>AMOUNT</code>: Payment amount per request (defaults to <code>"100"</code>)</li> | ||
| </ul> | ||
|
|
||
| <h2>Client Usage</h2> | ||
| <p>The client demonstrates how to automatically pay for API access using X402:</p> | ||
| <ol> | ||
| <li>Load your Solana keypair</li> | ||
| <li>Create a payment handler with X402</li> | ||
| <li>Wrap <code>fetch</code> to automatically handle payments</li> | ||
| <li>Call the protected endpoint (payment happens automatically)</li> | ||
| </ol> | ||
|
|
||
| <h2>X402 Middleware</h2> | ||
| <p>X402 middleware is configured using centralized settings in <code>src/config.ts</code>:</p> | ||
| <ul> | ||
| <li><strong>Network:</strong> Solana mainnet-beta (configurable via <code>NETWORK</code> env var)</li> | ||
| <li><strong>Asset:</strong> USDC (configurable via <code>ASSET</code> env var)</li> | ||
| <li><strong>Amount:</strong> 100 USDC per request (configurable via <code>AMOUNT</code> env var)</li> | ||
| <li><strong>Payment Address:</strong> Set via <code>PAY_TO_ADDRESS</code> env var</li> | ||
| <li><strong>Facilitator:</strong> Handles payment verification at <code>https://facilitator.corbits.io</code></li> | ||
| </ul> | ||
|
|
||
| <p>The middleware automatically:</p> | ||
| <ul> | ||
| <li>Validates incoming payment signatures</li> | ||
| <li>Verifies payment amounts</li> | ||
| <li>Grants access only after successful payment</li> | ||
| </ul> | ||
|
|
||
| <h2>Development</h2> | ||
| <p>For detailed setup instructions, deployment guides, and code examples, please refer to the <a href="https://github.com/v1xingyue/x402-express" target="_blank">GitHub repository README</a>.</p> | ||
| </div> | ||
| </body> | ||
| </html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "name": "express", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "type": "module", | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "scripts": { | ||
| "client": "tsx src/client.ts", | ||
| "server": "tsx src/server.ts" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^22.0.0", | ||
| "tsx": "^4.20.6", | ||
| "@faremeter/fetch": "^0.11.0", | ||
| "@faremeter/info": "^0.11.0", | ||
| "@faremeter/middleware": "^0.11.0", | ||
| "@faremeter/payment-solana": "^0.11.0", | ||
| "@solana/web3.js": "^1.98.4", | ||
v1xingyue marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "@types/express": "^5.0.0", | ||
v1xingyue marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "dotenv": "^17.2.3", | ||
| "express": "^4.18.2", | ||
| "ts-node": "^10.9.2", | ||
v1xingyue marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "undici": "^7.16.0" | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.