From 0fd1c8b0400be5c169a790349b0d124d53c0468f Mon Sep 17 00:00:00 2001 From: Muhammed Talha Korkmaz Date: Fri, 4 Oct 2024 19:46:31 +0300 Subject: [PATCH] helius initial --- src/components/helius/index.tsx | 32 +- src/pages/portfolio/[walletAddress]/index.tsx | 281 ++++++++++++++++++ 2 files changed, 297 insertions(+), 16 deletions(-) diff --git a/src/components/helius/index.tsx b/src/components/helius/index.tsx index 61f1902..70b4ff6 100644 --- a/src/components/helius/index.tsx +++ b/src/components/helius/index.tsx @@ -1,15 +1,15 @@ import Button from "./Button"; import WalletInput from "./WalletInput"; import Hero from "./Hero"; -import Logo from "./Logo"; -import Navigation from "./navigation/Navigation"; +// import Logo from "./Logo"; +// import Navigation from "./navigation/Navigation"; -import NFTCard from "./nfts/NFTCard"; -import NFTDetails from "./nfts/NFTDetails"; -import NFTFilters from "./nfts/NFTFilters"; -import NFTList from "./nfts/NFTList"; -import NFTMetrics from "./nfts/NFTMetrics"; -import NFTTable from "./nfts/NFTTable"; +// import NFTCard from "./nfts/NFTCard"; +// import NFTDetails from "./nfts/NFTDetails"; +// import NFTFilters from "./nfts/NFTFilters"; +// import NFTList from "./nfts/NFTList"; +// import NFTMetrics from "./nfts/NFTMetrics"; +// import NFTTable from "./nfts/NFTTable"; import TokenDetails from "./tokens/TokenDetails"; import TokenMetrics from "./tokens/TokenMetrics"; @@ -21,14 +21,14 @@ export { Button, DynamicTokenRow, Hero, - Logo, - NFTCard, - NFTDetails, - NFTFilters, - NFTList, - NFTMetrics, - NFTTable, - Navigation, + // Logo, + // NFTCard, + // NFTDetails, + // NFTFilters, + // NFTList, + // NFTMetrics, + // NFTTable, + // Navigation, TokenDetails, TokenMetrics, TokenTable, diff --git a/src/pages/portfolio/[walletAddress]/index.tsx b/src/pages/portfolio/[walletAddress]/index.tsx index e69de29..cb20c79 100644 --- a/src/pages/portfolio/[walletAddress]/index.tsx +++ b/src/pages/portfolio/[walletAddress]/index.tsx @@ -0,0 +1,281 @@ +import { TokenDetails, TokenMetrics, TokensList } from "components/helius"; +import { FungibleToken, NonFungibleToken } from "models"; +import React, { Suspense } from "react"; + +interface PortfolioPageProps { + searchParams: { view: string; details: string; tokenDetails: string }; + params: { walletAddress: string }; +} + +const PortfolioPage = async ({ searchParams, params }: PortfolioPageProps) => { + // Fetch both fungible and non-fungible token data + const { fungibleTokens, nonFungibleTokens } = await getAllAssets( + params.walletAddress + ); + + return ( +
+
+ {/* Navigation (Mobile / Side / Primary) */} + {/* */} + + {/* Main area */} +
+
+ {/* Tokens */} +
+ {searchParams.tokenDetails && ( +
+
+ item.id === searchParams.tokenDetails + )} + searchParams={searchParams} + walletAddress={params.walletAddress} + /> +
+
+ )} +
+ + {/* NFTS */} +
+ {searchParams.details && ( +
+
+ {/* item.id === searchParams.details + )} + searchParams={"view=" + searchParams.view} + walletAddress={params.walletAddress} + /> */} +
+
+ )} +
+ +
+ Loading...
} + key={searchParams.view} + > +
+ {searchParams.view === "tokens" && ( + <> + {/* Token Metrics */} + + + {/* Tokens List */} + + + )} + {searchParams.view === "nfts" && ( + <> + {/* NFTs Metrics */} + {/* */} + + {/* NFTs List */} + {/* */} + + )} +
+ +
+
+ +
+ + ); +}; + +const getAllAssets = async (walletAddress: string) => { + const url = process.env.NEXT_PUBLIC_HELIUS_RPC_URL; + + if (!url) { + throw new Error("NEXT_PUBLIC_HELIUS_RPC_URL is not set"); + } + + const response = await fetch(url, { + next: { revalidate: 5 }, + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: "my-id", + method: "searchAssets", + params: { + ownerAddress: walletAddress, + tokenType: "all", // Changed to "all" to fetch both types + displayOptions: { + showNativeBalance: true, + showInscription: true, + showCollectionMetadata: true, + }, + }, + }), + }); + + if (!response.ok) { + throw new Error(`Failed to fetch data`); + } + + const data = await response.json(); + const items: (FungibleToken | NonFungibleToken)[] = data.result.items; + + // Split the items into fungible and non-fungible tokens + let fungibleTokens: FungibleToken[] = items.filter( + (item): item is FungibleToken => + item.interface === "FungibleToken" || item.interface === "FungibleAsset" + ); + // Hardcoding the image for USDC + fungibleTokens = fungibleTokens.map((item) => { + if (item.id === "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") { + return { + ...item, + content: { + ...item.content, + files: [ + { + uri: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png", + cdn_uri: "", // Assuming this is correct + mime: "image/png", + }, + ], + links: { + image: + "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png", + }, + }, + }; + } else if (item.id === "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1") { + return { + ...item, + content: { + ...item.content, + files: [ + { + uri: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1/logo.png", + cdn_uri: "", // Assuming this is correct + mime: "image/png", + }, + ], + links: { + image: + "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1/logo.png", + }, + }, + }; + } + return item; + }); + const nonFungibleTokens: NonFungibleToken[] = items.filter( + (item): item is NonFungibleToken => + !["FungibleToken", "FungibleAsset"].includes(item.interface) + ); + + // Calculate SOL balance from lamports + const solBalance = data.result.nativeBalance.lamports; + //console.log(data.result); + + // Create SOL token object + const solToken = { + interface: "FungibleAsset", + id: "So11111111111111111111111111111111111111112", // Mint address as ID + content: { + $schema: "https://schema.metaplex.com/nft1.0.json", + json_uri: "", + files: [ + { + uri: "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png", + cdn_uri: "", // Assuming this is correct + mime: "image/png", + }, + ], + metadata: { + description: "Solana Token", + name: "Wrapped SOL", + symbol: "SOL", + token_standard: "Native Token", + }, + links: { + image: + "https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png", + }, + }, + authorities: [], // Assuming empty for SOL + compression: { + eligible: false, + compressed: false, + data_hash: "", + creator_hash: "", + asset_hash: "", + tree: "", + seq: 0, + leaf_id: 0, + }, + grouping: [], // Assuming empty for SOL + royalty: { + royalty_model: "", // Fill as needed + target: null, + percent: 0, + basis_points: 0, + primary_sale_happened: false, + locked: false, + }, + creators: [], // Assuming empty for SOL + ownership: { + frozen: false, + delegated: false, + delegate: null, + ownership_model: "token", + owner: nonFungibleTokens[0]?.ownership.owner, + }, + supply: null, // Assuming null for SOL + mutable: true, // Assuming true for SOL + burnt: false, // Assuming false for SOL + + token_info: { + symbol: "SOL", + balance: solBalance, + supply: 0, // Assuming null for SOL + decimals: 9, + token_program: "", // Fill as needed + associated_token_address: "", // Fill as needed + price_info: { + price_per_token: data.result.nativeBalance.price_per_sol, // Fill with actual price if available + total_price: data.result.nativeBalance.total_price, // Fill with actual total price if available + currency: "", // Fill as needed + }, + }, + }; + + // Add SOL token to the tokens array + if (solBalance > 0) { + fungibleTokens.push(solToken); + } + + return { fungibleTokens, nonFungibleTokens }; +}; +export default PortfolioPage;