create-x402-app 0.1.2 → 0.1.4
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/dist/index.js +54 -4
- package/package.json +2 -2
- package/templates/backend-express/README.md +56 -0
- package/templates/backend-express/env.example +8 -0
- package/templates/backend-express/gitignore +4 -0
- package/templates/backend-express/package.json +23 -0
- package/templates/backend-express/src/index.ts +79 -0
- package/templates/backend-express/tsconfig.json +18 -0
- package/templates/backend-hono/README.md +57 -0
- package/templates/backend-hono/env.example +8 -0
- package/templates/backend-hono/gitignore +4 -0
- package/templates/backend-hono/package.json +21 -0
- package/templates/backend-hono/src/index.ts +75 -0
- package/templates/backend-hono/tsconfig.json +18 -0
- package/templates/fullstack-express/README.md +308 -0
- package/templates/fullstack-express/_env.example +11 -0
- package/templates/fullstack-express/_gitignore +46 -0
- package/templates/fullstack-express/eslint.config.mjs +18 -0
- package/templates/fullstack-express/next-env.d.ts +6 -0
- package/templates/fullstack-express/next.config.ts +7 -0
- package/templates/fullstack-express/package.json +33 -0
- package/templates/fullstack-express/postcss.config.mjs +7 -0
- package/templates/fullstack-express/public/X402.png +0 -0
- package/templates/fullstack-express/src/app/api/info/route.ts +14 -0
- package/templates/fullstack-express/src/app/api/premium/route.ts +52 -0
- package/templates/fullstack-express/src/app/api/weather/route.ts +103 -0
- package/templates/fullstack-express/src/app/favicon.ico +0 -0
- package/templates/fullstack-express/src/app/globals.css +82 -0
- package/templates/fullstack-express/src/app/layout.tsx +42 -0
- package/templates/fullstack-express/src/app/page.tsx +511 -0
- package/templates/fullstack-express/src/components/grain-overlay.tsx +11 -0
- package/templates/fullstack-express/src/components/magnetic-button.tsx +90 -0
- package/templates/fullstack-express/src/components/ui/blur-fade.tsx +81 -0
- package/templates/fullstack-express/src/components/ui/magic-card.tsx +103 -0
- package/templates/fullstack-express/src/lib/utils.ts +6 -0
- package/templates/fullstack-express/src/types/ethereum.d.ts +11 -0
- package/templates/fullstack-express/tsconfig.json +34 -0
- package/templates/fullstack-hono/README.md +308 -0
- package/templates/fullstack-hono/_env.example +11 -0
- package/templates/fullstack-hono/_gitignore +46 -0
- package/templates/fullstack-hono/eslint.config.mjs +18 -0
- package/templates/fullstack-hono/next-env.d.ts +6 -0
- package/templates/fullstack-hono/next.config.ts +7 -0
- package/templates/fullstack-hono/package.json +33 -0
- package/templates/fullstack-hono/postcss.config.mjs +7 -0
- package/templates/fullstack-hono/public/X402.png +0 -0
- package/templates/fullstack-hono/src/app/api/info/route.ts +14 -0
- package/templates/fullstack-hono/src/app/api/premium/route.ts +52 -0
- package/templates/fullstack-hono/src/app/api/weather/route.ts +103 -0
- package/templates/fullstack-hono/src/app/favicon.ico +0 -0
- package/templates/fullstack-hono/src/app/globals.css +82 -0
- package/templates/fullstack-hono/src/app/layout.tsx +42 -0
- package/templates/fullstack-hono/src/app/page.tsx +511 -0
- package/templates/fullstack-hono/src/components/grain-overlay.tsx +11 -0
- package/templates/fullstack-hono/src/components/magnetic-button.tsx +90 -0
- package/templates/fullstack-hono/src/components/ui/blur-fade.tsx +81 -0
- package/templates/fullstack-hono/src/components/ui/magic-card.tsx +103 -0
- package/templates/fullstack-hono/src/lib/utils.ts +6 -0
- package/templates/fullstack-hono/src/types/ethereum.d.ts +11 -0
- package/templates/fullstack-hono/tsconfig.json +34 -0
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-x402-app",
|
|
34
|
-
version: "0.1.
|
|
34
|
+
version: "0.1.4",
|
|
35
35
|
description: "Create a new x402 pay-per-request API project",
|
|
36
36
|
keywords: [
|
|
37
37
|
"x402",
|
|
@@ -57,7 +57,7 @@ var require_package = __commonJS({
|
|
|
57
57
|
},
|
|
58
58
|
files: [
|
|
59
59
|
"dist",
|
|
60
|
-
"
|
|
60
|
+
"templates"
|
|
61
61
|
],
|
|
62
62
|
scripts: {
|
|
63
63
|
build: "tsup",
|
|
@@ -97,6 +97,53 @@ var packageJson = require_package();
|
|
|
97
97
|
function getTemplateDir(projectType, framework) {
|
|
98
98
|
return `${projectType}-${framework}`;
|
|
99
99
|
}
|
|
100
|
+
function getTemplatesDirectory() {
|
|
101
|
+
const possiblePaths = [
|
|
102
|
+
import_path.default.join(__dirname, "..", "templates"),
|
|
103
|
+
// When installed as package (most common)
|
|
104
|
+
import_path.default.join(__dirname, "templates")
|
|
105
|
+
// When running from source
|
|
106
|
+
];
|
|
107
|
+
for (const templatePath of possiblePaths) {
|
|
108
|
+
if (import_fs_extra.default.existsSync(templatePath)) {
|
|
109
|
+
return templatePath;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
let currentDir = __dirname;
|
|
113
|
+
let attempts = 0;
|
|
114
|
+
const maxAttempts = 10;
|
|
115
|
+
while (attempts < maxAttempts) {
|
|
116
|
+
const pkgPath = import_path.default.join(currentDir, "package.json");
|
|
117
|
+
if (import_fs_extra.default.existsSync(pkgPath)) {
|
|
118
|
+
try {
|
|
119
|
+
const pkg = import_fs_extra.default.readJsonSync(pkgPath);
|
|
120
|
+
if (pkg.name === "create-x402-app") {
|
|
121
|
+
const templatesPath = import_path.default.join(currentDir, "templates");
|
|
122
|
+
if (import_fs_extra.default.existsSync(templatesPath)) {
|
|
123
|
+
return templatesPath;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const parentDir = import_path.default.dirname(currentDir);
|
|
130
|
+
if (parentDir === currentDir) {
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
currentDir = parentDir;
|
|
134
|
+
attempts++;
|
|
135
|
+
}
|
|
136
|
+
const npxPaths = [
|
|
137
|
+
import_path.default.join(process.env.HOME || process.env.USERPROFILE || "", ".npm", "_npx", "templates"),
|
|
138
|
+
import_path.default.join(process.cwd(), "node_modules", "create-x402-app", "templates")
|
|
139
|
+
];
|
|
140
|
+
for (const templatePath of npxPaths) {
|
|
141
|
+
if (import_fs_extra.default.existsSync(templatePath)) {
|
|
142
|
+
return templatePath;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`Could not find templates directory. Searched from: ${__dirname}`);
|
|
146
|
+
}
|
|
100
147
|
function showBanner() {
|
|
101
148
|
return new Promise((resolve) => {
|
|
102
149
|
import_figlet.default.text("x402", {
|
|
@@ -288,15 +335,18 @@ async function main() {
|
|
|
288
335
|
}
|
|
289
336
|
const spinner = (0, import_ora.default)("Creating project...").start();
|
|
290
337
|
try {
|
|
291
|
-
const
|
|
338
|
+
const templatesDir = getTemplatesDirectory();
|
|
339
|
+
const templatePath = import_path.default.join(templatesDir, templateName);
|
|
292
340
|
if (!import_fs_extra.default.existsSync(templatePath)) {
|
|
293
341
|
spinner.fail(`Template not found: ${templateName}`);
|
|
294
342
|
console.log(import_chalk.default.yellow(`
|
|
295
343
|
Available templates:`));
|
|
296
|
-
const templatesDir = import_path.default.join(__dirname, "..", "templates");
|
|
297
344
|
if (import_fs_extra.default.existsSync(templatesDir)) {
|
|
298
345
|
const templates = import_fs_extra.default.readdirSync(templatesDir);
|
|
299
346
|
templates.forEach((t) => console.log(import_chalk.default.gray(` \u2022 ${t}`)));
|
|
347
|
+
} else {
|
|
348
|
+
console.log(import_chalk.default.red(`Templates directory not found at: ${templatesDir}`));
|
|
349
|
+
console.log(import_chalk.default.yellow(`__dirname: ${__dirname}`));
|
|
300
350
|
}
|
|
301
351
|
process.exit(1);
|
|
302
352
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-x402-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Create a new x402 pay-per-request API project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"x402",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
|
-
"
|
|
29
|
+
"templates"
|
|
30
30
|
],
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsup",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# x402 Backend - Express
|
|
2
|
+
|
|
3
|
+
A robust API server with pay-per-request endpoints using x402 on Mantle Network.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Configure environment
|
|
12
|
+
cp .env.example .env
|
|
13
|
+
# Edit .env with your App ID from https://mantle-x402.vercel.app
|
|
14
|
+
|
|
15
|
+
# Start development server
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Endpoints
|
|
20
|
+
|
|
21
|
+
| Endpoint | Price | Description |
|
|
22
|
+
|----------|-------|-------------|
|
|
23
|
+
| `GET /` | Free | API information |
|
|
24
|
+
| `GET /api/premium` | 0.001 MNT | Premium content |
|
|
25
|
+
| `GET /api/weather` | 0.0005 MNT | Weather data |
|
|
26
|
+
|
|
27
|
+
## Adding New Paid Endpoints
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { x402Express } from 'x402-mantle-sdk/server'
|
|
31
|
+
|
|
32
|
+
app.get(
|
|
33
|
+
'/api/my-endpoint',
|
|
34
|
+
x402Express({ price: '0.01', token: 'MNT', testnet: true }),
|
|
35
|
+
(req, res) => {
|
|
36
|
+
// Access payment info via req.x402
|
|
37
|
+
console.log('Payment verified:', req.x402.transactionHash)
|
|
38
|
+
res.json({ data: 'Your premium content' })
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Production
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Build
|
|
47
|
+
npm run build
|
|
48
|
+
|
|
49
|
+
# Start production server
|
|
50
|
+
npm start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Learn More
|
|
54
|
+
|
|
55
|
+
- [x402 Documentation](https://mantle-x402.vercel.app)
|
|
56
|
+
- [Express Documentation](https://expressjs.com)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "x402-backend-express",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "x402 API server with Express",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"cors": "^2.8.5",
|
|
13
|
+
"express": "^4.21.0",
|
|
14
|
+
"x402-mantle-sdk": "^0.2.3"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/cors": "^2.8.17",
|
|
18
|
+
"@types/express": "^4.17.21",
|
|
19
|
+
"@types/node": "^20.0.0",
|
|
20
|
+
"tsx": "^4.7.0",
|
|
21
|
+
"typescript": "^5.0.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import express from 'express'
|
|
2
|
+
import cors from 'cors'
|
|
3
|
+
import { x402Express } from 'x402-mantle-sdk/server'
|
|
4
|
+
|
|
5
|
+
const app = express()
|
|
6
|
+
|
|
7
|
+
// Middleware
|
|
8
|
+
app.use(cors())
|
|
9
|
+
app.use(express.json())
|
|
10
|
+
|
|
11
|
+
// Free endpoint - API info
|
|
12
|
+
app.get('/', (req, res) => {
|
|
13
|
+
res.json({
|
|
14
|
+
name: 'x402 API',
|
|
15
|
+
version: '1.0.0',
|
|
16
|
+
endpoints: {
|
|
17
|
+
info: 'GET / - API information (free)',
|
|
18
|
+
premium: 'GET /api/premium - Premium content (0.001 MNT)',
|
|
19
|
+
weather: 'GET /api/weather - Weather data (0.0005 MNT)',
|
|
20
|
+
},
|
|
21
|
+
network: 'mantle-sepolia',
|
|
22
|
+
docs: 'https://mantle-x402.vercel.app',
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Premium endpoint - requires 0.001 MNT
|
|
27
|
+
app.get(
|
|
28
|
+
'/api/premium',
|
|
29
|
+
x402Express({ price: '0.001', token: 'MNT', testnet: true }),
|
|
30
|
+
(req, res) => {
|
|
31
|
+
res.json({
|
|
32
|
+
success: true,
|
|
33
|
+
message: 'Premium content unlocked!',
|
|
34
|
+
data: {
|
|
35
|
+
secret: 'This is premium data that required payment.',
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
// Weather endpoint - requires 0.0005 MNT
|
|
43
|
+
app.get(
|
|
44
|
+
'/api/weather',
|
|
45
|
+
x402Express({ price: '0.0005', token: 'MNT', testnet: true }),
|
|
46
|
+
(req, res) => {
|
|
47
|
+
res.json({
|
|
48
|
+
success: true,
|
|
49
|
+
weather: {
|
|
50
|
+
location: 'San Francisco, CA',
|
|
51
|
+
temperature: 72,
|
|
52
|
+
unit: 'fahrenheit',
|
|
53
|
+
conditions: 'Sunny',
|
|
54
|
+
humidity: 45,
|
|
55
|
+
wind: '10 mph NW',
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
// Start server
|
|
62
|
+
const port = Number(process.env.PORT) || 3000
|
|
63
|
+
|
|
64
|
+
app.listen(port, () => {
|
|
65
|
+
console.log(`
|
|
66
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
67
|
+
║ x402 Express Server ║
|
|
68
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
69
|
+
║ Server running on http://localhost:${port} ║
|
|
70
|
+
║ ║
|
|
71
|
+
║ Endpoints: ║
|
|
72
|
+
║ GET / - API info (free) ║
|
|
73
|
+
║ GET /api/premium - Premium content (0.001 MNT) ║
|
|
74
|
+
║ GET /api/weather - Weather data (0.0005 MNT) ║
|
|
75
|
+
║ ║
|
|
76
|
+
║ Network: mantle-sepolia (testnet) ║
|
|
77
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
78
|
+
`)
|
|
79
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# x402 Backend - Hono
|
|
2
|
+
|
|
3
|
+
A lightweight API server with pay-per-request endpoints using x402 on Mantle Network.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Configure environment
|
|
12
|
+
cp .env.example .env
|
|
13
|
+
# Edit .env with your App ID from https://mantle-x402.vercel.app
|
|
14
|
+
|
|
15
|
+
# Start development server
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Endpoints
|
|
20
|
+
|
|
21
|
+
| Endpoint | Price | Description |
|
|
22
|
+
|----------|-------|-------------|
|
|
23
|
+
| `GET /` | Free | API information |
|
|
24
|
+
| `GET /api/premium` | 0.001 MNT | Premium content |
|
|
25
|
+
| `GET /api/weather` | 0.0005 MNT | Weather data |
|
|
26
|
+
|
|
27
|
+
## Adding New Paid Endpoints
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { x402 } from 'x402-mantle-sdk/server'
|
|
31
|
+
|
|
32
|
+
// Add middleware before the route handler
|
|
33
|
+
app.use('/api/my-endpoint', x402({
|
|
34
|
+
price: '0.01',
|
|
35
|
+
token: 'MNT',
|
|
36
|
+
testnet: true
|
|
37
|
+
}))
|
|
38
|
+
|
|
39
|
+
app.get('/api/my-endpoint', (c) => {
|
|
40
|
+
return c.json({ data: 'Your premium content' })
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Production
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Build
|
|
48
|
+
npm run build
|
|
49
|
+
|
|
50
|
+
# Start production server
|
|
51
|
+
npm start
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Learn More
|
|
55
|
+
|
|
56
|
+
- [x402 Documentation](https://mantle-x402.vercel.app)
|
|
57
|
+
- [Hono Documentation](https://hono.dev)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "x402-backend-hono",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "x402 API server with Hono",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@hono/node-server": "^1.13.0",
|
|
13
|
+
"hono": "^4.6.0",
|
|
14
|
+
"x402-mantle-sdk": "^0.2.3"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^20.0.0",
|
|
18
|
+
"tsx": "^4.7.0",
|
|
19
|
+
"typescript": "^5.0.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { serve } from '@hono/node-server'
|
|
2
|
+
import { Hono } from 'hono'
|
|
3
|
+
import { cors } from 'hono/cors'
|
|
4
|
+
import { logger } from 'hono/logger'
|
|
5
|
+
import { x402 } from 'x402-mantle-sdk/server'
|
|
6
|
+
|
|
7
|
+
const app = new Hono()
|
|
8
|
+
|
|
9
|
+
// Middleware
|
|
10
|
+
app.use('*', logger())
|
|
11
|
+
app.use('*', cors())
|
|
12
|
+
|
|
13
|
+
// Free endpoint - API info
|
|
14
|
+
app.get('/', (c) => {
|
|
15
|
+
return c.json({
|
|
16
|
+
name: 'x402 API',
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
endpoints: {
|
|
19
|
+
info: 'GET / - API information (free)',
|
|
20
|
+
premium: 'GET /api/premium - Premium content (0.001 MNT)',
|
|
21
|
+
weather: 'GET /api/weather - Weather data (0.0005 MNT)',
|
|
22
|
+
},
|
|
23
|
+
network: 'mantle-sepolia',
|
|
24
|
+
docs: 'https://mantle-x402.vercel.app',
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// Premium endpoint - requires 0.001 MNT
|
|
29
|
+
app.use('/api/premium', x402({ price: '0.001', token: 'MNT', testnet: true }))
|
|
30
|
+
app.get('/api/premium', (c) => {
|
|
31
|
+
return c.json({
|
|
32
|
+
success: true,
|
|
33
|
+
message: 'Premium content unlocked!',
|
|
34
|
+
data: {
|
|
35
|
+
secret: 'This is premium data that required payment.',
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Weather endpoint - requires 0.0005 MNT
|
|
42
|
+
app.use('/api/weather', x402({ price: '0.0005', token: 'MNT', testnet: true }))
|
|
43
|
+
app.get('/api/weather', (c) => {
|
|
44
|
+
return c.json({
|
|
45
|
+
success: true,
|
|
46
|
+
weather: {
|
|
47
|
+
location: 'San Francisco, CA',
|
|
48
|
+
temperature: 72,
|
|
49
|
+
unit: 'fahrenheit',
|
|
50
|
+
conditions: 'Sunny',
|
|
51
|
+
humidity: 45,
|
|
52
|
+
wind: '10 mph NW',
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// Start server
|
|
58
|
+
const port = Number(process.env.PORT) || 3000
|
|
59
|
+
|
|
60
|
+
console.log(`
|
|
61
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
62
|
+
║ x402 Hono Server ║
|
|
63
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
64
|
+
║ Server running on http://localhost:${port} ║
|
|
65
|
+
║ ║
|
|
66
|
+
║ Endpoints: ║
|
|
67
|
+
║ GET / - API info (free) ║
|
|
68
|
+
║ GET /api/premium - Premium content (0.001 MNT) ║
|
|
69
|
+
║ GET /api/weather - Weather data (0.0005 MNT) ║
|
|
70
|
+
║ ║
|
|
71
|
+
║ Network: mantle-sepolia (testnet) ║
|
|
72
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
73
|
+
`)
|
|
74
|
+
|
|
75
|
+
serve({ fetch: app.fetch, port })
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|