+ {JSON.stringify(attrs.object, null, 2)}
+```
+
+Většina polí se zobrazuje pomocí [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp).
+
+```tsx
+
+ { funs.length > 0 &&
+ <>
+ Functions:
+ {message}
+ +{status}
+ + ++ {" "} + 🦊 + Musíte si do prohlížeče nainstalovat MetaMask, virtuální peněženku Ethereum. + +
+ + ), + } + } +} +``` + +Co přesně tedy tento obrovský blok kódu dělá? + +Nejprve zkontroluje, zda je ve vašem prohlížeči povoleno `window.ethereum`. + +`window.ethereum` je globální API, které vkládá MetaMask a další poskytovatelé peněženek a které webovým stránkám umožňuje žádat o účty uživatelů Etherea. Pokud je schváleno, může číst data z blockchainů, ke kterým je uživatel připojen, a navrhovat uživateli podepisování zpráv a transakcí. Pro více informací se podívejte do [dokumentace MetaMasku](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)! + +Pokud `window.ethereum` _není_ přítomno, znamená to, že MetaMask není nainstalován. Výsledkem je vrácení objektu JSON, kde vrácená `adresa` je prázdný řetězec a objekt JSX `status` sděluje, že uživatel si musí nainstalovat MetaMask. + +Pokud `window.ethereum` _je_ přítomno, pak to začne být zajímavé. + +Pomocí smyčky try/catch se pokusíme připojit k MetaMasku voláním [`window.ethereum.request({ method: \"eth_requestAccounts\" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Volání této funkce otevře MetaMask v prohlížeči, kde bude uživatel vyzván k připojení své peněženky k vaší dapp. + +- Pokud se uživatel rozhodne připojit, `method: "eth_requestAccounts"` vrátí pole obsahující všechny adresy účtů uživatele, které se k dapp připojily. Celkově naše funkce `connectWallet` vrátí objekt JSON, který obsahuje _první_ `adresu` v tomto poli (viz řádek 9) a zprávu `status`, která vyzve uživatele k napsání zprávy do chytrého kontraktu. +- Pokud uživatel spojení odmítne, objekt JSON bude obsahovat prázdný řetězec pro vrácenou `adresu` a zprávu `status`, která odráží, že uživatel spojení odmítl. + +Nyní, když jsme napsali tuto funkci `connectWallet`, je dalším krokem její zavolání v naší komponentě `HelloWorld.js`. + +#### Přidání funkce `connectWallet` do vaší UI komponenty `HelloWorld.js` {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +Přejděte na funkci `connectWalletPressed` v `HelloWorld.js` a aktualizujte ji na následující: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +Všimli jste si, jak je většina naší funkčnosti abstrahována od naší komponenty `HelloWorld.js` do souboru `interact.js`? To proto, abychom dodrželi paradigma M-V-C! + +V `connectWalletPressed` jednoduše provedeme await volání naší importované funkce `connectWallet` a pomocí její odpovědi aktualizujeme naše proměnné `status` a `walletAddress` prostřednictvím jejich stavových háků (hooks). + +Nyní si oba soubory (`HelloWorld.js` a `interact.js`) uložme a otestujme naše UI. + +Otevřete si prohlížeč na stránce [http://localhost:3000/](http://localhost:3000/) a stiskněte tlačítko „Připojit peněženku“ vpravo nahoře. + +Pokud máte nainstalovaný MetaMask, měli byste být vyzváni k připojení své peněženky k vaší dapp. Přijměte výzvu k připojení. + +Měli byste vidět, že tlačítko peněženky nyní ukazuje, že je vaše adresa připojena! Super! 🔥 + +Dále zkuste obnovit stránku... to je divné. Naše tlačítko peněženky nás vyzývá k připojení MetaMasku, i když už je připojen... + +Ale žádný strach! To snadno vyřešíme (chápete?). implementací `getCurrentWalletConnected`, která zkontroluje, zda je adresa již připojena k naší dapp, a podle toho aktualizuje naše UI! + +#### Funkce `getCurrentWalletConnected` {#the-getcurrentwalletconnected-function} + +Aktualizujte svou funkci `getCurrentWalletConnected` v souboru `interact.js` na následující: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 Napište zprávu do textového pole výše.", + } + } else { + return { + address: "", + status: "🦊 Připojte se k MetaMask pomocí tlačítka vpravo nahoře.", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + ++ {" "} + 🦊 + Musíte si do prohlížeče nainstalovat MetaMask, virtuální peněženku Ethereum. + +
+ + ), + } + } +} +``` + +Tento kód je _velmi_ podobný funkci `connectWallet`, kterou jsme právě napsali v předchozím kroku. + +Hlavní rozdíl je v tom, že místo volání metody `eth_requestAccounts`, která otevře MetaMask, aby si uživatel mohl připojit svou peněženku, zde voláme metodu `eth_accounts`, která jednoduše vrací pole obsahující adresy MetaMask aktuálně připojené k naší dapp. + +Abychom tuto funkci viděli v akci, zavoláme ji ve funkci `useEffect` naší komponenty `HelloWorld.js`: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +Všimněte si, že odpověď z našeho volání `getCurrentWalletConnected` používáme k aktualizaci našich stavových proměnných `walletAddress` a `status`. + +Nyní, když jste přidali tento kód, zkusme obnovit okno našeho prohlížeče. + +Paráda! Tlačítko by mělo hlásit, že jste připojeni, a zobrazovat náhled adresy vaší připojené peněženky – i po obnovení! + +#### Implementace `addWalletListener` {#implement-addwalletlistener} + +Posledním krokem v nastavení peněženky naší dapp je implementace posluchače peněženky, aby se naše uživatelské rozhraní aktualizovalo, když se změní stav naší peněženky, například když se uživatel odpojí nebo přepne účty. + +Ve vašem souboru `HelloWorld.js` upravte svou funkci `addWalletListener` na následující: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 Napište zprávu do textového pole výše.") + } else { + setWallet("") + setStatus("🦊 Připojte se k MetaMask pomocí tlačítka vpravo nahoře.") + } + }) + } else { + setStatus( ++ {" "} + 🦊 + Musíte si do prohlížeče nainstalovat MetaMask, virtuální peněženku Ethereum. + +
+ ) + } +} +``` + +Vsadím se, že už ani nepotřebujete naši pomoc, abyste pochopili, co se zde děje, ale pro úplnost si to rychle rozebereme: + +- Nejprve naše funkce zkontroluje, zda je `window.ethereum` povoleno (tj. zda je MetaMask nainstalován). + - Pokud není, jednoduše nastavíme naši stavovou proměnnou `status` na řetězec JSX, který uživatele vyzve k instalaci MetaMasku. + - Pokud je povoleno, nastavíme na řádku 3 posluchače `window.ethereum.on(\"accountsChanged\")`, který naslouchá změnám stavu v peněžence MetaMask, což zahrnuje případy, kdy uživatel připojí další účet k dapp, přepne účty nebo odpojí účet. Pokud je připojen alespoň jeden účet, stavová proměnná `walletAddress` se aktualizuje jako první účet v poli `accounts` vráceném posluchačem. V opačném případě je `walletAddress` nastaveno jako prázdný řetězec. + +V neposlední řadě ji musíme zavolat v naší funkci `useEffect`: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +A to je vše! Úspěšně jsme dokončili programování veškeré funkčnosti naší peněženky! Nyní k našemu poslednímu úkolu: aktualizaci zprávy uložené v našem chytrém kontraktu! + +### Krok 6: Implementace funkce `updateMessage` {#step-6-implement-the-updateMessage-function} + +Tak jo, lidi, jsme v cílové rovince! Ve funkci `updateMessage` vašeho souboru `interact.js` uděláme následující: + +1. Ujistěte se, že zpráva, kterou chceme publikovat v našem chytrém kontraktu, je platná +2. Podepište naši transakci pomocí MetaMask +3. Zavolejte tuto funkci z naší frontendové komponenty `HelloWorld.js` + +Nebude to trvat dlouho; pojďme tuto dapp dokončit! + +#### Zpracování chyb na vstupu {#input-error-handling} + +Je přirozené, že na začátku funkce je nějaké zpracování chyb vstupů. + +Budeme chtít, aby se naše funkce vrátila dříve, pokud není nainstalováno rozšíření MetaMask, není připojena žádná peněženka (tj. předaná `adresa` je prázdný řetězec) nebo je `zpráva` prázdný řetězec. Přidejme následující zpracování chyb do `updateMessage`: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 Připojte svou peněženku MetaMask pro aktualizaci zprávy na blockchainu.", + } + } + + if (message.trim() === "") { + return { + status: "❌ Vaše zpráva nemůže být prázdný řetězec.", + } + } +} +``` + +Nyní, když máme správné zpracování chyb vstupů, je čas podepsat transakci přes MetaMask! + +#### Podepisování naší transakce {#signing-our-transaction} + +Pokud jste již obeznámeni s tradičními web3 Ethereum transakcemi, kód, který napíšeme dále, vám bude velmi povědomý. Pod kód pro zpracování chyb vstupů přidejte do `updateMessage` následující: + +```javascript +// interact.js + +//nastavení parametrů transakce +const transactionParameters = { + to: contractAddress, // Vyžadováno kromě publikací kontraktů. + from: address, // musí se shodovat s aktivní adresou uživatele. + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//podepsání transakce +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Zobrazte stav své transakce na Etherscanu! + +.env`! Prosím, ujistěte se, že nikdy nesdílíte ani nezveřejňujete svůj soubor `.env` s nikým, protože tím ohrožujete svá tajemství. Pokud používáte správu verzí, přidejte svůj soubor `.env` do souboru gitignore.
+