x402-mantle-sdk 0.1.0 → 0.2.1
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 +239 -44
- package/dist/client/index.cjs +40 -8
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +3 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.js +40 -8
- package/dist/client/index.js.map +1 -1
- package/dist/client/react.cjs +1178 -9
- package/dist/client/react.cjs.map +1 -1
- package/dist/client/react.d.cts +29 -1
- package/dist/client/react.d.ts +29 -1
- package/dist/client/react.js +1177 -9
- package/dist/client/react.js.map +1 -1
- package/dist/server/index.cjs +188 -34
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +80 -3
- package/dist/server/index.d.ts +80 -3
- package/dist/server/index.js +159 -7
- package/dist/server/index.js.map +1 -1
- package/package.json +15 -4
package/README.md
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
# @x402-devkit/sdk
|
|
2
2
|
|
|
3
|
-
Complete SDK for
|
|
3
|
+
> Complete SDK for monetizing APIs with HTTP 402 payments on Mantle Network
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@x402-devkit/sdk)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://mantle.xyz)
|
|
8
|
+
|
|
9
|
+
**@x402-devkit/sdk** enables developers to monetize APIs using HTTP 402 Payment Required status code with blockchain payments on Mantle Network. Protect your API routes, handle payments automatically, and track revenue—all with a few lines of code.
|
|
10
|
+
|
|
11
|
+
## ✨ Features
|
|
12
|
+
|
|
13
|
+
- 🚀 **Zero-Configuration Setup** - Get started in minutes
|
|
14
|
+
- 💰 **Automatic Payment Handling** - Seamless wallet integration
|
|
15
|
+
- 📊 **Real-Time Analytics** - Track endpoint usage and revenue
|
|
16
|
+
- 🔒 **Blockchain Verification** - On-chain payment validation
|
|
17
|
+
- 🎨 **Beautiful UI Components** - Ready-to-use React payment modals
|
|
18
|
+
- 🌐 **Multi-Token Support** - MNT, USDC, USDT, mETH, WMNT
|
|
19
|
+
- ⚡ **Ultra-Low Fees** - Gas costs under $0.001 on Mantle
|
|
20
|
+
- 🔄 **Auto Endpoint Tracking** - Endpoints appear in dashboard automatically
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
6
23
|
|
|
7
24
|
```bash
|
|
8
25
|
npm install @x402-devkit/sdk
|
|
9
26
|
```
|
|
10
27
|
|
|
11
|
-
## Quick Start
|
|
28
|
+
## 🚀 Quick Start
|
|
29
|
+
|
|
30
|
+
### 1. Create a Project
|
|
31
|
+
|
|
32
|
+
Visit the [x402 Dashboard](https://mantle-x402.vercel.app/dashboard) to create a project and get your `X402_APP_ID`.
|
|
12
33
|
|
|
13
|
-
###
|
|
34
|
+
### 2. Protect Your API Routes
|
|
14
35
|
|
|
15
36
|
```typescript
|
|
16
37
|
import { Hono } from 'hono'
|
|
@@ -18,7 +39,10 @@ import { x402 } from '@x402-devkit/sdk/server'
|
|
|
18
39
|
|
|
19
40
|
const app = new Hono()
|
|
20
41
|
|
|
21
|
-
//
|
|
42
|
+
// Set your project ID
|
|
43
|
+
process.env.X402_APP_ID = 'your-app-id-here'
|
|
44
|
+
|
|
45
|
+
// Protect any route with payment
|
|
22
46
|
app.use('/api/premium', x402({
|
|
23
47
|
price: '0.001',
|
|
24
48
|
token: 'MNT',
|
|
@@ -26,11 +50,11 @@ app.use('/api/premium', x402({
|
|
|
26
50
|
}))
|
|
27
51
|
|
|
28
52
|
app.get('/api/premium', (c) => {
|
|
29
|
-
return c.json({ data: 'Premium content' })
|
|
53
|
+
return c.json({ data: 'Premium content unlocked!' })
|
|
30
54
|
})
|
|
31
55
|
```
|
|
32
56
|
|
|
33
|
-
###
|
|
57
|
+
### 3. Handle Payments on Client
|
|
34
58
|
|
|
35
59
|
```typescript
|
|
36
60
|
import { x402Fetch } from '@x402-devkit/sdk/client'
|
|
@@ -40,7 +64,76 @@ const response = await x402Fetch('https://api.example.com/api/premium')
|
|
|
40
64
|
const data = await response.json()
|
|
41
65
|
```
|
|
42
66
|
|
|
43
|
-
|
|
67
|
+
**That's it!** Your API now accepts blockchain payments. 🎉
|
|
68
|
+
|
|
69
|
+
## 📖 Documentation
|
|
70
|
+
|
|
71
|
+
### Server Usage
|
|
72
|
+
|
|
73
|
+
#### Basic Middleware
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { x402 } from '@x402-devkit/sdk/server'
|
|
77
|
+
|
|
78
|
+
app.use('/api/data', x402({
|
|
79
|
+
price: '0.001',
|
|
80
|
+
token: 'MNT',
|
|
81
|
+
network: 'mantle' // or 'mantle-sepolia' for testnet
|
|
82
|
+
}))
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Advanced Options
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
app.use('/api/premium', x402({
|
|
89
|
+
price: '0.001',
|
|
90
|
+
token: 'USDC',
|
|
91
|
+
network: 'mantle',
|
|
92
|
+
endpoint: '/api/premium', // For dashboard tracking
|
|
93
|
+
method: 'GET', // For dashboard tracking
|
|
94
|
+
enableAnalytics: true // Auto-track payments (default: true)
|
|
95
|
+
}))
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Environment Variables
|
|
99
|
+
|
|
100
|
+
```env
|
|
101
|
+
# Required
|
|
102
|
+
X402_APP_ID=your-project-app-id
|
|
103
|
+
|
|
104
|
+
# Optional
|
|
105
|
+
X402_PLATFORM_URL=https://mantle-x402.vercel.app
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Client Usage
|
|
109
|
+
|
|
110
|
+
#### Automatic Payment Handling
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { x402Fetch } from '@x402-devkit/sdk/client'
|
|
114
|
+
|
|
115
|
+
// Automatically intercepts 402 responses and shows payment modal
|
|
116
|
+
const response = await x402Fetch('https://api.example.com/api/premium')
|
|
117
|
+
const data = await response.json()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### Custom Client Configuration
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { x402Client } from '@x402-devkit/sdk/client'
|
|
124
|
+
|
|
125
|
+
const client = x402Client({
|
|
126
|
+
autoRetry: true,
|
|
127
|
+
autoSwitchNetwork: true,
|
|
128
|
+
testnet: false
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
const response = await client.fetch('https://api.example.com/api/premium')
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### React Components
|
|
135
|
+
|
|
136
|
+
#### Basic Payment Modal
|
|
44
137
|
|
|
45
138
|
```tsx
|
|
46
139
|
import { PaymentModal } from '@x402-devkit/sdk/client/react'
|
|
@@ -54,7 +147,7 @@ function App() {
|
|
|
54
147
|
request={request}
|
|
55
148
|
isOpen={isOpen}
|
|
56
149
|
onComplete={(payment) => {
|
|
57
|
-
console.log('
|
|
150
|
+
console.log('Payment successful:', payment.transactionHash)
|
|
58
151
|
setIsOpen(false)
|
|
59
152
|
}}
|
|
60
153
|
onCancel={() => setIsOpen(false)}
|
|
@@ -63,41 +156,89 @@ function App() {
|
|
|
63
156
|
}
|
|
64
157
|
```
|
|
65
158
|
|
|
66
|
-
|
|
159
|
+
#### Enhanced Payment Modal
|
|
67
160
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- **React Components**: Ready-to-use payment modal
|
|
71
|
-
- **Mantle Network**: Native support for Mantle mainnet and testnet
|
|
72
|
-
- **Multiple Tokens**: Support for MNT, USDC, USDT, mETH, WMNT
|
|
73
|
-
- **Custom Networks**: Register custom networks and tokens
|
|
74
|
-
- **0.5% Platform Fee**: Automatic fee splitting to Treasury
|
|
161
|
+
```tsx
|
|
162
|
+
import { EnhancedPaymentModal } from '@x402-devkit/sdk/client/react'
|
|
75
163
|
|
|
76
|
-
|
|
164
|
+
function App() {
|
|
165
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
166
|
+
const [request, setRequest] = useState({
|
|
167
|
+
amount: '0.001',
|
|
168
|
+
token: 'MNT',
|
|
169
|
+
network: 'mantle',
|
|
170
|
+
recipient: '0x...',
|
|
171
|
+
description: 'Premium API access',
|
|
172
|
+
endpoint: '/api/premium-data'
|
|
173
|
+
})
|
|
77
174
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
175
|
+
return (
|
|
176
|
+
<EnhancedPaymentModal
|
|
177
|
+
request={request}
|
|
178
|
+
isOpen={isOpen}
|
|
179
|
+
onComplete={(payment) => {
|
|
180
|
+
console.log('Paid:', payment.transactionHash)
|
|
181
|
+
setIsOpen(false)
|
|
182
|
+
}}
|
|
183
|
+
onCancel={() => setIsOpen(false)}
|
|
184
|
+
description="Premium API access"
|
|
185
|
+
endpoint="/api/premium-data"
|
|
186
|
+
simulation={false} // Set to true for testing
|
|
187
|
+
/>
|
|
188
|
+
)
|
|
189
|
+
}
|
|
82
190
|
```
|
|
83
191
|
|
|
84
|
-
## Networks
|
|
192
|
+
## 🌐 Supported Networks
|
|
193
|
+
|
|
194
|
+
| Network | Chain ID | Status | Tokens |
|
|
195
|
+
|---------|----------|--------|--------|
|
|
196
|
+
| Mantle Mainnet | 5000 | ✅ Production | MNT, USDC, USDT, mETH, WMNT |
|
|
197
|
+
| Mantle Sepolia | 5003 | ✅ Testnet | MNT, USDC, mETH, WMNT |
|
|
198
|
+
|
|
199
|
+
## 💡 Use Cases
|
|
85
200
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
201
|
+
- **AI & LLM APIs** - Charge per token, per request, or per compute second
|
|
202
|
+
- **Data APIs** - Monetize datasets, market data, or proprietary information
|
|
203
|
+
- **Compute APIs** - Image processing, video transcoding, ML inference
|
|
204
|
+
- **Premium Content** - Articles, research, analysis with micropayments
|
|
205
|
+
- **IoT & Sensors** - Sell real-time sensor data with pay-per-read
|
|
90
206
|
|
|
91
|
-
##
|
|
207
|
+
## 📊 Dashboard & Analytics
|
|
208
|
+
|
|
209
|
+
All endpoints are automatically tracked in the [x402 Dashboard](https://mantle-x402.vercel.app/dashboard):
|
|
210
|
+
|
|
211
|
+
- **Automatic Endpoint Discovery** - Endpoints appear when first accessed
|
|
212
|
+
- **Real-Time Payment Tracking** - See payments as they happen
|
|
213
|
+
- **Revenue Analytics** - Track earnings per endpoint
|
|
214
|
+
- **Usage Statistics** - Monitor API usage patterns
|
|
215
|
+
|
|
216
|
+
## 🔧 API Reference
|
|
92
217
|
|
|
93
218
|
### Server Exports
|
|
94
219
|
|
|
95
220
|
```typescript
|
|
96
221
|
import {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
222
|
+
// Main middleware
|
|
223
|
+
x402,
|
|
224
|
+
|
|
225
|
+
// Payment verification
|
|
226
|
+
verifyPayment,
|
|
227
|
+
verifyPaymentOnChain,
|
|
228
|
+
|
|
229
|
+
// Network utilities
|
|
230
|
+
getNetworkConfig,
|
|
231
|
+
getTokenConfig,
|
|
232
|
+
registerCustomNetwork,
|
|
233
|
+
registerCustomTokens,
|
|
234
|
+
|
|
235
|
+
// Analytics
|
|
236
|
+
logPayment,
|
|
237
|
+
registerEndpoint,
|
|
238
|
+
|
|
239
|
+
// Platform
|
|
240
|
+
initializePlatform,
|
|
241
|
+
getProjectConfig,
|
|
101
242
|
} from '@x402-devkit/sdk/server'
|
|
102
243
|
```
|
|
103
244
|
|
|
@@ -105,26 +246,80 @@ import {
|
|
|
105
246
|
|
|
106
247
|
```typescript
|
|
107
248
|
import {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
249
|
+
// Fetch with 402 handling
|
|
250
|
+
x402Fetch,
|
|
251
|
+
x402Client,
|
|
252
|
+
|
|
253
|
+
// Wallet utilities
|
|
254
|
+
connectWallet,
|
|
255
|
+
detectWalletProvider,
|
|
256
|
+
ensureNetwork,
|
|
257
|
+
|
|
258
|
+
// Payment processing
|
|
259
|
+
processPayment,
|
|
260
|
+
|
|
261
|
+
// Constants
|
|
262
|
+
TREASURY_ADDRESS,
|
|
263
|
+
PLATFORM_FEE_BPS,
|
|
113
264
|
} from '@x402-devkit/sdk/client'
|
|
114
265
|
```
|
|
115
266
|
|
|
116
267
|
### React Exports
|
|
117
268
|
|
|
118
269
|
```typescript
|
|
119
|
-
import {
|
|
270
|
+
import {
|
|
271
|
+
PaymentModal, // Basic payment modal
|
|
272
|
+
EnhancedPaymentModal, // Enhanced modal with success states
|
|
273
|
+
} from '@x402-devkit/sdk/client/react'
|
|
120
274
|
```
|
|
121
275
|
|
|
122
|
-
##
|
|
276
|
+
## 🏗️ Architecture
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
@x402-devkit/sdk
|
|
280
|
+
├── /server # Server middleware (Hono, Express-compatible)
|
|
281
|
+
├── /client # Client SDK (fetch, wallet integration)
|
|
282
|
+
└── /client/react # React components (payment modals)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## 🔐 Security
|
|
286
|
+
|
|
287
|
+
- **On-Chain Verification** - All payments verified on blockchain
|
|
288
|
+
- **No Private Keys** - Wallet-based payments only
|
|
289
|
+
- **Idempotent Payments** - Duplicate transaction protection
|
|
290
|
+
- **Amount Tolerance** - Handles minor blockchain rounding
|
|
291
|
+
|
|
292
|
+
## 💰 Pricing & Fees
|
|
293
|
+
|
|
294
|
+
- **Platform Fee**: 0.5% (automatically split to Treasury)
|
|
295
|
+
- **Gas Costs**: < $0.001 per transaction on Mantle
|
|
296
|
+
- **No Hidden Fees**: Transparent fee structure
|
|
297
|
+
|
|
298
|
+
## 🤝 Contributing
|
|
299
|
+
|
|
300
|
+
Contributions are welcome! Please read our contributing guidelines first.
|
|
301
|
+
|
|
302
|
+
## 📄 License
|
|
303
|
+
|
|
304
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
305
|
+
|
|
306
|
+
## 🔗 Links
|
|
307
|
+
|
|
308
|
+
- **Dashboard**: [https://mantle-x402.vercel.app](https://mantle-x402.vercel.app)
|
|
309
|
+
- **Documentation**: [https://mantle-x402.vercel.app/dashboard?tab=docs](https://mantle-x402.vercel.app/dashboard?tab=docs)
|
|
310
|
+
- **GitHub**: [https://github.com/x402-devkit/x402](https://github.com/x402-devkit/x402)
|
|
311
|
+
- **Mantle Network**: [https://mantle.xyz](https://mantle.xyz)
|
|
312
|
+
|
|
313
|
+
## 🆘 Support
|
|
314
|
+
|
|
315
|
+
- **Issues**: [GitHub Issues](https://github.com/x402-devkit/x402/issues)
|
|
316
|
+
- **Discord**: [Join our community](https://discord.gg/x402)
|
|
317
|
+
- **Email**: support@x402.dev
|
|
318
|
+
|
|
319
|
+
## 🙏 Acknowledgments
|
|
123
320
|
|
|
124
|
-
|
|
125
|
-
- **Address**: `0xB27705342ACE73736AE490540Ea031cc06C3eF49`
|
|
126
|
-
- **Network**: Mantle Sepolia
|
|
321
|
+
Built for [Mantle Network](https://mantle.xyz) - the fastest and cheapest Layer 2 for Ethereum.
|
|
127
322
|
|
|
128
|
-
|
|
323
|
+
---
|
|
129
324
|
|
|
130
|
-
|
|
325
|
+
**Made with ❤️ for the Mantle ecosystem**
|
package/dist/client/index.cjs
CHANGED
|
@@ -293,11 +293,33 @@ var MetaMaskProvider = class {
|
|
|
293
293
|
if (!this.ethereum) {
|
|
294
294
|
throw new Error("MetaMask is not available");
|
|
295
295
|
}
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
|
|
296
|
+
const account = await this.getAccount();
|
|
297
|
+
if (!account) {
|
|
298
|
+
throw new Error("No account connected. Please connect your wallet first.");
|
|
299
|
+
}
|
|
300
|
+
const txWithFrom = {
|
|
301
|
+
...tx,
|
|
302
|
+
from: account
|
|
303
|
+
};
|
|
304
|
+
try {
|
|
305
|
+
const txHash = await this.ethereum.request({
|
|
306
|
+
method: "eth_sendTransaction",
|
|
307
|
+
params: [txWithFrom]
|
|
308
|
+
});
|
|
309
|
+
return txHash;
|
|
310
|
+
} catch (error) {
|
|
311
|
+
if (error.code === 4001) {
|
|
312
|
+
throw new Error("Transaction rejected by user");
|
|
313
|
+
} else if (error.code === -32602) {
|
|
314
|
+
throw new Error("Invalid transaction parameters");
|
|
315
|
+
} else if (error.message?.includes("insufficient funds") || error.message?.includes("insufficient balance")) {
|
|
316
|
+
throw new Error("Insufficient funds for this transaction");
|
|
317
|
+
} else if (error.message) {
|
|
318
|
+
throw new Error(error.message);
|
|
319
|
+
} else {
|
|
320
|
+
throw new Error(`Transaction failed: ${error.code || "Unknown error"}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
301
323
|
}
|
|
302
324
|
async signMessage(message) {
|
|
303
325
|
if (!this.ethereum) {
|
|
@@ -384,9 +406,15 @@ function encodeERC20Transfer(to, amount) {
|
|
|
384
406
|
return ERC20_TRANSFER_SIG + toHex + amountHex;
|
|
385
407
|
}
|
|
386
408
|
async function processPayment(request, wallet) {
|
|
409
|
+
if (!request.amount || !request.recipient || !request.network) {
|
|
410
|
+
throw new Error("Invalid payment request: missing required fields");
|
|
411
|
+
}
|
|
387
412
|
const tokenConfig = getTokenConfig(request.token, request.network);
|
|
388
413
|
const decimals = tokenConfig?.decimals ?? 18;
|
|
389
414
|
const totalAmount = amountToWei(request.amount, decimals);
|
|
415
|
+
if (totalAmount === 0n) {
|
|
416
|
+
throw new Error("Invalid payment amount: amount must be greater than 0");
|
|
417
|
+
}
|
|
390
418
|
const { merchantAmount, feeAmount } = calculateSplit(totalAmount);
|
|
391
419
|
let txHash;
|
|
392
420
|
if (tokenConfig) {
|
|
@@ -397,17 +425,21 @@ async function processPayment(request, wallet) {
|
|
|
397
425
|
};
|
|
398
426
|
txHash = await wallet.sendTransaction(tx);
|
|
399
427
|
} else {
|
|
428
|
+
const merchantValue = merchantAmount.toString(16);
|
|
400
429
|
const merchantTx = {
|
|
401
430
|
to: request.recipient,
|
|
402
|
-
value: `0x${
|
|
431
|
+
value: `0x${merchantValue}`
|
|
403
432
|
};
|
|
404
433
|
txHash = await wallet.sendTransaction(merchantTx);
|
|
405
434
|
if (feeAmount > 0n) {
|
|
435
|
+
const feeValue = feeAmount.toString(16);
|
|
406
436
|
const feeTx = {
|
|
407
437
|
to: TREASURY_ADDRESS,
|
|
408
|
-
value: `0x${
|
|
438
|
+
value: `0x${feeValue}`
|
|
409
439
|
};
|
|
410
|
-
|
|
440
|
+
wallet.sendTransaction(feeTx).catch((err) => {
|
|
441
|
+
console.warn("Fee transaction failed (non-critical):", err);
|
|
442
|
+
});
|
|
411
443
|
}
|
|
412
444
|
}
|
|
413
445
|
return {
|