@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,230 @@
|
|
|
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: 'React Integration Guide - Lumina Docs',
|
|
7
|
+
description: 'Complete guide to integrating Lumina SDK with React applications.',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function ReactGuidePage() {
|
|
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">React Integration</h1>
|
|
18
|
+
<p className="text-lg text-foreground/80">
|
|
19
|
+
Step-by-step guide to integrating Lumina with React. This guide covers setup, authentication, and transaction handling.
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div className="space-y-4">
|
|
24
|
+
<h2 className="text-2xl font-bold">Installation</h2>
|
|
25
|
+
<CodeBlock
|
|
26
|
+
code="npm install @lumina/sdk @lumina/react"
|
|
27
|
+
language="bash"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div className="space-y-4">
|
|
32
|
+
<h2 className="text-2xl font-bold">1. Wrap with LuminaProvider</h2>
|
|
33
|
+
<CodeBlock
|
|
34
|
+
code={`import React from 'react'
|
|
35
|
+
import { LuminaProvider } from '@lumina/react'
|
|
36
|
+
import App from './App'
|
|
37
|
+
|
|
38
|
+
export default function Root() {
|
|
39
|
+
return (
|
|
40
|
+
<LuminaProvider
|
|
41
|
+
apiKey={process.env.REACT_APP_LUMINA_API_KEY}
|
|
42
|
+
network="mainnet"
|
|
43
|
+
>
|
|
44
|
+
<App />
|
|
45
|
+
</LuminaProvider>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Render the root component
|
|
50
|
+
// ReactDOM.createRoot(document.getElementById('root')).render(<Root />)`}
|
|
51
|
+
language="tsx"
|
|
52
|
+
title="main.tsx or index.tsx"
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div className="space-y-4">
|
|
57
|
+
<h2 className="text-2xl font-bold">2. Use Hooks in Components</h2>
|
|
58
|
+
<CodeBlock
|
|
59
|
+
code={`'use client'
|
|
60
|
+
|
|
61
|
+
import { useLumina } from '@lumina/react'
|
|
62
|
+
|
|
63
|
+
export default function Dashboard() {
|
|
64
|
+
const { user, isConnected, logout } = useLumina()
|
|
65
|
+
|
|
66
|
+
if (!isConnected) {
|
|
67
|
+
return <div>Please connect your wallet</div>
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div>
|
|
72
|
+
<h1>Welcome, {user?.email}!</h1>
|
|
73
|
+
<p>Address: {user?.walletAddress}</p>
|
|
74
|
+
<button onClick={logout}>Logout</button>
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
}`}
|
|
78
|
+
language="tsx"
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div className="space-y-4">
|
|
83
|
+
<h2 className="text-2xl font-bold">3. Authentication Flow</h2>
|
|
84
|
+
<CodeBlock
|
|
85
|
+
code={`import { WalletLogin } from '@lumina/react'
|
|
86
|
+
import { useNavigate } from 'react-router-dom'
|
|
87
|
+
|
|
88
|
+
export default function LoginPage() {
|
|
89
|
+
const navigate = useNavigate()
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<WalletLogin
|
|
93
|
+
onSuccess={(user) => {
|
|
94
|
+
console.log('Logged in:', user)
|
|
95
|
+
navigate('/dashboard')
|
|
96
|
+
}}
|
|
97
|
+
authMethods={['email', 'passkey', 'google']}
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
100
|
+
}`}
|
|
101
|
+
language="tsx"
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<Callout type="info" title="React Router Integration">
|
|
106
|
+
Lumina works seamlessly with React Router. Use the <code className="bg-black/40 px-2 py-1 rounded text-xs">useNavigate</code> hook in the <code className="bg-black/40 px-2 py-1 rounded text-xs">onSuccess</code> callback to redirect after authentication.
|
|
107
|
+
</Callout>
|
|
108
|
+
|
|
109
|
+
<div className="space-y-4">
|
|
110
|
+
<h2 className="text-2xl font-bold">4. Protected Routes</h2>
|
|
111
|
+
<CodeBlock
|
|
112
|
+
code={`import { useLumina } from '@lumina/react'
|
|
113
|
+
import { Navigate } from 'react-router-dom'
|
|
114
|
+
|
|
115
|
+
export function ProtectedRoute({ children }) {
|
|
116
|
+
const { isConnected } = useLumina()
|
|
117
|
+
|
|
118
|
+
if (!isConnected) {
|
|
119
|
+
return <Navigate to="/login" replace />
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return children
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Usage
|
|
126
|
+
<ProtectedRoute>
|
|
127
|
+
<Dashboard />
|
|
128
|
+
</ProtectedRoute>`}
|
|
129
|
+
language="tsx"
|
|
130
|
+
/>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div className="space-y-4">
|
|
134
|
+
<h2 className="text-2xl font-bold">5. Handling Transactions</h2>
|
|
135
|
+
<CodeBlock
|
|
136
|
+
code={`import { useLumina, TransactionConfirm } from '@lumina/react'
|
|
137
|
+
import { useState } from 'react'
|
|
138
|
+
|
|
139
|
+
export function SendFunds() {
|
|
140
|
+
const { user } = useLumina()
|
|
141
|
+
const [isPending, setIsPending] = useState(false)
|
|
142
|
+
const [txHash, setTxHash] = useState<string | null>(null)
|
|
143
|
+
|
|
144
|
+
const handleSend = async () => {
|
|
145
|
+
const tx = {
|
|
146
|
+
to: '0x742d35Cc6634C0532925a3b844Bc1e8181f42f9f',
|
|
147
|
+
value: '0.1',
|
|
148
|
+
network: 'ethereum',
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
setIsPending(true)
|
|
152
|
+
try {
|
|
153
|
+
const result = await user?.sendTransaction(tx)
|
|
154
|
+
setTxHash(result?.hash)
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Transaction failed:', error)
|
|
157
|
+
} finally {
|
|
158
|
+
setIsPending(false)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div>
|
|
164
|
+
<button onClick={handleSend} disabled={isPending}>
|
|
165
|
+
{isPending ? 'Processing...' : 'Send 0.1 ETH'}
|
|
166
|
+
</button>
|
|
167
|
+
{txHash && <p>Transaction: {txHash}</p>}
|
|
168
|
+
</div>
|
|
169
|
+
)
|
|
170
|
+
}`}
|
|
171
|
+
language="tsx"
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<div className="space-y-4">
|
|
176
|
+
<h2 className="text-2xl font-bold">Complete Example App</h2>
|
|
177
|
+
<CodeBlock
|
|
178
|
+
code={`import React, { useState } from 'react'
|
|
179
|
+
import { LuminaProvider, WalletLogin, useLumina } from '@lumina/react'
|
|
180
|
+
|
|
181
|
+
function Dashboard() {
|
|
182
|
+
const { user, logout } = useLumina()
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<div className="p-8">
|
|
186
|
+
<h1>Dashboard</h1>
|
|
187
|
+
<p>Welcome, {user?.email}</p>
|
|
188
|
+
<p>Balance: {user?.balance} ETH</p>
|
|
189
|
+
<button onClick={logout}>Logout</button>
|
|
190
|
+
</div>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function LoginPage({ onSuccess }) {
|
|
195
|
+
return (
|
|
196
|
+
<WalletLogin
|
|
197
|
+
onSuccess={(user) => {
|
|
198
|
+
onSuccess(user)
|
|
199
|
+
}}
|
|
200
|
+
/>
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export default function App() {
|
|
205
|
+
const [loggedIn, setLoggedIn] = useState(false)
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
<LuminaProvider
|
|
209
|
+
apiKey={process.env.REACT_APP_LUMINA_API_KEY}
|
|
210
|
+
network="mainnet"
|
|
211
|
+
>
|
|
212
|
+
{loggedIn ? (
|
|
213
|
+
<Dashboard />
|
|
214
|
+
) : (
|
|
215
|
+
<LoginPage onSuccess={() => setLoggedIn(true)} />
|
|
216
|
+
)}
|
|
217
|
+
</LuminaProvider>
|
|
218
|
+
)
|
|
219
|
+
}`}
|
|
220
|
+
language="tsx"
|
|
221
|
+
/>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
<Callout type="success" title="React Guide Complete">
|
|
225
|
+
You now have everything you need to build a full React app with Lumina. Check out the <a href="/docs/guides/security" className="text-emerald-400 hover:underline">Security Guide</a> next.
|
|
226
|
+
</Callout>
|
|
227
|
+
</div>
|
|
228
|
+
</>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
@@ -0,0 +1,284 @@
|
|
|
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: 'Security Best Practices - Lumina Guides',
|
|
7
|
+
description: 'Security best practices for integrating Lumina into your application.',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function SecurityPage() {
|
|
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">Security Best Practices</h1>
|
|
18
|
+
<p className="text-lg text-foreground/80">
|
|
19
|
+
Learn how to securely integrate Lumina and protect your users' assets.
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<Callout type="warning" title="Security is Critical">
|
|
24
|
+
Wallet security is paramount. Follow these practices to ensure your users' assets are protected.
|
|
25
|
+
</Callout>
|
|
26
|
+
|
|
27
|
+
<div className="space-y-4">
|
|
28
|
+
<h2 className="text-2xl font-bold">1. API Key Management</h2>
|
|
29
|
+
<p className="text-foreground/80 mb-4">
|
|
30
|
+
Your API keys are credentials that grant access to Lumina. Handle them with care.
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<div className="space-y-3">
|
|
34
|
+
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
|
35
|
+
<p className="font-semibold text-emerald-400 mb-2">Do's</p>
|
|
36
|
+
<ul className="space-y-1 text-sm text-foreground/80">
|
|
37
|
+
<li>✓ Store secret keys in environment variables only</li>
|
|
38
|
+
<li>✓ Rotate keys regularly (every 90 days)</li>
|
|
39
|
+
<li>✓ Use key scoping to limit permissions</li>
|
|
40
|
+
<li>✓ Monitor key usage in the dashboard</li>
|
|
41
|
+
<li>✓ Use different keys for dev, staging, and production</li>
|
|
42
|
+
</ul>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div className="p-4 rounded-lg bg-white/5 border border-white/10">
|
|
46
|
+
<p className="font-semibold text-red-400 mb-2">Don'ts</p>
|
|
47
|
+
<ul className="space-y-1 text-sm text-foreground/80">
|
|
48
|
+
<li>✗ Commit keys to version control</li>
|
|
49
|
+
<li>✗ Share keys via email or chat</li>
|
|
50
|
+
<li>✗ Expose secret keys in client-side code</li>
|
|
51
|
+
<li>✗ Use the same key for multiple environments</li>
|
|
52
|
+
<li>✗ Log or display keys to users</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div className="space-y-4">
|
|
59
|
+
<h2 className="text-2xl font-bold">2. Environment Setup</h2>
|
|
60
|
+
<CodeBlock
|
|
61
|
+
code={`# .env.local (never commit this file)
|
|
62
|
+
NEXT_PUBLIC_LUMINA_API_KEY=pk_prod_xxxxx
|
|
63
|
+
LUMINA_SECRET_KEY=sk_prod_xxxxx
|
|
64
|
+
NEXT_PUBLIC_LUMINA_NETWORK=mainnet
|
|
65
|
+
|
|
66
|
+
# .env.example (safe to commit)
|
|
67
|
+
NEXT_PUBLIC_LUMINA_API_KEY=your_public_key_here
|
|
68
|
+
LUMINA_SECRET_KEY=your_secret_key_here
|
|
69
|
+
NEXT_PUBLIC_LUMINA_NETWORK=mainnet`}
|
|
70
|
+
language="env"
|
|
71
|
+
title="Environment Variable Setup"
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div className="space-y-4">
|
|
76
|
+
<h2 className="text-2xl font-bold">3. Transaction Verification</h2>
|
|
77
|
+
<p className="text-foreground/80 mb-4">
|
|
78
|
+
Always verify transactions before signing.
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
<CodeBlock
|
|
82
|
+
code={`'use client'
|
|
83
|
+
|
|
84
|
+
import { TransactionConfirm } from '@lumina/sdk'
|
|
85
|
+
|
|
86
|
+
export function SendFunds() {
|
|
87
|
+
const handleConfirm = async (txHash) => {
|
|
88
|
+
// Verify transaction on the blockchain
|
|
89
|
+
const receipt = await provider.getTransactionReceipt(txHash)
|
|
90
|
+
|
|
91
|
+
if (receipt.status === 1) {
|
|
92
|
+
// Transaction confirmed
|
|
93
|
+
console.log('Transaction confirmed:', txHash)
|
|
94
|
+
} else {
|
|
95
|
+
// Transaction failed
|
|
96
|
+
console.error('Transaction failed')
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<TransactionConfirm
|
|
102
|
+
transaction={{
|
|
103
|
+
to: '0x...',
|
|
104
|
+
value: '1.0',
|
|
105
|
+
data: '0x...',
|
|
106
|
+
network: 'ethereum',
|
|
107
|
+
}}
|
|
108
|
+
onConfirm={handleConfirm}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
}`}
|
|
112
|
+
language="tsx"
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div className="space-y-4">
|
|
117
|
+
<h2 className="text-2xl font-bold">4. SSL/TLS Configuration</h2>
|
|
118
|
+
<p className="text-foreground/80 mb-4">
|
|
119
|
+
Always use HTTPS in production and enforce it in your deployment:
|
|
120
|
+
</p>
|
|
121
|
+
|
|
122
|
+
<CodeBlock
|
|
123
|
+
code={`// next.config.mjs
|
|
124
|
+
export default {
|
|
125
|
+
headers: async () => {
|
|
126
|
+
return [
|
|
127
|
+
{
|
|
128
|
+
source: '/:path*',
|
|
129
|
+
headers: [
|
|
130
|
+
{
|
|
131
|
+
key: 'Strict-Transport-Security',
|
|
132
|
+
value: 'max-age=31536000; includeSubDomains',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
key: 'X-Content-Type-Options',
|
|
136
|
+
value: 'nosniff',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
key: 'X-Frame-Options',
|
|
140
|
+
value: 'DENY',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
}`}
|
|
147
|
+
language="typescript"
|
|
148
|
+
/>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div className="space-y-4">
|
|
152
|
+
<h2 className="text-2xl font-bold">5. Rate Limiting</h2>
|
|
153
|
+
<p className="text-foreground/80 mb-4">
|
|
154
|
+
Implement rate limiting on your API routes to prevent abuse.
|
|
155
|
+
</p>
|
|
156
|
+
|
|
157
|
+
<CodeBlock
|
|
158
|
+
code={`import { Ratelimit } from '@upstash/ratelimit'
|
|
159
|
+
import { Redis } from '@upstash/redis'
|
|
160
|
+
|
|
161
|
+
const ratelimit = new Ratelimit({
|
|
162
|
+
redis: Redis.fromEnv(),
|
|
163
|
+
limiter: Ratelimit.fixedWindow(10, '1 h'),
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
export async function POST(request) {
|
|
167
|
+
const identifier = request.headers.get('x-forwarded-for')
|
|
168
|
+
const { success } = await ratelimit.limit(identifier)
|
|
169
|
+
|
|
170
|
+
if (!success) {
|
|
171
|
+
return Response.json(
|
|
172
|
+
{ error: 'Rate limited' },
|
|
173
|
+
{ status: 429 }
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Handle request
|
|
178
|
+
}`}
|
|
179
|
+
language="typescript"
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<div className="space-y-4">
|
|
184
|
+
<h2 className="text-2xl font-bold">6. Input Validation</h2>
|
|
185
|
+
<p className="text-foreground/80 mb-4">
|
|
186
|
+
Always validate user input before sending to Lumina.
|
|
187
|
+
</p>
|
|
188
|
+
|
|
189
|
+
<CodeBlock
|
|
190
|
+
code={`import { isAddress } from 'ethers'
|
|
191
|
+
|
|
192
|
+
export function validateTransaction(tx) {
|
|
193
|
+
// Validate recipient address
|
|
194
|
+
if (!isAddress(tx.to)) {
|
|
195
|
+
throw new Error('Invalid recipient address')
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Validate amount
|
|
199
|
+
if (parseFloat(tx.value) <= 0) {
|
|
200
|
+
throw new Error('Amount must be greater than 0')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Validate network
|
|
204
|
+
const validNetworks = ['ethereum', 'polygon', 'arbitrum']
|
|
205
|
+
if (!validNetworks.includes(tx.network)) {
|
|
206
|
+
throw new Error('Invalid network')
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return true
|
|
210
|
+
}`}
|
|
211
|
+
language="typescript"
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div className="space-y-4">
|
|
216
|
+
<h2 className="text-2xl font-bold">7. Error Handling</h2>
|
|
217
|
+
<p className="text-foreground/80 mb-4">
|
|
218
|
+
Don't expose sensitive information in error messages.
|
|
219
|
+
</p>
|
|
220
|
+
|
|
221
|
+
<CodeBlock
|
|
222
|
+
code={`// BAD - Exposes sensitive info
|
|
223
|
+
console.log('API Key:', process.env.LUMINA_SECRET_KEY)
|
|
224
|
+
|
|
225
|
+
// GOOD - Safe error handling
|
|
226
|
+
try {
|
|
227
|
+
await lumina.sendTransaction(tx)
|
|
228
|
+
} catch (error) {
|
|
229
|
+
// Log to secure monitoring service
|
|
230
|
+
logToSentry({
|
|
231
|
+
message: 'Transaction failed',
|
|
232
|
+
context: { userId, amount: tx.value },
|
|
233
|
+
// Don't include keys or sensitive data
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
// Show generic message to user
|
|
237
|
+
showNotification('Transaction failed. Please try again.')
|
|
238
|
+
}`}
|
|
239
|
+
language="typescript"
|
|
240
|
+
/>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<div className="space-y-4">
|
|
244
|
+
<h2 className="text-2xl font-bold">8. Audit Logging</h2>
|
|
245
|
+
<p className="text-foreground/80 mb-4">
|
|
246
|
+
Log important events for security auditing.
|
|
247
|
+
</p>
|
|
248
|
+
|
|
249
|
+
<CodeBlock
|
|
250
|
+
code={`interface AuditLog {
|
|
251
|
+
timestamp: Date
|
|
252
|
+
userId: string
|
|
253
|
+
action: string
|
|
254
|
+
resource: string
|
|
255
|
+
result: 'success' | 'failure'
|
|
256
|
+
details?: Record<string, unknown>
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export async function logAuditEvent(event: AuditLog) {
|
|
260
|
+
await db.auditLogs.create({
|
|
261
|
+
...event,
|
|
262
|
+
timestamp: new Date(),
|
|
263
|
+
})
|
|
264
|
+
}`}
|
|
265
|
+
language="typescript"
|
|
266
|
+
/>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<Callout type="success" title="Security Checklist">
|
|
270
|
+
Before deploying to production:
|
|
271
|
+
<ul className="mt-3 space-y-2 text-sm">
|
|
272
|
+
<li>✓ All API keys are in environment variables</li>
|
|
273
|
+
<li>✓ HTTPS is enforced</li>
|
|
274
|
+
<li>✓ Input validation is implemented</li>
|
|
275
|
+
<li>✓ Error handling is secure</li>
|
|
276
|
+
<li>✓ Rate limiting is enabled</li>
|
|
277
|
+
<li>✓ Audit logging is in place</li>
|
|
278
|
+
<li>✓ Security headers are configured</li>
|
|
279
|
+
</ul>
|
|
280
|
+
</Callout>
|
|
281
|
+
</div>
|
|
282
|
+
</>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react'
|
|
4
|
+
import { DocsSidebar } from '@/components/docs/docs-sidebar'
|
|
5
|
+
import { TableOfContents } from '@/components/docs/table-of-contents'
|
|
6
|
+
|
|
7
|
+
export default function DocsLayout({
|
|
8
|
+
children,
|
|
9
|
+
}: {
|
|
10
|
+
children: React.ReactNode
|
|
11
|
+
}) {
|
|
12
|
+
const [sidebarOpen, setSidebarOpen] = useState(false)
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="flex h-screen overflow-hidden bg-background">
|
|
16
|
+
<DocsSidebar isOpen={sidebarOpen} onClose={() => setSidebarOpen(false)} />
|
|
17
|
+
|
|
18
|
+
<main className="flex-1 overflow-y-auto">
|
|
19
|
+
<div className="max-w-7xl mx-auto px-6 py-8">
|
|
20
|
+
<div className="flex gap-8">
|
|
21
|
+
<article className="flex-1 min-w-0">
|
|
22
|
+
{children}
|
|
23
|
+
</article>
|
|
24
|
+
<aside className="hidden xl:block w-5 shrink-0">
|
|
25
|
+
<TableOfContents />
|
|
26
|
+
</aside>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</main>
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|