@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.
- package/BUTTON_FIXES.md +59 -0
- package/DOCS_INDEX.md +332 -0
- package/DOCUMENTATION.md +252 -0
- package/DOCUMENTATION_BUILD_SUMMARY.md +376 -0
- package/DOCUMENTATION_COMPLETE.md +311 -0
- package/FEATURES.md +333 -0
- package/Lumina-sdk/src/components/lumina-provider.tsx +46 -0
- package/Lumina-sdk/src/components/transaction-confirm.tsx +242 -0
- package/Lumina-sdk/src/components/wallet-display.tsx +157 -0
- package/Lumina-sdk/src/components/wallet-login.tsx +163 -0
- package/Lumina-sdk/src/hooks/use-mobile.ts +19 -0
- package/Lumina-sdk/src/hooks/use-toast.ts +191 -0
- package/Lumina-sdk/src/index.ts +0 -0
- package/Lumina-sdk/src/lib/api.ts +66 -0
- package/Lumina-sdk/src/lib/utils.ts +6 -0
- package/Lumina-sdk/src/package.json +42 -0
- package/Lumina-sdk/src/tsconfig.json +19 -0
- package/NEW_FILES_MANIFEST.txt +146 -0
- package/README.md +298 -0
- package/app/dashboard/analytics/page.tsx +218 -0
- package/app/dashboard/api-keys/page.tsx +260 -0
- package/app/dashboard/billing/page.tsx +412 -0
- package/app/dashboard/integration/page.tsx +185 -0
- package/app/dashboard/layout.tsx +18 -0
- package/app/dashboard/page.tsx +244 -0
- package/app/dashboard/settings/page.tsx +285 -0
- package/app/dashboard/users/page.tsx +148 -0
- package/app/docs/api/authentication/page.tsx +246 -0
- package/app/docs/api/endpoints/page.tsx +397 -0
- package/app/docs/api/errors/page.tsx +305 -0
- package/app/docs/api/overview/page.tsx +306 -0
- package/app/docs/examples/basic-setup/page.tsx +256 -0
- package/app/docs/examples/multi-chain/page.tsx +331 -0
- package/app/docs/examples/nextjs-full-stack/page.tsx +332 -0
- package/app/docs/getting-started/environment-setup/page.tsx +243 -0
- package/app/docs/getting-started/installation/page.tsx +187 -0
- package/app/docs/getting-started/introduction/page.tsx +178 -0
- package/app/docs/getting-started/quick-start/page.tsx +199 -0
- package/app/docs/guides/nextjs/page.tsx +358 -0
- package/app/docs/guides/react/page.tsx +230 -0
- package/app/docs/guides/security/page.tsx +284 -0
- package/app/docs/layout.tsx +32 -0
- package/app/docs/page.tsx +180 -0
- package/app/docs/sdk/lumina-provider/page.tsx +186 -0
- package/app/docs/sdk/transaction-confirm/page.tsx +331 -0
- package/app/docs/sdk/wallet-display/page.tsx +224 -0
- package/app/docs/sdk/wallet-login/page.tsx +207 -0
- package/app/docs/troubleshooting/common-issues/page.tsx +301 -0
- package/app/docs/troubleshooting/faq/page.tsx +105 -0
- package/app/globals.css +125 -0
- package/app/invite/[token]/page.tsx +78 -0
- package/app/layout.tsx +36 -0
- package/app/login/page.tsx +175 -0
- package/app/page.tsx +336 -0
- package/app/sdk-demo/page.tsx +239 -0
- package/components/dashboard-sidebar.tsx +113 -0
- package/components/docs/breadcrumb.tsx +51 -0
- package/components/docs/callout.tsx +53 -0
- package/components/docs/code-block.tsx +77 -0
- package/components/docs/docs-sidebar.tsx +214 -0
- package/components/docs/table-of-contents.tsx +83 -0
- package/components/sdk/lumina-provider.tsx +46 -0
- package/components/sdk/transaction-confirm.tsx +242 -0
- package/components/sdk/wallet-display.tsx +157 -0
- package/components/sdk/wallet-login.tsx +163 -0
- package/components/theme-provider.tsx +11 -0
- package/components/ui/accordion.tsx +66 -0
- package/components/ui/alert-dialog.tsx +157 -0
- package/components/ui/alert.tsx +66 -0
- package/components/ui/aspect-ratio.tsx +11 -0
- package/components/ui/avatar.tsx +53 -0
- package/components/ui/badge.tsx +46 -0
- package/components/ui/breadcrumb.tsx +109 -0
- package/components/ui/button-group.tsx +83 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/calendar.tsx +213 -0
- package/components/ui/card.tsx +92 -0
- package/components/ui/carousel.tsx +241 -0
- package/components/ui/chart.tsx +351 -0
- package/components/ui/checkbox.tsx +32 -0
- package/components/ui/collapsible.tsx +33 -0
- package/components/ui/command.tsx +184 -0
- package/components/ui/context-menu.tsx +252 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/drawer.tsx +135 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/empty.tsx +104 -0
- package/components/ui/field.tsx +244 -0
- package/components/ui/form.tsx +167 -0
- package/components/ui/hover-card.tsx +44 -0
- package/components/ui/input-group.tsx +169 -0
- package/components/ui/input-otp.tsx +77 -0
- package/components/ui/input.tsx +21 -0
- package/components/ui/item.tsx +193 -0
- package/components/ui/kbd.tsx +28 -0
- package/components/ui/label.tsx +24 -0
- package/components/ui/menubar.tsx +276 -0
- package/components/ui/navigation-menu.tsx +166 -0
- package/components/ui/pagination.tsx +127 -0
- package/components/ui/popover.tsx +48 -0
- package/components/ui/progress.tsx +31 -0
- package/components/ui/radio-group.tsx +45 -0
- package/components/ui/resizable.tsx +56 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/select.tsx +185 -0
- package/components/ui/separator.tsx +28 -0
- package/components/ui/sheet.tsx +139 -0
- package/components/ui/sidebar.tsx +726 -0
- package/components/ui/skeleton.tsx +13 -0
- package/components/ui/slider.tsx +59 -0
- package/components/ui/sonner.tsx +25 -0
- package/components/ui/spinner.tsx +16 -0
- package/components/ui/switch.tsx +29 -0
- package/components/ui/table.tsx +116 -0
- package/components/ui/tabs.tsx +66 -0
- package/components/ui/textarea.tsx +18 -0
- package/components/ui/toast.tsx +129 -0
- package/components/ui/toaster.tsx +35 -0
- package/components/ui/toggle-group.tsx +73 -0
- package/components/ui/toggle.tsx +47 -0
- package/components/ui/tooltip.tsx +61 -0
- package/components/ui/use-mobile.tsx +19 -0
- package/components/ui/use-toast.ts +191 -0
- package/components.json +21 -0
- package/hooks/use-mobile.ts +19 -0
- package/hooks/use-toast.ts +191 -0
- package/lib/api.ts +66 -0
- package/lib/utils.ts +6 -0
- package/next-env.d.ts +6 -0
- package/next.config.mjs +11 -0
- package/package.json +73 -0
- package/pnpm-workspace.yaml +5 -0
- package/postcss.config.mjs +8 -0
- package/public/apple-icon.png +0 -0
- package/public/fav.jpeg +0 -0
- package/public/fav.png +0 -0
- package/public/icon-dark-32x32.png +0 -0
- package/public/icon-light-32x32.png +0 -0
- package/public/icon.png +0 -0
- package/public/icon.svg +26 -0
- package/public/logo.jpeg +0 -0
- package/public/logo.png +0 -0
- package/public/logo2.jpeg +0 -0
- package/public/logo2.png +0 -0
- package/public/placeholder-logo.png +0 -0
- package/public/placeholder-logo.svg +1 -0
- package/public/placeholder-user.jpg +0 -0
- package/public/placeholder.jpg +0 -0
- package/public/placeholder.svg +1 -0
- package/styles/globals.css +209 -0
- package/tailwind.config.ts +15 -0
- 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'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'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'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
|
+
}
|