diff --git a/core/utils/templateMappings.ts b/core/utils/templateMappings.ts index 702d76a..a339886 100644 --- a/core/utils/templateMappings.ts +++ b/core/utils/templateMappings.ts @@ -198,7 +198,8 @@ export const buildTemplate = async (appConfig: ConfigType): Promise config.network === 'ethereum' || config.network === 'ethereum-sepolia' || config.network === 'polygon' || - config.network === 'polygon-amoy' + config.network === 'polygon-amoy' || + config.network === 'etherlink-testnet' ) { config.chain = 'evm'; } else if (config.network === 'solana-devnet' || config.network === 'solana-mainnet') { diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/cards/SendTransactionCard.tsx b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/cards/SendTransactionCard.tsx index f2d3a1c..e4155c6 100644 --- a/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/cards/SendTransactionCard.tsx +++ b/scaffolds/nextjs-dedicated-wallet/template/src/components/magic/cards/SendTransactionCard.tsx @@ -6,7 +6,7 @@ import FormInput from '@/components/ui/FormInput'; import ErrorText from '@/components/ui/ErrorText'; import Card from '@/components/ui/Card'; import CardHeader from '@/components/ui/CardHeader'; -import { getFaucetUrl, getNetworkToken } from '@/utils/network'; +import { getFaucetUrl, getNetworkToken, isEip1559Supported } from '@/utils/network'; import showToast from '@/utils/showToast'; import Spacer from '@/components/ui/Spacer'; import TransactionHistory from '@/components/ui/TransactionHistory'; @@ -29,7 +29,7 @@ const SendTransaction = () => { setToAddressError(false); }, [amount, toAddress]); - const sendTransaction = useCallback(() => { + const sendTransaction = useCallback(async () => { if (!web3?.utils.isAddress(toAddress)) { return setToAddressError(true); } @@ -41,7 +41,8 @@ const SendTransaction = () => { from: publicAddress, to: toAddress, value: web3.utils.toWei(amount, 'ether'), - gas: 21000, + // Specify `gasPrice` if network doesn't support EIP-1559 + ...(!isEip1559Supported() && { gasPrice: await web3.eth.getGasPrice() }), }; web3.eth .sendTransaction(txnParams as any) diff --git a/scaffolds/nextjs-dedicated-wallet/template/src/utils/network.ts b/scaffolds/nextjs-dedicated-wallet/template/src/utils/network.ts index cbd31fc..fe95287 100644 --- a/scaffolds/nextjs-dedicated-wallet/template/src/utils/network.ts +++ b/scaffolds/nextjs-dedicated-wallet/template/src/utils/network.ts @@ -3,6 +3,7 @@ export enum Network { POLYGON = 'polygon', ETHEREUM_SEPOLIA = 'ethereum-sepolia', ETHEREUM = 'ethereum', + ETHERLINK_TESTNET = 'etherlink-testnet', ZKSYNC = 'zksync', ZKSYNC_SEPOLIA = 'zksync-sepolia', } @@ -17,6 +18,8 @@ export const getNetworkUrl = () => { return 'https://eth-sepolia.g.alchemy.com/v2/fYFybLQFR9Zr2GCRcgALmAktStFKr0i0'; case Network.ETHEREUM: return 'https://eth-mainnet.g.alchemy.com/v2/fYFybLQFR9Zr2GCRcgALmAktStFKr0i0'; + case Network.ETHERLINK_TESTNET: + return 'https://node.ghostnet.etherlink.com'; case Network.ZKSYNC: return 'https://mainnet.era.zksync.io'; case Network.ZKSYNC_SEPOLIA: @@ -40,6 +43,8 @@ export const getChainId = () => { return 300; case Network.ETHEREUM: return 1; + case Network.ETHERLINK_TESTNET: + return 128123; } }; @@ -53,6 +58,8 @@ export const getNetworkToken = () => { case Network.ZKSYNC: case Network.ZKSYNC_SEPOLIA: return 'ETH'; + case Network.ETHERLINK_TESTNET: + return 'XTZ'; } }; @@ -62,8 +69,10 @@ export const getFaucetUrl = () => { return 'https://faucet.polygon.technology/'; case Network.ETHEREUM_SEPOLIA: return 'https://sepoliafaucet.com/'; + case Network.ETHERLINK_TESTNET: + return 'https://faucet.etherlink.com/'; case Network.ZKSYNC_SEPOLIA: - return 'https://faucet.quicknode.com/ethereum/sepolia' + return 'https://faucet.quicknode.com/ethereum/sepolia'; } }; @@ -77,6 +86,8 @@ export const getNetworkName = () => { return 'Ethereum (Sepolia)'; case Network.ETHEREUM: return 'Ethereum (Mainnet)'; + case Network.ETHERLINK_TESTNET: + return 'Etherlink (Testnet)'; case Network.ZKSYNC: return 'zkSync (Mainnet)'; case Network.ZKSYNC_SEPOLIA: @@ -94,9 +105,25 @@ export const getBlockExplorer = (address: string) => { return `https://etherscan.io/address/${address}`; case Network.ETHEREUM_SEPOLIA: return `https://sepolia.etherscan.io/address/${address}`; + case Network.ETHERLINK_TESTNET: + return `https://testnet-explorer.etherlink.com//address/${address}`; case Network.ZKSYNC: return `https://explorer.zksync.io/address/${address}`; case Network.ZKSYNC_SEPOLIA: return `https://sepolia.explorer.zksync.io/address/${address}`; } }; + +export const isEip1559Supported = () => { + switch (process.env.NEXT_PUBLIC_BLOCKCHAIN_NETWORK) { + case Network.POLYGON: + case Network.POLYGON_AMOY: + case Network.ETHEREUM_SEPOLIA: + case Network.ETHEREUM: + case Network.ZKSYNC: + case Network.ZKSYNC_SEPOLIA: + return true; + case Network.ETHERLINK_TESTNET: + return false; + } +}; diff --git a/scaffolds/nextjs-universal-wallet/template/src/components/magic/cards/SendTransactionsCard.tsx b/scaffolds/nextjs-universal-wallet/template/src/components/magic/cards/SendTransactionsCard.tsx index 7ccc23a..bf23288 100644 --- a/scaffolds/nextjs-universal-wallet/template/src/components/magic/cards/SendTransactionsCard.tsx +++ b/scaffolds/nextjs-universal-wallet/template/src/components/magic/cards/SendTransactionsCard.tsx @@ -10,7 +10,7 @@ import CardHeader from '../../ui/CardHeader'; import TransactionHistory from '../../ui/TransactionHistory'; import ErrorText from '../../ui/Error'; import { useMagicContext } from '@/components/magic/MagicProvider'; -import { getFaucetUrl, getNetworkToken } from '@/utils/networks'; +import { getFaucetUrl, getNetworkToken, isEip1559Supported } from '@/utils/networks'; const SendTransaction = () => { const { web3 } = useMagicContext(); @@ -30,7 +30,7 @@ const SendTransaction = () => { setToAddressError(false); }, [amount, toAddress]); - const sendTransaction = useCallback(() => { + const sendTransaction = useCallback(async () => { if (!web3?.utils.isAddress(toAddress)) { return setToAddressError(true); } @@ -42,7 +42,8 @@ const SendTransaction = () => { from: publicAddress, to: toAddress, value: web3.utils.toWei(amount, 'ether'), - gas: 21000, + // Specify `gasPrice` if network doesn't support EIP-1559 + ...(!isEip1559Supported() && { gasPrice: await web3.eth.getGasPrice() }), }; web3.eth .sendTransaction(txnParams as any) diff --git a/scaffolds/nextjs-universal-wallet/template/src/utils/networks.ts b/scaffolds/nextjs-universal-wallet/template/src/utils/networks.ts index b518b22..1d812a8 100644 --- a/scaffolds/nextjs-universal-wallet/template/src/utils/networks.ts +++ b/scaffolds/nextjs-universal-wallet/template/src/utils/networks.ts @@ -3,6 +3,7 @@ export enum Network { POLYGON = 'polygon', ETHEREUM_SEPOLIA = 'ethereum-sepolia', ETHEREUM = 'ethereum', + ETHERLINK_TESTNET = 'etherlink-testnet', ZKSYNC = 'zksync', ZKSYNC_SEPOLIA = 'zksync-sepolia', } @@ -17,6 +18,8 @@ export const getNetworkUrl = () => { return 'https://eth-sepolia.g.alchemy.com/v2/3jKhhva6zBqwp_dnwPlF4d0rFZhu2pjD'; case Network.ETHEREUM: return 'https://eth-mainnet.g.alchemy.com/v2/3jKhhva6zBqwp_dnwPlF4d0rFZhu2pjD'; + case Network.ETHERLINK_TESTNET: + return 'https://node.ghostnet.etherlink.com'; case Network.ZKSYNC: return 'https://mainnet.era.zksync.io'; case Network.ZKSYNC_SEPOLIA: @@ -33,13 +36,15 @@ export const getChainId = () => { case Network.POLYGON_AMOY: return 80002; case Network.ETHEREUM_SEPOLIA: - return 1155111; + return 11155111; case Network.ZKSYNC: return 324; case Network.ZKSYNC_SEPOLIA: return 300; case Network.ETHEREUM: return 1; + case Network.ETHERLINK_TESTNET: + return 128123; } }; @@ -53,6 +58,8 @@ export const getNetworkToken = () => { case Network.ZKSYNC: case Network.ZKSYNC_SEPOLIA: return 'ETH'; + case Network.ETHERLINK_TESTNET: + return 'XTZ'; } }; @@ -62,8 +69,10 @@ export const getFaucetUrl = () => { return 'https://faucet.polygon.technology/'; case Network.ETHEREUM_SEPOLIA: return 'https://sepoliafaucet.com/'; + case Network.ETHERLINK_TESTNET: + return 'https://faucet.etherlink.com/'; case Network.ZKSYNC_SEPOLIA: - return 'https://faucet.quicknode.com/ethereum/sepolia' + return 'https://faucet.quicknode.com/ethereum/sepolia'; } }; @@ -77,6 +86,8 @@ export const getNetworkName = () => { return 'Ethereum (Sepolia)'; case Network.ETHEREUM: return 'Ethereum (Mainnet)'; + case Network.ETHERLINK_TESTNET: + return 'Etherlink (Testnet)'; case Network.ZKSYNC: return 'zkSync (Mainnet)'; case Network.ZKSYNC_SEPOLIA: @@ -94,9 +105,25 @@ export const getBlockExplorer = (address: string) => { return `https://etherscan.io/address/${address}`; case Network.ETHEREUM_SEPOLIA: return `https://sepolia.etherscan.io/address/${address}`; + case Network.ETHERLINK_TESTNET: + return `https://testnet-explorer.etherlink.com//address/${address}`; case Network.ZKSYNC: return `https://explorer.zksync.io/address/${address}`; case Network.ZKSYNC_SEPOLIA: - return `https://sepolia.explorer.zksync.io/address/${address}` + return `https://sepolia.explorer.zksync.io/address/${address}`; + } +}; + +export const isEip1559Supported = () => { + switch (process.env.NEXT_PUBLIC_BLOCKCHAIN_NETWORK) { + case Network.POLYGON: + case Network.POLYGON_AMOY: + case Network.ETHEREUM_SEPOLIA: + case Network.ETHEREUM: + case Network.ZKSYNC: + case Network.ZKSYNC_SEPOLIA: + return true; + case Network.ETHERLINK_TESTNET: + return false; } }; diff --git a/scaffolds/prompts.ts b/scaffolds/prompts.ts index 6eefe7f..115b54e 100644 --- a/scaffolds/prompts.ts +++ b/scaffolds/prompts.ts @@ -137,7 +137,7 @@ export namespace BlockchainNetworkPrompt { name: 'chain', message: 'Which blockchain do you want to use?', choices: [ - { name: 'evm', message: 'EVM (Ethereum, Polygon, etc.)' }, + { name: 'evm', message: 'EVM (Ethereum, Etherlink, Polygon, etc.)' }, { name: 'solana', message: 'Solana' }, { name: 'flow', message: 'Flow' }, ], @@ -173,6 +173,7 @@ export namespace BlockchainNetworkPrompt { choices: [ { name: 'ethereum', message: 'Ethereum (Mainnet)' }, { name: 'ethereum-sepolia', message: 'Ethereum (Sepolia Testnet)' }, + { name: 'etherlink-testnet', message: 'Etherlink (Testnet)' }, { name: 'polygon', message: 'Polygon (Mainnet)' }, { name: 'polygon-amoy', message: 'Polygon (Amoy Testnet)' }, { name: 'zksync', message: 'zkSync (Mainnet)' },