{
"data": {
"jgold.near": {
"widget": {
"multisender-pretest": {
"": "const MultiSenderWidget = ({ context, NearAPI }) => {\r\n // Initialize the state\r\n if (!state) {\r\n State.init({\r\n tokenContract: \"\",\r\n csvInput: \"\",\r\n isConnected: context.accountId ? true : false, // Check if user is connected\r\n errorMessage: \"\",\r\n showModal: false,\r\n transactions: [],\r\n tokens: [],\r\n accountId: context.accountId || \"\", // Initialize accountId from context\r\n });\r\n\r\n if (context.accountId) {\r\n fetchAndLogTokens(context.accountId);\r\n }\r\n }\r\n\r\n const fetchAndLogTokens = async (accountId) => {\r\n try {\r\n console.log(\"Fetching tokens for account:\", accountId);\r\n // Fetch tokens for the given account\r\n const response = await fetch(\r\n `https://api.near-indexer.com/account/${accountId}/tokens`\r\n );\r\n const tokenList = await response.json();\r\n console.log(\"Available Tokens:\", tokenList);\r\n State.update({ tokens: tokenList });\r\n } catch (error) {\r\n console.error(\"Error fetching tokens:\", error);\r\n }\r\n };\r\n\r\n const parseCSVtoJSON = (csvInput) => {\r\n const rows = csvInput\r\n .split(\";\")\r\n .map((row) => row.trim())\r\n .filter((row) => row.length > 0);\r\n const formattedList = [];\r\n let errorMessage = \"\";\r\n\r\n rows.forEach((row, index) => {\r\n const [recipient, amount] = row.split(\",\").map((item) => item.trim());\r\n\r\n if (!recipient || !amount || isNaN(amount)) {\r\n errorMessage = `Invalid input in row ${index + 1}: ${row}`;\r\n return;\r\n }\r\n\r\n formattedList.push({ recipient, amount });\r\n });\r\n\r\n if (errorMessage) {\r\n State.update({ errorMessage });\r\n return false;\r\n } else {\r\n return formattedList;\r\n }\r\n };\r\n\r\n const handleMultiSend = () => {\r\n const csvInput = state.csvInput;\r\n const tokenContract = state.tokenContract;\r\n\r\n console.log(\"Button Clicked, State:\", state);\r\n\r\n if (!csvInput) {\r\n State.update({ errorMessage: \"CSV Input is empty or undefined\" });\r\n return;\r\n }\r\n\r\n const transactions = parseCSVtoJSON(csvInput);\r\n\r\n if (!transactions) {\r\n console.log(\"Validation failed:\", state.errorMessage);\r\n return;\r\n }\r\n\r\n console.log(\"Parsed Transactions:\", transactions);\r\n State.update({ transactions, showModal: true });\r\n };\r\n\r\n const confirmSendTokens = () => {\r\n const tokenContract = state.tokenContract;\r\n const transactions = state.transactions;\r\n\r\n // Prepare batch transactions\r\n const batchTransactions = transactions.map((tx) => ({\r\n contractName: tokenContract,\r\n methodName: \"ft_transfer\",\r\n args: {\r\n receiver_id: tx.recipient,\r\n amount: tx.amount,\r\n },\r\n gas: \"300000000000000\", // gas limit\r\n deposit: \"1\", // deposit, in yoctoNEAR\r\n }));\r\n\r\n Near.call(batchTransactions)\r\n .then(() => {\r\n console.log(\"Tokens sent successfully\");\r\n State.update({\r\n errorMessage: \"Tokens sent successfully!\",\r\n showModal: false,\r\n });\r\n })\r\n .catch((error) => {\r\n console.error(\"Error during multisend:\", error);\r\n State.update({\r\n errorMessage: `Error during multisend: ${error.message}`,\r\n showModal: false,\r\n });\r\n });\r\n };\r\n\r\n const handleCSVInput = (e) => {\r\n const csvInput = e.target.value;\r\n console.log(\"Updating CSV Input:\", csvInput);\r\n State.update({ csvInput });\r\n };\r\n\r\n const handleTokenContractInput = (e) => {\r\n const tokenContract = e.target.value;\r\n console.log(\"Updating Token Contract:\", tokenContract);\r\n State.update({ tokenContract });\r\n };\r\n\r\n const closeModal = () => {\r\n console.log(\"Closing Modal\");\r\n State.update({ showModal: false });\r\n };\r\n\r\n return (\r\n <div>\r\n <h1>Bulk ft_transfer</h1>\r\n <div>\r\n <h6>Sender Account ID</h6>\r\n <p>{state.accountId}</p>\r\n </div>\r\n <div>\r\n <label>Token Contract:</label>\r\n <input\r\n type=\"text\"\r\n value={state.tokenContract}\r\n onChange={handleTokenContractInput}\r\n placeholder=\"Enter token contract address\"\r\n />\r\n </div>\r\n\r\n <br />\r\n <div>\r\n <label>CSV Input:</label>\r\n <br />\r\n <textarea\r\n placeholder=\"wallet1.near, amount1; wallet2.near, amount2; ...\"\r\n value={state.csvInput}\r\n onChange={handleCSVInput}\r\n />\r\n </div>\r\n <br />\r\n <div>\r\n <button onClick={handleMultiSend}>Send Tokens</button>\r\n </div>\r\n <br />\r\n {state.errorMessage && (\r\n <div style={{ color: \"red\" }}>\r\n <strong>Error:</strong> {state.errorMessage}\r\n </div>\r\n )}\r\n <div>\r\n <h3>CSV Template:</h3>\r\n <br />\r\n <p>wallet1.near, amount1; wallet2.near, amount2; ...</p>\r\n <br />\r\n <h5>\r\n *** Please make sure to add the tokens decimals ***\r\n <br />* ex: add 18 `0` at the end of the amount to send. *\r\n </h5>\r\n <h6>\r\n ** check the token contract for the correct amount to add for that\r\n token. **\r\n </h6>\r\n </div>\r\n\r\n {state.showModal && (\r\n <div style={fixedModalStyle}>\r\n <div style={fixedModalContentStyle}>\r\n <h2>Confirm Transactions</h2>\r\n <ul>\r\n {state.transactions.map((tx, index) => (\r\n <li key={index}>\r\n {tx.recipient}: {tx.amount}\r\n </li>\r\n ))}\r\n </ul>\r\n <div style={buttonContainerStyle}>\r\n <button style={confirmButtonStyle} onClick={confirmSendTokens}>\r\n Confirm\r\n </button>\r\n <button style={cancelButtonStyle} onClick={closeModal}>\r\n Cancel\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nconst fixedModalStyle = {\r\n position: \"fixed\",\r\n top: \"20%\",\r\n left: \"50%\",\r\n transform: \"translate(-50%, -20%)\",\r\n backgroundColor: \"white\",\r\n padding: \"20px\",\r\n boxShadow: \"0 0 10px rgba(0, 0, 0, 0.3)\",\r\n zIndex: 1000,\r\n};\r\n\r\nconst fixedModalContentStyle = {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n};\r\n\r\nconst buttonContainerStyle = {\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n width: \"100%\",\r\n};\r\n\r\nconst confirmButtonStyle = {\r\n backgroundColor: \"green\",\r\n color: \"white\",\r\n padding: \"10px 20px\",\r\n border: \"none\",\r\n borderRadius: \"5px\",\r\n cursor: \"pointer\",\r\n marginRight: \"10px\",\r\n};\r\n\r\nconst cancelButtonStyle = {\r\n backgroundColor: \"red\",\r\n color: \"white\",\r\n padding: \"10px 20px\",\r\n border: \"none\",\r\n borderRadius: \"5px\",\r\n cursor: \"pointer\",\r\n};\r\n\r\nreturn <MultiSenderWidget context={context} NearAPI={NearAPI} />;\r\n",
"metadata": {
"name": "Bulk ft_transfer",
"description": "Bulk ft_transfer",
"tags": {
"app": "",
"token-send": ""
}
}
}
}
}
}
}