@jerydam/lumina-sdk 0.1.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.
Files changed (152) hide show
  1. package/BUTTON_FIXES.md +59 -0
  2. package/DOCS_INDEX.md +332 -0
  3. package/DOCUMENTATION.md +252 -0
  4. package/DOCUMENTATION_BUILD_SUMMARY.md +376 -0
  5. package/DOCUMENTATION_COMPLETE.md +311 -0
  6. package/FEATURES.md +333 -0
  7. package/Lumina-sdk/src/components/lumina-provider.tsx +46 -0
  8. package/Lumina-sdk/src/components/transaction-confirm.tsx +242 -0
  9. package/Lumina-sdk/src/components/wallet-display.tsx +157 -0
  10. package/Lumina-sdk/src/components/wallet-login.tsx +163 -0
  11. package/Lumina-sdk/src/hooks/use-mobile.ts +19 -0
  12. package/Lumina-sdk/src/hooks/use-toast.ts +191 -0
  13. package/Lumina-sdk/src/index.ts +0 -0
  14. package/Lumina-sdk/src/lib/api.ts +66 -0
  15. package/Lumina-sdk/src/lib/utils.ts +6 -0
  16. package/Lumina-sdk/src/package.json +42 -0
  17. package/Lumina-sdk/src/tsconfig.json +19 -0
  18. package/NEW_FILES_MANIFEST.txt +146 -0
  19. package/README.md +298 -0
  20. package/app/dashboard/analytics/page.tsx +218 -0
  21. package/app/dashboard/api-keys/page.tsx +260 -0
  22. package/app/dashboard/billing/page.tsx +412 -0
  23. package/app/dashboard/integration/page.tsx +185 -0
  24. package/app/dashboard/layout.tsx +18 -0
  25. package/app/dashboard/page.tsx +244 -0
  26. package/app/dashboard/settings/page.tsx +285 -0
  27. package/app/dashboard/users/page.tsx +148 -0
  28. package/app/docs/api/authentication/page.tsx +246 -0
  29. package/app/docs/api/endpoints/page.tsx +397 -0
  30. package/app/docs/api/errors/page.tsx +305 -0
  31. package/app/docs/api/overview/page.tsx +306 -0
  32. package/app/docs/examples/basic-setup/page.tsx +256 -0
  33. package/app/docs/examples/multi-chain/page.tsx +331 -0
  34. package/app/docs/examples/nextjs-full-stack/page.tsx +332 -0
  35. package/app/docs/getting-started/environment-setup/page.tsx +243 -0
  36. package/app/docs/getting-started/installation/page.tsx +187 -0
  37. package/app/docs/getting-started/introduction/page.tsx +178 -0
  38. package/app/docs/getting-started/quick-start/page.tsx +199 -0
  39. package/app/docs/guides/nextjs/page.tsx +358 -0
  40. package/app/docs/guides/react/page.tsx +230 -0
  41. package/app/docs/guides/security/page.tsx +284 -0
  42. package/app/docs/layout.tsx +32 -0
  43. package/app/docs/page.tsx +180 -0
  44. package/app/docs/sdk/lumina-provider/page.tsx +186 -0
  45. package/app/docs/sdk/transaction-confirm/page.tsx +331 -0
  46. package/app/docs/sdk/wallet-display/page.tsx +224 -0
  47. package/app/docs/sdk/wallet-login/page.tsx +207 -0
  48. package/app/docs/troubleshooting/common-issues/page.tsx +301 -0
  49. package/app/docs/troubleshooting/faq/page.tsx +105 -0
  50. package/app/globals.css +125 -0
  51. package/app/invite/[token]/page.tsx +78 -0
  52. package/app/layout.tsx +36 -0
  53. package/app/login/page.tsx +175 -0
  54. package/app/page.tsx +336 -0
  55. package/app/sdk-demo/page.tsx +239 -0
  56. package/components/dashboard-sidebar.tsx +113 -0
  57. package/components/docs/breadcrumb.tsx +51 -0
  58. package/components/docs/callout.tsx +53 -0
  59. package/components/docs/code-block.tsx +77 -0
  60. package/components/docs/docs-sidebar.tsx +214 -0
  61. package/components/docs/table-of-contents.tsx +83 -0
  62. package/components/sdk/lumina-provider.tsx +46 -0
  63. package/components/sdk/transaction-confirm.tsx +242 -0
  64. package/components/sdk/wallet-display.tsx +157 -0
  65. package/components/sdk/wallet-login.tsx +163 -0
  66. package/components/theme-provider.tsx +11 -0
  67. package/components/ui/accordion.tsx +66 -0
  68. package/components/ui/alert-dialog.tsx +157 -0
  69. package/components/ui/alert.tsx +66 -0
  70. package/components/ui/aspect-ratio.tsx +11 -0
  71. package/components/ui/avatar.tsx +53 -0
  72. package/components/ui/badge.tsx +46 -0
  73. package/components/ui/breadcrumb.tsx +109 -0
  74. package/components/ui/button-group.tsx +83 -0
  75. package/components/ui/button.tsx +60 -0
  76. package/components/ui/calendar.tsx +213 -0
  77. package/components/ui/card.tsx +92 -0
  78. package/components/ui/carousel.tsx +241 -0
  79. package/components/ui/chart.tsx +351 -0
  80. package/components/ui/checkbox.tsx +32 -0
  81. package/components/ui/collapsible.tsx +33 -0
  82. package/components/ui/command.tsx +184 -0
  83. package/components/ui/context-menu.tsx +252 -0
  84. package/components/ui/dialog.tsx +143 -0
  85. package/components/ui/drawer.tsx +135 -0
  86. package/components/ui/dropdown-menu.tsx +257 -0
  87. package/components/ui/empty.tsx +104 -0
  88. package/components/ui/field.tsx +244 -0
  89. package/components/ui/form.tsx +167 -0
  90. package/components/ui/hover-card.tsx +44 -0
  91. package/components/ui/input-group.tsx +169 -0
  92. package/components/ui/input-otp.tsx +77 -0
  93. package/components/ui/input.tsx +21 -0
  94. package/components/ui/item.tsx +193 -0
  95. package/components/ui/kbd.tsx +28 -0
  96. package/components/ui/label.tsx +24 -0
  97. package/components/ui/menubar.tsx +276 -0
  98. package/components/ui/navigation-menu.tsx +166 -0
  99. package/components/ui/pagination.tsx +127 -0
  100. package/components/ui/popover.tsx +48 -0
  101. package/components/ui/progress.tsx +31 -0
  102. package/components/ui/radio-group.tsx +45 -0
  103. package/components/ui/resizable.tsx +56 -0
  104. package/components/ui/scroll-area.tsx +58 -0
  105. package/components/ui/select.tsx +185 -0
  106. package/components/ui/separator.tsx +28 -0
  107. package/components/ui/sheet.tsx +139 -0
  108. package/components/ui/sidebar.tsx +726 -0
  109. package/components/ui/skeleton.tsx +13 -0
  110. package/components/ui/slider.tsx +59 -0
  111. package/components/ui/sonner.tsx +25 -0
  112. package/components/ui/spinner.tsx +16 -0
  113. package/components/ui/switch.tsx +29 -0
  114. package/components/ui/table.tsx +116 -0
  115. package/components/ui/tabs.tsx +66 -0
  116. package/components/ui/textarea.tsx +18 -0
  117. package/components/ui/toast.tsx +129 -0
  118. package/components/ui/toaster.tsx +35 -0
  119. package/components/ui/toggle-group.tsx +73 -0
  120. package/components/ui/toggle.tsx +47 -0
  121. package/components/ui/tooltip.tsx +61 -0
  122. package/components/ui/use-mobile.tsx +19 -0
  123. package/components/ui/use-toast.ts +191 -0
  124. package/components.json +21 -0
  125. package/hooks/use-mobile.ts +19 -0
  126. package/hooks/use-toast.ts +191 -0
  127. package/lib/api.ts +66 -0
  128. package/lib/utils.ts +6 -0
  129. package/next-env.d.ts +6 -0
  130. package/next.config.mjs +11 -0
  131. package/package.json +73 -0
  132. package/pnpm-workspace.yaml +5 -0
  133. package/postcss.config.mjs +8 -0
  134. package/public/apple-icon.png +0 -0
  135. package/public/fav.jpeg +0 -0
  136. package/public/fav.png +0 -0
  137. package/public/icon-dark-32x32.png +0 -0
  138. package/public/icon-light-32x32.png +0 -0
  139. package/public/icon.png +0 -0
  140. package/public/icon.svg +26 -0
  141. package/public/logo.jpeg +0 -0
  142. package/public/logo.png +0 -0
  143. package/public/logo2.jpeg +0 -0
  144. package/public/logo2.png +0 -0
  145. package/public/placeholder-logo.png +0 -0
  146. package/public/placeholder-logo.svg +1 -0
  147. package/public/placeholder-user.jpg +0 -0
  148. package/public/placeholder.jpg +0 -0
  149. package/public/placeholder.svg +1 -0
  150. package/styles/globals.css +209 -0
  151. package/tailwind.config.ts +15 -0
  152. package/tsconfig.json +41 -0
