<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Offshift Bridge</title> <script src="./web3.min.js"></script> <link href="./styles.css" rel="stylesheet"> </head> <body> <div id="main" class="dark"> <div class="min-h-screen bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 py-6 flex flex-col justify-center sm:py-12 text-white dark:bg-gradient-to-r dark:from-gray-800 dark:to-gray-900"> <div class="dark:bg-gray-800 dark:text-white w-full mx-auto rounded-3xl shadow-lg bg-white px-10 pt-16 pb-10 text-gray-600" style="max-width: 400px"> <div class="overflow-hidden relative mb-10"> <div class="font-semibold text-center text-2xl mb-4 text-gray-900 dark:text-white">Offshift Bridge </div> <div class="container mx-auto mb-1 pt-8 justify-center"> <p class="mx-auto mb-3 dark:text-purple-500 text-center font-bold pb-3" id="net">Non Web3 enabled browser detected</p> <p class="mx-auto mb-3 dark:text-purple-500 text-center font-bold pb-3">Amount</p> <input id="tokenAmount" type="number" class="dark:border-gray-800 focus:ring-2 dark:bg-gray-600 shadow appearance-none border rounded py-2 px-20 text-grey-darker"> </div> <div class="container w-full pt-10 text-center"> <button id="btttn" onclick="handle()" class="dark:bg-gradient-to-r dark:from-purple-800 px-7 py-3 shadow-md no-underline rounded-full bg-gradient-to-r from-green-400 to-blue-500 hover:from-pink-500 hover:to-yellow-500 text-white font-sans font-semibold text-xl border-blue btn-primary hover:text-white hover:bg-blue-light focus:outline-none active:shadow-none justify-center">Approve</button> </div> </div> </div> </div> </body> </html> <script> if (typeof ethereum != "undefined") { ethereum.request({ method: 'eth_requestAccounts' }).catch((err) => alert("Please connect metamask to the site")); } else { alert("None ethereum browser detected, Please install metmask !!!"); } web3 = new Web3(window.ethereum); web3.eth.getAccounts(async function (error, accounts) { web3.eth.accounts = accounts; web3.eth.defaultAccount = accounts[0]; }); let network = ""; async function setup() { let netId = await web3.eth.net.getId(); if (netId == 1) { network = "ethereum"; } else if (netId == 56) { network = "binance"; } else { alert("please switch to a supported network") } net.innerText = `Using ${network} network`; } let state = "Approve"; function handle() { if (state == "Approve") { approve(); } else { bridge(); } } async function bridge() { let bridge_contract; let token = ""; if (network == "ethereum") { bridge_contract = new web3.eth.Contract(bridge_abi, "0xe138c66982Fd5c890c60b94FDBa1747faF092c20"); token = "0xABe580E7ee158dA464b51ee1a83Ac0289622e6be"; } else if (network == "binance") { bridge_contract = new web3.eth.Contract(bridge_abi, "0xcDC5DeeFa9F540bAC261829B6c64163E2CfF92Ca"); token = "0xe138c66982Fd5c890c60b94FDBa1747faF092c20"; } let amount = web3.utils.toWei(parseFloat(tokenAmount.value).toString(), 'ether'); btttn.classList.add("opacity-40"); btttn.disabled = true; if (network == "ethereum") { let gas = (await bridge_contract.methods.move(amount).estimateGas({ from: ethereum.selectedAddress, value: 2 })) * await web3.eth.getGasPrice(); await bridge_contract.methods.move(amount).send({ from: ethereum.selectedAddress, value: gas }); } else { await bridge_contract.methods.move(amount).send({ from: ethereum.selectedAddress}); } state = "Approve"; btttn.innerText = state; btttn.classList.remove("opacity-40"); btttn.disabled = false; //addToken(token); alert("Tokens moved, transcation may take up to 30 minutes in order to complete"); } async function approve() { let token = ""; let bridge_address = ""; if (network == "ethereum") { token = new web3.eth.Contract(token_abi, "0xABe580E7ee158dA464b51ee1a83Ac0289622e6be"); bridge_address = "0xe138c66982Fd5c890c60b94FDBa1747faF092c20"; } else if (network == "binance") { token = new web3.eth.Contract(token_abi, "0xe138c66982Fd5c890c60b94FDBa1747faF092c20"); bridge_address = "0xcDC5DeeFa9F540bAC261829B6c64163E2CfF92Ca"; } btttn.classList.add("opacity-40"); btttn.disabled = true; let amount = web3.utils.toWei(parseFloat(tokenAmount.value).toString(), 'ether'); if (await token.methods.allowance(ethereum.selectedAddress, bridge_address).call() >= amount) { state = "MOVE"; btttn.innerText = state; btttn.classList.remove("opacity-40"); btttn.disabled = false; return 1; } await token.methods.approve(bridge_address, amount).send({ from: ethereum.selectedAddress }); state = "MOVE"; btttn.innerText = state; btttn.classList.remove("opacity-40"); btttn.disabled = false; } async function addToken(addy) { const tokenAddress = addy; const tokenSymbol = 'XFT'; const tokenDecimals = 18; const tokenImage = 'https://assets.coingecko.com/coins/images/11977/small/CsBrPiA.png?1614570441'; try { // wasAdded is a boolean. Like any RPC method, an error may be thrown. const wasAdded = await ethereum.request({ method: 'wallet_watchAsset', params: { type: 'ERC20', // Initially only supports ERC20, but eventually more! options: { address: tokenAddress, // The address that the token is at. symbol: tokenSymbol, // A ticker symbol or shorthand, up to 5 chars. decimals: tokenDecimals, // The number of decimals in the token image: tokenImage, // A string url of the token logo }, }, }); if (wasAdded) { console.log('!!!!'); } else { console.log('Your loss!'); } } catch (error) { console.log(error); } } let token_abi = [ { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" } ] let bridge_abi = [ { "inputs": [ { "internalType": "address", "name": "_token", "type": "address" }, { "internalType": "address", "name": "_bridge", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "address", "name": "recv", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "bridged", "type": "event" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "move", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "stop", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ]; setup(); ethereum.on('chainChanged', (_chainId) => window.location.reload()); </script>