fix: update placeholder
This commit is contained in:
parent
de04de2bfe
commit
fca81d8ead
|
@ -1,15 +1,15 @@
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button";
|
||||||
import "@lumeweb/sdk/lib/style.css"
|
import "@lumeweb/sdk/lib/style.css";
|
||||||
import "@/styles/global.css"
|
import "@/styles/global.css";
|
||||||
import React, {
|
import React, {
|
||||||
createContext,
|
createContext,
|
||||||
createRef,
|
createRef,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useState
|
useState,
|
||||||
} from "react"
|
} from "react";
|
||||||
import {
|
import {
|
||||||
type AuthContextType,
|
type AuthContextType,
|
||||||
AuthProvider,
|
AuthProvider,
|
||||||
|
@ -22,53 +22,49 @@ import {
|
||||||
useAuth,
|
useAuth,
|
||||||
useLumeStatus,
|
useLumeStatus,
|
||||||
useNetworks,
|
useNetworks,
|
||||||
LumeDashboardTrigger
|
LumeDashboardTrigger,
|
||||||
} from "@lumeweb/sdk"
|
} from "@lumeweb/sdk";
|
||||||
import * as kernel from "@lumeweb/libkernel/kernel"
|
import * as kernel from "@lumeweb/libkernel/kernel";
|
||||||
import { kernelLoaded } from "@lumeweb/libkernel/kernel"
|
import { kernelLoaded } from "@lumeweb/libkernel/kernel";
|
||||||
import {
|
import {
|
||||||
dnsClient,
|
dnsClient,
|
||||||
ethClient,
|
ethClient,
|
||||||
ipfsClient,
|
ipfsClient,
|
||||||
networkRegistryClient,
|
networkRegistryClient,
|
||||||
peerDiscoveryClient,
|
peerDiscoveryClient,
|
||||||
swarmClient
|
swarmClient,
|
||||||
} from "@/lib/clients"
|
} from "@/lib/clients";
|
||||||
import { ethers } from "ethers"
|
import { ethers } from "ethers";
|
||||||
import * as ethersBytes from "@ethersproject/bytes"
|
import * as ethersBytes from "@ethersproject/bytes";
|
||||||
import { createProvider } from "@lumeweb/kernel-eth-client"
|
import { createProvider } from "@lumeweb/kernel-eth-client";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import jdu from "json-data-uri"
|
import jdu from "json-data-uri";
|
||||||
import { ERC721_ABI } from "@/lib/erc721-abi"
|
import { ERC721_ABI } from "@/lib/erc721-abi";
|
||||||
import {
|
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||||
Card,
|
import LogoImg from "@/assets/lume-logo.png";
|
||||||
CardContent,
|
let BOOT_FUNCTIONS: (() => Promise<any>)[] = [];
|
||||||
CardHeader,
|
|
||||||
} from "@/components/ui/card"
|
|
||||||
import LogoImg from "@/assets/lume-logo.png"
|
|
||||||
let BOOT_FUNCTIONS: (() => Promise<any>)[] = []
|
|
||||||
|
|
||||||
export const AppContext = createContext<any>(undefined)
|
export const AppContext = createContext<any>(undefined);
|
||||||
|
|
||||||
export function useApp() {
|
export function useApp() {
|
||||||
const context = useContext(AppContext)
|
const context = useContext(AppContext);
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error("useApp must be used within an AppProvider")
|
throw new Error("useApp must be used within an AppProvider");
|
||||||
}
|
}
|
||||||
|
|
||||||
return context
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AppProviderProps {
|
interface AppProviderProps {
|
||||||
children: ReactNode
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = createProvider()
|
const provider = createProvider();
|
||||||
|
|
||||||
const ERC721_TRANSFER_EVENT_SIGNATURE = ethers.id(
|
const ERC721_TRANSFER_EVENT_SIGNATURE = ethers.id(
|
||||||
"Transfer(address,address,uint256)"
|
"Transfer(address,address,uint256)"
|
||||||
)
|
);
|
||||||
|
|
||||||
async function findPotentialERC721Contracts(
|
async function findPotentialERC721Contracts(
|
||||||
address: string
|
address: string
|
||||||
|
@ -79,24 +75,24 @@ async function findPotentialERC721Contracts(
|
||||||
topics: [
|
topics: [
|
||||||
ERC721_TRANSFER_EVENT_SIGNATURE,
|
ERC721_TRANSFER_EVENT_SIGNATURE,
|
||||||
null,
|
null,
|
||||||
ethersBytes.hexZeroPad(address, 32)
|
ethersBytes.hexZeroPad(address, 32),
|
||||||
]
|
],
|
||||||
})
|
});
|
||||||
|
|
||||||
const potentialContracts = new Set<string>()
|
const potentialContracts = new Set<string>();
|
||||||
logs.forEach((log: any) => potentialContracts.add(log.address))
|
logs.forEach((log: any) => potentialContracts.add(log.address));
|
||||||
|
|
||||||
const confirmedERC721Contracts: string[] = []
|
const confirmedERC721Contracts: string[] = [];
|
||||||
for (let contractAddress of potentialContracts) {
|
for (let contractAddress of potentialContracts) {
|
||||||
if (await isERC721(contractAddress)) {
|
if (await isERC721(contractAddress)) {
|
||||||
confirmedERC721Contracts.push(contractAddress)
|
confirmedERC721Contracts.push(contractAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return confirmedERC721Contracts
|
return confirmedERC721Contracts;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TRANSFER_EVENT_SIGNATURE = ethers.id("Transfer(address,address,uint256)")
|
const TRANSFER_EVENT_SIGNATURE = ethers.id("Transfer(address,address,uint256)");
|
||||||
|
|
||||||
async function fetchTokensViaTransferEvent(
|
async function fetchTokensViaTransferEvent(
|
||||||
address: string,
|
address: string,
|
||||||
|
@ -109,93 +105,93 @@ async function fetchTokensViaTransferEvent(
|
||||||
topics: [
|
topics: [
|
||||||
TRANSFER_EVENT_SIGNATURE,
|
TRANSFER_EVENT_SIGNATURE,
|
||||||
null,
|
null,
|
||||||
ethersBytes.hexZeroPad(address, 32)
|
ethersBytes.hexZeroPad(address, 32),
|
||||||
]
|
],
|
||||||
})
|
});
|
||||||
|
|
||||||
const tokenIds: number[] = []
|
const tokenIds: number[] = [];
|
||||||
logs.forEach((log) => {
|
logs.forEach((log) => {
|
||||||
if (log.topics && log.topics.length === 4) {
|
if (log.topics && log.topics.length === 4) {
|
||||||
const tokenIdBigNumber = ethers.toNumber(log.topics[3])
|
const tokenIdBigNumber = ethers.toNumber(log.topics[3]);
|
||||||
tokenIds.push(tokenIdBigNumber)
|
tokenIds.push(tokenIdBigNumber);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return tokenIds
|
return tokenIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchOwnedNFTs(
|
async function fetchOwnedNFTs(
|
||||||
address: string,
|
address: string,
|
||||||
confirmedERC721Contracts: string[]
|
confirmedERC721Contracts: string[]
|
||||||
): Promise<{ contract: string; tokenId: number; metadata: any }[]> {
|
): Promise<{ contract: string; tokenId: number; metadata: any }[]> {
|
||||||
const ownedNFTs = []
|
const ownedNFTs = [];
|
||||||
|
|
||||||
for (let contractAddress of confirmedERC721Contracts) {
|
for (let contractAddress of confirmedERC721Contracts) {
|
||||||
const contract = new ethers.Contract(contractAddress, ERC721_ABI, provider)
|
const contract = new ethers.Contract(contractAddress, ERC721_ABI, provider);
|
||||||
let tokenIds: number[] = []
|
let tokenIds: number[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const balance = await contract.balanceOf(address)
|
const balance = await contract.balanceOf(address);
|
||||||
for (let i = 0; i < balance; i++) {
|
for (let i = 0; i < balance; i++) {
|
||||||
const tokenId = await contract.tokenOfOwnerByIndex(address, i)
|
const tokenId = await contract.tokenOfOwnerByIndex(address, i);
|
||||||
tokenIds.push(tokenId.toNumber())
|
tokenIds.push(tokenId.toNumber());
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If tokenOfOwnerByIndex is not available, fall back to fetchTokensViaTransferEvent
|
// If tokenOfOwnerByIndex is not available, fall back to fetchTokensViaTransferEvent
|
||||||
tokenIds = await fetchTokensViaTransferEvent(address, contractAddress)
|
tokenIds = await fetchTokensViaTransferEvent(address, contractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let tokenId of tokenIds) {
|
for (let tokenId of tokenIds) {
|
||||||
try {
|
try {
|
||||||
const uri = await contract.tokenURI(tokenId)
|
const uri = await contract.tokenURI(tokenId);
|
||||||
// const metadata = await fetchMetadataFromURI(uri);
|
// const metadata = await fetchMetadataFromURI(uri);
|
||||||
ownedNFTs.push({
|
ownedNFTs.push({
|
||||||
contract: contractAddress,
|
contract: contractAddress,
|
||||||
tokenId: tokenId,
|
tokenId: tokenId,
|
||||||
metadata: uri
|
metadata: uri,
|
||||||
})
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(
|
console.error(
|
||||||
`Failed to fetch metadata for token ${tokenId} from contract ${contractAddress}: ${error.message}`
|
`Failed to fetch metadata for token ${tokenId} from contract ${contractAddress}: ${error.message}`
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ownedNFTs
|
return ownedNFTs;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isERC721(address: string): Promise<boolean> {
|
async function isERC721(address: string): Promise<boolean> {
|
||||||
const contract = new ethers.Contract(address, ERC721_ABI, provider)
|
const contract = new ethers.Contract(address, ERC721_ABI, provider);
|
||||||
try {
|
try {
|
||||||
// Try calling some ERC-721 methods to confirm if this is an ERC-721 contract.
|
// Try calling some ERC-721 methods to confirm if this is an ERC-721 contract.
|
||||||
await contract.name()
|
await contract.name();
|
||||||
await contract.symbol()
|
await contract.symbol();
|
||||||
return true
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppProvider: React.FC<AppProviderProps> = ({ children }) => {
|
const AppProvider: React.FC<AppProviderProps> = ({ children }) => {
|
||||||
return <AppContext.Provider value={{}}>{children}</AppContext.Provider>
|
return <AppContext.Provider value={{}}>{children}</AppContext.Provider>;
|
||||||
}
|
};
|
||||||
|
|
||||||
async function boot(status: LumeStatusContextType, auth: AuthContextType) {
|
async function boot(status: LumeStatusContextType, auth: AuthContextType) {
|
||||||
kernel.init().then(() => {
|
kernel.init().then(() => {
|
||||||
status.setInited(true)
|
status.setInited(true);
|
||||||
})
|
});
|
||||||
|
|
||||||
await kernelLoaded()
|
await kernelLoaded();
|
||||||
|
|
||||||
auth.setIsLoggedIn(true)
|
auth.setIsLoggedIn(true);
|
||||||
|
|
||||||
BOOT_FUNCTIONS.push(
|
BOOT_FUNCTIONS.push(
|
||||||
async () =>
|
async () =>
|
||||||
await swarmClient.addRelay(
|
await swarmClient.addRelay(
|
||||||
"2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d"
|
"2d7ae1517caf4aae4de73c6d6f400765d2dd00b69d65277a29151437ef1c7d1d"
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
|
|
||||||
// IRC
|
// IRC
|
||||||
BOOT_FUNCTIONS.push(
|
BOOT_FUNCTIONS.push(
|
||||||
|
@ -203,40 +199,40 @@ async function boot(status: LumeStatusContextType, auth: AuthContextType) {
|
||||||
await peerDiscoveryClient.register(
|
await peerDiscoveryClient.register(
|
||||||
"zrjHTx8tSQFWnmZ9JzK7XmJirqJQi2WRBLYp3fASaL2AfBQ"
|
"zrjHTx8tSQFWnmZ9JzK7XmJirqJQi2WRBLYp3fASaL2AfBQ"
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
BOOT_FUNCTIONS.push(
|
BOOT_FUNCTIONS.push(
|
||||||
async () => await networkRegistryClient.registerType("content")
|
async () => await networkRegistryClient.registerType("content")
|
||||||
)
|
);
|
||||||
BOOT_FUNCTIONS.push(
|
BOOT_FUNCTIONS.push(
|
||||||
async () => await networkRegistryClient.registerType("blockchain")
|
async () => await networkRegistryClient.registerType("blockchain")
|
||||||
)
|
);
|
||||||
BOOT_FUNCTIONS.push(async () => await ethClient.register())
|
BOOT_FUNCTIONS.push(async () => await ethClient.register());
|
||||||
BOOT_FUNCTIONS.push(async () => await ipfsClient.register())
|
BOOT_FUNCTIONS.push(async () => await ipfsClient.register());
|
||||||
|
|
||||||
const resolvers = [
|
const resolvers = [
|
||||||
"zrjEYq154PS7boERAbRAKMyRGzAR6CTHVRG6mfi5FV4q9FA" // ENS
|
"zrjEYq154PS7boERAbRAKMyRGzAR6CTHVRG6mfi5FV4q9FA", // ENS
|
||||||
]
|
];
|
||||||
|
|
||||||
for (const resolver of resolvers) {
|
for (const resolver of resolvers) {
|
||||||
BOOT_FUNCTIONS.push(async () => dnsClient.registerResolver(resolver))
|
BOOT_FUNCTIONS.push(async () => dnsClient.registerResolver(resolver));
|
||||||
}
|
}
|
||||||
BOOT_FUNCTIONS.push(async () => status.setReady(true))
|
BOOT_FUNCTIONS.push(async () => status.setReady(true));
|
||||||
|
|
||||||
await bootup()
|
await bootup();
|
||||||
|
|
||||||
await Promise.all([ethClient.ready(), ipfsClient.ready()])
|
await Promise.all([ethClient.ready(), ipfsClient.ready()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bootup() {
|
async function bootup() {
|
||||||
for (const entry of Object.entries(BOOT_FUNCTIONS)) {
|
for (const entry of Object.entries(BOOT_FUNCTIONS)) {
|
||||||
console.log(entry[1].toString())
|
console.log(entry[1].toString());
|
||||||
await entry[1]()
|
await entry[1]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoginDash() {
|
function LoginDash() {
|
||||||
const { isLoggedIn } = useAuth()
|
const { isLoggedIn } = useAuth();
|
||||||
const { ready, inited } = useLumeStatus()
|
const { ready, inited } = useLumeStatus();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -259,130 +255,130 @@ function LoginDash() {
|
||||||
</LumeDashboard>
|
</LumeDashboard>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function asyncIterableToUint8Array(asyncIterable: any) {
|
async function asyncIterableToUint8Array(asyncIterable: any) {
|
||||||
const chunks = []
|
const chunks = [];
|
||||||
let totalLength = 0
|
let totalLength = 0;
|
||||||
|
|
||||||
for await (const chunk of asyncIterable) {
|
for await (const chunk of asyncIterable) {
|
||||||
chunks.push(chunk)
|
chunks.push(chunk);
|
||||||
totalLength += chunk.length
|
totalLength += chunk.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = new Uint8Array(totalLength)
|
const result = new Uint8Array(totalLength);
|
||||||
let offset = 0
|
let offset = 0;
|
||||||
for (const chunk of chunks) {
|
for (const chunk of chunks) {
|
||||||
result.set(chunk, offset)
|
result.set(chunk, offset);
|
||||||
offset += chunk.length
|
offset += chunk.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uint8ArrayToBase64(byteArray: Uint8Array) {
|
function uint8ArrayToBase64(byteArray: Uint8Array) {
|
||||||
let base64 = ""
|
let base64 = "";
|
||||||
const characters =
|
const characters =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
let padding = 0
|
let padding = 0;
|
||||||
for (let i = 0; i < byteArray.length; i += 3) {
|
for (let i = 0; i < byteArray.length; i += 3) {
|
||||||
const a = byteArray[i]
|
const a = byteArray[i];
|
||||||
const b = byteArray[i + 1]
|
const b = byteArray[i + 1];
|
||||||
const c = byteArray[i + 2]
|
const c = byteArray[i + 2];
|
||||||
|
|
||||||
const triplet = (a << 16) + ((b || 0) << 8) + (c || 0)
|
const triplet = (a << 16) + ((b || 0) << 8) + (c || 0);
|
||||||
|
|
||||||
base64 += characters.charAt((triplet & 0xfc0000) >> 18)
|
base64 += characters.charAt((triplet & 0xfc0000) >> 18);
|
||||||
base64 += characters.charAt((triplet & 0x03f000) >> 12)
|
base64 += characters.charAt((triplet & 0x03f000) >> 12);
|
||||||
base64 += characters.charAt((triplet & 0x000fc0) >> 6)
|
base64 += characters.charAt((triplet & 0x000fc0) >> 6);
|
||||||
base64 += characters.charAt(triplet & 0x00003f)
|
base64 += characters.charAt(triplet & 0x00003f);
|
||||||
|
|
||||||
if (byteArray.length - i < 3) {
|
if (byteArray.length - i < 3) {
|
||||||
padding = 3 - (byteArray.length - i)
|
padding = 3 - (byteArray.length - i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add padding if necessary
|
// Add padding if necessary
|
||||||
if (padding > 0) {
|
if (padding > 0) {
|
||||||
base64 = base64.slice(0, -padding) + (padding === 1 ? "=" : "==")
|
base64 = base64.slice(0, -padding) + (padding === 1 ? "=" : "==");
|
||||||
}
|
}
|
||||||
|
|
||||||
return base64
|
return base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const status = useLumeStatus()
|
const status = useLumeStatus();
|
||||||
const auth = useAuth()
|
const auth = useAuth();
|
||||||
const [nftList, setNftList] = useState<any[]>([])
|
const [nftList, setNftList] = useState<any[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
boot(status, auth)
|
boot(status, auth);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const { networks } = useNetworks()
|
const { networks } = useNetworks();
|
||||||
|
|
||||||
const ipfsStatus = networks
|
const ipfsStatus = networks
|
||||||
.filter((item) => item.name.toLowerCase() === "ipfs")
|
.filter((item) => item.name.toLowerCase() === "ipfs")
|
||||||
?.pop()
|
?.pop();
|
||||||
|
|
||||||
const ethStatus = networks
|
const ethStatus = networks
|
||||||
.filter((item) => item.name.toLowerCase() === "ethereum")
|
.filter((item) => item.name.toLowerCase() === "ethereum")
|
||||||
?.pop()
|
?.pop();
|
||||||
|
|
||||||
const ready = ethStatus?.ready && status.ready
|
const ready = ethStatus?.ready && status.ready;
|
||||||
|
|
||||||
const inputRef = createRef<HTMLInputElement>()
|
const inputRef = createRef<HTMLInputElement>();
|
||||||
|
|
||||||
async function search(e: any | Event) {
|
async function search(e: any | Event) {
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
|
|
||||||
let address = inputRef?.current?.value as string
|
let address = inputRef?.current?.value as string;
|
||||||
|
|
||||||
address = await ethers.resolveAddress(address, provider)
|
address = await ethers.resolveAddress(address, provider);
|
||||||
|
|
||||||
const contracts = await findPotentialERC721Contracts(address)
|
const contracts = await findPotentialERC721Contracts(address);
|
||||||
|
|
||||||
const nfts = await fetchOwnedNFTs(address, contracts)
|
const nfts = await fetchOwnedNFTs(address, contracts);
|
||||||
|
|
||||||
const list = []
|
const list = [];
|
||||||
|
|
||||||
for (const nft of nfts) {
|
for (const nft of nfts) {
|
||||||
let meta
|
let meta;
|
||||||
if (typeof nft.metadata === "string") {
|
if (typeof nft.metadata === "string") {
|
||||||
try {
|
try {
|
||||||
meta = await (await fetch(nft.metadata)).json()
|
meta = await (await fetch(nft.metadata)).json();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
meta = {
|
meta = {
|
||||||
image: "", // TODO: Improve this by bringing an actual image
|
image: "", // TODO: Improve this by bringing an actual image
|
||||||
name: "Failed to Load",
|
name: "Failed to Load",
|
||||||
fail: true
|
fail: true,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
meta = jdu.parse(nft.metadata)
|
meta = jdu.parse(nft.metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
let image
|
let image;
|
||||||
|
|
||||||
if (!meta.fail) {
|
if (!meta.fail) {
|
||||||
const imageCID = meta.image.replace("ipfs://", "")
|
const imageCID = meta.image.replace("ipfs://", "");
|
||||||
|
|
||||||
image = await asyncIterableToUint8Array(
|
image = await asyncIterableToUint8Array(
|
||||||
ipfsClient.cat(imageCID).iterable()
|
ipfsClient.cat(imageCID).iterable()
|
||||||
)
|
);
|
||||||
} else {
|
} else {
|
||||||
image = meta.image
|
image = meta.image;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.push({
|
list.push({
|
||||||
image,
|
image,
|
||||||
name: meta.name,
|
name: meta.name,
|
||||||
base64: meta.fail
|
base64: meta.fail,
|
||||||
})
|
});
|
||||||
|
|
||||||
setNftList(list)
|
setNftList(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +414,7 @@ function App() {
|
||||||
</svg>
|
</svg>
|
||||||
<Input
|
<Input
|
||||||
className="pl-10 w-full bg-zinc-900 border-zinc-700 text-white ring-offset-primary"
|
className="pl-10 w-full bg-zinc-900 border-zinc-700 text-white ring-offset-primary"
|
||||||
placeholder="Introduce ETH Address or ENS. eg: 0x00...ABC or vitalik.ens"
|
placeholder="Introduce ETH Address or ENS. eg: 0x00...ABC or vitalik.eth"
|
||||||
type="search"
|
type="search"
|
||||||
disabled={!ready}
|
disabled={!ready}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
@ -433,7 +429,13 @@ function App() {
|
||||||
{auth.isLoggedIn && !ethStatus?.ready ? (
|
{auth.isLoggedIn && !ethStatus?.ready ? (
|
||||||
<span className="max-w-4xl w-full block my-1 p-4 rounded-lg opacity-80 bg-yellow-900/70 border border-yellow-500 text-yellow-500">
|
<span className="max-w-4xl w-full block my-1 p-4 rounded-lg opacity-80 bg-yellow-900/70 border border-yellow-500 text-yellow-500">
|
||||||
You'll need to wait for a couple minutes before we can start
|
You'll need to wait for a couple minutes before we can start
|
||||||
searching. You are currently locally syncing to the ETH network. <b className="font-bold">Current Progress: {ethStatus?.sync ? `${ethStatus?.sync.toLocaleString()}%` : 'Initializing...'}</b>
|
searching. You are currently locally syncing to the ETH network.{" "}
|
||||||
|
<b className="font-bold">
|
||||||
|
Current Progress:{" "}
|
||||||
|
{ethStatus?.sync
|
||||||
|
? `${ethStatus?.sync.toLocaleString()}%`
|
||||||
|
: "Initializing..."}
|
||||||
|
</b>
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
|
||||||
|
@ -453,7 +455,7 @@ function App() {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
|
@ -467,5 +469,5 @@ export default function () {
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
</LumeStatusProvider>
|
</LumeStatusProvider>
|
||||||
</AppProvider>
|
</AppProvider>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue