diff --git a/client/src/constants.js b/client/src/constants.js index 7a636004c..1ee464d11 100644 --- a/client/src/constants.js +++ b/client/src/constants.js @@ -119,6 +119,26 @@ export const NETWORKS_INGAME = { }, }; +// Deprectated networks +// status: {deprecated | deprecation-planned} +export const NETWORKS_DEPRECATION = { + GOERLI: { + id: "5", + status: "deprecation-planned", + date: "jan-2024" + }, + OPTIMISM_GOERLI: { + id: "420", + status: "deprecation-planned", + date: "jan-2024" + }, + ARBITRUM_GOERLI: { + id: "421613", + status: "deprecation-planned", + date: "jan-2024" + } +}; + // Web3 export const Web3 = pkgWeb3; diff --git a/client/src/containers/App.js b/client/src/containers/App.js index 9d6135b3d..bb0f09634 100644 --- a/client/src/containers/App.js +++ b/client/src/containers/App.js @@ -8,12 +8,26 @@ import parse from "html-react-parser"; import { connect } from "react-redux"; import { bindActionCreators } from "redux"; import { withRouter } from "../hoc/withRouter"; -import { randGoodIcon } from "../utils/^^"; -import { deployAdminContracts } from '../utils/deploycontract'; +import { randGoodIcon, randBadIcon } from "../utils/^^"; +import { deployAdminContracts } from "../utils/deploycontract"; +import { + networkOnDeprecationOrDeprecated, + isDeprecatedNetwork, + deprecationStatus, + deprecationDate +} from "../utils/networkDeprecation"; class App extends React.Component { constructor() { super(); + this.state = { + chainId: 0, + }; + if (window.ethereum) { + window.ethereum.request({ method: "eth_chainId" }).then((id) => { + this.setState({ chainId: Number(id) }); + }); + } // Analytics ReactGA.initialize(constants.GOOGLE_ANALYTICS_ID); @@ -31,7 +45,7 @@ class App extends React.Component { let target = this.props.levels[0].deployedAddress; for (let i = 0; i < this.props.levels.length; i++) { const level = this.props.levels[i]; - if (!level.deployedAddress) { + if (!level.deployedAddress) { return this.props.navigate(`${constants.PATH_LEVEL_ROOT}${i}`); } const completed = this.props.completedLevels[level.deployedAddress]; @@ -54,41 +68,58 @@ class App extends React.Component { // change the network to Sepolia network async function switchToSepolia() { - let elements = document.querySelectorAll('.progress-bar-wrapper'); - const deployWindow = document.querySelectorAll('.deploy-window-bg'); + let elements = document.querySelectorAll(".progress-bar-wrapper"); + const deployWindow = document.querySelectorAll(".deploy-window-bg"); try { await window.ethereum.request({ - method: 'wallet_switchEthereumChain', - params: [{ chainId: `0x${Number(constants.NETWORKS.SEPOLIA.id).toString(16)}` }],//if on wrong network giving option to switch to sepolia network. + method: "wallet_switchEthereumChain", + params: [ + { + chainId: `0x${Number(constants.NETWORKS.SEPOLIA.id).toString( + 16 + )}`, + }, + ], //if on wrong network giving option to switch to sepolia network. }); - deployWindow[0].style.display = 'none'; + deployWindow[0].style.display = "none"; } catch (switchError) { // This error code indicates that the chain has not been added to MetaMask. if (switchError.code === 4902) { try { await window.ethereum.request({ - method: 'wallet_addEthereumChain', + method: "wallet_addEthereumChain", params: [ { - chainId: [{ chainId: `0x${Number(constants.NETWORKS.SEPOLIA.id).toString(16)}` }] + chainId: [ + { + chainId: `0x${Number( + constants.NETWORKS.SEPOLIA.id + ).toString(16)}`, + }, + ], }, ], }); - deployWindow[0].style.display = 'none'; + deployWindow[0].style.display = "none"; } catch (addError) { if (addError.code === 4001) { //User has rejected changing the request - elements[0].style.display = 'none'; + elements[0].style.display = "none"; } - console.error("Can't add nor switch to the selected network") + console.error("Can't add nor switch to the selected network"); } } else if (switchError.code === 4001) { //User has rejected changing the request - if (elements[0]) elements[0].style.display = 'none'; + if (elements[0]) elements[0].style.display = "none"; } } } + async function continueAnyway() { + const deployWindow = document.querySelectorAll(".deploy-window-bg"); + deployWindow[0].style.display = "none"; + } + return (
{/* Parent container */} @@ -118,35 +149,49 @@ class App extends React.Component { - {/* Deploy Window */} + {/*not Deployed window*/}
-
-

{randGoodIcon()}

-

{strings.deployMessageTitle}

-
- {strings.deployMessage} -
    - {supportedNetworks.map((network, idx) => -
  • {network}
  • - )} -
-

{strings.deployConfirmation}

-
- - + {!networkOnDeprecationOrDeprecated(this.state.chainId) ? ( +
+ {/*deploy window*/} +

{randGoodIcon()}

+

{strings.deployMessageTitle}

+
+ {strings.deployMessage} + {supportedNetworksList(supportedNetworks)} +

{strings.deployConfirmation}

+
+ + +
+

{strings.deployNote}

-

{strings.deployNote}

-
+ ) : ( +
+ {/*deprecation window*/} +

{randBadIcon()}

+

+ {isDeprecatedNetwork(this.state.chainId)? strings.deprecatedNetwork : strings.networkBeingDeprecated} +

+
+ {strings.deployMessage} + {supportedNetworksList(supportedNetworks)} +
+ + {!isDeprecatedNetwork(this.state.chainId) && + + } +
+
+ )}
{/* Levels */} @@ -176,4 +221,18 @@ function mapDispatchToProps(dispatch) { return bindActionCreators({}, dispatch); } +function supportedNetworksList(_supportedNetworks) { + return ( + ) +} + export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App)); diff --git a/client/src/gamedata/ar/strings.json b/client/src/gamedata/ar/strings.json index 16f79acfb..c93fe0f8e 100644 --- a/client/src/gamedata/ar/strings.json +++ b/client/src/gamedata/ar/strings.json @@ -26,11 +26,14 @@ "getNewInstance": "احصل على نسخة جديدة", "deployMessageTitle": "لم يتم نشر اللعبة", "deployMessage": "تدُعم اللُعبة حاليًا هذه الشبكات فقط:", + "deprecatedNetwork": "شبكة عفا عليها الزمن", + "networkBeingDeprecated":"يتم إهمال الشبكة", "deployConfirmation": "هل تريد نشر العقود على هذه الشبكة أم التبديل إلى شبكة Sepolia", "deployNote": "ملاحظة: إذا قمت بنشر جميع المستويات ، فسنرشدك إلى إرسال اللعبة المنشورة بالكامل على هذه الشبكة.", "deployGame": "نشر اللعبة", "switchToSepolia": "قم بالتبديل إلى Sepolia", "deployLevel": "نشر المستوى", + "continueAnyway" : "استمر على أي حال", "helperDeployAllContracts": "نشر جميع العقود المتبقية على الشبكة الحالية.", "confirmMainnetDeploy": "أنت على الشبكة الرئيسية ، اللعبة ليس لها قيمة نقدية ، يجب ألا تنشر في هذه الشبكة.", "submitLevelFooter": "انشر جميع المستويات (publishAllContracts () في الكونسول) لإضافة الشبكة الحالية إلى مستودع Github كشبكة جديدة مدعومة.", diff --git a/client/src/gamedata/en/strings.json b/client/src/gamedata/en/strings.json index 331462fc4..16a170607 100644 --- a/client/src/gamedata/en/strings.json +++ b/client/src/gamedata/en/strings.json @@ -25,11 +25,14 @@ "submitInstance": "Submit instance", "getNewInstance": "Get new instance", "deployMessageTitle": "Game not deployed", + "deprecatedNetwork": "Network deprecated", + "networkBeingDeprecated": "Network being deprecated", "deployMessage": "Currently the game supports only these networks:", "deployConfirmation": "Do you want to deploy the contracts on this network or switch to the Sepolia network?", "deployNote": "Note: If you deploy all levels, we'll guide you to submit the whole deployed game on this network.", "deployGame": "Deploy game", "switchToSepolia": "Switch to Sepolia", + "continueAnyway" : "Continue anyway", "deployLevel": "Deploy Level", "helperDeployAllContracts": "Deploy all the remaining contracts on the current network.", "confirmMainnetDeploy": "You are on a mainnet, the game has no monetary value, you should not deploy in this network.", diff --git a/client/src/gamedata/es/strings.json b/client/src/gamedata/es/strings.json index 8b3f5bfe6..a4a66d832 100644 --- a/client/src/gamedata/es/strings.json +++ b/client/src/gamedata/es/strings.json @@ -25,11 +25,14 @@ "submitInstance": "Comprueba instancia", "getNewInstance": "Nueva instancia", "deployMessageTitle": "Juego no desplegado", + "deprecatedNetwork": "Red obsoleta", + "networkBeingDeprecated": "Red en desuso", "deployMessage": "Actualmente, el juego solo es compatible con estas redes.:", "deployConfirmation": "¿Quieres implementar los contratos en esta red o cambiar a la red Sepolia?", "deployNote": "Nota: si implementa todos los niveles, lo guiaremos para que envíe todo el juego implementado en esta red.", "deployGame": "Desplegar juego", "switchToSepolia": "Cambiar a Sepolia", + "continueAnyway" : "Continuar en esta red", "deployLevel": "Desplegar implementación", "helperDeployAllContracts": "Implemente todos los contratos restantes en la red actual.", "confirmMainnetDeploy": "Estás en una red principal, el juego no tiene valor monetario, no debes implementarlo en esta red.", diff --git a/client/src/gamedata/fr/strings.json b/client/src/gamedata/fr/strings.json index 3fa13c08f..46dd98165 100644 --- a/client/src/gamedata/fr/strings.json +++ b/client/src/gamedata/fr/strings.json @@ -25,11 +25,14 @@ "submitInstance": "Soumettre une instance", "getNewInstance": "Créer une nouvelle instance", "deployMessageTitle": "Jeu non déployé", + "deprecatedNetwork": "Réseau obsolète", + "networkBeingDeprecated": "Réseau désaffecté", "deployMessage": "Actuellement, le jeu ne prend en charge que ces réseaux:", "deployConfirmation": "Voulez-vous déployer les contrats sur ce réseau ou passer au réseau Sepolia?", "deployNote": "Remarque: Si vous déployez tous les niveaux, nous vous guiderons pour soumettre l'ensemble du jeu déployé sur ce réseau.", "deployGame": "Déploier le jeu", "switchToSepolia": "Passer à Sepolia", + "continueAnyway" : "Continuer quand même", "deployLevel": "Déploier le niveau", "helperDeployAllContracts": "Déployez tous les contrats restants sur le réseau actuel.", "confirmMainnetDeploy": "Vous êtes sur un MainNet, le jeu n'a pas de valeur monétaire, vous ne devez pas déployer dans ce réseau.", diff --git a/client/src/gamedata/ja/strings.json b/client/src/gamedata/ja/strings.json index dac3bddd3..cd5f121e7 100644 --- a/client/src/gamedata/ja/strings.json +++ b/client/src/gamedata/ja/strings.json @@ -26,11 +26,14 @@ "getNewInstance": "インスタンスの生成", "deployMessageTitle": "ゲームが展開されていません", "deployMessage": "現在、ゲームはこれらのネットワークのみをサポートしています:", + "deprecatedNetwork": "ネットワークは放棄されています", + "networkBeingDeprecated": "将来的には、ネットワークは使用できなくなります。", "deployConfirmation": "コントラクトをこのネットワークに展開しますか、それとも Sepolia ネットワークに切り替えますか?", "deployNote": "注: すべてのレベルを展開する場合は、展開されたゲーム全体をこのネットワークに送信するように案内されます。", "deployGame": "ゲームを展開する", "switchToSepolia": "Sepolia 切り替える", "deployLevel": "配備レベル", + "continueAnyway" : "とにかく続けます", "helperDeployAllContracts": "残りのすべてのコントラクトを現在のネットワークにデプロイします。", "confirmMainnetDeploy": "あなたはメインネット上にいます。ゲームには金銭的価値がありません。このネットワークに展開するべきではありません", "submitLevelFooter": "すべてのレベルをデプロイ (コンソールで deployAllContracts()) して、現在のネットワークを新しいサポート対象ネットワークとして Github リポジトリ に追加します。", diff --git a/client/src/gamedata/pt_br/strings.json b/client/src/gamedata/pt_br/strings.json index dd74eebcd..a2fa8431a 100644 --- a/client/src/gamedata/pt_br/strings.json +++ b/client/src/gamedata/pt_br/strings.json @@ -24,6 +24,20 @@ "sources": "Código", "submitInstance": "Enviar instância", "getNewInstance": "Obter nova instância", + "deployMessageTitle": "Jogo não implantado", + "deprecatedNetwork": "Rede obsoleta", + "networkBeingDeprecated": "Rede sendo obsoleta", + "deployMessage": "Atualmente o jogo suporta apenas estas redes:", + "deployConfirmation": "Deseja implantar os contratos nesta rede ou mudar para a rede Sepolia?", + "deployNote": "Observação: se você implantar todos os níveis, orientaremos você a enviar todo o jogo implantado nesta rede.", + "deployGame": "Implantar jogo", + "switchToSepolia": "Mudar para Sepolia", + "continueAnyway" : "Continue de qualquer maneira", + "deployLevel": "Implantar nível", + "helperDeployAllContracts": "Implante todos os contratos restantes na rede atual.", + "confirmMainnetDeploy": "Você está em uma rede principal, o jogo não tem valor monetário, você não deve implantar nesta rede.", + "submitLevelFooter": "Implante todos os níveis (deployAllContracts() no console) para adicionar a rede atual ao nosso repositório GitHub como uma nova rede suportada.", + "submitGameFooter": "Incrível! O jogo inteiro está implantado nesta rede. Clique aqui para levantar um problema no GitHub e enviá-lo para nós :)", "nextLevel": "Vá para o próximo nível", "uLevels": "Níveis", "lLevels": "níveis", @@ -39,6 +53,8 @@ "lCreated": "criado", "instance": "Instância", "numberOf": "Número de ", + "warning": "Aviso", + "warningMessage": "Não há provedor web3 e o jogo está no modo somente leitura", "levelAuthor": "Autor(es) do nível:", "pleaseWait": "POR FAVOR, AGUARDE", "donate": "Esse nível te ensinou algo útil? Doe para o autor do nível (na mainnet):", @@ -88,6 +104,10 @@ "troubleshooting": "Às vezes \n\n(a) o estado do aplicativo ou (b) o estado do plugin do MetaMask \n\npode ficar um pouco confuso, especialmente depois de trocar de rede, desbloquear, etc. Se o que você está vendo não faz muito sentido, tente atualizar o aplicativo, desabilitar e habilitar seu plugin metamask ou até mesmo reiniciar seu navegador. \n\nSe você encontrar problemas, por favor nos informe em ethernaut@zeppelin.solutions", "poweredBy": "powered by ", "setupMetamask": "Se você ainda não tem, instale o [MetaMask browser extension](https://metamask.io/) (no Chrome, Firefox, Brave ou Opera em seu computador). \n\nConfigure a carteira da extensão e use o seletor de rede para apontar para a rede preferida no canto superior esquerdo da interface da extensão. Alternativamente, você pode usar o botão para alternar entre as redes. Se você selecionar uma rede não suportada, o jogo irá notificá-lo e levá-lo para o Sepolia testnet padrão. \n\nUma vez feito, volte aqui e recarregue a página", + "FifthyPercentMessage": "Otimo trabalho! Você está na metade do Ethernaut e está ficando muito bom em quebrar coisas. Trabalhar como pesquisador de segurança Blockchain na OpenZeppelin pode ser divertido... https://grnh.se/fdbf1c043us", + "SeventyFivePercentMessage": "75%: Bom trabalho, já... você está bem fundo na toca do coelho agora... quem sabe aonde isso o levará... https://grnh.se/d4a786e43us", + "NinetyPercentMessage": "90%: Você está quase lá! Faltam apenas mais alguns desafios até você completar o Ethernaut! Você já considerou uma carreira em Segurança Blockchain?https://grnh.se/cfcca8c83us", + "HundredPercentMessage": "100%: Parabéns! Sua jornada pela toca do coelho web3 é impressionante e deve ser comemorada! Agora você tem as habilidades necessárias para quebrar contratos inteligentes! O que vem a seguir daqui em diante? Inscreva-se para ser um pesquisador de segurança Blockchain na OpenZeppelin e contribua para proteger os principais protocolos da web3! https://grnh.se/26c05aac3us", "Menu": "Menu", "Networks": "Redes", "Languages": "línguas", diff --git a/client/src/gamedata/ru/strings.json b/client/src/gamedata/ru/strings.json index 74c6d6500..6d5090516 100644 --- a/client/src/gamedata/ru/strings.json +++ b/client/src/gamedata/ru/strings.json @@ -25,11 +25,14 @@ "submitInstance": "Отправить инстанс на проверку", "getNewInstance": "Создать новый инстанс", "deployMessageTitle": "Игра не развернута", + "deprecatedNetwork": "заброшенная сеть", + "networkBeingDeprecated": "сеть в процессе закрытия", "deployMessage": "На данный момент игра поддерживает только эти сети:", "deployConfirmation": "Вы хотите развернуть контракты в этой сети или переключиться на сеть Sepolia??", "deployNote": "Примечание. Если вы развернете все уровни, мы посоветуем вам отправить всю развернутую игру в эту сеть.", "deployGame": "Развернуть игру", "switchToSepolia": "Переключиться на Sepolia", + "continueAnyway" : "Продолжай в любом случае", "deployLevel": "Уровень развертывания", "helperDeployAllContracts": "Разверните все оставшиеся контракты в текущей сети.", "confirmMainnetDeploy": "Вы находитесь в основной сети, игра не имеет денежной стоимости, вам не следует развертывать ее в этой сети.", diff --git a/client/src/gamedata/tr/strings.json b/client/src/gamedata/tr/strings.json index 56eed471c..87723d506 100644 --- a/client/src/gamedata/tr/strings.json +++ b/client/src/gamedata/tr/strings.json @@ -25,11 +25,14 @@ "submitInstance": "Durum gönder", "getNewInstance": "Yeni durum al", "deployMessageTitle": "Oyun dağıtılmadı", + "deprecatedNetwork": "Ağ kullanımdan kaldırıldı", + "networkBeingDeprecated": "Ağ kullanımdan kaldırılıyor", "deployMessage": "Şu anda oyun yalnızca bu ağları desteklemektedir:", "deployConfirmation": "Sözleşmeleri bu ağa dağıtmak mı yoksa Sepolia ağına geçmek mi istiyorsunuz?", "deployNote": "Not: Tüm seviyeleri dağıtıyorsanız, konuşlandırılan tüm oyunu bu ağa göndermenize rehberlik edeceğiz.", "deployGame": "Oyunu dağıtın", "switchToSepolia": "Sepolia'ye geç", + "continueAnyway" : "Her halükarda devam et", "deployLevel": "Seviye dağıtma", "helperDeployAllContracts": "Kalan tüm sözleşmeleri mevcut ağda dağıtın.", "confirmMainnetDeploy": "Bir Mainnet'tesiniz, oyunun parasal bir değeri yok, bu ağda dağıtmamalısınız.", diff --git a/client/src/gamedata/zh_cn/strings.json b/client/src/gamedata/zh_cn/strings.json index 981a5429a..6e368e85c 100644 --- a/client/src/gamedata/zh_cn/strings.json +++ b/client/src/gamedata/zh_cn/strings.json @@ -25,11 +25,14 @@ "submitInstance": "提交该实例", "getNewInstance": "生成新实例", "deployMessageTitle": "Game not deployed", + "deprecatedNetwork": "Network deprecated", + "networkBeingDeprecated": "Network being deprecated", "deployMessage": "Currently the game supports only these networks:", "deployConfirmation": "Do you want to deploy the contracts on this network or switch to the Sepolia network?", "deployNote": "Note: If you deploy all levels, we'll guide you to submit the whole deployed game on this network.", "deployGame": "Deploy game", "switchToSepolia": "Switch to Sepolia", + "continueAnyway" : "Continue anyway", "deployLevel": "Deploy Level", "helperDeployAllContracts": "Deploy all the remaining contracts on the current network.", "confirmMainnetDeploy": "You are on a mainnet, the game has no monetary value, you should not deploy in this network.", diff --git a/client/src/gamedata/zh_tw/strings.json b/client/src/gamedata/zh_tw/strings.json index ce97df2b9..0c85b70a0 100644 --- a/client/src/gamedata/zh_tw/strings.json +++ b/client/src/gamedata/zh_tw/strings.json @@ -25,11 +25,15 @@ "submitInstance": "提交該實例", "getNewInstance": "產生新實例", "deployMessageTitle": "遊戲未部署", + "deprecatedNetwork": "網路已棄用", + "networkBeingDeprecated": "網路將來將被棄用", "deployMessage": "目前,遊戲僅支持這些網絡:", "deployConfirmation": "您要在此網絡上部署合同或切換到Sepolia網絡嗎?", "deployNote": "注意:如果您部署所有級別,我們將指導您在此網絡上提交整個部署的遊戲。", "deployGame": "部署遊戲", "switchToSepolia": "切換到Sepolia", + "continueAnyway" : "仍然繼續", + "deployLevel": "部署級別", "helperDeployAllContracts": "在當前網絡上部署所有其餘合同。", "confirmMainnetDeploy": "您在主網上,遊戲沒有貨幣價值,您不應在此網絡中部署。", diff --git a/client/src/middlewares/setNetwork.js b/client/src/middlewares/setNetwork.js index 89f725804..8af99e814 100644 --- a/client/src/middlewares/setNetwork.js +++ b/client/src/middlewares/setNetwork.js @@ -2,6 +2,7 @@ import * as actions from '../actions'; import * as constants from '../constants'; import { deployRemainingContracts, isLocalDeployed } from '../utils/contractutil'; import { deployAdminContracts } from '../utils/deploycontract'; +import { networkOnDeprecationOrDeprecated } from '../utils/networkDeprecation'; let elements = document.querySelectorAll('.progress-bar-wrapper'); @@ -17,7 +18,7 @@ const setNetwork = store => next => action => { elements = document.querySelectorAll('.progress-bar-wrapper'); const hasBeenLocalDeployed = isLocalDeployed(action.id); - if (!onPredeployedNetwork(action.id) && !hasBeenLocalDeployed) { + if ((!onPredeployedNetwork(action.id) || networkOnDeprecationOrDeprecated(action.id)) && !hasBeenLocalDeployed) { const deployWindow = document.querySelectorAll('.deploy-window-bg'); if (deployWindow[0]) deployWindow[0].style.display = 'block'; } @@ -39,5 +40,4 @@ export function onPredeployedNetwork(id) { return onRightNetwork; } - export default setNetwork diff --git a/client/src/utils/networkDeprecation.js b/client/src/utils/networkDeprecation.js new file mode 100644 index 000000000..6755cb59a --- /dev/null +++ b/client/src/utils/networkDeprecation.js @@ -0,0 +1,26 @@ +import * as constants from '../constants'; + +export function networkOnDeprecationOrDeprecated(id) { + const onDeprecationOrDeprecatedNetworkIds = Object.keys(constants.NETWORKS_DEPRECATION) + .map(network => Number(constants.NETWORKS_DEPRECATION[network].id)); + return onDeprecationOrDeprecatedNetworkIds.includes(Number(id)); + } + +export function isDeprecatedNetwork(id) { + const deprecatedNetworksIds = Object.keys(constants.NETWORKS_DEPRECATION) + .filter(network => constants.NETWORKS_DEPRECATION[network].status === "deprecated") + .map(network => Number(constants.NETWORKS_DEPRECATION[network].id)); + return deprecatedNetworksIds.includes(Number(id)); +} + +export function deprecationStatus(id) { + const network = Object.keys(constants.NETWORKS_DEPRECATION) + .filter(network => constants.NETWORKS_DEPRECATION[network].id === id)[0]; + return constants.NETWORKS_DEPRECATION[network].status; +} + +export function deprecationDate(id) { + const network = Object.keys(constants.NETWORKS_DEPRECATION) + .filter(network => constants.NETWORKS_DEPRECATION[network].id === id)[0]; + return constants.NETWORKS_DEPRECATION[network].date; +}