diff --git a/src/App.css b/src/App.css index be7f1d8..26635be 100644 --- a/src/App.css +++ b/src/App.css @@ -22,4 +22,10 @@ html, body { color: rgb(163, 0, 0); font-weight: bold; /* other styles as needed */ +} + +.footer { + font-size: 12px; + display: flex; + justify-content: center; } \ No newline at end of file diff --git a/src/App.js b/src/App.js index cc9afa6..a18ac7d 100644 --- a/src/App.js +++ b/src/App.js @@ -18,6 +18,9 @@ function App() { const [injectTokenAddress, setInjectTokenAddress] = useState(""); const [poolNames, setPoolNames] = useState({}); const [periodFinishTimestamps, setPeriodFinishTimestamps] = useState({}); + const [isEditMode, setIsEditMode] = useState(false); + const [editableData, setEditableData] = useState({}); + const [generatedJson, setGeneratedJson] = useState(null); const params = useParams(); const urlNetwork = params.network; @@ -44,6 +47,16 @@ function App() { base: "https://developer-access-mainnet.base.org", }; + const chainIds = { + mainnet: "1", + polygon: "137", + arbitrum: "42161", + gnosis: "100", + zkevm: "1101", + avalanche: "43114", + base: "8453", + }; + const [provider, setProvider] = useState(new ethers.providers.JsonRpcProvider(networkChoice.mainnet)); const [contract, setContract] = useState(new ethers.Contract(contractAddress, InjectorABI, provider)); @@ -131,9 +144,77 @@ function App() { setContractAddress(address); setProvider(newProvider); setContract(newContract); + + setGeneratedJson(null); + setEditableData({}); } }; + function updateEditableData(address, field, value) { + setEditableData((prevData) => ({ + ...prevData, + [address]: { + ...prevData[address], + [field]: value, + }, + })); + } + + function generateJsonOutput() { + const gaugeAddresses = Object.keys(editableData); + const amountsPerPeriod = gaugeAddresses.map((address) => { + return convertToBaseUnit(editableData[address].amountPerPeriod, injectTokenAddress); + }); + const maxPeriods = gaugeAddresses.map((address) => editableData[address].maxPeriods); + const currentChainId = chainIds[selectedNetwork]; + + const jsonData = { + version: "1.0", + chainId: currentChainId, + createdAt: Date.now(), + meta: { + name: "Transactions Batch", + description: "Child Chain Injector Program Load", + txBuilderVersion: "1.16.3", + }, + transactions: [ + { + to: contractAddress, + value: "0", + data: null, + contractMethod: { + inputs: [ + { + name: "gaugeAddresses", + type: "address[]", + internalType: "address[]", + }, + { + name: "amountsPerPeriod", + type: "uint256[]", + internalType: "uint256[]", + }, + { + name: "maxPeriods", + type: "uint8[]", + internalType: "uint8[]", + }, + ], + name: "setRecipientList", + payable: false, + }, + contractInputsValues: { + gaugeAddresses: gaugeAddresses, + amountsPerPeriod: amountsPerPeriod, + maxPeriods: maxPeriods, + }, + }, + ], + }; + + setGeneratedJson(JSON.stringify(jsonData, null, 2)); + } + useEffect(() => { if (urlNetwork && urlAddress) { const selectionValue = `${urlNetwork}-${urlAddress}`; @@ -174,6 +255,14 @@ function App() { // eslint-disable-next-line }, [contractAddress, selectedNetwork, injectTokenAddress]); + useEffect(() => { + if (!isEditMode && Object.keys(editableData).length > 0) { + generateJsonOutput(); + } + + // eslint-disable-next-line + }, [isEditMode, editableData]); + function formatTokenAmount(amount, tokenAddress) { if (amount === null || amount === undefined) return "Loading..."; @@ -183,6 +272,22 @@ function App() { return ethers.utils.formatUnits(formattedAmount, decimals); } + function convertToBaseUnit(amount, tokenAddress) { + const decimals = tokenDecimals[tokenAddress.toLowerCase()] || 18; + return ethers.utils.parseUnits(amount.toString(), decimals).toString(); + } + + function downloadJsonFile() { + const blob = new Blob([generatedJson], { type: "application/json" }); + const href = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = href; + link.download = "data.json"; // or any other filename you wish + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + const totalProduct = addresses.reduce((sum, address) => { const amountPerPeriod = accountInfo[address]?.amountPerPeriod || 0; const maxPeriods = accountInfo[address]?.maxPeriods || 0; @@ -217,6 +322,8 @@ function App() { ))} + {"\u00A0\u00A0\u00A0"} +

Watch List Results

@@ -237,39 +344,57 @@ function App() { - {addresses.map((address, index) => ( - - {address} - {poolNames[address] || "Loading..."} - {formatTokenAmount(accountInfo[address]?.amountPerPeriod, injectTokenAddress)} - {accountInfo[address]?.isActive.toString() || "Loading..."} - {accountInfo[address]?.maxPeriods.toString() || "Loading..."} - {accountInfo[address]?.periodNumber.toString() || "Loading..."} - - {accountInfo[address]?.lastInjectionTimeStamp > 0 - ? new Date(accountInfo[address]?.lastInjectionTimeStamp * 1000).toLocaleDateString() - : periodFinishTimestamps[address] - ? new Date(periodFinishTimestamps[address] * 1000).toLocaleDateString() - : "N/A"} - - - {accountInfo[address]?.isActive && accountInfo[address]?.periodNumber < accountInfo[address]?.maxPeriods - ? new Date( - (accountInfo[address]?.lastInjectionTimeStamp > 0 ? accountInfo[address]?.lastInjectionTimeStamp : periodFinishTimestamps[address]) * 1000 + - 7 * 24 * 3600 * 1000 - ).toLocaleDateString() - : "N/A"} - - - {accountInfo[address]?.isActive && accountInfo[address]?.periodNumber < accountInfo[address]?.maxPeriods - ? new Date( - (accountInfo[address]?.lastInjectionTimeStamp > 0 ? accountInfo[address]?.lastInjectionTimeStamp : periodFinishTimestamps[address]) * 1000 + - 7 * (accountInfo[address]?.maxPeriods - accountInfo[address]?.periodNumber + 1) * 24 * 3600 * 1000 - ).toLocaleDateString() - : "N/A"} - - - ))} + {addresses.map((address, index) => { + const currentData = editableData[address] || { + amountPerPeriod: formatTokenAmount(accountInfo[address]?.amountPerPeriod, injectTokenAddress), + maxPeriods: accountInfo[address]?.maxPeriods.toString(), + }; + return ( + + {address} + {poolNames[address] || "Loading..."} + + {isEditMode ? ( + updateEditableData(address, "amountPerPeriod", e.target.value)} /> + ) : ( + currentData.amountPerPeriod || "Loading..." + )} + + {accountInfo[address]?.isActive.toString() || "Loading..."} + + {isEditMode ? ( + updateEditableData(address, "maxPeriods", e.target.value)} /> + ) : ( + currentData.maxPeriods || "Loading..." + )} + + {accountInfo[address]?.periodNumber.toString() || "Loading..."} + + {accountInfo[address]?.lastInjectionTimeStamp > 0 + ? new Date(accountInfo[address]?.lastInjectionTimeStamp * 1000).toLocaleDateString() + : periodFinishTimestamps[address] + ? new Date(periodFinishTimestamps[address] * 1000).toLocaleDateString() + : "N/A"} + + + {accountInfo[address]?.isActive && accountInfo[address]?.periodNumber < accountInfo[address]?.maxPeriods + ? new Date( + (accountInfo[address]?.lastInjectionTimeStamp > 0 ? accountInfo[address]?.lastInjectionTimeStamp : periodFinishTimestamps[address]) * 1000 + + 7 * 24 * 3600 * 1000 + ).toLocaleDateString() + : "N/A"} + + + {accountInfo[address]?.isActive && accountInfo[address]?.periodNumber < accountInfo[address]?.maxPeriods + ? new Date( + (accountInfo[address]?.lastInjectionTimeStamp > 0 ? accountInfo[address]?.lastInjectionTimeStamp : periodFinishTimestamps[address]) * 1000 + + 7 * (accountInfo[address]?.maxPeriods - accountInfo[address]?.periodNumber + 1) * 24 * 3600 * 1000 + ).toLocaleDateString() + : "N/A"} + + + ); + })} ) : ( @@ -298,7 +423,26 @@ function App() { https://injector-schedule.web.app/{selectedNetwork}/{contractAddress}

+ +
+ {generatedJson &&
{generatedJson}
} +
+
+ +
); }