create-x402-app 0.1.7 → 0.1.9

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 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.7",
34
+ version: "0.1.9",
35
35
  description: "Create a new x402 pay-per-request API project",
36
36
  keywords: [
37
37
  "x402",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-x402-app",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Create a new x402 pay-per-request API project",
5
5
  "keywords": [
6
6
  "x402",
@@ -1,52 +1,100 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
- import { processPaymentMiddleware, initializePlatform } from 'x402-mantle-sdk/server'
2
+ import { processPaymentMiddleware, initializePlatform, clearCache } from 'x402-mantle-sdk/server'
3
+
4
+ // Configuration - Set these in your .env file
5
+ const appId = process.env.X402_APP_ID || ''
6
+ const platformUrl = process.env.X402_PLATFORM_URL || 'https://mantle-x402.vercel.app'
7
+
8
+ if (!process.env.X402_APP_ID) {
9
+ process.env.X402_APP_ID = appId
10
+ }
11
+ if (!process.env.X402_PLATFORM_URL) {
12
+ process.env.X402_PLATFORM_URL = platformUrl
13
+ }
3
14
 
4
15
  let initialized = false
16
+ let initError: Error | null = null
5
17
 
6
- export async function GET(request: NextRequest) {
7
- // Initialize platform once
8
- if (!initialized) {
18
+ const initPlatform = async () => {
19
+ try {
9
20
  await initializePlatform()
10
21
  initialized = true
22
+ initError = null
23
+ } catch (error) {
24
+ initError = error as Error
25
+ console.error('Platform initialization failed:', error)
11
26
  }
27
+ }
12
28
 
13
- // Convert headers to plain object
14
- const headers: Record<string, string> = {}
15
- request.headers.forEach((value, key) => {
16
- headers[key] = value
17
- })
18
-
19
- // Process payment - returns 402 if payment required
20
- const result = await processPaymentMiddleware(
21
- { price: '0.001', token: 'MNT', testnet: true },
22
- headers
23
- )
24
-
25
- // Payment required - return 402 with payment details
26
- if (result.paymentRequired) {
27
- const response = NextResponse.json(result.paymentRequired.body, { status: 402 })
28
- Object.entries(result.paymentRequired.headers).forEach(([key, value]) => {
29
- response.headers.set(key, value)
30
- })
31
- return response
32
- }
29
+ export async function GET(request: NextRequest) {
30
+ try {
31
+ // Initialize platform on first request
32
+ if (!initialized && !initError) {
33
+ await initPlatform()
34
+ } else if (initError) {
35
+ try { clearCache() } catch {}
36
+ initError = null
37
+ await initPlatform()
38
+ }
33
39
 
34
- // Payment verified - return premium content
35
- if (result.allowed) {
36
- return NextResponse.json({
37
- success: true,
38
- message: 'Premium content unlocked!',
39
- data: {
40
- secret: 'This is premium data that required payment.',
41
- timestamp: new Date().toISOString(),
42
- },
40
+ if (initError) {
41
+ return NextResponse.json(
42
+ { error: 'Platform initialization failed', details: (initError as Error).message },
43
+ { status: 500 }
44
+ )
45
+ }
46
+
47
+ // Payment options
48
+ const paymentOptions = {
49
+ price: '0.001',
50
+ token: 'MNT',
51
+ testnet: true,
52
+ }
53
+
54
+ // Convert headers to plain object
55
+ const headers: Record<string, string> = {}
56
+ request.headers.forEach((value, key) => {
57
+ headers[key] = value
43
58
  })
44
- }
45
59
 
46
- // Error handling
47
- if (result.error) {
48
- return NextResponse.json({ error: result.error.message }, { status: result.error.status })
49
- }
60
+ // Process payment middleware
61
+ const result = await processPaymentMiddleware(paymentOptions, headers)
50
62
 
51
- return NextResponse.json({ error: 'Unexpected error' }, { status: 500 })
63
+ // Payment required - return 402 with payment details
64
+ if (result.paymentRequired) {
65
+ const response = NextResponse.json(result.paymentRequired.body, { status: 402 })
66
+ Object.entries(result.paymentRequired.headers).forEach(([key, value]) => {
67
+ response.headers.set(key, value)
68
+ })
69
+ return response
70
+ }
71
+
72
+ // Error
73
+ if (result.error) {
74
+ return NextResponse.json(
75
+ { error: result.error.message },
76
+ { status: result.error.status }
77
+ )
78
+ }
79
+
80
+ // Payment verified - return premium content
81
+ if (result.allowed) {
82
+ return NextResponse.json({
83
+ success: true,
84
+ message: 'Premium content unlocked!',
85
+ data: {
86
+ secret: 'This is premium data that required payment.',
87
+ timestamp: new Date().toISOString(),
88
+ },
89
+ })
90
+ }
91
+
92
+ return NextResponse.json({ error: 'Unexpected error' }, { status: 500 })
93
+ } catch (error) {
94
+ console.error('Error in premium route:', error)
95
+ return NextResponse.json(
96
+ { error: 'Internal server error', message: error instanceof Error ? error.message : 'Unknown error' },
97
+ { status: 500 }
98
+ )
99
+ }
52
100
  }
@@ -144,7 +144,18 @@ export default function Home() {
144
144
  const res = await fetch(`${API_BASE}${endpoint}`)
145
145
 
146
146
  if (res.status === 402) {
147
- const body = await res.json().catch(() => ({}))
147
+ let body = {}
148
+ const contentType = res.headers.get("content-type")
149
+ if (contentType && contentType.includes("application/json")) {
150
+ try {
151
+ const text = await res.text()
152
+ if (text.trim()) {
153
+ body = JSON.parse(text)
154
+ }
155
+ } catch {
156
+ // Ignore JSON parse errors, use empty object
157
+ }
158
+ }
148
159
 
149
160
  const amount = res.headers.get("x-402-amount") || body.amount || "0"
150
161
  const token = res.headers.get("x-402-token") || body.token || "MNT"
@@ -165,7 +176,22 @@ export default function Home() {
165
176
  return
166
177
  }
167
178
 
168
- const data = await res.json()
179
+ let data = {}
180
+ const contentType = res.headers.get("content-type")
181
+ if (contentType && contentType.includes("application/json")) {
182
+ try {
183
+ const text = await res.text()
184
+ if (text.trim()) {
185
+ data = JSON.parse(text)
186
+ }
187
+ } catch (err) {
188
+ setError("Failed to parse response as JSON")
189
+ return
190
+ }
191
+ } else {
192
+ const text = await res.text()
193
+ data = { message: text || "Request successful" }
194
+ }
169
195
  setResponse(data)
170
196
  } catch (err) {
171
197
  setError(err instanceof Error ? err.message : "Request failed")
@@ -193,7 +219,23 @@ export default function Home() {
193
219
  "X-402-Transaction-Hash": payment.transactionHash,
194
220
  },
195
221
  })
196
- const data = await res.json()
222
+
223
+ let data = {}
224
+ const contentType = res.headers.get("content-type")
225
+ if (contentType && contentType.includes("application/json")) {
226
+ try {
227
+ const text = await res.text()
228
+ if (text.trim()) {
229
+ data = JSON.parse(text)
230
+ }
231
+ } catch {
232
+ lastError = "Failed to parse response"
233
+ continue
234
+ }
235
+ } else {
236
+ const text = await res.text()
237
+ data = { message: text || "Request successful" }
238
+ }
197
239
 
198
240
  if (res.ok) {
199
241
  setResponse(data)
@@ -231,7 +273,24 @@ export default function Home() {
231
273
 
232
274
  try {
233
275
  const res = await fetch(`${API_BASE}${endpoint}`)
234
- const data = await res.json()
276
+
277
+ let data = {}
278
+ const contentType = res.headers.get("content-type")
279
+ if (contentType && contentType.includes("application/json")) {
280
+ try {
281
+ const text = await res.text()
282
+ if (text.trim()) {
283
+ data = JSON.parse(text)
284
+ }
285
+ } catch (err) {
286
+ setError("Failed to parse response as JSON")
287
+ return
288
+ }
289
+ } else {
290
+ const text = await res.text()
291
+ data = { message: text || "Request successful" }
292
+ }
293
+
235
294
  setResponse(data)
236
295
  } catch (err) {
237
296
  setError(err instanceof Error ? err.message : "Request failed")
@@ -1,52 +1,100 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
- import { processPaymentMiddleware, initializePlatform } from 'x402-mantle-sdk/server'
2
+ import { processPaymentMiddleware, initializePlatform, clearCache } from 'x402-mantle-sdk/server'
3
+
4
+ // Configuration - Set these in your .env file
5
+ const appId = process.env.X402_APP_ID || ''
6
+ const platformUrl = process.env.X402_PLATFORM_URL || 'https://mantle-x402.vercel.app'
7
+
8
+ if (!process.env.X402_APP_ID) {
9
+ process.env.X402_APP_ID = appId
10
+ }
11
+ if (!process.env.X402_PLATFORM_URL) {
12
+ process.env.X402_PLATFORM_URL = platformUrl
13
+ }
3
14
 
4
15
  let initialized = false
16
+ let initError: Error | null = null
5
17
 
6
- export async function GET(request: NextRequest) {
7
- // Initialize platform once
8
- if (!initialized) {
18
+ const initPlatform = async () => {
19
+ try {
9
20
  await initializePlatform()
10
21
  initialized = true
22
+ initError = null
23
+ } catch (error) {
24
+ initError = error as Error
25
+ console.error('Platform initialization failed:', error)
11
26
  }
27
+ }
12
28
 
13
- // Convert headers to plain object
14
- const headers: Record<string, string> = {}
15
- request.headers.forEach((value, key) => {
16
- headers[key] = value
17
- })
18
-
19
- // Process payment - returns 402 if payment required
20
- const result = await processPaymentMiddleware(
21
- { price: '0.001', token: 'MNT', testnet: true },
22
- headers
23
- )
24
-
25
- // Payment required - return 402 with payment details
26
- if (result.paymentRequired) {
27
- const response = NextResponse.json(result.paymentRequired.body, { status: 402 })
28
- Object.entries(result.paymentRequired.headers).forEach(([key, value]) => {
29
- response.headers.set(key, value)
30
- })
31
- return response
32
- }
29
+ export async function GET(request: NextRequest) {
30
+ try {
31
+ // Initialize platform on first request
32
+ if (!initialized && !initError) {
33
+ await initPlatform()
34
+ } else if (initError) {
35
+ try { clearCache() } catch {}
36
+ initError = null
37
+ await initPlatform()
38
+ }
33
39
 
34
- // Payment verified - return premium content
35
- if (result.allowed) {
36
- return NextResponse.json({
37
- success: true,
38
- message: 'Premium content unlocked!',
39
- data: {
40
- secret: 'This is premium data that required payment.',
41
- timestamp: new Date().toISOString(),
42
- },
40
+ if (initError) {
41
+ return NextResponse.json(
42
+ { error: 'Platform initialization failed', details: (initError as Error).message },
43
+ { status: 500 }
44
+ )
45
+ }
46
+
47
+ // Payment options
48
+ const paymentOptions = {
49
+ price: '0.001',
50
+ token: 'MNT',
51
+ testnet: true,
52
+ }
53
+
54
+ // Convert headers to plain object
55
+ const headers: Record<string, string> = {}
56
+ request.headers.forEach((value, key) => {
57
+ headers[key] = value
43
58
  })
44
- }
45
59
 
46
- // Error handling
47
- if (result.error) {
48
- return NextResponse.json({ error: result.error.message }, { status: result.error.status })
49
- }
60
+ // Process payment middleware
61
+ const result = await processPaymentMiddleware(paymentOptions, headers)
50
62
 
51
- return NextResponse.json({ error: 'Unexpected error' }, { status: 500 })
63
+ // Payment required - return 402 with payment details
64
+ if (result.paymentRequired) {
65
+ const response = NextResponse.json(result.paymentRequired.body, { status: 402 })
66
+ Object.entries(result.paymentRequired.headers).forEach(([key, value]) => {
67
+ response.headers.set(key, value)
68
+ })
69
+ return response
70
+ }
71
+
72
+ // Error
73
+ if (result.error) {
74
+ return NextResponse.json(
75
+ { error: result.error.message },
76
+ { status: result.error.status }
77
+ )
78
+ }
79
+
80
+ // Payment verified - return premium content
81
+ if (result.allowed) {
82
+ return NextResponse.json({
83
+ success: true,
84
+ message: 'Premium content unlocked!',
85
+ data: {
86
+ secret: 'This is premium data that required payment.',
87
+ timestamp: new Date().toISOString(),
88
+ },
89
+ })
90
+ }
91
+
92
+ return NextResponse.json({ error: 'Unexpected error' }, { status: 500 })
93
+ } catch (error) {
94
+ console.error('Error in premium route:', error)
95
+ return NextResponse.json(
96
+ { error: 'Internal server error', message: error instanceof Error ? error.message : 'Unknown error' },
97
+ { status: 500 }
98
+ )
99
+ }
52
100
  }
@@ -144,7 +144,18 @@ export default function Home() {
144
144
  const res = await fetch(`${API_BASE}${endpoint}`)
145
145
 
146
146
  if (res.status === 402) {
147
- const body = await res.json().catch(() => ({}))
147
+ let body = {}
148
+ const contentType = res.headers.get("content-type")
149
+ if (contentType && contentType.includes("application/json")) {
150
+ try {
151
+ const text = await res.text()
152
+ if (text.trim()) {
153
+ body = JSON.parse(text)
154
+ }
155
+ } catch {
156
+ // Ignore JSON parse errors, use empty object
157
+ }
158
+ }
148
159
 
149
160
  const amount = res.headers.get("x-402-amount") || body.amount || "0"
150
161
  const token = res.headers.get("x-402-token") || body.token || "MNT"
@@ -165,7 +176,22 @@ export default function Home() {
165
176
  return
166
177
  }
167
178
 
168
- const data = await res.json()
179
+ let data = {}
180
+ const contentType = res.headers.get("content-type")
181
+ if (contentType && contentType.includes("application/json")) {
182
+ try {
183
+ const text = await res.text()
184
+ if (text.trim()) {
185
+ data = JSON.parse(text)
186
+ }
187
+ } catch (err) {
188
+ setError("Failed to parse response as JSON")
189
+ return
190
+ }
191
+ } else {
192
+ const text = await res.text()
193
+ data = { message: text || "Request successful" }
194
+ }
169
195
  setResponse(data)
170
196
  } catch (err) {
171
197
  setError(err instanceof Error ? err.message : "Request failed")
@@ -193,7 +219,23 @@ export default function Home() {
193
219
  "X-402-Transaction-Hash": payment.transactionHash,
194
220
  },
195
221
  })
196
- const data = await res.json()
222
+
223
+ let data = {}
224
+ const contentType = res.headers.get("content-type")
225
+ if (contentType && contentType.includes("application/json")) {
226
+ try {
227
+ const text = await res.text()
228
+ if (text.trim()) {
229
+ data = JSON.parse(text)
230
+ }
231
+ } catch {
232
+ lastError = "Failed to parse response"
233
+ continue
234
+ }
235
+ } else {
236
+ const text = await res.text()
237
+ data = { message: text || "Request successful" }
238
+ }
197
239
 
198
240
  if (res.ok) {
199
241
  setResponse(data)
@@ -231,7 +273,24 @@ export default function Home() {
231
273
 
232
274
  try {
233
275
  const res = await fetch(`${API_BASE}${endpoint}`)
234
- const data = await res.json()
276
+
277
+ let data = {}
278
+ const contentType = res.headers.get("content-type")
279
+ if (contentType && contentType.includes("application/json")) {
280
+ try {
281
+ const text = await res.text()
282
+ if (text.trim()) {
283
+ data = JSON.parse(text)
284
+ }
285
+ } catch (err) {
286
+ setError("Failed to parse response as JSON")
287
+ return
288
+ }
289
+ } else {
290
+ const text = await res.text()
291
+ data = { message: text || "Request successful" }
292
+ }
293
+
235
294
  setResponse(data)
236
295
  } catch (err) {
237
296
  setError(err instanceof Error ? err.message : "Request failed")