From 27a5e5c500723d4e236f2f74ff4f246c91615171 Mon Sep 17 00:00:00 2001 From: Danish Arora Date: Tue, 9 Sep 2025 13:15:57 +0530 Subject: [PATCH] wip --- .env.example | 3 +- package-lock.json | 19 ++++- package.json | 1 + src/App.tsx | 2 + src/lib/services/Ordinal/index.ts | 54 -------------- src/lib/services/Ordinal/types.ts | 25 ------- src/lib/services/OrdinalService.ts | 17 +++++ src/pages/OrdiscanPage.tsx | 110 +++++++++++++++++++++++++++++ src/pages/ProfilePage.tsx | 18 +++-- 9 files changed, 161 insertions(+), 88 deletions(-) delete mode 100644 src/lib/services/Ordinal/index.ts delete mode 100644 src/lib/services/Ordinal/types.ts create mode 100644 src/lib/services/OrdinalService.ts create mode 100644 src/pages/OrdiscanPage.tsx diff --git a/.env.example b/.env.example index 589050a..774c4fb 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,3 @@ VITE_REOWN_SECRET= -VITE_OPCHAN_MOCK_ORDINAL_CHECK= \ No newline at end of file +VITE_OPCHAN_MOCK_ORDINAL_CHECK= +VITE_ORDISCAN_API_KEY= \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6c15483..51f3cc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ "input-otp": "^1.2.4", "lucide-react": "^0.462.0", "next-themes": "^0.3.0", + "ordiscan": "^1.3.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", @@ -12582,6 +12583,18 @@ "node": ">= 0.8.0" } }, + "node_modules/ordiscan": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ordiscan/-/ordiscan-1.3.0.tgz", + "integrity": "sha512-IV8yayKGIRtfkI3rQ1gu+aKQ6UmNHXB910qUuWrraCcuk6U/YkE+6X8Bh+jW2P8L8/lOfYA6DLVeKCVPkj8c6g==", + "license": "MIT", + "dependencies": { + "zod": "^3.24.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/ox": { "version": "0.6.9", "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", @@ -15870,9 +15883,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index b6bdeac..8d20cf6 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "input-otp": "^1.2.4", "lucide-react": "^0.462.0", "next-themes": "^0.3.0", + "ordiscan": "^1.3.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", diff --git a/src/App.tsx b/src/App.tsx index a51f247..ac8a229 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,6 +26,7 @@ import Dashboard from './pages/Dashboard'; import Index from './pages/Index'; import ProfilePage from './pages/ProfilePage'; import BookmarksPage from './pages/BookmarksPage'; +import OrdiscanPage from './pages/OrdiscanPage'; import { appkitConfig } from './lib/wallet/config'; import { WagmiProvider } from 'wagmi'; import { config } from './lib/wallet/config'; @@ -52,6 +53,7 @@ const App = () => ( } /> } /> } /> + } /> } /> diff --git a/src/lib/services/Ordinal/index.ts b/src/lib/services/Ordinal/index.ts deleted file mode 100644 index 12ae4b0..0000000 --- a/src/lib/services/Ordinal/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { OrdinalApiResponse } from './types'; - -const BASE_URL = 'https://dashboard.logos.co/api/operators/wallet'; - -export class OrdinalAPI { - /** - * Fetches Ordinal operator details for a given Bitcoin address. - * @param address - The Bitcoin address to query. - * @returns A promise that resolves with the API response. - */ - async getOperatorDetails(address: string): Promise { - if (import.meta.env.VITE_OPCHAN_MOCK_ORDINAL_CHECK === 'true') { - console.log( - `[DEV] Bypassing ordinal verification for address: ${address}` - ); - return { - has_operators: true, - error_message: '', - data: [], - }; - } - - const url = `${BASE_URL}/${address}/detail/`; - - try { - const response = await fetch(url, { - method: 'GET', - headers: { Accept: 'application/json' }, - }); - - if (!response.ok) { - const errorBody = await response.text().catch(() => ''); - throw new Error( - `HTTP error! status: ${response.status}, message: ${errorBody || response.statusText}` - ); - } - - const data: OrdinalApiResponse = await response.json(); - - if (data.error_message) { - console.warn( - `API returned an error message for address ${address}: ${data.error_message}` - ); - } - return data; - } catch (error) { - console.error( - `Failed to fetch ordinal details for address ${address}:`, - error - ); - throw error; - } - } -} diff --git a/src/lib/services/Ordinal/types.ts b/src/lib/services/Ordinal/types.ts deleted file mode 100644 index ca19ab4..0000000 --- a/src/lib/services/Ordinal/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -export interface OrdinalDetail { - name: string; - archetype_name: string; - comp: string; - background: string; - skin: string; - helmet: string; - jacket: string; - image_200_url: string; - image_200_jpeg_url: string; - image_400_url: string; - image_400_jpeg_url: string; - image_1024_url: string; - image_1024_jpeg_url: string; - image_2048_url: string; - image_2048_jpeg_url: string; - image_pixalated_url: string; - mp4_url: string; -} - -export interface OrdinalApiResponse { - has_operators: boolean; - error_message: string; - data: OrdinalDetail[]; -} diff --git a/src/lib/services/OrdinalService.ts b/src/lib/services/OrdinalService.ts new file mode 100644 index 0000000..ba4f7b6 --- /dev/null +++ b/src/lib/services/OrdinalService.ts @@ -0,0 +1,17 @@ +import { Ordiscan } from 'ordiscan'; + +console.log(import.meta.env.VITE_ORDISCAN_API_KEY); +const ordiscan = new Ordiscan(import.meta.env.VITE_ORDISCAN_API_KEY); + +export class OrdinalAPI { + /** + * Fetches Ordinal operator details for a given Bitcoin address. + * @param address - The Bitcoin address to query. + * @returns A promise that resolves with the API response. + */ + async getOperatorDetails(address: string) { + const response = await ordiscan.address.getInscriptions({address: address}) + console.log(response); + return response; + } +} diff --git a/src/pages/OrdiscanPage.tsx b/src/pages/OrdiscanPage.tsx new file mode 100644 index 0000000..f23630f --- /dev/null +++ b/src/pages/OrdiscanPage.tsx @@ -0,0 +1,110 @@ +import { useState } from 'react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card'; +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Loader2 } from 'lucide-react'; +import { OrdinalAPI } from '@/lib/services/OrdinalService'; + +const ordinalAPI = new OrdinalAPI(); + +export default function OrdiscanPage() { + const [address, setAddress] = useState(''); + const [loading, setLoading] = useState(false); + const [data, setData] = useState | null>( + null + ); + const [error, setError] = useState(null); + + const handleSearch = async () => { + if (!address.trim()) { + setError('Please enter a Bitcoin address'); + return; + } + + setLoading(true); + setError(null); + setData(null); + + try { + const result = await ordinalAPI.getOperatorDetails(address.trim()); + setData(result); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to fetch data'); + console.error('Ordiscan API error:', err); + } finally { + setLoading(false); + } + }; + + return ( +
+ + + + Ordiscan Explorer + + + Search for Bitcoin inscriptions and ordinal operator details + + + +
+ setAddress(e.target.value)} + onKeyDown={e => e.key === 'Enter' && handleSearch()} + className="flex-1" + /> + +
+ + {error && ( + + {error} + + )} + + {data && ( + + + Inscriptions Data + + +
+                  {JSON.stringify(data, null, 2)}
+                
+
+
+ )} + + {!data && !loading && !error && ( +
+ Enter a Bitcoin address to search for inscriptions +
+ )} +
+
+
+ ); +} diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 5939f39..8fcfba0 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -59,7 +59,9 @@ export default function ProfilePage() { const [isEditing, setIsEditing] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [callSign, setCallSign] = useState(''); - const [displayPreference, setDisplayPreference] = useState(EDisplayPreference.WALLET_ADDRESS); + const [displayPreference, setDisplayPreference] = useState( + EDisplayPreference.WALLET_ADDRESS + ); const [walletWizardOpen, setWalletWizardOpen] = useState(false); // Initialize and update local state when user data changes @@ -67,8 +69,11 @@ export default function ProfilePage() { if (currentUser) { // Use the same data source as the display (userInfo) for consistency const currentCallSign = userInfo.callSign || currentUser.callSign || ''; - const currentDisplayPreference = userInfo.displayPreference || currentUser.displayPreference || EDisplayPreference.WALLET_ADDRESS; - + const currentDisplayPreference = + userInfo.displayPreference || + currentUser.displayPreference || + EDisplayPreference.WALLET_ADDRESS; + setCallSign(currentCallSign); setDisplayPreference(currentDisplayPreference); } @@ -174,8 +179,11 @@ export default function ProfilePage() { const handleCancel = () => { // Reset to the same data source as display for consistency const currentCallSign = userInfo.callSign || currentUser.callSign || ''; - const currentDisplayPreference = userInfo.displayPreference || currentUser.displayPreference || EDisplayPreference.WALLET_ADDRESS; - + const currentDisplayPreference = + userInfo.displayPreference || + currentUser.displayPreference || + EDisplayPreference.WALLET_ADDRESS; + setCallSign(currentCallSign); setDisplayPreference(currentDisplayPreference); setIsEditing(false);