From aba28bbb66ad7bcdc30f59e6daebf19aa15e6be3 Mon Sep 17 00:00:00 2001 From: Matias Benary Date: Tue, 24 Sep 2024 11:24:14 -0300 Subject: [PATCH 01/23] wip --- .../tools/FungibleToken/ListToken.tsx | 2 +- .../tools/Linkdrops/CreateTokenDrop.tsx | 89 +++++-- src/components/tools/Linkdrops/SelectFT.tsx | 130 ++++++++++ src/components/tools/Linkdrops/index.tsx | 4 +- src/components/tools/Linkdrops/near-icon.svg | 3 + src/hooks/useFT.ts | 62 +++++ src/pages/tools.tsx | 39 +-- src/utils/white-list.json | 242 +++++++++--------- 8 files changed, 409 insertions(+), 162 deletions(-) create mode 100644 src/components/tools/Linkdrops/SelectFT.tsx create mode 100644 src/components/tools/Linkdrops/near-icon.svg create mode 100644 src/hooks/useFT.ts diff --git a/src/components/tools/FungibleToken/ListToken.tsx b/src/components/tools/FungibleToken/ListToken.tsx index 077d80d65..828d59cb8 100644 --- a/src/components/tools/FungibleToken/ListToken.tsx +++ b/src/components/tools/FungibleToken/ListToken.tsx @@ -14,7 +14,7 @@ const ListToken = ({ tokens }: { tokens: FT[] }) => { {token.name} {token.symbol} - {BigInt(token.total_supply) / BigInt(Math.pow(10, Number(token.decimals)))} + {(BigInt(token.total_supply) / BigInt(Math.pow(10, Number(token.decimals)))).toString()} {token.name} ); diff --git a/src/components/tools/Linkdrops/CreateTokenDrop.tsx b/src/components/tools/Linkdrops/CreateTokenDrop.tsx index a6a701f0b..0e07c4474 100644 --- a/src/components/tools/Linkdrops/CreateTokenDrop.tsx +++ b/src/components/tools/Linkdrops/CreateTokenDrop.tsx @@ -7,6 +7,7 @@ import { useForm } from 'react-hook-form'; import generateAndStore from '@/utils/linkdrops'; import { NearContext } from '../../WalletSelector'; +import SelectFT from './SelectFT'; type FormData = { dropName: string; @@ -26,10 +27,27 @@ function displayBalance(balance: number) { return display; } +const KEYPOM_CONTRACT_ADDRESS = 'v2.keypom.near'; + +const formattedBalance = (balance: string, decimals = 24) => { + const numericBalance = Number(balance); + console.log("numericBalance",numericBalance); + console.log("decimals",decimals); + + + if (isNaN(numericBalance) || isNaN(decimals)) { + return '0'; + } + console.log(BigInt(Math.pow(10, decimals))); + + return (Number(numericBalance) / Math.pow(10, decimals)).toFixed(decimals); + // return result % 1 === 0 ? result.toString() : result.toFixed(5).replace(/\.?0+$/, ''); +}; + const getDeposit = (amountPerLink: number, numberLinks: number) => parseNearAmount(((0.0426 + amountPerLink) * numberLinks).toString()); -const CreateTokenDrop = () => { +const CreateTokenDrop = ({tokens}:{tokens:any}) => { const { register, handleSubmit, @@ -43,7 +61,9 @@ const CreateTokenDrop = () => { const { wallet, signedAccountId } = useContext(NearContext); const [currentNearAmount, setCurrentNearAmount] = useState(0); + const [token, setToken] = useState('near'); + console.log("tokens",tokens); useEffect(() => { if (!wallet || !signedAccountId) return; @@ -61,36 +81,66 @@ const CreateTokenDrop = () => { loadBalance(); }, [wallet, signedAccountId]); + const onSubmit: SubmitHandler = async (data) => { if (!wallet) throw new Error('Wallet has not initialized yet'); - + const dropId = Date.now().toString(); try { const args = { - deposit_per_use: parseNearAmount(data.amountPerLink.toString()), + deposit_per_use: token==="near"?parseNearAmount(data.amountPerLink.toString()):'0', + drop_id: dropId, metadata: JSON.stringify({ dropName: data.dropName, }), public_keys: generateAndStore(data.dropName, data.numberLinks), + ft : token==="near"?undefined:{ + sender_id: signedAccountId, + contract_id: token, + balance_per_use: "1000" + } }; - await wallet.signAndSendTransactions({ - transactions: [ - { - receiverId: 'v2.keypom.near', - actions: [ - { - type: 'FunctionCall', - params: { - methodName: 'create_drop', - args, - gas: '300000000000000', - deposit: getDeposit(data.amountPerLink, data.numberLinks), + + const transactions = [ + { + receiverId: 'v2.keypom.near', + actions: [ + { + type: 'FunctionCall', + params: { + methodName: 'create_drop', + args, + gas: '300000000000000', + deposit: getDeposit(data.amountPerLink, data.numberLinks), + }, + }, + ], + } + ] + + if(token!=="near"){ + + transactions.push( { + receiverId: token, + actions: [ + { + type: 'FunctionCall', + params: { + methodName: 'ft_transfer_call', + args: { + receiver_id: KEYPOM_CONTRACT_ADDRESS, + amount: "2000",//TODO cambiar + msg: dropId, }, + gas: '300000000000000', + deposit: 1, }, - ], - }, - ], - }); + }, + ], + }) + } + + await wallet.signAndSendTransactions({transactions}); openToast({ type: 'success', @@ -116,6 +166,7 @@ const CreateTokenDrop = () => {
+ { + return +} + +const SelectFT = ({tokens,setToken}:{tokens:any,setToken:(token:string)=>void}) => { + const [isOpen, setIsOpen] = useState(false); + const [selectedCurrency, setSelectedCurrency] = useState(nearCoin); + + return ( +
+ + + setIsOpen(!isOpen)} type='button'> + + {selectedCurrency.icon && {selectedCurrency.symbol}} + {!selectedCurrency.icon && } + {selectedCurrency.contract_id} ({selectedCurrency.symbol}) + + + + + {isOpen && ( + + + {tokens.map((token) => ( + + ))} + + )} + +
+ ); +}; + +export default SelectFT; \ No newline at end of file diff --git a/src/components/tools/Linkdrops/index.tsx b/src/components/tools/Linkdrops/index.tsx index 765ba9013..6553a1604 100644 --- a/src/components/tools/Linkdrops/index.tsx +++ b/src/components/tools/Linkdrops/index.tsx @@ -8,7 +8,7 @@ import CreateNFTDrop from './CreateNFTDrop'; import CreateTokenDrop from './CreateTokenDrop'; import ListTokenDrop from './ListTokenDrop'; -const Linkdrops = ({ drops }: { drops: Drops[] }) => { +const Linkdrops = ({ drops,tokens }: { drops: Drops[],tokens: any }) => { const [selector, setSelector] = useState(false); return ( @@ -22,7 +22,7 @@ const Linkdrops = ({ drops }: { drops: Drops[] }) => { /> NFT
- {!selector && } + {!selector && } {selector && } diff --git a/src/components/tools/Linkdrops/near-icon.svg b/src/components/tools/Linkdrops/near-icon.svg new file mode 100644 index 000000000..ed33db6be --- /dev/null +++ b/src/components/tools/Linkdrops/near-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/hooks/useFT.ts b/src/hooks/useFT.ts new file mode 100644 index 000000000..f8ff5b5c2 --- /dev/null +++ b/src/hooks/useFT.ts @@ -0,0 +1,62 @@ +import { NearContext } from "@/components/WalletSelector"; +import { useContext, useEffect, useState, useCallback } from "react"; +import whiteList from '@/utils/white-list.json'; + +export const accounts_ft = async (accountId: string) => { + const response = await fetch(`https://api.fastnear.com/v1/account/${accountId}/ft`); + return await response.json(); +}; + +const useFT = () => { + const { wallet, signedAccountId } = useContext(NearContext); + const [tokens, setTokens] = useState([]); + const [loading, setLoading] = useState(false); + + const fetchTokens = useCallback(async () => { + if (!wallet || !signedAccountId) return; + + setLoading(true); + try { + const res = await accounts_ft(signedAccountId); + const tokensWithMetadata = await Promise.all( + res.tokens + .filter(token => token.balance !== '0') + .map(async (token) => { + const tokenVerified = whiteList.find((item) => item.contract_id === token.contract_id); + if (!tokenVerified) { + let metadata = {}; + try { + metadata = await wallet.viewMethod({ contractId: token.contract_id, method: 'ft_metadata' }); + } catch (error) { + console.error(`Error fetching metadata for ${token.contract_id}:`, error); + } + return { + ...metadata, + contract_id: token.contract_id, + balance: token.balance, + verified: false, + }; + } + return { + ...tokenVerified, + balance: token.balance, + verified: true, + }; + }), + ); + setTokens(tokensWithMetadata); + } catch (error) { + console.error("Error fetching fungible tokens:", error); + } finally { + setLoading(false); + } + }, [wallet, signedAccountId]); + + useEffect(() => { + fetchTokens(); + }, [fetchTokens]); + + return { tokens, loading, reloadTokens: fetchTokens }; +}; + +export default useFT; \ No newline at end of file diff --git a/src/pages/tools.tsx b/src/pages/tools.tsx index ddc149630..cb12c298a 100644 --- a/src/pages/tools.tsx +++ b/src/pages/tools.tsx @@ -9,27 +9,27 @@ import NonFungibleToken from '@/components/tools/NonFungibleToken'; import { NearContext } from '@/components/WalletSelector'; import { useDefaultLayout } from '@/hooks/useLayout'; import useLinkdrops from '@/hooks/useLinkdrops'; -import type { Txns } from '@/hooks/useNearBlocksTxns'; -import useNearBlocksTxns from '@/hooks/useNearBlocksTxns'; +import useNearBlocksTxns, { Txns } from '@/hooks/useNearBlocksTxns'; import { useSignInRedirect } from '@/hooks/useSignInRedirect'; import type { NextPageWithLayout } from '@/utils/types'; +import useFT from '@/hooks/useFT'; export type FT = { - decimals: number; - icon: string; - name: string; - symbol: string; - total_supply: string; -}; + decimals: number, + icon: string, + name: string, + symbol: string, + total_supply: string, +} export type NFT = { - description: string; - media: string; - title: string; - token_id: string; -}; + description: string, + media: string, + title: string, + token_id: string, +} -const processTransactionsToFt = (transactions: Txns[]): FT[] => { +const processTransactionsToFt = (transactions: Txns[]):FT[] => { if (!transactions) return []; return transactions.map((txn) => { @@ -44,7 +44,7 @@ const processTransactionsToFt = (transactions: Txns[]): FT[] => { }); }; -const processTransactionsToNFT = (transactions: Txns[]): NFT[] => { +const processTransactionsToNFT = (transactions: Txns[]):NFT[] => { if (!transactions) return []; return transactions.map((txn) => { @@ -63,14 +63,15 @@ const ToolsPage: NextPageWithLayout = () => { const selectedTab = (router.query.tab as string) || 'ft'; const { signedAccountId } = useContext(NearContext); const drops = useLinkdrops(); + const {tokens} = useFT(); const { transactions: fts } = useNearBlocksTxns('tkn.primitives.near', 'create_token'); const ftProcessed = processTransactionsToFt(fts); - + + const { transactions: nfts } = useNearBlocksTxns('nft.primitives.near', 'nft_mint'); const nftsProcessed = processTransactionsToNFT(nfts); - console.log('near', { nftsProcessed, ftProcessed }); - + const { requestAuthentication } = useSignInRedirect(); return (
@@ -109,7 +110,7 @@ const ToolsPage: NextPageWithLayout = () => { - + diff --git a/src/utils/white-list.json b/src/utils/white-list.json index 501843d55..5b965816b 100644 --- a/src/utils/white-list.json +++ b/src/utils/white-list.json @@ -1,6 +1,6 @@ [ { - "token_name": "wrap.near", + "contract_id": "wrap.near", "spec": "ft-1.0.0", "name": "Wrapped NEAR fungible token", "symbol": "wNEAR", @@ -10,7 +10,7 @@ "decimals": 24 }, { - "token_name": "059a1f1dea1020297588c316ffc30a58a1a0d4a2.factory.bridge.near", + "contract_id": "059a1f1dea1020297588c316ffc30a58a1a0d4a2.factory.bridge.near", "spec": "ft-1.0.0", "name": "Bastion", "symbol": "BSTN", @@ -20,7 +20,7 @@ "decimals": 18 }, { - "token_name": "usdt.tether-token.near", + "contract_id": "usdt.tether-token.near", "spec": "ft-1.0.0", "name": "Tether USD", "symbol": "USDt", @@ -30,7 +30,7 @@ "decimals": 6 }, { - "token_name": "deip-token.near", + "contract_id": "deip-token.near", "spec": "ft-1.0.0", "name": "DEIP Token", "symbol": "DEIP", @@ -40,7 +40,7 @@ "decimals": 18 }, { - "token_name": "usn", + "contract_id": "usn", "spec": "ft-1.0.0", "name": "USN", "symbol": "USN", @@ -50,7 +50,7 @@ "decimals": 18 }, { - "token_name": "c944e90c64b2c07662a292be6244bdf05cda44a7.factory.bridge.near", + "contract_id": "c944e90c64b2c07662a292be6244bdf05cda44a7.factory.bridge.near", "spec": "ft-1.0.0", "name": "Graph Token", "symbol": "GRT", @@ -60,7 +60,7 @@ "decimals": 18 }, { - "token_name": "2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near", + "contract_id": "2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near", "spec": "ft-1.0.0", "name": "Wrapped BTC", "symbol": "WBTC", @@ -70,7 +70,7 @@ "decimals": 8 }, { - "token_name": "7e5981c2e072f53a0323d3d80baca3e31fb1550c.factory.bridge.near", + "contract_id": "7e5981c2e072f53a0323d3d80baca3e31fb1550c.factory.bridge.near", "spec": "ft-1.0.0", "name": "JovJou", "symbol": "JOVJOU", @@ -80,7 +80,7 @@ "decimals": 18 }, { - "token_name": "dbio.near", + "contract_id": "dbio.near", "spec": "ft-1.0.0", "name": "Debio", "symbol": "DBIO", @@ -90,7 +90,7 @@ "decimals": 18 }, { - "token_name": "berryclub.ek.near", + "contract_id": "berryclub.ek.near", "spec": "ft-1.0.0", "name": "Banana", "symbol": "BANANA", @@ -100,7 +100,7 @@ "decimals": 18 }, { - "token_name": "6f259637dcd74c767781e37bc6133cd6a68aa161.factory.bridge.near", + "contract_id": "6f259637dcd74c767781e37bc6133cd6a68aa161.factory.bridge.near", "spec": "ft-1.0.0", "name": "HuobiToken", "symbol": "HT", @@ -110,7 +110,7 @@ "decimals": 18 }, { - "token_name": "atocha-token.near", + "contract_id": "atocha-token.near", "spec": "ft-1.0.0", "name": "Atocha Coin", "symbol": "ATO", @@ -120,7 +120,7 @@ "decimals": 18 }, { - "token_name": "853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near", + "contract_id": "853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near", "spec": "ft-1.0.0", "name": "Frax", "symbol": "FRAX", @@ -130,7 +130,7 @@ "decimals": 18 }, { - "token_name": "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near", + "contract_id": "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near", "spec": "ft-1.0.0", "name": "Bridged USDC", "symbol": "USDC.e", @@ -140,7 +140,7 @@ "decimals": 6 }, { - "token_name": "52a047ee205701895ee06a375492490ec9c597ce.factory.bridge.near", + "contract_id": "52a047ee205701895ee06a375492490ec9c597ce.factory.bridge.near", "spec": "ft-1.0.0", "name": "Pulse", "symbol": "PULSE", @@ -150,7 +150,7 @@ "decimals": 18 }, { - "token_name": "meta-token.near", + "contract_id": "meta-token.near", "spec": "ft-1.0.0", "name": "Meta Token", "symbol": "$META", @@ -160,7 +160,7 @@ "decimals": 24 }, { - "token_name": "0c10bf8fcb7bf5412187a595ab97a3609160b5c6.factory.bridge.near", + "contract_id": "0c10bf8fcb7bf5412187a595ab97a3609160b5c6.factory.bridge.near", "spec": "ft-1.0.0", "name": "Decentralized USD", "symbol": "USDD", @@ -170,7 +170,7 @@ "decimals": 18 }, { - "token_name": "token.sweat", + "contract_id": "token.sweat", "spec": "ft-1.0", "name": "SWEAT", "symbol": "SWEAT", @@ -180,7 +180,7 @@ "decimals": 18 }, { - "token_name": "501ace9c35e60f03a2af4d484f49f9b1efde9f40.factory.bridge.near", + "contract_id": "501ace9c35e60f03a2af4d484f49f9b1efde9f40.factory.bridge.near", "spec": "ft-1.0.0", "name": "solace", "symbol": "SOLACE", @@ -190,7 +190,7 @@ "decimals": 18 }, { - "token_name": "de30da39c46104798bb5aa3fe8b9e0e1f348163f.factory.bridge.near", + "contract_id": "de30da39c46104798bb5aa3fe8b9e0e1f348163f.factory.bridge.near", "spec": "ft-1.0.0", "name": "Gitcoin", "symbol": "GTC", @@ -200,7 +200,7 @@ "decimals": 18 }, { - "token_name": "utopia.secretskelliessociety.near", + "contract_id": "utopia.secretskelliessociety.near", "spec": "ft-1.0.0", "name": "Utopia", "symbol": "UTO", @@ -210,7 +210,7 @@ "decimals": 8 }, { - "token_name": "token.bocachica_mars.near", + "contract_id": "token.bocachica_mars.near", "spec": "ft-1.0.0", "name": "Boca Chica", "symbol": "CHICA", @@ -220,7 +220,7 @@ "decimals": 18 }, { - "token_name": "cf3c8be2e2c42331da80ef210e9b1b307c03d36a.factory.bridge.near", + "contract_id": "cf3c8be2e2c42331da80ef210e9b1b307c03d36a.factory.bridge.near", "spec": "ft-1.0.0", "name": "BetProtocolToken", "symbol": "BEPRO", @@ -230,7 +230,7 @@ "decimals": 18 }, { - "token_name": "39a15a0695c77cbe5fd4f06ab0ccb7bad62f696f.factory.bridge.near", + "contract_id": "39a15a0695c77cbe5fd4f06ab0ccb7bad62f696f.factory.bridge.near", "spec": "ft-1.0.0", "name": "rMutantCoin", "symbol": "rMC", @@ -240,7 +240,7 @@ "decimals": 18 }, { - "token_name": "1f9840a85d5af5bf1d1762f925bdaddc4201f984.factory.bridge.near", + "contract_id": "1f9840a85d5af5bf1d1762f925bdaddc4201f984.factory.bridge.near", "spec": "ft-1.0.0", "name": "Uniswap", "symbol": "UNI", @@ -250,7 +250,7 @@ "decimals": 18 }, { - "token_name": "fusotao-token.near", + "contract_id": "fusotao-token.near", "spec": "ft-1.0.0", "name": "FUSOTAO", "symbol": "TAO", @@ -260,7 +260,7 @@ "decimals": 18 }, { - "token_name": "1ab43204a195a0fd37edec621482afd3792ef90b.factory.bridge.near", + "contract_id": "1ab43204a195a0fd37edec621482afd3792ef90b.factory.bridge.near", "spec": "ft-1.0.0", "name": "Aurigami Token", "symbol": "PLY", @@ -270,7 +270,7 @@ "decimals": 18 }, { - "token_name": "v2-nearx.stader-labs.near", + "contract_id": "v2-nearx.stader-labs.near", "spec": "ft-1.0.0", "name": "NearX", "symbol": "NearX", @@ -280,7 +280,7 @@ "decimals": 24 }, { - "token_name": "6b175474e89094c44da98b954eedeac495271d0f.factory.bridge.near", + "contract_id": "6b175474e89094c44da98b954eedeac495271d0f.factory.bridge.near", "spec": "ft-1.0.0", "name": "Dai Stablecoin", "symbol": "DAI", @@ -290,7 +290,7 @@ "decimals": 18 }, { - "token_name": "token.paras.near", + "contract_id": "token.paras.near", "spec": "ft-1.0.0", "name": "PARAS", "symbol": "PARAS", @@ -300,7 +300,7 @@ "decimals": 18 }, { - "token_name": "token.cheddar.near", + "contract_id": "token.cheddar.near", "spec": "ft-1.0.0", "name": "Cheddar", "symbol": "Cheddar", @@ -310,7 +310,7 @@ "decimals": 24 }, { - "token_name": "7f5c4aded107f66687e6e55dee36a3a8fa3de030.factory.bridge.near", + "contract_id": "7f5c4aded107f66687e6e55dee36a3a8fa3de030.factory.bridge.near", "spec": "ft-1.0.0", "name": "Endemic", "symbol": "END", @@ -320,7 +320,7 @@ "decimals": 18 }, { - "token_name": "memelol.near", + "contract_id": "memelol.near", "spec": "ft-1.0.0", "name": "LOL Memecoin", "symbol": "LOL", @@ -330,7 +330,7 @@ "decimals": 24 }, { - "token_name": "0316eb71485b0ab14103307bf65a021042c6d380.factory.bridge.near", + "contract_id": "0316eb71485b0ab14103307bf65a021042c6d380.factory.bridge.near", "spec": "ft-1.0.0", "name": "Huobi BTC", "symbol": "HBTC", @@ -340,7 +340,7 @@ "decimals": 18 }, { - "token_name": "token.v2.ref-finance.near", + "contract_id": "token.v2.ref-finance.near", "spec": "ft-1.0.0", "name": "Ref Finance Token", "symbol": "REF", @@ -350,7 +350,7 @@ "decimals": 18 }, { - "token_name": "6a8c1211d36be23d326a6b0bc4e29b482595d0a3.factory.bridge.near", + "contract_id": "6a8c1211d36be23d326a6b0bc4e29b482595d0a3.factory.bridge.near", "spec": "ft-1.0.0", "name": "PachaVerse DAO", "symbol": "PACHA", @@ -360,7 +360,7 @@ "decimals": 18 }, { - "token_name": "a0dc23fa9f42146e62e027c50f866d8bdcc46a8a.factory.bridge.near", + "contract_id": "a0dc23fa9f42146e62e027c50f866d8bdcc46a8a.factory.bridge.near", "spec": "ft-1.0.0", "name": "Qu!D", "symbol": "QD", @@ -370,7 +370,7 @@ "decimals": 24 }, { - "token_name": "intel.tkn.near", + "contract_id": "intel.tkn.near", "spec": "ft-1.0.0", "name": "INTEAR", "symbol": "INTEL", @@ -380,7 +380,7 @@ "decimals": 18 }, { - "token_name": "aurora", + "contract_id": "aurora", "spec": "ft-1.0.0", "name": "Ether", "symbol": "ETH", @@ -390,7 +390,7 @@ "decimals": 18 }, { - "token_name": "e99de844ef3ef72806cf006224ef3b813e82662f.factory.bridge.near", + "contract_id": "e99de844ef3ef72806cf006224ef3b813e82662f.factory.bridge.near", "spec": "ft-1.0.0", "name": "YouMinter", "symbol": "UMINT", @@ -400,7 +400,7 @@ "decimals": 18 }, { - "token_name": "benthedog.near", + "contract_id": "benthedog.near", "spec": "ft-1.0.0", "name": "Ben the Dog", "symbol": "BENDOG", @@ -410,7 +410,7 @@ "decimals": 9 }, { - "token_name": "f56b164efd3cfc02ba739b719b6526a6fa1ca32a.factory.bridge.near", + "contract_id": "f56b164efd3cfc02ba739b719b6526a6fa1ca32a.factory.bridge.near", "spec": "ft-1.0.0", "name": "Curio Governance Token", "symbol": "CGT", @@ -420,7 +420,7 @@ "decimals": 18 }, { - "token_name": "ft.zomland.near", + "contract_id": "ft.zomland.near", "spec": "ft-1.0.0", "name": "ZomLand Token", "symbol": "ZML", @@ -430,7 +430,7 @@ "decimals": 24 }, { - "token_name": "c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near", + "contract_id": "c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near", "spec": "ft-1.0.0", "name": "Wrapped Ether", "symbol": "WETH", @@ -440,7 +440,7 @@ "decimals": 18 }, { - "token_name": "neiro.token0.near", + "contract_id": "neiro.token0.near", "spec": "ft-1.0.0", "name": "NEIRO", "symbol": "NEIRO", @@ -450,7 +450,7 @@ "decimals": 18 }, { - "token_name": "token.0xshitzu.near", + "contract_id": "token.0xshitzu.near", "spec": "ft-1.0.0", "name": "SHITZU", "symbol": "SHITZU", @@ -460,7 +460,7 @@ "decimals": 18 }, { - "token_name": "token.pumpopoly.near", + "contract_id": "token.pumpopoly.near", "spec": "ft-1.0.0", "name": "Pumpopoly fungible token", "symbol": "PUMPOPOLY", @@ -470,7 +470,7 @@ "decimals": 24 }, { - "token_name": "jumptoken.jumpfinance.near", + "contract_id": "jumptoken.jumpfinance.near", "spec": "ft-1.0.0", "name": "JUMP", "symbol": "JUMP", @@ -480,7 +480,7 @@ "decimals": 18 }, { - "token_name": "818f49467021bdaadae69e071e79ad2fd7226a1e.factory.bridge.near", + "contract_id": "818f49467021bdaadae69e071e79ad2fd7226a1e.factory.bridge.near", "spec": "ft-1.0.0", "name": "FAME", "symbol": "FAME", @@ -490,7 +490,7 @@ "decimals": 18 }, { - "token_name": "token.lonkingnearbackto2024.near", + "contract_id": "token.lonkingnearbackto2024.near", "spec": "ft-1.0.0", "name": "LONK fungible token", "symbol": "LONK", @@ -500,7 +500,7 @@ "decimals": 8 }, { - "token_name": "sol.token.a11bd.near", + "contract_id": "sol.token.a11bd.near", "spec": "ft-1.0.0", "name": "Solana", "symbol": "SOL", @@ -510,7 +510,7 @@ "decimals": 24 }, { - "token_name": "4691937a7508860f876c9c0a2a617e7d9e945d4b.factory.bridge.near", + "contract_id": "4691937a7508860f876c9c0a2a617e7d9e945d4b.factory.bridge.near", "spec": "ft-1.0.0", "name": "Wootrade Network", "symbol": "WOO", @@ -520,7 +520,7 @@ "decimals": 18 }, { - "token_name": "v1.dacha-finance.near", + "contract_id": "v1.dacha-finance.near", "spec": "ft-1.0.0", "name": "Potato 🥔", "symbol": "POTATO", @@ -530,7 +530,7 @@ "decimals": 21 }, { - "token_name": "ust.token.a11bd.near", + "contract_id": "ust.token.a11bd.near", "spec": "ft-1.0.0", "name": "TerraUSD", "symbol": "UST", @@ -540,7 +540,7 @@ "decimals": 24 }, { - "token_name": "linear-protocol.near", + "contract_id": "linear-protocol.near", "spec": "ft-1.0.0", "name": "LiNEAR", "symbol": "LINEAR", @@ -550,7 +550,7 @@ "decimals": 24 }, { - "token_name": "4e807467ba9e3119d5356c5568ef63e9c321b471.factory.bridge.near", + "contract_id": "4e807467ba9e3119d5356c5568ef63e9c321b471.factory.bridge.near", "spec": "ft-1.0.0", "name": "Otto Token", "symbol": "OTTO", @@ -560,7 +560,7 @@ "decimals": 18 }, { - "token_name": "blackdragon.tkn.near", + "contract_id": "blackdragon.tkn.near", "spec": "ft-1.0.0", "name": "Black Dragon", "symbol": "BLACKDRAGON", @@ -570,7 +570,7 @@ "decimals": 24 }, { - "token_name": "802d89b6e511b335f05024a65161bce7efc3f311.factory.bridge.near", + "contract_id": "802d89b6e511b335f05024a65161bce7efc3f311.factory.bridge.near", "spec": "ft-1.0.0", "name": "LNR", "symbol": "LNR", @@ -580,7 +580,7 @@ "decimals": 18 }, { - "token_name": "3540abe4f288b280a0740ad5121aec337c404d15.factory.bridge.near", + "contract_id": "3540abe4f288b280a0740ad5121aec337c404d15.factory.bridge.near", "spec": "ft-1.0.0", "name": "TPRO", "symbol": "TPRO", @@ -590,7 +590,7 @@ "decimals": 18 }, { - "token_name": "babyblackdragon.tkn.near", + "contract_id": "babyblackdragon.tkn.near", "spec": "ft-1.0.0", "name": "BABYBLACKDRAGON", "symbol": "BABYBLACKDRAGON", @@ -600,7 +600,7 @@ "decimals": 24 }, { - "token_name": "apys.token.a11bd.near", + "contract_id": "apys.token.a11bd.near", "spec": "ft-1.0.0", "name": "APYSwap", "symbol": "APYS", @@ -610,7 +610,7 @@ "decimals": 24 }, { - "token_name": "438e48ed4ce6beecf503d43b9dbd3c30d516e7fd.factory.bridge.near", + "contract_id": "438e48ed4ce6beecf503d43b9dbd3c30d516e7fd.factory.bridge.near", "spec": "ft-1.0.0", "name": "UWON", "symbol": "UWON", @@ -620,7 +620,7 @@ "decimals": 18 }, { - "token_name": "cusd.token.a11bd.near", + "contract_id": "cusd.token.a11bd.near", "spec": "ft-1.0.0", "name": "Celo Dollar", "symbol": "cUSD", @@ -630,7 +630,7 @@ "decimals": 24 }, { - "token_name": "a4ef4b0b23c1fc81d3f9ecf93510e64f58a4a016.factory.bridge.near", + "contract_id": "a4ef4b0b23c1fc81d3f9ecf93510e64f58a4a016.factory.bridge.near", "spec": "ft-1.0.0", "name": "1MILNFT", "symbol": "1MIL", @@ -640,7 +640,7 @@ "decimals": 18 }, { - "token_name": "d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near", + "contract_id": "d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near", "spec": "ft-1.0.0", "name": "HAPI", "symbol": "HAPI", @@ -650,7 +650,7 @@ "decimals": 18 }, { - "token_name": "mpdao-token.near", + "contract_id": "mpdao-token.near", "spec": "ft-1.0.0", "name": "metapool.app DAO Governance Token", "symbol": "mpDAO", @@ -660,7 +660,7 @@ "decimals": 6 }, { - "token_name": "514910771af9ca656af840dff83e8264ecf986ca.factory.bridge.near", + "contract_id": "514910771af9ca656af840dff83e8264ecf986ca.factory.bridge.near", "spec": "ft-1.0.0", "name": "ChainLink Token", "symbol": "LINK", @@ -670,7 +670,7 @@ "decimals": 18 }, { - "token_name": "f5cfbc74057c610c8ef151a439252680ac68c6dc.factory.bridge.near", + "contract_id": "f5cfbc74057c610c8ef151a439252680ac68c6dc.factory.bridge.near", "spec": "ft-1.0.0", "name": "Octopus Network Token", "symbol": "OCT", @@ -680,7 +680,7 @@ "decimals": 18 }, { - "token_name": "509a38b7a1cc0dcd83aa9d06214663d9ec7c7f4a.factory.bridge.near", + "contract_id": "509a38b7a1cc0dcd83aa9d06214663d9ec7c7f4a.factory.bridge.near", "spec": "ft-1.0.0", "name": "BlocksquareToken", "symbol": "BST", @@ -690,7 +690,7 @@ "decimals": 18 }, { - "token_name": "9aeb50f542050172359a0e1a25a9933bc8c01259.factory.bridge.near", + "contract_id": "9aeb50f542050172359a0e1a25a9933bc8c01259.factory.bridge.near", "spec": "ft-1.0.0", "name": "oinfinance", "symbol": "OIN", @@ -700,7 +700,7 @@ "decimals": 8 }, { - "token_name": "usmeme.tg", + "contract_id": "usmeme.tg", "spec": "ft-1.0.0", "name": "USMeme", "symbol": "USM", @@ -710,7 +710,7 @@ "decimals": 8 }, { - "token_name": "slush.tkn.near", + "contract_id": "slush.tkn.near", "spec": "ft-1.0.0", "name": "Slushie", "symbol": "SLUSH", @@ -720,7 +720,7 @@ "decimals": 18 }, { - "token_name": "arepita.near", + "contract_id": "arepita.near", "spec": "ft-1.0.0", "name": "Arepita", "symbol": "ARP", @@ -730,7 +730,7 @@ "decimals": 6 }, { - "token_name": "0000000000085d4780b73119b644ae5ecd22b376.factory.bridge.near", + "contract_id": "0000000000085d4780b73119b644ae5ecd22b376.factory.bridge.near", "spec": "ft-1.0.0", "name": "TrueUSD", "symbol": "TUSD", @@ -740,7 +740,7 @@ "decimals": 18 }, { - "token_name": "meta-pool.near", + "contract_id": "meta-pool.near", "spec": "ft-1.0.0", "name": "Staked NEAR", "symbol": "STNEAR", @@ -750,7 +750,7 @@ "decimals": 24 }, { - "token_name": "edge-fast.near", + "contract_id": "edge-fast.near", "spec": "ft-1.0.0", "name": "Edge Video AI", "symbol": "FAST", @@ -760,7 +760,7 @@ "decimals": 24 }, { - "token_name": "dragonsoultoken.near", + "contract_id": "dragonsoultoken.near", "spec": "ft-1.0.0", "name": "Dragon Soul", "symbol": "DGS", @@ -770,7 +770,7 @@ "decimals": 18 }, { - "token_name": "phoenix-bonds.near", + "contract_id": "phoenix-bonds.near", "spec": "ft-1.0.0", "name": "Phoenix NEAR", "symbol": "pNEAR", @@ -780,7 +780,7 @@ "decimals": 24 }, { - "token_name": "v3.oin_finance.near", + "contract_id": "v3.oin_finance.near", "spec": "ft-1.0.0", "name": "nUSDO", "symbol": "nUSDO", @@ -790,7 +790,7 @@ "decimals": 8 }, { - "token_name": "2bb360ef17faaf3b33e6513bf6c5c382c6aa8c28.factory.bridge.near", + "contract_id": "2bb360ef17faaf3b33e6513bf6c5c382c6aa8c28.factory.bridge.near", "spec": "ft-1.0.0", "name": "Bridgit DAO", "symbol": "BRGT", @@ -800,7 +800,7 @@ "decimals": 18 }, { - "token_name": "16.contract.portalbridge.near", + "contract_id": "16.contract.portalbridge.near", "spec": "ft-1.0.0", "name": "USD Coin", "symbol": "USDC", @@ -810,7 +810,7 @@ "decimals": 6 }, { - "token_name": "ftv2.nekotoken.near", + "contract_id": "ftv2.nekotoken.near", "spec": "ft-1.0.0", "name": "NEKO", "symbol": "NEKO", @@ -821,7 +821,7 @@ "decimals": 24 }, { - "token_name": "111111111117dc0aa78b770fa6a738034120c302.factory.bridge.near", + "contract_id": "111111111117dc0aa78b770fa6a738034120c302.factory.bridge.near", "spec": "ft-1.0.0", "name": "1INCH Token", "symbol": "1INCH", @@ -831,7 +831,7 @@ "decimals": 18 }, { - "token_name": "0aabcc65ef352ad84b1326df188c95b6ab856c1c.factory.bridge.near", + "contract_id": "0aabcc65ef352ad84b1326df188c95b6ab856c1c.factory.bridge.near", "spec": "ft-1.0.0", "name": "Scorefam", "symbol": "SFT", @@ -841,7 +841,7 @@ "decimals": 8 }, { - "token_name": "ndc.tkn.near", + "contract_id": "ndc.tkn.near", "spec": "ft-1.0.0", "name": "ObamaSonicTrumpSkidanovPolosukhinSonicInuTen", "symbol": "NDC", @@ -851,7 +851,7 @@ "decimals": 18 }, { - "token_name": "neat.nrc-20.near", + "contract_id": "neat.nrc-20.near", "spec": "ft-1.0.0", "name": "NEAT", "symbol": "NEAT", @@ -861,7 +861,7 @@ "decimals": 8 }, { - "token_name": "3ea8ea4237344c9931214796d9417af1a1180770.factory.bridge.near", + "contract_id": "3ea8ea4237344c9931214796d9417af1a1180770.factory.bridge.near", "spec": "ft-1.0.0", "name": "Flux Token", "symbol": "FLX", @@ -871,7 +871,7 @@ "decimals": 18 }, { - "token_name": "discovol-token.near", + "contract_id": "discovol-token.near", "spec": "ft-1.0.0", "name": "DISCOVOL TOKEN", "symbol": "DISC", @@ -881,7 +881,7 @@ "decimals": 14 }, { - "token_name": "30d20208d987713f46dfd34ef128bb16c404d10f.factory.bridge.near", + "contract_id": "30d20208d987713f46dfd34ef128bb16c404d10f.factory.bridge.near", "spec": "ft-1.0.0", "name": "Stader", "symbol": "SD", @@ -891,7 +891,7 @@ "decimals": 18 }, { - "token_name": "abr.a11bd.near", + "contract_id": "abr.a11bd.near", "spec": "ft-1.0.0", "name": "ABR", "symbol": "ABR", @@ -901,7 +901,7 @@ "decimals": 24 }, { - "token_name": "myriadcore.near", + "contract_id": "myriadcore.near", "spec": "ft-1.0.0", "name": "Myria", "symbol": "MYRIA", @@ -911,7 +911,7 @@ "decimals": 18 }, { - "token_name": "dac17f958d2ee523a2206206994597c13d831ec7.factory.bridge.near", + "contract_id": "dac17f958d2ee523a2206206994597c13d831ec7.factory.bridge.near", "spec": "ft-1.0.0", "name": "Tether USD", "symbol": "USDT.e", @@ -921,7 +921,7 @@ "decimals": 6 }, { - "token_name": "0000000de40dfa9b17854cbc7869d80f9f98d823.factory.bridge.near", + "contract_id": "0000000de40dfa9b17854cbc7869d80f9f98d823.factory.bridge.near", "spec": "ft-1.0.0", "name": "delta.theta", "symbol": "DLTA", @@ -931,7 +931,7 @@ "decimals": 18 }, { - "token_name": "farm.berryclub.ek.near", + "contract_id": "farm.berryclub.ek.near", "spec": "ft-1.0.0", "name": "Cucumber", "symbol": "CUCUMBER", @@ -941,7 +941,7 @@ "decimals": 18 }, { - "token_name": "xtoken.ref-finance.near", + "contract_id": "xtoken.ref-finance.near", "spec": "ft-1.0.0", "name": "xRef Finance Token", "symbol": "xREF", @@ -951,7 +951,7 @@ "decimals": 18 }, { - "token_name": "44ee4ae1e0c2e6160715f24c02fd8df72afe31f2.factory.bridge.near", + "contract_id": "44ee4ae1e0c2e6160715f24c02fd8df72afe31f2.factory.bridge.near", "spec": "ft-1.0.0", "name": "ANS.BEST - knowledgeFi", "symbol": "ANS", @@ -961,7 +961,7 @@ "decimals": 18 }, { - "token_name": "1494ca1f11d487c2bbe4543e90080aeba4ba3c2b.factory.bridge.near", + "contract_id": "1494ca1f11d487c2bbe4543e90080aeba4ba3c2b.factory.bridge.near", "spec": "ft-1.0.0", "name": "DefiPulse Index", "symbol": "DPI", @@ -971,7 +971,7 @@ "decimals": 18 }, { - "token_name": "3231cb76718cdef2155fc47b5286d82e6eda273f.factory.bridge.near", + "contract_id": "3231cb76718cdef2155fc47b5286d82e6eda273f.factory.bridge.near", "spec": "ft-1.0.0", "name": "Monerium EUR emoney", "symbol": "EURe", @@ -981,7 +981,7 @@ "decimals": 18 }, { - "token_name": "8353b92201f19b4812eee32efd325f7ede123718.factory.bridge.near", + "contract_id": "8353b92201f19b4812eee32efd325f7ede123718.factory.bridge.near", "spec": "ft-1.0.0", "name": "Scamfari", "symbol": "SCM", @@ -991,7 +991,7 @@ "decimals": 18 }, { - "token_name": "celo.token.a11bd.near", + "contract_id": "celo.token.a11bd.near", "spec": "ft-1.0.0", "name": "Celo", "symbol": "CELO", @@ -1001,7 +1001,7 @@ "decimals": 24 }, { - "token_name": "9c2dc0c3cc2badde84b0025cf4df1c5af288d835.factory.bridge.near", + "contract_id": "9c2dc0c3cc2badde84b0025cf4df1c5af288d835.factory.bridge.near", "spec": "ft-1.0.0", "name": "COR Token", "symbol": "COR", @@ -1011,7 +1011,7 @@ "decimals": 18 }, { - "token_name": "marmaj.tkn.near", + "contract_id": "marmaj.tkn.near", "spec": "ft-1.0.0", "name": "marma j token", "symbol": "marmaj", @@ -1021,7 +1021,7 @@ "decimals": 18 }, { - "token_name": "luna.token.a11bd.near", + "contract_id": "luna.token.a11bd.near", "spec": "ft-1.0.0", "name": "Luna", "symbol": "LUNA", @@ -1031,7 +1031,7 @@ "decimals": 24 }, { - "token_name": "bean.tkn.near", + "contract_id": "bean.tkn.near", "spec": "ft-1.0.0", "name": "BEAN", "symbol": "BEAN", @@ -1041,7 +1041,7 @@ "decimals": 18 }, { - "token_name": "token.burrow.near", + "contract_id": "token.burrow.near", "spec": "ft-1.0.0", "name": "Burrow Token", "symbol": "BRRR", @@ -1051,7 +1051,7 @@ "decimals": 18 }, { - "token_name": "hat.tkn.near", + "contract_id": "hat.tkn.near", "spec": "ft-1.0.0", "name": "Buidlers Wear Hard Hats", "symbol": "HAT", @@ -1061,7 +1061,7 @@ "decimals": 18 }, { - "token_name": "cc6f64b74614f52e7fd808a48ad01a26ca778200.factory.bridge.near", + "contract_id": "cc6f64b74614f52e7fd808a48ad01a26ca778200.factory.bridge.near", "spec": "ft-1.0.0", "name": "AURORA_2022_11_18", "symbol": "AURORA_2211", @@ -1071,7 +1071,7 @@ "decimals": 18 }, { - "token_name": "nkok.tkn.near", + "contract_id": "nkok.tkn.near", "spec": "ft-1.0.0", "name": "Nearkok", "symbol": "nKOK", @@ -1081,7 +1081,7 @@ "decimals": 18 }, { - "token_name": "touched.tkn.near", + "contract_id": "touched.tkn.near", "spec": "ft-1.0.0", "name": "Jensen Touched Illia", "symbol": "TOUCHED", @@ -1091,7 +1091,7 @@ "decimals": 24 }, { - "token_name": "pixeltoken.near", + "contract_id": "pixeltoken.near", "spec": "ft-1.0.0", "name": "Pixeltoken", "symbol": "PXT", @@ -1101,7 +1101,7 @@ "decimals": 6 }, { - "token_name": "aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near", + "contract_id": "aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near", "spec": "ft-1.0.0", "name": "Aurora", "symbol": "AURORA", @@ -1111,7 +1111,7 @@ "decimals": 18 }, { - "token_name": "nearnvidia.near", + "contract_id": "nearnvidia.near", "spec": "ft-1.0.0", "name": "NearVidia", "symbol": "NEARVIDIA", @@ -1121,7 +1121,7 @@ "decimals": 8 }, { - "token_name": "c6903b623f1548f533eb367f6f1b7d717b9351c2.factory.bridge.near", + "contract_id": "c6903b623f1548f533eb367f6f1b7d717b9351c2.factory.bridge.near", "spec": "ft-1.0.0", "name": "Presence DAO", "symbol": "PRESENCE", @@ -1131,7 +1131,7 @@ "decimals": 18 }, { - "token_name": "dd.tg", + "contract_id": "dd.tg", "spec": "ft-1.0.0", "name": "DoubleDog", "symbol": "DD", @@ -1141,7 +1141,7 @@ "decimals": 8 }, { - "token_name": "22.contract.portalbridge.near", + "contract_id": "22.contract.portalbridge.near", "spec": "ft-1.0.0", "name": "Wrapped SOL", "symbol": "SOL", @@ -1151,7 +1151,7 @@ "decimals": 8 }, { - "token_name": "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1", + "contract_id": "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1", "spec": "ft-1.0.0", "name": "USDC", "symbol": "USDC", @@ -1161,7 +1161,7 @@ "decimals": 6 }, { - "token_name": "far.tokens.fewandfar.near", + "contract_id": "far.tokens.fewandfar.near", "spec": "ft-1.0.0", "name": "Few and Far", "symbol": "FAR", @@ -1171,7 +1171,7 @@ "decimals": 8 }, { - "token_name": "a663b02cf0a4b149d2ad41910cb81e23e1c41c32.factory.bridge.near", + "contract_id": "a663b02cf0a4b149d2ad41910cb81e23e1c41c32.factory.bridge.near", "spec": "ft-1.0.0", "name": "Staked FRAX", "symbol": "sFRAX", @@ -1181,7 +1181,7 @@ "decimals": 18 }, { - "token_name": "gear.enleap.near", + "contract_id": "gear.enleap.near", "spec": "ft-1.0.0", "name": "GEAR", "symbol": "GEAR", @@ -1191,7 +1191,7 @@ "decimals": 18 }, { - "token_name": "967da4048cd07ab37855c090aaf366e4ce1b9f48.factory.bridge.near", + "contract_id": "967da4048cd07ab37855c090aaf366e4ce1b9f48.factory.bridge.near", "spec": "ft-1.0.0", "name": "Ocean Token", "symbol": "OCEAN", @@ -1201,7 +1201,7 @@ "decimals": 18 }, { - "token_name": "token.stlb.near", + "contract_id": "token.stlb.near", "spec": "ft-1.0.0", "name": "SeatlabNFT", "symbol": "SEAT", From e47e536b4f56cd72112aa13cdec4658f7817dc2d Mon Sep 17 00:00:00 2001 From: gagdiez Date: Tue, 24 Sep 2024 17:15:30 +0200 Subject: [PATCH 02/23] wip: small fixes --- src/components/WalletSelector.ts | 8 +- .../tools/Linkdrops/CreateNFTDrop.tsx | 1 - .../tools/Linkdrops/CreateTokenDrop.tsx | 93 +++++++++---------- src/components/tools/Linkdrops/SelectFT.tsx | 85 +++++++---------- src/components/tools/Linkdrops/index.tsx | 9 +- src/hooks/useFT.ts | 34 ++++--- src/pages/tools.tsx | 14 ++- 7 files changed, 117 insertions(+), 127 deletions(-) diff --git a/src/components/WalletSelector.ts b/src/components/WalletSelector.ts index 61ba6b8ff..720150e79 100644 --- a/src/components/WalletSelector.ts +++ b/src/components/WalletSelector.ts @@ -168,7 +168,7 @@ export class Wallet { return providers.getTransactionLastResult(transaction); }; - getBalance = async (accountId: string) => { + getBalance = async (accountId: string, format = true) => { const walletSelector = await this.selector; const { network } = walletSelector.options; const provider = new providers.JsonRpcProvider({ url: network.nodeUrl }); @@ -180,7 +180,11 @@ export class Wallet { finality: 'final', }); // return amount on NEAR - return account.amount ? Number(utils.format.formatNearAmount(account.amount)) : 0; + if (format){ + return account.amount ? Number(utils.format.formatNearAmount(account.amount)) : 0; + } else { + return account.amount || 0; + } }; signAndSendTransactions = async ({ transactions }: { transactions: any[] }) => { diff --git a/src/components/tools/Linkdrops/CreateNFTDrop.tsx b/src/components/tools/Linkdrops/CreateNFTDrop.tsx index 868b681d5..b58ce7651 100644 --- a/src/components/tools/Linkdrops/CreateNFTDrop.tsx +++ b/src/components/tools/Linkdrops/CreateNFTDrop.tsx @@ -144,7 +144,6 @@ const CreateNFTDrop = () => { }; return ( <> - NFT Drop { - const numericBalance = Number(balance); - console.log("numericBalance",numericBalance); - console.log("decimals",decimals); - - - if (isNaN(numericBalance) || isNaN(decimals)) { - return '0'; - } - console.log(BigInt(Math.pow(10, decimals))); - - return (Number(numericBalance) / Math.pow(10, decimals)).toFixed(decimals); - // return result % 1 === 0 ? result.toString() : result.toFixed(5).replace(/\.?0+$/, ''); + const balanceStr = balance.toString(); + const integerPart = balanceStr.slice(0, -decimals) || '0'; + const decimalPart = balanceStr.slice(-decimals).padStart(decimals, '0'); + return `${integerPart}.${decimalPart.slice(2)}`; }; +const parseAmount = (amount: string, decimals: number) => { + const [integer, decimal] = amount.split('.'); + const integerPart = integer || '0'; + const decimalPart = decimal || '0'; + return integerPart + decimalPart.padEnd(decimals, '0'); +} + const getDeposit = (amountPerLink: number, numberLinks: number) => parseNearAmount(((0.0426 + amountPerLink) * numberLinks).toString()); -const CreateTokenDrop = ({tokens}:{tokens:any}) => { +const CreateTokenDrop = () => { const { register, handleSubmit, @@ -60,47 +62,41 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { }); const { wallet, signedAccountId } = useContext(NearContext); - const [currentNearAmount, setCurrentNearAmount] = useState(0); - const [token, setToken] = useState('near'); + const [balance, setBalance] = useState('0'); + const [token, setToken] = useState(null); + const { tokens } = useTokens(); - console.log("tokens",tokens); useEffect(() => { - if (!wallet || !signedAccountId) return; - - const loadBalance = async () => { - try { - const balance = await wallet.getBalance(signedAccountId); - const requiredGas = 0.00005; - const cost = 0.0426; - setCurrentNearAmount(balance - requiredGas - cost); - } catch (error) { - console.error(error); - } - }; - - loadBalance(); - }, [wallet, signedAccountId]); + if (!wallet || !signedAccountId || !tokens.length) return; + setToken(tokens[0]); + }, [wallet, signedAccountId, tokens]); + useEffect(() => { + if (!token) return; + console.log(token); + const balance = token.balance; + const decimals = token.decimals; + setBalance(formattedBalance(balance, decimals)); + }, [token]); const onSubmit: SubmitHandler = async (data) => { if (!wallet) throw new Error('Wallet has not initialized yet'); const dropId = Date.now().toString(); try { const args = { - deposit_per_use: token==="near"?parseNearAmount(data.amountPerLink.toString()):'0', + deposit_per_use: token.contract_id === "near" ? parseNearAmount(data.amountPerLink.toString()) : '0', drop_id: dropId, metadata: JSON.stringify({ dropName: data.dropName, }), public_keys: generateAndStore(data.dropName, data.numberLinks), - ft : token==="near"?undefined:{ + ft: token.contract_id === "near" ? undefined : { sender_id: signedAccountId, - contract_id: token, - balance_per_use: "1000" + contract_id: token.contract_id, + balance_per_use: parseAmount(data.amountPerLink.toString(), token.decimals), } }; - const transactions = [ { receiverId: 'v2.keypom.near', @@ -118,10 +114,10 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { } ] - if(token!=="near"){ - - transactions.push( { - receiverId: token, + if (token.contract_id !== "near") { + + transactions.push({ + receiverId: token.contract_id, actions: [ { type: 'FunctionCall', @@ -129,7 +125,7 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { methodName: 'ft_transfer_call', args: { receiver_id: KEYPOM_CONTRACT_ADDRESS, - amount: "2000",//TODO cambiar + amount: parseAmount(data.amountPerLink.toString(), token.decimals),//TODO cambiar msg: dropId, }, gas: '300000000000000', @@ -139,8 +135,8 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { ], }) } - - await wallet.signAndSendTransactions({transactions}); + + await wallet.signAndSendTransactions({ transactions }); openToast({ type: 'success', @@ -161,12 +157,9 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { }; return ( <> - - Create a LinkDrop - - + { allowNegative: false, allowDecimal: true, }} - assistive={`${displayBalance(currentNearAmount)} available`} + assistive={`${balance} available`} placeholder="Enter an amount" error={errors.amountPerLink?.message} {...register('amountPerLink', { @@ -206,8 +199,8 @@ const CreateTokenDrop = ({tokens}:{tokens:any}) => { value: 0.0000000001, }, max: { - message: `Must be equal to or less than ${currentNearAmount}`, - value: currentNearAmount, + message: `Must be equal to or less than ${balance}`, + value: balance, }, valueAsNumber: true, required: 'Amount per link is required', diff --git a/src/components/tools/Linkdrops/SelectFT.tsx b/src/components/tools/Linkdrops/SelectFT.tsx index 20b59f330..57730e637 100644 --- a/src/components/tools/Linkdrops/SelectFT.tsx +++ b/src/components/tools/Linkdrops/SelectFT.tsx @@ -63,66 +63,53 @@ const Label = styled.label` margin-bottom: 4px; ` const nearCoin = { - contract_id: 'near', - symbol: 'NEAR', - icon: NearIconSvg, + contract_id: 'near', + symbol: 'NEAR', + icon: NearIconSvg, } -const ImgDefault = ()=>{ - return +const ImgDefault = () => { + return } -const SelectFT = ({tokens,setToken}:{tokens:any,setToken:(token:string)=>void}) => { +const SelectFT = ({ tokens, setToken }: { tokens: any, setToken: (token: any) => void }) => { const [isOpen, setIsOpen] = useState(false); const [selectedCurrency, setSelectedCurrency] = useState(nearCoin); return (
- - - setIsOpen(!isOpen)} type='button'> - - {selectedCurrency.icon && {selectedCurrency.symbol}} - {!selectedCurrency.icon && } - {selectedCurrency.contract_id} ({selectedCurrency.symbol}) - - - + + + setIsOpen(!isOpen)} type='button'> + + {selectedCurrency.icon && {selectedCurrency.symbol}} + {!selectedCurrency.icon && } + {selectedCurrency.contract_id} ({selectedCurrency.symbol}) + + + - {isOpen && ( - + {isOpen && ( + + {tokens.map((token) => ( - {tokens.map((token) => ( - - ))} - - )} - + key={token.contract_id} + onClick={() => { + setSelectedCurrency(token); + setIsOpen(false); + setToken(token); + }} + > + + {token.icon && {token.symbol}} + {!token.icon && } + {token.contract_id} ({token.symbol}) + + + ))} + + )} +
); }; diff --git a/src/components/tools/Linkdrops/index.tsx b/src/components/tools/Linkdrops/index.tsx index 6553a1604..72855d07c 100644 --- a/src/components/tools/Linkdrops/index.tsx +++ b/src/components/tools/Linkdrops/index.tsx @@ -1,4 +1,4 @@ -import { Flex, Switch } from '@near-pagoda/ui'; +import { Flex, Switch, Text } from '@near-pagoda/ui'; import { Coins, ImageSquare } from '@phosphor-icons/react'; import { useState } from 'react'; @@ -8,11 +8,14 @@ import CreateNFTDrop from './CreateNFTDrop'; import CreateTokenDrop from './CreateTokenDrop'; import ListTokenDrop from './ListTokenDrop'; -const Linkdrops = ({ drops,tokens }: { drops: Drops[],tokens: any }) => { +const Linkdrops = ({ drops }: { drops: Drops[] }) => { const [selector, setSelector] = useState(false); return ( <> + + Create a LinkDrop + Token { /> NFT - {!selector && } + {!selector && } {selector && } diff --git a/src/hooks/useFT.ts b/src/hooks/useFT.ts index f8ff5b5c2..9a16ddebe 100644 --- a/src/hooks/useFT.ts +++ b/src/hooks/useFT.ts @@ -1,13 +1,14 @@ import { NearContext } from "@/components/WalletSelector"; import { useContext, useEffect, useState, useCallback } from "react"; import whiteList from '@/utils/white-list.json'; +import NearIconSvg from '@/components/sidebar-navigation/icons/near-icon.svg'; export const accounts_ft = async (accountId: string) => { const response = await fetch(`https://api.fastnear.com/v1/account/${accountId}/ft`); return await response.json(); }; -const useFT = () => { +const useTokens = () => { const { wallet, signedAccountId } = useContext(NearContext); const [tokens, setTokens] = useState([]); const [loading, setLoading] = useState(false); @@ -18,32 +19,37 @@ const useFT = () => { setLoading(true); try { const res = await accounts_ft(signedAccountId); - const tokensWithMetadata = await Promise.all( + let tokensWithMetadata = await Promise.all( res.tokens .filter(token => token.balance !== '0') .map(async (token) => { - const tokenVerified = whiteList.find((item) => item.contract_id === token.contract_id); - if (!tokenVerified) { - let metadata = {}; + let metadata = whiteList.find((item) => item.contract_id === token.contract_id); + + if (!metadata) { try { metadata = await wallet.viewMethod({ contractId: token.contract_id, method: 'ft_metadata' }); } catch (error) { console.error(`Error fetching metadata for ${token.contract_id}:`, error); } - return { - ...metadata, - contract_id: token.contract_id, - balance: token.balance, - verified: false, - }; } + return { - ...tokenVerified, + ...metadata, + contract_id: token.contract_id, balance: token.balance, - verified: true, }; }), ); + + const nearBalance = await wallet.getBalance(signedAccountId, false); + tokensWithMetadata.unshift({ + contract_id: 'near', + symbol: 'NEAR', + icon: NearIconSvg, + balance: nearBalance, + decimals: 24, + }); + setTokens(tokensWithMetadata); } catch (error) { console.error("Error fetching fungible tokens:", error); @@ -59,4 +65,4 @@ const useFT = () => { return { tokens, loading, reloadTokens: fetchTokens }; }; -export default useFT; \ No newline at end of file +export default useTokens; \ No newline at end of file diff --git a/src/pages/tools.tsx b/src/pages/tools.tsx index cb12c298a..2ec39c73b 100644 --- a/src/pages/tools.tsx +++ b/src/pages/tools.tsx @@ -12,7 +12,7 @@ import useLinkdrops from '@/hooks/useLinkdrops'; import useNearBlocksTxns, { Txns } from '@/hooks/useNearBlocksTxns'; import { useSignInRedirect } from '@/hooks/useSignInRedirect'; import type { NextPageWithLayout } from '@/utils/types'; -import useFT from '@/hooks/useFT'; +import useTokens from '@/hooks/useFT'; export type FT = { decimals: number, @@ -29,7 +29,7 @@ export type NFT = { token_id: string, } -const processTransactionsToFt = (transactions: Txns[]):FT[] => { +const processTransactionsToFt = (transactions: Txns[]): FT[] => { if (!transactions) return []; return transactions.map((txn) => { @@ -44,7 +44,7 @@ const processTransactionsToFt = (transactions: Txns[]):FT[] => { }); }; -const processTransactionsToNFT = (transactions: Txns[]):NFT[] => { +const processTransactionsToNFT = (transactions: Txns[]): NFT[] => { if (!transactions) return []; return transactions.map((txn) => { @@ -63,15 +63,13 @@ const ToolsPage: NextPageWithLayout = () => { const selectedTab = (router.query.tab as string) || 'ft'; const { signedAccountId } = useContext(NearContext); const drops = useLinkdrops(); - const {tokens} = useFT(); const { transactions: fts } = useNearBlocksTxns('tkn.primitives.near', 'create_token'); const ftProcessed = processTransactionsToFt(fts); - - + const { transactions: nfts } = useNearBlocksTxns('nft.primitives.near', 'nft_mint'); const nftsProcessed = processTransactionsToNFT(nfts); - + const { requestAuthentication } = useSignInRedirect(); return (
@@ -110,7 +108,7 @@ const ToolsPage: NextPageWithLayout = () => { - + From d5e3e30cda5b318f4cee6bdf873215c5de7d98ae Mon Sep 17 00:00:00 2001 From: Matias Benary Date: Wed, 25 Sep 2024 10:19:48 -0300 Subject: [PATCH 03/23] feat: added ft linkdrops --- src/components/WalletSelector.ts | 2 +- .../tools/Linkdrops/CreateTokenDrop.tsx | 66 +++++------ src/components/tools/Linkdrops/SelectFT.tsx | 64 ++++++++--- src/hooks/useFT.ts | 68 ------------ src/hooks/useTokens.ts | 104 ++++++++++++++++++ src/pages/tools.tsx | 26 ++--- 6 files changed, 193 insertions(+), 137 deletions(-) delete mode 100644 src/hooks/useFT.ts create mode 100644 src/hooks/useTokens.ts diff --git a/src/components/WalletSelector.ts b/src/components/WalletSelector.ts index 720150e79..8ee99eb64 100644 --- a/src/components/WalletSelector.ts +++ b/src/components/WalletSelector.ts @@ -180,7 +180,7 @@ export class Wallet { finality: 'final', }); // return amount on NEAR - if (format){ + if (format) { return account.amount ? Number(utils.format.formatNearAmount(account.amount)) : 0; } else { return account.amount || 0; diff --git a/src/components/tools/Linkdrops/CreateTokenDrop.tsx b/src/components/tools/Linkdrops/CreateTokenDrop.tsx index ec298598a..5e4ec53e0 100644 --- a/src/components/tools/Linkdrops/CreateTokenDrop.tsx +++ b/src/components/tools/Linkdrops/CreateTokenDrop.tsx @@ -1,15 +1,15 @@ -import { Button, Flex, Form, Input, openToast, Text } from '@near-pagoda/ui'; +import { Button, Flex, Form, Input, openToast } from '@near-pagoda/ui'; import { parseNearAmount } from 'near-api-js/lib/utils/format'; import { useContext, useEffect, useState } from 'react'; import type { SubmitHandler } from 'react-hook-form'; import { useForm } from 'react-hook-form'; +import type { Token } from '@/hooks/useTokens'; +import useTokens from '@/hooks/useTokens'; import generateAndStore from '@/utils/linkdrops'; import { NearContext } from '../../WalletSelector'; import SelectFT from './SelectFT'; -import useTokens from '@/hooks/useFT'; -import { CopySimple } from '@phosphor-icons/react'; type FormData = { dropName: string; @@ -17,34 +17,21 @@ type FormData = { amountPerLink: number; }; -// balance is already formatted here (e.g. 1.2345) -function displayBalance(balance: number) { - let display = Math.floor(balance * 100) / 100; - - if (balance < 1) { - display = Math.floor(balance * 100000) / 100000; - if (balance && !display) return '< 0.00001'; - return display; - } - - return display; -} - const KEYPOM_CONTRACT_ADDRESS = 'v2.keypom.near'; const formattedBalance = (balance: string, decimals = 24) => { const balanceStr = balance.toString(); const integerPart = balanceStr.slice(0, -decimals) || '0'; const decimalPart = balanceStr.slice(-decimals).padStart(decimals, '0'); - return `${integerPart}.${decimalPart.slice(2)}`; + return Number(`${integerPart}.${decimalPart.slice(0, 2)}`); }; const parseAmount = (amount: string, decimals: number) => { const [integer, decimal] = amount.split('.'); const integerPart = integer || '0'; const decimalPart = decimal || '0'; - return integerPart + decimalPart.padEnd(decimals, '0'); -} + return BigInt(integerPart + decimalPart.padEnd(decimals, '0')); +}; const getDeposit = (amountPerLink: number, numberLinks: number) => parseNearAmount(((0.0426 + amountPerLink) * numberLinks).toString()); @@ -62,8 +49,8 @@ const CreateTokenDrop = () => { }); const { wallet, signedAccountId } = useContext(NearContext); - const [balance, setBalance] = useState('0'); - const [token, setToken] = useState(null); + const [balance, setBalance] = useState(0); + const [token, setToken] = useState(); const { tokens } = useTokens(); useEffect(() => { @@ -81,25 +68,29 @@ const CreateTokenDrop = () => { const onSubmit: SubmitHandler = async (data) => { if (!wallet) throw new Error('Wallet has not initialized yet'); + if (!token) throw new Error('Token has not been selected yet'); const dropId = Date.now().toString(); try { const args = { - deposit_per_use: token.contract_id === "near" ? parseNearAmount(data.amountPerLink.toString()) : '0', + deposit_per_use: token.contract_id === 'near' ? parseNearAmount(data.amountPerLink.toString()) : '0', drop_id: dropId, metadata: JSON.stringify({ dropName: data.dropName, }), public_keys: generateAndStore(data.dropName, data.numberLinks), - ft: token.contract_id === "near" ? undefined : { - sender_id: signedAccountId, - contract_id: token.contract_id, - balance_per_use: parseAmount(data.amountPerLink.toString(), token.decimals), - } + ft: + token.contract_id === 'near' + ? undefined + : { + sender_id: signedAccountId, + contract_id: token.contract_id, + balance_per_use: parseAmount(data.amountPerLink.toString(), token.decimals).toString(), + }, }; - const transactions = [ + const transactions: any[] = [ { - receiverId: 'v2.keypom.near', + receiverId: KEYPOM_CONTRACT_ADDRESS, actions: [ { type: 'FunctionCall', @@ -107,15 +98,14 @@ const CreateTokenDrop = () => { methodName: 'create_drop', args, gas: '300000000000000', - deposit: getDeposit(data.amountPerLink, data.numberLinks), + deposit: getDeposit(token.contract_id === 'near' ? data.amountPerLink : 0, data.numberLinks), }, }, ], - } - ] - - if (token.contract_id !== "near") { + }, + ]; + if (token.contract_id !== 'near') { transactions.push({ receiverId: token.contract_id, actions: [ @@ -125,15 +115,15 @@ const CreateTokenDrop = () => { methodName: 'ft_transfer_call', args: { receiver_id: KEYPOM_CONTRACT_ADDRESS, - amount: parseAmount(data.amountPerLink.toString(), token.decimals),//TODO cambiar + amount: parseAmount(data.amountPerLink.toString(), token.decimals) * BigInt(data.numberLinks), msg: dropId, }, gas: '300000000000000', - deposit: 1, + deposit: '1', }, }, ], - }) + }); } await wallet.signAndSendTransactions({ transactions }); @@ -190,7 +180,7 @@ const CreateTokenDrop = () => { allowNegative: false, allowDecimal: true, }} - assistive={`${balance} available`} + assistive={balance ? `${balance} available` : 'loading ...'} placeholder="Enter an amount" error={errors.amountPerLink?.message} {...register('amountPerLink', { diff --git a/src/components/tools/Linkdrops/SelectFT.tsx b/src/components/tools/Linkdrops/SelectFT.tsx index 57730e637..1c8d01c0e 100644 --- a/src/components/tools/Linkdrops/SelectFT.tsx +++ b/src/components/tools/Linkdrops/SelectFT.tsx @@ -1,8 +1,11 @@ import { CaretDown } from '@phosphor-icons/react'; +import Image from 'next/image'; import { useState } from 'react'; import styled from 'styled-components'; + +import type { Token } from '@/hooks/useTokens'; + import NearIconSvg from './near-icon.svg'; -import Image from 'next/image'; const SelectContainer = styled.div` position: relative; @@ -56,23 +59,36 @@ const CurrencyInfo = styled.div` `; const Label = styled.label` - display: block; - font: var(--text-xs); - font-weight: 600; - color: var(--sand12); - margin-bottom: 4px; -` + display: block; + font: var(--text-xs); + font-weight: 600; + color: var(--sand12); + margin-bottom: 4px; +`; const nearCoin = { contract_id: 'near', symbol: 'NEAR', icon: NearIconSvg, -} +}; const ImgDefault = () => { - return -} + return ( + + + + + ); +}; -const SelectFT = ({ tokens, setToken }: { tokens: any, setToken: (token: any) => void }) => { +const SelectFT = ({ tokens, setToken }: { tokens: Token[]; setToken: (token: any) => void }) => { const [isOpen, setIsOpen] = useState(false); const [selectedCurrency, setSelectedCurrency] = useState(nearCoin); @@ -80,11 +96,21 @@ const SelectFT = ({ tokens, setToken }: { tokens: any, setToken: (token: any) =>
- setIsOpen(!isOpen)} type='button'> + setIsOpen(!isOpen)} type="button"> - {selectedCurrency.icon && {selectedCurrency.symbol}} + {selectedCurrency.icon && ( + {selectedCurrency.symbol} + )} {!selectedCurrency.icon && } - {selectedCurrency.contract_id} ({selectedCurrency.symbol}) + + {selectedCurrency.contract_id} ({selectedCurrency.symbol}) + @@ -101,9 +127,13 @@ const SelectFT = ({ tokens, setToken }: { tokens: any, setToken: (token: any) => }} > - {token.icon && {token.symbol}} + {token.icon && ( + {token.symbol} + )} {!token.icon && } - {token.contract_id} ({token.symbol}) + + {token.contract_id} ({token.symbol}) + ))} @@ -114,4 +144,4 @@ const SelectFT = ({ tokens, setToken }: { tokens: any, setToken: (token: any) => ); }; -export default SelectFT; \ No newline at end of file +export default SelectFT; diff --git a/src/hooks/useFT.ts b/src/hooks/useFT.ts deleted file mode 100644 index 9a16ddebe..000000000 --- a/src/hooks/useFT.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { NearContext } from "@/components/WalletSelector"; -import { useContext, useEffect, useState, useCallback } from "react"; -import whiteList from '@/utils/white-list.json'; -import NearIconSvg from '@/components/sidebar-navigation/icons/near-icon.svg'; - -export const accounts_ft = async (accountId: string) => { - const response = await fetch(`https://api.fastnear.com/v1/account/${accountId}/ft`); - return await response.json(); -}; - -const useTokens = () => { - const { wallet, signedAccountId } = useContext(NearContext); - const [tokens, setTokens] = useState([]); - const [loading, setLoading] = useState(false); - - const fetchTokens = useCallback(async () => { - if (!wallet || !signedAccountId) return; - - setLoading(true); - try { - const res = await accounts_ft(signedAccountId); - let tokensWithMetadata = await Promise.all( - res.tokens - .filter(token => token.balance !== '0') - .map(async (token) => { - let metadata = whiteList.find((item) => item.contract_id === token.contract_id); - - if (!metadata) { - try { - metadata = await wallet.viewMethod({ contractId: token.contract_id, method: 'ft_metadata' }); - } catch (error) { - console.error(`Error fetching metadata for ${token.contract_id}:`, error); - } - } - - return { - ...metadata, - contract_id: token.contract_id, - balance: token.balance, - }; - }), - ); - - const nearBalance = await wallet.getBalance(signedAccountId, false); - tokensWithMetadata.unshift({ - contract_id: 'near', - symbol: 'NEAR', - icon: NearIconSvg, - balance: nearBalance, - decimals: 24, - }); - - setTokens(tokensWithMetadata); - } catch (error) { - console.error("Error fetching fungible tokens:", error); - } finally { - setLoading(false); - } - }, [wallet, signedAccountId]); - - useEffect(() => { - fetchTokens(); - }, [fetchTokens]); - - return { tokens, loading, reloadTokens: fetchTokens }; -}; - -export default useTokens; \ No newline at end of file diff --git a/src/hooks/useTokens.ts b/src/hooks/useTokens.ts new file mode 100644 index 000000000..36ef06c26 --- /dev/null +++ b/src/hooks/useTokens.ts @@ -0,0 +1,104 @@ +import { useCallback, useContext, useEffect, useState } from 'react'; + +import NearIconSvg from '@/components/sidebar-navigation/icons/near-icon.svg'; +import { NearContext } from '@/components/WalletSelector'; +import whiteList from '@/utils/white-list.json'; + +export interface FastNearFT { + account_id: string; + tokens: TokenFastNear[]; +} + +export interface TokenFastNear { + balance: string; + contract_id: string; + last_update_block_height: number; +} + +export const accounts_ft = async (accountId: string): Promise => { + const response = await fetch(`https://api.fastnear.com/v1/account/${accountId}/ft`); + return (await response.json()) as FastNearFT; +}; + +export interface Token { + contract_id: string; + spec: string; + name: string; + symbol: string; + icon: null | string; + reference: null | string; + reference_hash: string | null; + decimals: number; + tax_rate?: number; + balance: string; +} + +const useTokens = () => { + const { wallet, signedAccountId } = useContext(NearContext); + const [tokens, setTokens] = useState([]); + const [loading, setLoading] = useState(false); + + const fetchTokens = useCallback(async () => { + if (!wallet || !signedAccountId) return; + + setLoading(true); + try { + const res = await accounts_ft(signedAccountId); + const tokensWithMetadata: Token[] = await Promise.all( + res.tokens + .filter((token) => token.balance !== '0') + .map(async (token) => { + let metadata = whiteList.find((item) => item.contract_id === token.contract_id); + + if (!metadata) { + try { + metadata = await wallet.viewMethod({ contractId: token.contract_id, method: 'ft_metadata' }); + } catch (error) { + console.error(`Error fetching metadata for ${token.contract_id}:`, error); + } + } + + return { + contract_id: token.contract_id, + spec: (metadata && metadata.spec) || '1.0.0', + name: (metadata && metadata.name) || '', + symbol: (metadata && metadata.symbol) || '', + icon: (metadata && metadata.icon) || null, + reference: (metadata && metadata.reference) || null, + reference_hash: (metadata && metadata.reference_hash) || null, + decimals: (metadata && metadata.decimals) || 0, + tax_rate: metadata?.tax_rate, + balance: token.balance, + }; + }), + ); + + const nearBalance = await wallet.getBalance(signedAccountId, false); + tokensWithMetadata.unshift({ + contract_id: 'near', + symbol: 'NEAR', + icon: NearIconSvg, + balance: nearBalance, + decimals: 24, + spec: '1.0.0', + name: 'NEAR', + reference: null, + reference_hash: null, + }); + + setTokens(tokensWithMetadata); + } catch (error) { + console.error('Error fetching fungible tokens:', error); + } finally { + setLoading(false); + } + }, [wallet, signedAccountId]); + + useEffect(() => { + fetchTokens(); + }, [fetchTokens]); + + return { tokens, loading, reloadTokens: fetchTokens }; +}; + +export default useTokens; diff --git a/src/pages/tools.tsx b/src/pages/tools.tsx index 2ec39c73b..06d3175f3 100644 --- a/src/pages/tools.tsx +++ b/src/pages/tools.tsx @@ -9,25 +9,25 @@ import NonFungibleToken from '@/components/tools/NonFungibleToken'; import { NearContext } from '@/components/WalletSelector'; import { useDefaultLayout } from '@/hooks/useLayout'; import useLinkdrops from '@/hooks/useLinkdrops'; -import useNearBlocksTxns, { Txns } from '@/hooks/useNearBlocksTxns'; +import type { Txns } from '@/hooks/useNearBlocksTxns'; +import useNearBlocksTxns from '@/hooks/useNearBlocksTxns'; import { useSignInRedirect } from '@/hooks/useSignInRedirect'; import type { NextPageWithLayout } from '@/utils/types'; -import useTokens from '@/hooks/useFT'; export type FT = { - decimals: number, - icon: string, - name: string, - symbol: string, - total_supply: string, -} + decimals: number; + icon: string; + name: string; + symbol: string; + total_supply: string; +}; export type NFT = { - description: string, - media: string, - title: string, - token_id: string, -} + description: string; + media: string; + title: string; + token_id: string; +}; const processTransactionsToFt = (transactions: Txns[]): FT[] => { if (!transactions) return []; From 00c312d9cdae285bcbf15650071fa9e75330db0b Mon Sep 17 00:00:00 2001 From: gagdiez Date: Wed, 25 Sep 2024 16:24:34 +0200 Subject: [PATCH 04/23] wip --- next.config.js | 2 +- .../tools/FungibleToken/CommunityTools.tsx | 15 ++++++++++ src/components/tools/FungibleToken/index.tsx | 3 ++ .../tools/Linkdrops/CreateTokenDrop.tsx | 28 +++++++++++-------- .../tools/Linkdrops/ListTokenDrop.tsx | 11 ++++---- src/components/tools/Linkdrops/SelectFT.tsx | 2 +- .../tools/NonFungibleToken/ListToken.tsx | 10 ++++++- src/hooks/useLinkdrops.ts | 3 +- src/hooks/useNFT.ts | 4 +-- 9 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 src/components/tools/FungibleToken/CommunityTools.tsx diff --git a/next.config.js b/next.config.js index 2562d36e3..ca7cf4f34 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','ipfs.io'], + domains: ['ipfs.near.social','ipfs.io', 'ipfs.fleek.co'], }, experimental: { optimizePackageImports: ['@phosphor-icons/react'], diff --git a/src/components/tools/FungibleToken/CommunityTools.tsx b/src/components/tools/FungibleToken/CommunityTools.tsx new file mode 100644 index 000000000..f1821a012 --- /dev/null +++ b/src/components/tools/FungibleToken/CommunityTools.tsx @@ -0,0 +1,15 @@ +import { Button, Text } from '@near-pagoda/ui'; + +const CommunityTools = () => { + return ( + <> + + Community tools + + For more advanced options use community tools: +
diff --git a/src/utils/types.ts b/src/utils/types.ts index a0e4703fa..bcbab454e 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -160,6 +160,16 @@ export interface Keys { export interface Simple { lazy_register: null; } +export type FT = { + contract_id: string; + balance: string; + metadata: { + decimals: number; + icon: string; + name: string; + symbol: string; + }; +}; export interface NFT { contract_id: string; token_id: string; From c31667b5aa07b1c50c1f271897a561e82101e01c Mon Sep 17 00:00:00 2001 From: gagdiez Date: Sun, 13 Oct 2024 17:58:44 +0200 Subject: [PATCH 17/23] fix: nft creator --- .../tools/FungibleToken/CreateTokenForm.tsx | 7 +- .../tools/FungibleToken/ListToken.tsx | 2 +- .../tools/NonFungibleToken/CommunityTools.tsx | 9 +- .../tools/NonFungibleToken/ListToken.tsx | 17 ++- .../tools/NonFungibleToken/MintNft.tsx | 127 ++++++++++-------- .../tools/NonFungibleToken/index.tsx | 2 +- src/pages/tools.tsx | 7 +- 7 files changed, 92 insertions(+), 79 deletions(-) diff --git a/src/components/tools/FungibleToken/CreateTokenForm.tsx b/src/components/tools/FungibleToken/CreateTokenForm.tsx index 4dd3f2bd8..c0603091e 100644 --- a/src/components/tools/FungibleToken/CreateTokenForm.tsx +++ b/src/components/tools/FungibleToken/CreateTokenForm.tsx @@ -78,10 +78,10 @@ const CreateTokenForm = ({ reload }: { reload: (delay: number) => void }) => { }, account_id: signedAccountId, }; - console.log(FACTORY_CONTRACT, args); + const deposit = await wallet?.viewMethod({ contractId: FACTORY_CONTRACT, method: 'get_required', args }); - setRequiredDeposit(Number(formatNearAmount(deposit)).toFixed(2)); + setRequiredDeposit(formatNearAmount(deposit, 2)); if (!actuallySubmit) return; @@ -117,7 +117,6 @@ const CreateTokenForm = ({ reload }: { reload: (delay: number) => void }) => { [wallet, signedAccountId, reload], ); - // Call onSubmit with form data and false whenever form data changes useEffect(() => { onSubmit(formData, false); }, [onSubmit, formData]); @@ -198,7 +197,7 @@ const CreateTokenForm = ({ reload }: { reload: (delay: number) => void }) => {