diff --git a/bridge_ui/locales/en-US/translation.json b/bridge_ui/locales/en-US/translation.json new file mode 100644 index 00000000..d0f58c68 --- /dev/null +++ b/bridge_ui/locales/en-US/translation.json @@ -0,0 +1,302 @@ +{ + "Alephium": "Alephium", + "Bridge": "Bridge", + "Token Bridge": "Token Bridge", + "Tokens_one": "Token", + "Tokens_other": "Tokens", + "Explorer": "Explorer", + "A bridge that offers unlimited transfers across chains for tokens.": "A bridge that offers unlimited transfers across chains for tokens.", + "Caution! You are using the {{ networkName }} build of this app.": "Caution! You are using the {{ networkName }} build of this app.", + "Caution! You have enabled the beta. Enter the secret code again to disable.": "Caution! You have enabled the beta. Enter the secret code again to disable.", + "View the FAQ": "View the FAQ", + "Redeem": "Redeem", + "Redeem tokens": "Redeem tokens", + "Send tokens": "Send tokens", + "Transactions": "Transactions", + "Select tokens to send through the website.": "Select tokens to send through the website.", + "Token Origin Verifier": "Token Origin Verifier", + "Source": "Source", + "Chain": "Chain", + "Source Chain": "Source Chain", + "Source Tx (paste here)": "Source Tx (paste here)", + "Target": "Target", + "Target Chain": "Target Chain", + "Target Address": "Target Address", + "Origin Chain": "Origin Chain", + "Origin Token Address": "Origin Token Address", + "Origin Token ID": "Origin Token ID", + "Go to Migration Page": "Go to Migration Page", + "Amount": "Amount", + "Next": "Next", + "Previous": "Previous", + "If you have sent your tokens but have not redeemed them, you may paste in the Source Transaction ID (from Step 3) to resume your transfer.": "If you have sent your tokens but have not redeemed them, you may paste in the Source Transaction ID (from Step 3) to resume your transfer.", + "Recover": "Recover", + "Advanced": "Advanced", + "Signed VAA (Hex)": "Signed VAA (Hex)", + "Emitter Chain": "Emitter Chain", + "Emitter Address": "Emitter Address", + "Sequence": "Sequence", + "Timestamp": "Timestamp", + "Guardian Set": "Guardian Set", + "Relayer Fee": "Relayer Fee", + "Transaction not found or not confirmed": "Transaction not found or not confirmed", + "Sequence not found": "Sequence not found", + "The transaction is awaiting confirmation": "The transaction is awaiting confirmation", + "The transaction is not confirmed": "The transaction is not confirmed", + "An error occurred while fetching the transaction info": "An error occurred while fetching the transaction info", + "Wallet is not connected": "Wallet is not connected", + "Relay request rejected.": "Relay request rejected.", + "Error": "Error", + "This transaction is eligible to be relayed": "This transaction is eligible to be relayed", + "Request Relay": "Request Relay", + "This transaction is eligible to be relayed by {{ chainName }}": "This transaction is eligible to be relayed by {{ chainName }}", + "This is wrapped by the Bridge! Here is the original token:": "This is wrapped by the Bridge! Here is the original token:", + "Transferring to {{ chainName }} will unwrap the token": "Transferring to {{ chainName }} will unwrap the token", + "This token has not yet been registered on {{ chainName }}": "This token has not yet been registered on {{ chainName }}", + "When bridged, this asset becomes:": "When bridged, this asset becomes:", + "Source Information": "Source Information", + "Enter a token from any supported chain to get started.": "Enter a token from any supported chain to get started.", + "Paste an address": "Paste an address", + "Bridge Results": "Bridge Results", + "Select a chain to see the result of bridging this token.": "Select a chain to see the result of bridging this token.", + "Other Chain": "Other Chain", + "Token Registration": "Token Registration", + "This form allows you to register a token on a new foreign chain. Tokens must be registered before they can be transferred.": "This form allows you to register a token on a new foreign chain. Tokens must be registered before they can be transferred.", + "Create wrapped token": "Create wrapped token", + "Send attestation": "Send attestation", + "Stats": "Stats", + "You will transfer {{ sourceAmount }}": "You will transfer {{ sourceAmount }}", + "from": "from", + "to": "to", + "on {{ chainName }}": "on {{ chainName }}", + "to {{ chainName }}": "to {{ chainName }}", + "Select a recipient chain and address.": "Select a recipient chain and address.", + "Bridged tokens": "Bridged tokens", + "Sent to": "Sent to", + "Current balance": "Current balance", + "and receive {{ amount }}": "and receive {{ amount }}", + "Create": "Create", + "Update": "Update", + "The create wrapped transaction was submitted.": "The create wrapped transaction was submitted.", + "addTokenToTokenList": "Remember to add the token to the <1>token list.", + "Attest Another Token!": "Attest Another Token!", + "Return to Transfer": "Return to Transfer", + "missingMetaplexMetadata": "This token is missing on-chain (Metaplex) metadata. Without it, the wrapped token's name and symbol will be empty. See the <1>metaplex repositoryfor details.", + "Transaction confirmed": "Transaction confirmed", + "Local token pool already exists": "Local token pool already exists", + "Waiting for transaction confirmation": "Waiting for transaction confirmation", + "Create Local Token Pool": "Create Local Token Pool", + "The token has been attested!": "The token has been attested!", + "Asset": "Asset", + "You will attest": "You will attest", + "You will have to pay transaction fees on {{ chainName }} to attest this token.": "You will have to pay transaction fees on {{ chainName }} to attest this token.", + "Note: there will be several transactions": "Note: there will be several transactions", + "Attest": "Attest", + "Could not migrate the tokens.": "Could not migrate the tokens.", + "Successfully migrated the tokens.": "Successfully migrated the tokens.", + "Successfully migrated your tokens. They will become available once this transaction confirms.": "Successfully migrated your tokens. They will become available once this transaction confirms.", + "Current Token": "Current Token", + "will become": "will become", + "Wormhole Token": "Wormhole Token", + "The swap pool has insufficient funds.": "The swap pool has insufficient funds.", + "Convert": "Convert", + "Connect": "Connect", + "Disconnect": "Disconnect", + "Connect your wallet to proceed.": "Connect your wallet to proceed.", + "Unable to retrieve necessary information. This asset may not be supported.": "Unable to retrieve necessary information. This asset may not be supported.", + "Enter an amount to transfer.": "Enter an amount to transfer.", + "The transfer amount must be greater than zero.": "The transfer amount must be greater than zero.", + "There are not sufficient funds in your wallet for this transfer.": "There are not sufficient funds in your wallet for this transfer.", + "There are not sufficient funds in the pool for this transfer.": "There are not sufficient funds in the pool for this transfer.", + "Balance": "Balance", + "This action will convert": "This action will convert", + "Utilizing this pool": "Utilizing this pool", + "Migrate": "Migrate", + "Migrate {{ tokensAmount }} Tokens": "Migrate {{ tokensAmount }} Tokens", + "Successfully migrated your tokens! They will be available once this transaction confirms.": "Successfully migrated your tokens! They will be available once this transaction confirms.", + "Please connect your wallet.": "Please connect your wallet.", + "Failed to send the transaction.": "Failed to send the transaction.", + "This asset is not eligible for migration.": "This asset is not eligible for migration.", + "Invalid token account.": "Invalid token account.", + "Convert assets from other bridges to Wormhole V2 tokens": "Convert assets from other bridges to Wormhole V2 tokens", + "Migrate Assets": "Migrate Assets", + "Unable to perform migration.": "Unable to perform migration.", + "Failed to load migration information for token": "Failed to load migration information for token", + "Unable to retrieve token balances.": "Unable to retrieve token balances.", + "Failed to retrieve available token information.": "Failed to retrieve available token information.", + "This page allows you to convert certain wrapped tokens into Wormhole V2 tokens.": "This page allows you to convert certain wrapped tokens into Wormhole V2 tokens.", + "This page allows you to convert certain wrapped tokens on {{ chainName }} into Wormhole V2 tokens.": "This page allows you to convert certain wrapped tokens on {{ chainName }} into Wormhole V2 tokens.", + "You have some assets that are eligible for migration! Click the 'Convert' button to swap them for Wormhole tokens.": "You have some assets that are eligible for migration! Click the 'Convert' button to swap them for Wormhole tokens.", + "You don't have any assets eligible for migration.": "You don't have any assets eligible for migration.", + "Unable to retrive the specific token.": "Unable to retrive the specific token.", + "Wallet is not connected.": "Wallet is not connected.", + "Token ID is required.": "Token ID is required.", + "Wormhole v1 assets cannot be transferred with this bridge.": "Wormhole v1 assets cannot be transferred with this bridge.", + "Wormhole v1 assets should not be transferred with this bridge.": "Wormhole v1 assets should not be transferred with this bridge.", + "Copy": "Copy", + "Copied": "Copied", + "Reload Tokens": "Reload Tokens", + "Not Implemented": "Not Implemented", + "Unknown": "Unknown", + "This is a legacy asset eligible for migration.": "This is a legacy asset eligible for migration.", + "Unable to retrieve required information about this token. Ensure your wallet is connected, then refresh the list.": "Unable to retrieve required information about this token. Ensure your wallet is connected, then refresh the list.", + "Could not find the specified address.": "Could not find the specified address.", + "Loading available tokens": "Loading available tokens", + "Searching for results": "Searching for results", + "Select a token": "Select a token", + "Search name or paste address": "Search name or paste address", + "Token ID": "Token ID", + "Other Assets": "Other Assets", + "Markets for these {{ chainName }} tokens exist for the corresponding tokens on {{ targetChainName }}": "Markets for these {{ chainName }} tokens exist for the corresponding tokens on {{ targetChainName }}", + "No results found": "No results found", + "Failed to get {{ chainName }} block number": "Failed to get {{ chainName }} block number", + "Failed to get tx number": "Failed to get tx number", + "Failed to get txs": "Failed to get txs", + "View on {{ explorerName }}": "View on {{ explorerName }}", + "No transactions yet": "No transactions yet", + "Add to Wallet": "Add to Wallet", + "Add to Metamask": "Add to Metamask", + "The token already exists": "The token already exists", + "Featured markets": "Featured markets", + "Please connect your wallet to check for transfer completion.": "Please connect your wallet to check for transfer completion.", + "Waiting for a relayer to process your transfer.": "Waiting for a relayer to process your transfer.", + "Your fees will be refunded on the target chain": "Your fees will be refunded on the target chain", + "Manually redeem instead": "Manually redeem instead", + "{{ chainName }} pays gas for you": "{{ chainName }} pays gas for you", + "Your transfer is complete.": "Your transfer is complete.", + "Automatically unwrap to native currency": "Automatically unwrap to native currency", + "Return to relayer view": "Return to relayer view", + "These tokens have already been redeemed.": "These tokens have already been redeemed.", + "Click here to see how to add them to your wallet.": "Click here to see how to add them to your wallet.", + "Token Address": "Token Address", + "Transfer More Tokens!": "Transfer More Tokens!", + "Receive the tokens on the target chain": "Receive the tokens on the target chain", + "Success!": "Success!", + "The redeem transaction was submitted": "The redeem transaction was submitted", + "The redeem transaction was submitted automatically by the relayer": "The redeem transaction was submitted automatically by the relayer", + "The tokens will become available once the transaction confirms.": "The tokens will become available once the transaction confirms.", + "Register Now": "Register Now", + "A different wallet is connected than in Step 1.": "A different wallet is connected than in Step 1.", + "Failed to approve the token transfer.": "Failed to approve the token transfer.", + "Transfer the tokens to the Alephium Bridge.": "Transfer the tokens to the Alephium Bridge.", + "This will initiate the transfer on {{ chainName }} and wait for finalization. If you navigate away from this page before completing Step 4, you will have to perform the recovery workflow to complete the transfer.": "This will initiate the transfer on {{ chainName }} and wait for finalization. If you navigate away from this page before completing Step 4, you will have to perform the recovery workflow to complete the transfer.", + "approveUnlimitedTokens_one": "Approve Unlimited Token", + "approveUnlimitedTokens_other": "Approve Unlimited Tokens", + "approveTokens_one": "Approve {{ count }} Token", + "approveTokens_other": "Approve {{ count }} Tokens", + "Transfer": "Transfer", + "Are you sure?": "Are you sure?", + "You are about to perform this transfer": "You are about to perform this transfer", + "Cancel": "Cancel", + "Confirm": "Confirm", + "The tokens have entered the bridge!": "The tokens have entered the bridge!", + "This is a Shuttle-wrapped asset from Polygon! Transferring it will result in a double wrapped (Bridge-wrapped Shuttle-wrapped) asset, which has no liquid markets.": "This is a Shuttle-wrapped asset from Polygon! Transferring it will result in a double wrapped (Bridge-wrapped Shuttle-wrapped) asset, which has no liquid markets.", + "bridgeWrappedTokensNoLiquid": "The tokens you will receive are <1>Bridge Wrapped Tokenswhich currently have no liquid markets!", + "bridgeWrappedTokens": "The tokens you will receive are <1>Bridge Wrapped Tokensand will need to be exchanged for the underlying tokens.", + "You will not receive native {{ token }} on {{ chainName }}": "You will not receive native {{ token }} on {{ chainName }}", + "To receive native {{ token }}, you will have to perform a swap with the wrapped tokens once you are done bridging.": "To receive native {{ token }}, you will have to perform a swap with the wrapped tokens once you are done bridging.", + "Lido stETH rewards can only be received on Ethereum. Use the value accruing wrapper token wstETH instead.": "Lido stETH rewards can only be received on Ethereum. Use the value accruing wrapper token wstETH instead.", + "Click here to see available markets for wrapped tokens.": "Click here to see available markets for wrapped tokens.", + "Waiting for wallet approval": "Waiting for wallet approval", + "Select your wallet": "Select your wallet", + "Automatic redeem is unavailable for this token.": "Automatic redeem is unavailable for this token.", + "Automatic Payment": "Automatic Payment", + "Manual Payment": "Manual Payment", + "Pay with additional tokens and use a relayer": "Pay with additional tokens and use a relayer", + "Pay with additional {{ token }} and use a relayer": "Pay with additional {{ token }} and use a relayer", + "Pay with your own funds on target chain": "Pay with your own funds on target chain", + "Pay with your own funds on {{ chainName }}": "Pay with your own funds on {{ chainName }}", + "Pay with your own {{ token }} on target chain": "Pay with your own {{ token }} on target chain", + "Pay with your own {{ token }} on {{ chainName }}": "Pay with your own {{ token }} on {{ chainName }}", + "How would you like to pay the target chain fees?": "How would you like to pay the target chain fees?", + "This Interface is open-source software providing access to Alephium's Bridge, a cross-chain messaging protocol.": "This Interface is open-source software providing access to Alephium's Bridge, a cross-chain messaging protocol.", + "It is a fork based on the open-source code of the Wormhole Bridge and is not affiliated with or endorsed by the Wormhole Foundation.": "It is a fork based on the open-source code of the Wormhole Bridge and is not affiliated with or endorsed by the Wormhole Foundation.", + "THIS INTERFACE AND THE BRIDGE PROTOCOL ARE PROVIDED \"AS IS\", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.": "THIS INTERFACE AND THE BRIDGE PROTOCOL ARE PROVIDED \"AS IS\", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.", + "By using or accessing this Interface or Bridge, you agree that no developer or entity involved in creating, deploying, maintaining, operating this Interface or Bridge, or causing or supporting any of the foregoing, will be liable in any manner for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of, this Interface or Bridge, or this Interface or Bridge themselves, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.": "By using or accessing this Interface or Bridge, you agree that no developer or entity involved in creating, deploying, maintaining, operating this Interface or Bridge, or causing or supporting any of the foregoing, will be liable in any manner for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of, this Interface or Bridge, or this Interface or Bridge themselves, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.", + "By using or accessing this Interface, you represent that you are not subject to sanctions or otherwise designated on any list of prohibited or restricted parties or excluded or denied persons, including but not limited to the lists maintained by the United States' Department of Treasury's Office of Foreign Assets Control, the United Nations Security Council, the European Union or its Member States, or any other government authority.": "By using or accessing this Interface, you represent that you are not subject to sanctions or otherwise designated on any list of prohibited or restricted parties or excluded or denied persons, including but not limited to the lists maintained by the United States' Department of Treasury's Office of Foreign Assets Control, the United Nations Security Council, the European Union or its Member States, or any other government authority.", + "This wallet may not have sufficient funds to pay for the upcoming transaction fees.": "This wallet may not have sufficient funds to pay for the upcoming transaction fees.", + "This wallet has a very low {{ token }} balance and may not be able to pay for the upcoming transaction fees.": "This wallet has a very low {{ token }} balance and may not be able to pay for the upcoming transaction fees.", + "Max": "Max", + "Loading available relayers": "Loading available relayers", + "Select a relayer": "Select a relayer", + "No relayers are available at this time.": "No relayers are available at this time.", + "Waiting for {{ blockDiff }} / {{ expectedBlocks }} confirmations on {{ chainName }}": "Waiting for {{ blockDiff }} / {{ expectedBlocks }} confirmations on {{ chainName }}", + "Waiting for confirmations on {{ chainName }}, {{ minutes }} minutes remaining": "Waiting for confirmations on {{ chainName }}, {{ minutes }} minutes remaining", + "Waiting for Wormhole Network consensus": "Waiting for Wormhole Network consensus", + "Waiting for finality on {{ chainName }} which may take up to 15 minutes.": "Waiting for finality on {{ chainName }} which may take up to 15 minutes.", + "Last finalized block number": "Last finalized block number", + "This transaction's block number": "This transaction's block number", + "An error occurred while fetching balances": "An error occurred while fetching balances", + "Unwrap Native Tokens": "Unwrap Native Tokens", + "Unwrap (withdraw) native tokens from their wrapped form (e.g. WETH → ETH)": "Unwrap (withdraw) native tokens from their wrapped form (e.g. WETH → ETH)", + "Unwrap All": "Unwrap All", + "An error occurred while getting the network": "An error occurred while getting the network", + "An error occurred while getting the signer address": "An error occurred while getting the signer address", + "An error occurred while requesting eth accounts": "An error occurred while requesting eth accounts", + "Please install MetaMask": "Please install MetaMask", + "Error enabling WalletConnect session": "Error enabling WalletConnect session", + "Could not retrieve contract metadata": "Could not retrieve contract metadata", + "Failed to get source asset info from {{ chainName }}": "Failed to get source asset info from {{ chainName }}", + "Failed to get source asset info from solana": "Failed to get source asset info from solana", + "Failed to get source asset info from terra": "Failed to get source asset info from terra", + "Failed to get source asset info from alephium": "Failed to get source asset info from alephium", + "Failed to get source asset info from algorand": "Failed to get source asset info from algorand", + "Failed to retrieve required data.": "Failed to retrieve required data.", + "No contract address": "No contract address", + "Could not retrieve the foreign asset.": "Could not retrieve the foreign asset.", + "Unable to determine existence of wrapped asset": "Unable to determine existence of wrapped asset", + "Failed to get token wrapper contract id": "Failed to get token wrapper contract id", + "Failed to check if the transfer tx has been completed": "Failed to check if the transfer tx has been completed", + "Transfer source chain is undefined": "Transfer source chain is undefined", + "Failed to get balance": "Failed to get balance", + "token address": "token address", + "Unable to retrive your EVM tokens": "Unable to retrive your EVM tokens", + "Failed to load alephium token metadata": "Failed to load alephium token metadata", + "Cannot load your Ethereum NFTs at the moment.": "Cannot load your Ethereum NFTs at the moment.", + "Cannot load your Ethereum tokens at the moment.": "Cannot load your Ethereum tokens at the moment.", + "Fetching VAA": "Fetching VAA", + "Fetched Signed VAA": "Fetched Signed VAA", + "Invalid local token: {{ tokenId }}, expected a 64 bytes hex string": "Invalid local token: {{ tokenId }}, expected a 64 bytes hex string", + "Transfer failed, please try again later": "Transfer failed, please try again later", + "Wallet is not connected to {{ cluster }}": "Wallet is not connected to {{ cluster }}", + "Expected Chain ID": "Expected Chain ID", + "Invalid foreign arguments.": "Invalid foreign arguments.", + "Unable to find address.": "Unable to find address.", + "Unable to determine original asset.": "Unable to determine original asset.", + "Failed to retrieve the relayer token info.": "Failed to retrieve the relayer token info.", + "Failed to get alephium balance": "Failed to get alephium balance", + "Cannot load wallet balance": "Cannot load wallet balance", + "Est. Fees": "Est. Fees", + "Select a source chain": "Select a source chain", + "Select an NFT": "Select an NFT", + "Token account unavailable": "Token account unavailable", + "Token amount unavailable": "Token amount unavailable", + "For non-NFTs, use the Transfer flow": "For non-NFTs, use the Transfer flow", + "Failed to load NFT Metadata.": "Failed to load NFT Metadata.", + "This NFT has a URL longer than the maximum supported length of 200.": "This NFT has a URL longer than the maximum supported length of 200.", + "Balance must be greater than zero": "Balance must be greater than zero", + "Invalid amount": "Invalid amount", + "Enter an amount": "Enter an amount", + "Amount must be greater than zero": "Amount must be greater than zero", + "Amount may not be greater than balance": "Amount may not be greater than balance", + "Target asset unavailable. Is the token registered?": "Target asset unavailable. Is the token registered?", + "Error in source": "Error in source", + "Select a target chain": "Select a target chain", + "Select a different target and source": "Select a different target and source", + "Target account unavailable": "Target account unavailable", + "Invalid relayer fee.": "Invalid relayer fee.", + "Token is ineligible for relay.": "Token is ineligible for relay.", + "The amount being transferred plus fees exceeds the wallet's balance.": "The amount being transferred plus fees exceeds the wallet's balance.", + "An unknown error occurred.": "An unknown error occurred.", + "Failed to fetch token list from {{ url }}": "Failed to fetch token list from {{ url }}", + "Failed to get tx status": "Failed to get tx status", + "Failed to get event for tx": "Failed to get event for tx", + "Failed to get alephium token info": "Failed to get alephium token info", + "Token {{ tokenId }} does not exists in the token-list": "Token {{ tokenId }} does not exists in the token-list", + "Invalid token info, expected: {{ localTokenInfo }}, have: {{ tokenInfo }}": "Invalid token info, expected: {{ localTokenInfo }}, have: {{ tokenInfo }}", + "Invalid contract id or contract address": "Invalid contract id or contract address", + "Token {{ tokenAddress }} does not exist in the token list": "Token {{ tokenAddress }} does not exist in the token list", + "Failed to get tokens": "Failed to get tokens", + "response status": "response status", + "Invalid response, expect a token list": "Invalid response, expect a token list" +} diff --git a/bridge_ui/package-lock.json b/bridge_ui/package-lock.json index b99ea776..77a952d3 100644 --- a/bridge_ui/package-lock.json +++ b/bridge_ui/package-lock.json @@ -47,6 +47,7 @@ "qrcode.react": "^3.0.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-i18next": "^14.1.2", "react-modal": "^3.15.1", "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", @@ -4070,10 +4071,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.18.3", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -4090,6 +4092,11 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/@babel/template": { "version": "7.16.7", "license": "MIT", @@ -24734,6 +24741,14 @@ "node": ">= 12" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-webpack-plugin": { "version": "5.5.0", "license": "MIT", @@ -24913,6 +24928,29 @@ "version": "1.0.4", "license": "BSD-3-Clause" }, + "node_modules/i18next": { + "version": "23.11.5", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz", + "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "peer": true, + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/ice-cap": { "version": "0.0.4", "dev": true, @@ -37007,6 +37045,27 @@ "version": "6.0.11", "license": "MIT" }, + "node_modules/react-i18next": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", + "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "17.0.2", "license": "MIT" @@ -44368,6 +44427,14 @@ "dev": true, "license": "MIT" }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/vuvuzela": { "version": "1.0.3", "dev": true, @@ -49334,9 +49401,18 @@ } }, "@babel/runtime": { - "version": "7.18.3", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } } }, "@babel/runtime-corejs3": { @@ -64273,6 +64349,14 @@ } } }, + "html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "requires": { + "void-elements": "3.1.0" + } + }, "html-webpack-plugin": { "version": "5.5.0", "requires": { @@ -64381,6 +64465,15 @@ "hyphenate-style-name": { "version": "1.0.4" }, + "i18next": { + "version": "23.11.5", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz", + "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==", + "peer": true, + "requires": { + "@babel/runtime": "^7.23.2" + } + }, "ice-cap": { "version": "0.0.4", "dev": true, @@ -72650,6 +72743,15 @@ "react-error-overlay": { "version": "6.0.11" }, + "react-i18next": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", + "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==", + "requires": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + } + }, "react-is": { "version": "17.0.2" }, @@ -77744,6 +77846,11 @@ "version": "1.1.2", "dev": true }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" + }, "vuvuzela": { "version": "1.0.3", "dev": true, diff --git a/bridge_ui/package.json b/bridge_ui/package.json index 639c7418..7a4a2166 100644 --- a/bridge_ui/package.json +++ b/bridge_ui/package.json @@ -42,6 +42,7 @@ "qrcode.react": "^3.0.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-i18next": "^14.1.2", "react-modal": "^3.15.1", "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", diff --git a/bridge_ui/src/App.js b/bridge_ui/src/App.js index c06f89bb..4127bf37 100644 --- a/bridge_ui/src/App.js +++ b/bridge_ui/src/App.js @@ -47,6 +47,7 @@ import { useWallet } from "@alephium/web3-react"; import { useEffect } from "react"; import { web3 } from "@alephium/web3"; import backgroundGradient from "./images/top-gradient.png"; +import { useTranslation } from "react-i18next"; const useStyles = makeStyles((theme) => ({ appBar: { @@ -129,6 +130,7 @@ const useStyles = makeStyles((theme) => ({ })); function App() { + const { t } = useTranslation(); const classes = useStyles(); const isBeta = useBetaContext(); const { push } = useHistory(); @@ -152,7 +154,7 @@ function App() { {CLUSTER === "mainnet" ? null : ( - Caution! You are using the {CLUSTER} build of this app. + {t("Caution! You are using the {{ networkName }} build of this app.", { networkName: CLUSTER })} )} @@ -171,7 +173,7 @@ function App() { > Alephium @@ -184,7 +186,7 @@ function App() { color="inherit" className={classes.link} > - Bridge + {t("Bridge")} - Explorer + {t("Explorer")} - Alephium + {t("Alephium")} - + - Caution! You have enabled the beta. Enter the secret code again to - disable. + {t("Caution! You have enabled the beta. Enter the secret code again to disable.")} ) : null} @@ -236,13 +237,12 @@ function App() { subtitle={ <> - A bridge that offers unlimited transfers across chains for - tokens. + {t("A bridge that offers unlimited transfers across chains for tokens.")} } > - Token Bridge 🌉 + {t("Token Bridge")} 🌉 - + {/* */} - + ({ })); function Create() { + const { t } = useTranslation(); const classes = useStyles(); const targetChain = useSelector(selectAttestTargetChain); const originAsset = useSelector(selectAttestSourceAsset); @@ -61,7 +63,7 @@ function Create() { showLoader={showLoader} error={error} > - {shouldUpdate ? "Update" : "Create"} + {shouldUpdate ? t("Update") : t("Create")} diff --git a/bridge_ui/src/components/Attest/CreatePreview.tsx b/bridge_ui/src/components/Attest/CreatePreview.tsx index 1273d855..c583a570 100644 --- a/bridge_ui/src/components/Attest/CreatePreview.tsx +++ b/bridge_ui/src/components/Attest/CreatePreview.tsx @@ -11,6 +11,7 @@ import ShowTx from "../ShowTx"; import { useHistory } from "react-router"; import { getHowToAddToTokenListUrl } from "../../utils/consts"; import { Alert } from "@material-ui/lab"; +import { Trans, useTranslation } from "react-i18next"; const useStyles = makeStyles((theme) => ({ description: { @@ -22,6 +23,7 @@ const useStyles = makeStyles((theme) => ({ })); export default function CreatePreview() { + const { t } = useTranslation(); const { push } = useHistory(); const classes = useStyles(); const dispatch = useDispatch(); @@ -36,7 +38,7 @@ export default function CreatePreview() { }, [dispatch, push]); const explainerString = - "Success! The create wrapped transaction was submitted."; + `${t('Success!')} ${t("The create wrapped transaction was submitted.")}`; const howToAddToTokenListUrl = getHowToAddToTokenListUrl(targetChain); return ( @@ -51,22 +53,22 @@ export default function CreatePreview() { {createTx ? : null} {howToAddToTokenListUrl ? ( - Remember to add the token to the{" "} - + }} > - token list - - {"."} + {'Remember to add the token to the <1>token list.'} + ) : null} - Attest Another Token! + {t("Attest Another Token!")} - Return to Transfer + {t("Return to Transfer")} ); diff --git a/bridge_ui/src/components/Attest/Send.tsx b/bridge_ui/src/components/Attest/Send.tsx index 15a1198c..e5bb70de 100644 --- a/bridge_ui/src/components/Attest/Send.tsx +++ b/bridge_ui/src/components/Attest/Send.tsx @@ -23,6 +23,7 @@ import { createLocalTokenPool } from "../../utils/alephium"; import { useWallet } from "@alephium/web3-react"; import { useSnackbar } from "notistack"; import { setStep } from "../../store/attestSlice"; +import { Trans, useTranslation } from "react-i18next"; const useStyles = makeStyles((theme) => ({ alert: { @@ -31,6 +32,7 @@ const useStyles = makeStyles((theme) => ({ })); const SolanaTokenMetadataWarning = () => { + const { t } = useTranslation(); const sourceAsset = useSelector(selectAttestSourceAsset); const sourceAssetArrayed = useMemo(() => { return [sourceAsset]; @@ -44,21 +46,21 @@ const SolanaTokenMetadataWarning = () => { return !metaplexData.data?.get(sourceAsset) ? ( - This token is missing on-chain (Metaplex) metadata. Without it, the - wrapped token's name and symbol will be empty. See the{" "} - + }} > - metaplex repository - {" "} - for details. + {"This token is missing on-chain (Metaplex) metadata. Without it, the wrapped token's name and symbol will be empty. See the <1>metaplex repositoryfor details."} + ) : null; }; function CreateLocalTokenPool({ localTokenId }: { localTokenId: string }) { + const { t } = useTranslation() const alphWallet = useWallet() const dispatch = useDispatch() const { enqueueSnackbar } = useSnackbar() @@ -80,11 +82,11 @@ function CreateLocalTokenPool({ localTokenId }: { localTokenId: string }) { await waitAlphTxConfirmed(alphWallet.nodeProvider, createLocalTokenPoolTxId, 1) console.log(`create local token pool tx id: ${createLocalTokenPoolTxId}`) enqueueSnackbar(null, { - content: Transaction confirmed + content: {t("Transaction confirmed")} }) } else { enqueueSnackbar(null, { - content: Local token pool already exists + content: {t("Local token pool already exists")} }) } } catch (error) { @@ -94,7 +96,7 @@ function CreateLocalTokenPool({ localTokenId }: { localTokenId: string }) { setIsSending(false) dispatch(setStep(3)) } - }, [alphWallet, signedVAAHex, enqueueSnackbar, localTokenId, dispatch]) + }, [alphWallet, signedVAAHex, enqueueSnackbar, localTokenId, dispatch, t]) const isReady = signedVAAHex !== undefined && alphWallet !== undefined && !isSending return ( @@ -105,13 +107,14 @@ function CreateLocalTokenPool({ localTokenId }: { localTokenId: string }) { showLoader={isSending} error={error} > - {isSending ? 'Waiting for transaction confirmation...' : 'Create Local Token Pool'} + {isSending ? `${t('Waiting for transaction confirmation')}...` : t('Create Local Token Pool')} ) } function Send() { + const { t } = useTranslation(); const { handleClick, disabled, showLoader } = useHandleAttest(); const sourceChain = useSelector(selectAttestSourceChain); const sourceAsset = useSelector(selectAttestSourceAsset); @@ -131,7 +134,7 @@ function Send() { showLoader={showLoader} error={statusMessage} > - Attest + {t("Attest")} {sourceChain === CHAIN_ID_SOLANA && } diff --git a/bridge_ui/src/components/Attest/SendPreview.tsx b/bridge_ui/src/components/Attest/SendPreview.tsx index 051d3f31..614d602a 100644 --- a/bridge_ui/src/components/Attest/SendPreview.tsx +++ b/bridge_ui/src/components/Attest/SendPreview.tsx @@ -1,4 +1,5 @@ import { makeStyles, Typography } from "@material-ui/core"; +import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; import { selectAttestSourceChain, @@ -20,11 +21,12 @@ const useStyles = makeStyles((theme) => ({ })); export default function SendPreview() { + const { t } = useTranslation(); const classes = useStyles(); const sourceChain = useSelector(selectAttestSourceChain); const attestTx = useSelector(selectAttestAttestTx); - const explainerString = "The token has been attested!"; + const explainerString = t("The token has been attested!"); return ( <> diff --git a/bridge_ui/src/components/Attest/Source.tsx b/bridge_ui/src/components/Attest/Source.tsx index 9b5024c2..41f7394e 100644 --- a/bridge_ui/src/components/Attest/Source.tsx +++ b/bridge_ui/src/components/Attest/Source.tsx @@ -1,5 +1,6 @@ import { makeStyles, TextField } from "@material-ui/core"; import { useCallback } from "react"; +import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { incrementStep, @@ -25,6 +26,7 @@ const useStyles = makeStyles((theme) => ({ })); function Source() { + const { t } = useTranslation(); const classes = useStyles(); const dispatch = useDispatch(); const sourceChain = useSelector(selectAttestSourceChain); @@ -59,7 +61,7 @@ function Source() { /> - Next + {t("Next")} ); diff --git a/bridge_ui/src/components/Attest/SourcePreview.tsx b/bridge_ui/src/components/Attest/SourcePreview.tsx index a15ef290..742d0090 100644 --- a/bridge_ui/src/components/Attest/SourcePreview.tsx +++ b/bridge_ui/src/components/Attest/SourcePreview.tsx @@ -1,4 +1,5 @@ import { makeStyles, Typography } from "@material-ui/core"; +import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; import { selectAttestSourceAsset, @@ -14,6 +15,7 @@ const useStyles = makeStyles((theme) => ({ })); export default function SourcePreview() { + const { t } = useTranslation(); const classes = useStyles(); const sourceChain = useSelector(selectAttestSourceChain); const sourceAsset = useSelector(selectAttestSourceAsset); @@ -21,9 +23,9 @@ export default function SourcePreview() { const explainerContent = sourceChain && sourceAsset ? ( <> - You will attest + {t("You will attest")} - on {CHAINS_BY_ID[sourceChain].name} + {t("on {{ chainName }}", { chainName: CHAINS_BY_ID[sourceChain].name })} ) : ( "" diff --git a/bridge_ui/src/components/Attest/Target.tsx b/bridge_ui/src/components/Attest/Target.tsx index a6928379..44cf4c0e 100644 --- a/bridge_ui/src/components/Attest/Target.tsx +++ b/bridge_ui/src/components/Attest/Target.tsx @@ -2,6 +2,7 @@ import { isEVMChain } from "@alephium/wormhole-sdk"; import { makeStyles, Typography } from "@material-ui/core"; import { Alert } from "@material-ui/lab"; import { useCallback, useMemo } from "react"; +import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { GasEstimateSummary } from "../../hooks/useTransactionFees"; import { incrementStep, setTargetChain } from "../../store/attestSlice"; @@ -25,6 +26,7 @@ const useStyles = makeStyles((theme) => ({ })); function Target() { + const { t } = useTranslation(); const classes = useStyles(); const dispatch = useDispatch(); const sourceChain = useSelector(selectAttestSourceChain); @@ -58,8 +60,7 @@ function Target() { - You will have to pay transaction fees on{" "} - {CHAINS_BY_ID[targetChain].name} to attest this token.{" "} + {t("You will have to pay transaction fees on {{ chainName }} to attest this token.", { chainName: CHAINS_BY_ID[targetChain].name })} {isEVMChain(targetChain) && ( - Next + {t("Next")} ); diff --git a/bridge_ui/src/components/Attest/TargetPreview.tsx b/bridge_ui/src/components/Attest/TargetPreview.tsx index de350de5..50506d0c 100644 --- a/bridge_ui/src/components/Attest/TargetPreview.tsx +++ b/bridge_ui/src/components/Attest/TargetPreview.tsx @@ -1,4 +1,5 @@ import { makeStyles, Typography } from "@material-ui/core"; +import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; import { selectAttestTargetChain } from "../../store/selectors"; import { CHAINS_BY_ID } from "../../utils/consts"; @@ -10,10 +11,11 @@ const useStyles = makeStyles((theme) => ({ })); export default function TargetPreview() { + const { t } = useTranslation(); const classes = useStyles(); const targetChain = useSelector(selectAttestTargetChain); - const explainerString = `to ${CHAINS_BY_ID[targetChain].name}`; + const explainerString = t('to {{ chainName }}', { chainName: CHAINS_BY_ID[targetChain].name } ); return ( ({ })); export default function WaitingForWalletMessage() { + const { t } = useTranslation(); const classes = useStyles(); const isSending = useSelector(selectAttestIsSending); const isWalletApproved = useSelector(selectAttestIsWalletApproved) @@ -32,7 +34,7 @@ export default function WaitingForWalletMessage() { {isWalletApproved ? WAITING_FOR_TX_CONFIRMATION : WAITING_FOR_WALLET_APPROVAL}{" "} {targetChain === CHAIN_ID_SOLANA && isCreating - ? "Note: there will be several transactions" + ? t("Note: there will be several transactions") : null} ) : null; diff --git a/bridge_ui/src/components/Attest/index.tsx b/bridge_ui/src/components/Attest/index.tsx index 688203f0..056af78d 100644 --- a/bridge_ui/src/components/Attest/index.tsx +++ b/bridge_ui/src/components/Attest/index.tsx @@ -8,6 +8,7 @@ import { } from "@material-ui/core"; import { Alert } from "@material-ui/lab"; import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { setStep } from "../../store/attestSlice"; import { @@ -32,6 +33,7 @@ const useStyles = makeStyles((theme) => ({ })); function Attest() { + const { t } = useTranslation() const classes = useStyles(); const dispatch = useDispatch(); const activeStep = useSelector(selectAttestActiveStep); @@ -51,10 +53,9 @@ function Attest() { }, [preventNavigation]); return ( - Token Registration + {t("Token Registration")} - This form allows you to register a token on a new foreign chain. Tokens - must be registered before they can be transferred. + {t("This form allows you to register a token on a new foreign chain. Tokens must be registered before they can be transferred.")}
@@ -63,7 +64,7 @@ function Attest() { disabled={preventNavigation || isCreateComplete} > dispatch(setStep(0))} icon={null}> - 1. Source + 1. {t("Source")} {activeStep === 0 ? : } @@ -74,7 +75,7 @@ function Attest() { disabled={preventNavigation || isCreateComplete} > dispatch(setStep(1))} icon={null}> - 2. Target + 2. {t("Target")} {activeStep === 1 ? : } @@ -82,7 +83,7 @@ function Attest() { = 2} disabled={isSendComplete}> dispatch(setStep(2))} icon={null}> - 3. Send attestation + 3. {t("Send attestation")} {activeStep === 2 ? : } @@ -94,7 +95,7 @@ function Attest() { disabled={!isSendComplete} icon={null} > - 4. Create wrapped token + 4. {t("Create wrapped token")} {isCreateComplete ? : } diff --git a/bridge_ui/src/components/EvmConnectWalletDialog.tsx b/bridge_ui/src/components/EvmConnectWalletDialog.tsx index 92fb3a87..6c5b914a 100644 --- a/bridge_ui/src/components/EvmConnectWalletDialog.tsx +++ b/bridge_ui/src/components/EvmConnectWalletDialog.tsx @@ -19,6 +19,7 @@ import { import { getEvmChainId } from "../utils/consts"; import { EVM_RPC_MAP } from "../utils/metaMaskChainParameters"; import useIsWalletReady from "../hooks/useIsWalletReady"; +import { useTranslation } from "react-i18next"; const useStyles = makeStyles((theme) => ({ flexTitle: { @@ -77,6 +78,7 @@ const EvmConnectWalletDialog = ({ onClose: () => void; chainId: ChainId; }) => { + const { t } = useTranslation(); const { availableConnections, connect, chainId: evmChainId } = useEthereumProvider(); const enableAutoSwitch = evmChainId === undefined const { forceNetworkSwitch } = useIsWalletReady(chainId, enableAutoSwitch) @@ -109,7 +111,7 @@ const EvmConnectWalletDialog = ({
-
Select your wallet
+
{t("Select your wallet")}
diff --git a/bridge_ui/src/components/FeeMethodSelector.tsx b/bridge_ui/src/components/FeeMethodSelector.tsx index a91d1c4f..740fd39e 100644 --- a/bridge_ui/src/components/FeeMethodSelector.tsx +++ b/bridge_ui/src/components/FeeMethodSelector.tsx @@ -15,6 +15,7 @@ import { import clsx from "clsx"; import { parseUnits } from "ethers/lib/utils"; import { useCallback, useEffect } from "react"; +import { useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import SmartAddress from "../components/SmartAddress"; import { useAcalaRelayerInfo } from "../hooks/useAcalaRelayerInfo"; @@ -84,6 +85,7 @@ const useStyles = makeStyles((theme) => ({ })); function FeeMethodSelector() { + const { t } = useTranslation(); const classes = useStyles(); const originAsset = useSelector(selectTransferOriginAsset); const originChain = useSelector(selectTransferOriginChain); @@ -191,13 +193,13 @@ function FeeMethodSelector() { {CHAINS_BY_ID[targetChain].name} - {CHAINS_BY_ID[targetChain].name} pays gas for you 🎉 + {t("{{ chainName }} pays gas for you", { chainName: CHAINS_BY_ID[targetChain].name })}
) : ( <> - {"Automatic redeem is unavailable for this token."} + {t("Automatic redeem is unavailable for this token.")}
@@ -234,17 +236,17 @@ function FeeMethodSelector() {
{relayerEligible ? (
- Automatic Payment + {t("Automatic Payment")} - {`Pay with additional ${ - sourceSymbol ? sourceSymbol : "tokens" - } and use a relayer`} + {sourceSymbol ? + t('Pay with additional {{ token }} and use a relayer', { token: sourceSymbol }) : + t('Pay with additional tokens and use a relayer')}
) : ( <> - {"Automatic redeem is unavailable for this token."} + {t("Automatic redeem is unavailable for this token.")}
@@ -278,6 +280,8 @@ function FeeMethodSelector() { ); + const chainName = CHAINS_BY_ID[targetChain]?.name + const token = getDefaultNativeCurrencySymbol(targetChain) const manualRedeemContent = (
- {"Manual Payment"} + {t("Manual Payment")} - {`Pay with your own ${ - targetChain === CHAIN_ID_TERRA - ? "funds" - : getDefaultNativeCurrencySymbol(targetChain) - } on ${CHAINS_BY_ID[targetChain]?.name || "target chain"}`} + {targetChain === CHAIN_ID_TERRA && chainName ? + t('Pay with your own funds on {{ chainName }}', { chainName }) : + targetChain === CHAIN_ID_TERRA ? + t('Pay with your own funds on target chain') : + chainName ? + t('Pay with your own {{ token }} on {{ chainName }}', { token, chainName }) : + t('Pay with your own {{ token }} on target chain', { token })}
@@ -323,7 +329,7 @@ function FeeMethodSelector() { variant="subtitle2" color="textSecondary" > - How would you like to pay the target chain fees? + {t("How would you like to pay the target chain fees?")} {targetIsAcala ? acalaRelayerContent : relayerContent} {manualRedeemContent} diff --git a/bridge_ui/src/components/Footer.tsx b/bridge_ui/src/components/Footer.tsx index d15481b9..6eb25c74 100644 --- a/bridge_ui/src/components/Footer.tsx +++ b/bridge_ui/src/components/Footer.tsx @@ -1,4 +1,5 @@ import { makeStyles, Typography } from "@material-ui/core"; +import { useTranslation } from "react-i18next"; const useStyles = makeStyles((theme) => ({ footer: { @@ -50,6 +51,7 @@ const useStyles = makeStyles((theme) => ({ })); export default function Footer() { + const { t } = useTranslation(); const classes = useStyles(); return (