diff --git a/next.config.js b/next.config.js index 9087c1113..2562d36e3 100644 --- a/next.config.js +++ b/next.config.js @@ -4,7 +4,7 @@ const nextConfig = { compiler: { styledComponents: true }, reactStrictMode: true, images: { - domains: ['ipfs.near.social'], + domains: ['ipfs.near.social','ipfs.io'], }, experimental: { optimizePackageImports: ['@phosphor-icons/react'], diff --git a/src/components/NTFImage.tsx b/src/components/NTFImage.tsx index 40309c9e9..66b8e6fc9 100644 --- a/src/components/NTFImage.tsx +++ b/src/components/NTFImage.tsx @@ -22,6 +22,15 @@ interface NftImageProps { const DEFAULT_IMAGE = 'https://ipfs.near.social/ipfs/bafkreibmiy4ozblcgv3fm3gc6q62s55em33vconbavfd2ekkuliznaq3zm'; +const getImage = (key: string) => { + const imgUrl = localStorage.getItem(`keysImage:${key}`); + return imgUrl || null; +}; + +const setImage = (key: string, url: string) => { + localStorage.setItem(`keysImage:${key}`, url); +}; + export const NftImage: React.FC = ({ nft, ipfs_cid, alt }) => { const { wallet } = useContext(NearContext); const [imageUrl, setImageUrl] = useState(DEFAULT_IMAGE); @@ -29,13 +38,17 @@ export const NftImage: React.FC = ({ nft, ipfs_cid, alt }) => { const fetchNftData = useCallback(async () => { if (!wallet || !nft || !nft.contractId || !nft.tokenId || ipfs_cid) return; + const imgCache = getImage(nft.tokenId); + if (imgCache) { + setImageUrl(imgCache); + return; + } const [nftMetadata, tokenData] = await Promise.all([ wallet.viewMethod({ contractId: nft.contractId, method: 'nft_metadata' }), wallet.viewMethod({ contractId: nft.contractId, method: 'nft_token', args: { token_id: nft.tokenId } }), ]); - const tokenMetadata = tokenData.metadata; - const tokenMedia = tokenMetadata?.media || ''; + const tokenMedia = tokenData?.metadata?.media || ''; if (tokenMedia.startsWith('https://') || tokenMedia.startsWith('http://') || tokenMedia.startsWith('data:image')) { setImageUrl(tokenMedia); @@ -54,5 +67,10 @@ export const NftImage: React.FC = ({ nft, ipfs_cid, alt }) => { } }, [ipfs_cid, fetchNftData]); + useEffect(() => { + if (!wallet || !nft || !nft.contractId || !nft.tokenId || ipfs_cid || DEFAULT_IMAGE === imageUrl) return; + setImage(nft.tokenId, imageUrl); + }, [imageUrl, wallet, nft, ipfs_cid]); + return ; }; diff --git a/src/components/tools/FungibleToken/CreateTokenForm.tsx b/src/components/tools/FungibleToken/CreateTokenForm.tsx index e980a8253..93528081c 100644 --- a/src/components/tools/FungibleToken/CreateTokenForm.tsx +++ b/src/components/tools/FungibleToken/CreateTokenForm.tsx @@ -1,11 +1,11 @@ -import { NearContext } from '@/components/WalletSelector'; -import { Button, FileInput, Flex, Form, Input, openToast, Text } from '@near-pagoda/ui'; +import { Button, FileInput, Flex, Form, Grid, Input, openToast, Text } from '@near-pagoda/ui'; import React, { useContext } from 'react'; import type { SubmitHandler } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form'; +import { NearContext } from '@/components/WalletSelector'; + type FormData = { - owner_id: string; total_supply: string; name: string; symbol: string; @@ -19,7 +19,12 @@ const MAX_FILE_SIZE = 10 * 1024; const ACCEPTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml']; const CreateTokenForm: React.FC = () => { - const { control, register, handleSubmit, formState: { errors, isSubmitting } } = useForm(); + const { + control, + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = useForm(); const { wallet, signedAccountId } = useContext(NearContext); @@ -45,40 +50,44 @@ const CreateTokenForm: React.FC = () => { if (data.icon[0]) { base64Image = await convertToBase64(data.icon[0]); } - const total_supply = BigInt(data.total_supply) * BigInt(10) ** BigInt(data.decimals) + + const total_supply = BigInt(data.total_supply) * BigInt(Math.pow(10, Number(data.decimals))); + const args = { args: { - owner_id: data.owner_id, + owner_id: signedAccountId, total_supply: total_supply.toString(), metadata: { - spec: "ft-1.0.0", + spec: 'ft-1.0.0', name: data.name, symbol: data.symbol, icon: base64Image, decimals: data.decimals, }, }, - account_id: data.owner_id, + account_id: signedAccountId, }; const requiredDeposit = await wallet?.viewMethod({ contractId: FACTORY_CONTRACT, method: 'get_required', args }); - + try { const result = await wallet?.signAndSendTransactions({ - transactions: [{ - receiverId: FACTORY_CONTRACT, - actions: [ - { - type: 'FunctionCall', - params: { - methodName: 'create_token', - args, - gas: "300000000000000", - deposit: requiredDeposit + transactions: [ + { + receiverId: FACTORY_CONTRACT, + actions: [ + { + type: 'FunctionCall', + params: { + methodName: 'create_token', + args, + gas: '300000000000000', + deposit: requiredDeposit, + }, }, - }, - ], - }] + ], + }, + ], }); if (result) { @@ -110,30 +119,40 @@ const CreateTokenForm: React.FC = () => {
- - - - + + + + + + + +
{ Accepted Formats: PNG, JPEG, GIF, SVG | Ideal dimension: 1:1 | Max size: 10kb
- -