@@ -0,0 +1,199 @@
1
+ import { Breadcrumb } from '@/components/docs/breadcrumb'
2
+ import { CodeBlock } from '@/components/docs/code-block'
3
+ import { Callout } from '@/components/docs/callout'
4
+
5
+ export const metadata = {
6
+ title: 'Quick Start - Lumina Documentation',
7
+ description: 'Get up and running with Lumina in 5 minutes.',
8
+ }
9
+
10
+ export default function QuickStartPage() {
11
+ return (
12
+ <>
13
+ <Breadcrumb />
14
+
15
+ <div className="space-y-8">
16
+ <div className="space-y-4">
17
+ <h1 className="text-4xl font-bold text-white">Quick Start</h1>
18
+ <p className="text-lg text-foreground/80">
19
+ Build your first Lumina integration in 5 minutes. This guide covers the essential steps to get users logging in and transacting.
20
+ </p>
21
+ </div>
22
+
23
+ <Callout type="info">
24
+ This guide assumes you&apos;ve already installed Lumina. If not, start with <a href="/docs/getting-started/installation" className="text-emerald-400 hover:underline">Installation</a>.
25
+ </Callout>
26
+
27
+ <div className="space-y-4">
28
+ <h2 className="text-2xl font-bold">Step 1: Create a Login Page</h2>
29
+ <p className="text-foreground/80 mb-4">
30
+ Use the <code className="bg-white/10 px-2 py-1 rounded text-sm">WalletLogin</code> component to add authentication:
31
+ </p>
32
+
33
+ <CodeBlock
34
+ code={`'use client'
35
+
36
+ import { WalletLogin } from '@lumina/sdk'
37
+
38
+ export default function LoginPage() {
39
+ const handleLoginSuccess = (user) => {
40
+ console.log('User logged in:', user)
41
+ // Redirect to dashboard
42
+ }
43
+
44
+ return (
45
+ <div className="flex items-center justify-center min-h-screen">
46
+ <WalletLogin
47
+ onSuccess={handleLoginSuccess}
48
+ authMethods={['email', 'passkey', 'google']}
49
+ />
50
+ </div>
51
+ )
52
+ }`}
53
+ language="tsx"
54
+ title="app/login/page.tsx"
55
+ />
56
+ </div>
57
+
58
+ <div className="space-y-4">
59
+ <h2 className="text-2xl font-bold">Step 2: Display Wallet Balance</h2>
60
+ <p className="text-foreground/80 mb-4">
61
+ Once logged in, show the user&apos;s wallet using the <code className="bg-white/10 px-2 py-1 rounded text-sm">WalletDisplay</code> component:
62
+ </p>
63
+
64
+ <CodeBlock
65
+ code={`'use client'
66
+
67
+ import { WalletDisplay, useLumina } from '@lumina/sdk'
68
+
69
+ export default function WalletPage() {
70
+ const { user, logout } = useLumina()
71
+
72
+ if (!user) {
73
+ return <div>Loading...</div>
74
+ }
75
+
76
+ return (
77
+ <div className="p-8">
78
+ <h1>Your Wallet</h1>
79
+ <WalletDisplay
80
+ address={user.walletAddress}
81
+ balance={user.balance}
82
+ network="ethereum"
83
+ onLogout={logout}
84
+ />
85
+ </div>
86
+ )
87
+ }`}
88
+ language="tsx"
89
+ title="app/wallet/page.tsx"
90
+ />
91
+ </div>
92
+
93
+ <div className="space-y-4">
94
+ <h2 className="text-2xl font-bold">Step 3: Add a Transaction Button</h2>
95
+ <p className="text-foreground/80 mb-4">
96
+ Enable users to send transactions with <code className="bg-white/10 px-2 py-1 rounded text-sm">TransactionConfirm</code>:
97
+ </p>
98
+
99
+ <CodeBlock
100
+ code={`'use client'
101
+
102
+ import { TransactionConfirm, useLumina } from '@lumina/sdk'
103
+ import { useState } from 'react'
104
+
105
+ export default function SendPage() {
106
+ const { user } = useLumina()
107
+ const [showConfirm, setShowConfirm] = useState(false)
108
+
109
+ const transaction = {
110
+ to: '0x742d35Cc6634C0532925a3b844Bc1e8181f42f9f',
111
+ value: '0.1', // ETH
112
+ network: 'ethereum',
113
+ }
114
+
115
+ const handleSend = async () => {
116
+ setShowConfirm(true)
117
+ }
118
+
119
+ const handleConfirm = async (txHash) => {
120
+ console.log('Transaction sent:', txHash)
121
+ setShowConfirm(false)
122
+ }
123
+
124
+ return (
125
+ <div className="p-8">
126
+ <button
127
+ onClick={handleSend}
128
+ className="px-4 py-2 bg-emerald-600 rounded-lg hover:bg-emerald-700"
129
+ >
130
+ Send 0.1 ETH
131
+ </button>
132
+
133
+ {showConfirm && (
134
+ <TransactionConfirm
135
+ transaction={transaction}
136
+ onConfirm={handleConfirm}
137
+ onCancel={() => setShowConfirm(false)}
138
+ />
139
+ )}
140
+ </div>
141
+ )
142
+ }`}
143
+ language="tsx"
144
+ title="app/send/page.tsx"
145
+ />
146
+ </div>
147
+
148
+ <div className="space-y-4">
149
+ <h2 className="text-2xl font-bold">Step 4: Test Locally</h2>
150
+ <p className="text-foreground/80 mb-4">
151
+ Start your dev server and test your integration:
152
+ </p>
153
+
154
+ <CodeBlock
155
+ code="npm run dev"
156
+ language="bash"
157
+ />
158
+
159
+ <p className="text-foreground/80 text-sm">
160
+ Your app is now running at <code className="bg-white/10 px-2 py-1 rounded">http://localhost:3000</code>. Visit the login page and try authenticating!
161
+ </p>
162
+ </div>
163
+
164
+ <Callout type="info" title="Testing on Testnet">
165
+ For development, we recommend using testnet networks (Sepolia for Ethereum, Goerli, etc.). Set <code className="bg-black/40 px-2 py-1 rounded text-xs">NEXT_PUBLIC_LUMINA_NETWORK=testnet</code> in your environment variables.
166
+ </Callout>
167
+
168
+ <div className="space-y-4">
169
+ <h2 className="text-2xl font-bold">What&apos;s Next?</h2>
170
+ <p className="text-foreground/80 mb-4">
171
+ Now that you have a working integration, explore:
172
+ </p>
173
+ <ul className="space-y-2 text-foreground/80 text-sm">
174
+ <li className="flex gap-3">
175
+ <span className="text-emerald-400">▸</span>
176
+ <a href="/docs/sdk/wallet-login" className="text-emerald-400 hover:underline">Advanced WalletLogin options</a> - Custom styling and auth flows
177
+ </li>
178
+ <li className="flex gap-3">
179
+ <span className="text-emerald-400">▸</span>
180
+ <a href="/docs/guides/security" className="text-emerald-400 hover:underline">Security best practices</a> - Protect your users
181
+ </li>
182
+ <li className="flex gap-3">
183
+ <span className="text-emerald-400">▸</span>
184
+ <a href="/docs/api/transactions" className="text-emerald-400 hover:underline">Transaction API</a> - Advanced transaction handling
185
+ </li>
186
+ <li className="flex gap-3">
187
+ <span className="text-emerald-400">▸</span>
188
+ <a href="/docs/guides/multi-chain" className="text-emerald-400 hover:underline">Multi-chain support</a> - Support multiple networks
189
+ </li>
190
+ </ul>
191
+ </div>
192
+
193
+ <Callout type="success" title="You're Ready!">
194
+ You've successfully integrated Lumina into your app. Check out the <a href="/docs/examples" className="text-emerald-400 hover:underline">Examples</a> section for more complex use cases.
195
+ </Callout>
196
+ </div>
197
+ </>
198
+ )
199
+ }
@@ -0,0 +1,358 @@
1
+ 'use client'
2
+
3
+ import { Breadcrumb } from '@/components/docs/breadcrumb'
4
+ import { TableOfContents } from '@/components/docs/table-of-contents'
5
+ import { CodeBlock } from '@/components/docs/code-block'
6
+ import { Callout } from '@/components/docs/callout'
7
+
8
+ export default function NextjsGuidePage() {
9
+ const headings = [
10
+ { id: 'setup', level: 2, text: 'Setup' },
11
+ { id: 'app-router', level: 2, text: 'App Router Integration' },
12
+ { id: 'pages-router', level: 2, text: 'Pages Router Integration' },
13
+ { id: 'api-routes', level: 2, text: 'API Routes' },
14
+ { id: 'middleware', level: 2, text: 'Middleware' },
15
+ { id: 'best-practices', level: 2, text: 'Best Practices' },
16
+ ]
17
+
18
+ return (
19
+ <div className="flex gap-8 max-w-7xl mx-auto px-4 py-8">
20
+ <main className="flex-1 min-w-0">
21
+ <Breadcrumb
22
+ items={[
23
+ { label: 'Docs', href: '/docs' },
24
+ { label: 'Guides', href: '/docs/guides/react' },
25
+ { label: 'Next.js' },
26
+ ]}
27
+ />
28
+
29
+ <div className="mt-8 prose prose-invert max-w-none">
30
+ <h1>Next.js Integration Guide</h1>
31
+
32
+ <p className="text-lg text-foreground/80">
33
+ Complete guide to integrating Lumina wallet with Next.js applications using both App Router and Pages Router.
34
+ </p>
35
+
36
+ <h2 id="setup">Setup</h2>
37
+
38
+ <CodeBlock
39
+ code={`# Install dependencies
40
+ npm install @lumina/react
41
+
42
+ # Or with pnpm
43
+ pnpm add @lumina/react`}
44
+ language="bash"
45
+ title="Installation"
46
+ />
47
+
48
+ <h2 id="app-router">App Router Integration</h2>
49
+
50
+ <h3>Create Provider Component</h3>
51
+ <CodeBlock
52
+ code={`// app/providers.tsx
53
+ 'use client'
54
+
55
+ import { ReactNode } from 'react'
56
+ import { LuminaProvider } from '@lumina/react'
57
+
58
+ export function Providers({ children }: { children: ReactNode }) {
59
+ return (
60
+ <LuminaProvider
61
+ publicKey={process.env.NEXT_PUBLIC_LUMINA_PUBLIC_KEY!}
62
+ network="ethereum"
63
+ >
64
+ {children}
65
+ </LuminaProvider>
66
+ )
67
+ }`}
68
+ language="typescript"
69
+ title="Provider"
70
+ />
71
+
72
+ <h3>Root Layout</h3>
73
+ <CodeBlock
74
+ code={`// app/layout.tsx
75
+ import { Providers } from './providers'
76
+
77
+ export default function RootLayout({
78
+ children,
79
+ }: {
80
+ children: React.ReactNode
81
+ }) {
82
+ return (
83
+ <html lang="en">
84
+ <body>
85
+ <Providers>{children}</Providers>
86
+ </body>
87
+ </html>
88
+ )
89
+ }`}
90
+ language="typescript"
91
+ title="Layout"
92
+ />
93
+
94
+ <h3>Use in Pages</h3>
95
+ <CodeBlock
96
+ code={`// app/wallet/page.tsx
97
+ 'use client'
98
+
99
+ import { WalletDisplay, WalletLogin } from '@lumina/react'
100
+ import { useState } from 'react'
101
+
102
+ export default function WalletPage() {
103
+ const [isLoggedIn, setIsLoggedIn] = useState(false)
104
+
105
+ return (
106
+ <div>
107
+ {!isLoggedIn ? (
108
+ <WalletLogin
109
+ onSuccess={() => setIsLoggedIn(true)}
110
+ />
111
+ ) : (
112
+ <WalletDisplay />
113
+ )}
114
+ </div>
115
+ )
116
+ }`}
117
+ language="typescript"
118
+ title="Page Component"
119
+ />
120
+
121
+ <h2 id="pages-router">Pages Router Integration</h2>
122
+
123
+ <h3>Custom App</h3>
124
+ <CodeBlock
125
+ code={`// pages/_app.tsx
126
+ import type { AppProps } from 'next/app'
127
+ import { LuminaProvider } from '@lumina/react'
128
+
129
+ function MyApp({ Component, pageProps }: AppProps) {
130
+ return (
131
+ <LuminaProvider
132
+ publicKey={process.env.NEXT_PUBLIC_LUMINA_PUBLIC_KEY!}
133
+ network="ethereum"
134
+ >
135
+ <Component {...pageProps} />
136
+ </LuminaProvider>
137
+ )
138
+ }
139
+
140
+ export default MyApp`}
141
+ language="typescript"
142
+ title="App Component"
143
+ />
144
+
145
+ <h3>Pages Router Page</h3>
146
+ <CodeBlock
147
+ code={`// pages/wallet.tsx
148
+ import { WalletDisplay, WalletLogin } from '@lumina/react'
149
+ import { useState } from 'react'
150
+
151
+ export default function WalletPage() {
152
+ const [isLoggedIn, setIsLoggedIn] = useState(false)
153
+
154
+ return (
155
+ <div>
156
+ {!isLoggedIn ? (
157
+ <WalletLogin onSuccess={() => setIsLoggedIn(true)} />
158
+ ) : (
159
+ <WalletDisplay />
160
+ )}
161
+ </div>
162
+ )
163
+ }`}
164
+ language="typescript"
165
+ title="Page"
166
+ />
167
+
168
+ <h2 id="api-routes">API Routes</h2>
169
+
170
+ <h3>Create Wallet</h3>
171
+ <CodeBlock
172
+ code={`// app/api/wallets/route.ts
173
+ import { NextRequest, NextResponse } from 'next/server'
174
+
175
+ export async function POST(request: NextRequest) {
176
+ try {
177
+ const { userId } = await request.json()
178
+
179
+ const response = await fetch(
180
+ 'https://api.lumina.dev/v1/wallets',
181
+ {
182
+ method: 'POST',
183
+ headers: {
184
+ 'Authorization': \`Bearer \${process.env.LUMINA_SECRET_KEY}\`,
185
+ 'Content-Type': 'application/json',
186
+ },
187
+ body: JSON.stringify({
188
+ user_id: userId,
189
+ network: 'ethereum',
190
+ }),
191
+ }
192
+ )
193
+
194
+ const data = await response.json()
195
+
196
+ if (!response.ok) {
197
+ return NextResponse.json(
198
+ { error: data.error.message },
199
+ { status: response.status }
200
+ )
201
+ }
202
+
203
+ return NextResponse.json(data.data)
204
+ } catch (error) {
205
+ return NextResponse.json(
206
+ { error: 'Failed to create wallet' },
207
+ { status: 500 }
208
+ )
209
+ }
210
+ }`}
211
+ language="typescript"
212
+ title="Create Wallet Route"
213
+ />
214
+
215
+ <h3>Confirm Transaction</h3>
216
+ <CodeBlock
217
+ code={`// app/api/transactions/confirm/route.ts
218
+ import { NextRequest, NextResponse } from 'next/server'
219
+
220
+ export async function POST(request: NextRequest) {
221
+ try {
222
+ const { transactionId, signature, nonce } = await request.json()
223
+
224
+ const response = await fetch(
225
+ \`https://api.lumina.dev/v1/transactions/\${transactionId}/confirm\`,
226
+ {
227
+ method: 'POST',
228
+ headers: {
229
+ 'Authorization': \`Bearer \${process.env.LUMINA_SECRET_KEY}\`,
230
+ 'Content-Type': 'application/json',
231
+ },
232
+ body: JSON.stringify({ signature, nonce }),
233
+ }
234
+ )
235
+
236
+ const data = await response.json()
237
+
238
+ if (!response.ok) {
239
+ return NextResponse.json(
240
+ { error: data.error.message },
241
+ { status: response.status }
242
+ )
243
+ }
244
+
245
+ return NextResponse.json(data.data)
246
+ } catch (error) {
247
+ return NextResponse.json(
248
+ { error: 'Failed to confirm transaction' },
249
+ { status: 500 }
250
+ )
251
+ }
252
+ }`}
253
+ language="typescript"
254
+ title="Confirm Transaction Route"
255
+ />
256
+
257
+ <h2 id="middleware">Middleware</h2>
258
+
259
+ <CodeBlock
260
+ code={`// middleware.ts
261
+ import { NextRequest, NextResponse } from 'next/server'
262
+
263
+ export function middleware(request: NextRequest) {
264
+ // Add custom headers
265
+ const requestHeaders = new Headers(request.headers)
266
+ requestHeaders.set('x-lumina-timestamp', new Date().toISOString())
267
+
268
+ // Protect wallet routes
269
+ if (request.nextUrl.pathname.startsWith('/wallet')) {
270
+ const token = request.cookies.get('wallet_token')
271
+ if (!token) {
272
+ return NextResponse.redirect(new URL('/login', request.url))
273
+ }
274
+ }
275
+
276
+ return NextResponse.next({
277
+ request: {
278
+ headers: requestHeaders,
279
+ },
280
+ })
281
+ }
282
+
283
+ export const config = {
284
+ matcher: ['/wallet/:path*', '/api/wallets/:path*'],
285
+ }`}
286
+ language="typescript"
287
+ title="Middleware Example"
288
+ />
289
+
290
+ <h2 id="best-practices">Best Practices</h2>
291
+
292
+ <h3>Environment Variables</h3>
293
+ <CodeBlock
294
+ code={`# .env.local
295
+ NEXT_PUBLIC_LUMINA_PUBLIC_KEY=pk_live_abc123...
296
+ LUMINA_SECRET_KEY=sk_live_xyz789...
297
+ NEXT_PUBLIC_LUMINA_API_URL=https://api.lumina.dev
298
+ NEXT_PUBLIC_LUMINA_NETWORK=ethereum`}
299
+ language="bash"
300
+ title=".env.local"
301
+ />
302
+
303
+ <h3>Error Handling in API Routes</h3>
304
+ <CodeBlock
305
+ code={`// lib/lumina.ts
306
+ export async function callLuminaAPI(
307
+ endpoint: string,
308
+ options: RequestInit
309
+ ) {
310
+ const response = await fetch(
311
+ \`https://api.lumina.dev/v1\${endpoint}\`,
312
+ {
313
+ ...options,
314
+ headers: {
315
+ 'Authorization': \`Bearer \${process.env.LUMINA_SECRET_KEY}\`,
316
+ 'Content-Type': 'application/json',
317
+ ...options.headers,
318
+ },
319
+ }
320
+ )
321
+
322
+ const data = await response.json()
323
+
324
+ if (!response.ok) {
325
+ throw new Error(data.error.message)
326
+ }
327
+
328
+ return data.data
329
+ }`}
330
+ language="typescript"
331
+ title="Helper Function"
332
+ />
333
+
334
+ <Callout type="info">
335
+ Use the App Router for new Next.js projects. It provides better performance and uses React Server Components.
336
+ </Callout>
337
+
338
+ <Callout type="warning">
339
+ Never expose your secret API key in client-side code. Always use API routes for server-side operations.
340
+ </Callout>
341
+ </div>
342
+
343
+ <div className="flex justify-between mt-12 pt-8 border-t border-white/10">
344
+ <a href="/docs/guides/react" className="text-emerald-400 hover:text-emerald-300">
345
+ ← React Guide
346
+ </a>
347
+ <a href="/docs/examples/nextjs-full-stack" className="text-emerald-400 hover:text-emerald-300">
348
+ Full Stack Example →
349
+ </a>
350
+ </div>
351
+ </main>
352
+
353
+ <aside className="hidden lg:block w-64 flex-shrink-0">
354
+ <TableOfContents headings={headings} />
355
+ </aside>
356
+ </div>
357
+ )
358
+ }