{"id":19909286,"url":"https://github.com/kauemurakami/api-ethereum-wallet","last_synced_at":"2026-05-06T00:05:29.114Z","repository":{"id":252866743,"uuid":"825491015","full_name":"kauemurakami/api-ethereum-wallet","owner":"kauemurakami","description":"Create API with Node.js and Hardhat to use in dApp","archived":false,"fork":false,"pushed_at":"2024-08-20T17:58:44.000Z","size":95,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-29T04:33:59.744Z","etag":null,"topics":["blockchain","dapp","ethereum","ethereum-contract","ethereum-dapp","ganache","hardhat","hardhat-deploy","hardhat-deployment","hardhat-network","hardhat-node","infura","metamask","remix","solidity","truffle","web3"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kauemurakami.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-07T23:29:42.000Z","updated_at":"2024-08-20T17:58:47.000Z","dependencies_parsed_at":"2025-01-11T22:23:16.765Z","dependency_job_id":"e16d06e6-7fc8-46a7-89eb-d30b5c44e88b","html_url":"https://github.com/kauemurakami/api-ethereum-wallet","commit_stats":null,"previous_names":["kauemurakami/api-ethereum-wallet"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kauemurakami/api-ethereum-wallet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kauemurakami%2Fapi-ethereum-wallet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kauemurakami%2Fapi-ethereum-wallet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kauemurakami%2Fapi-ethereum-wallet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kauemurakami%2Fapi-ethereum-wallet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kauemurakami","download_url":"https://codeload.github.com/kauemurakami/api-ethereum-wallet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kauemurakami%2Fapi-ethereum-wallet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32672686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","dapp","ethereum","ethereum-contract","ethereum-dapp","ganache","hardhat","hardhat-deploy","hardhat-deployment","hardhat-network","hardhat-node","infura","metamask","remix","solidity","truffle","web3"],"created_at":"2024-11-12T21:14:51.776Z","updated_at":"2026-05-06T00:05:29.077Z","avatar_url":"https://github.com/kauemurakami.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Criando uma API com node.js e hardhat de uma carteira ethereum\n\n### Pré requisitos\n - [VSCode](https://code.visualstudio.com/)\n - [Node.js](https://nodejs.org/pt)  \n\n### Intro\nEste projeto é a reconstrução [deste projeto](https://github.com/kauemurakami/etherum-wallet) feito com [flutter](https://flutter.dev/), [Ganache Truffle Switch](https://archive.trufflesuite.com/ganache/), [Remix](https://remix-project.org/), [Infura](https://www.infura.io/) mas que resolvi refazer ao descobrir que o [Ganache Truffle Switch](https://archive.trufflesuite.com/ganache/) não tem mais suporte desde o começo do ano de 2024.  \n[Ganache Truffle Switch](https://archive.trufflesuite.com/ganache/) é uma ferramenta que fornece um blockchain [Ethereum](https://ethereum.org/pt-br/) local, permitindo o desenvolvimento, teste e depuração de contratos inteligentes em um ambiente controlado. Ele simula a rede [Ethereum](https://ethereum.org/pt-br/), proporcionando uma plataforma onde você pode experimentar sem a necessidade de gastar [Ether](https://en.wikipedia.org/wiki/Ethereum#:~:text=Ether%20(ETH)%20is%20the%20cryptocurrency,adding%20blocks%20to%20the%20blockchain.) real ou esperar por confirmações de transações, leia mais sobre na documentação.\u003cbr/\u003e\u003cbr/\u003e\nMas e dessa vez, o que usar pra emular um ambiente de testes para a blocchain [Ethereum](https://ethereum.org/pt-br/)?  \nPra isso usaremos o [Hardhat](https://hardhat.org/), que também nos possibilita as mesmas funcionalidades do [Ganache Truffle Switch](https://archive.trufflesuite.com/ganache/) e mais algumas como:  \n - **Compilação de Contratos Inteligentes**: \u003cspan style=\"font-size:0.9em;\"\u003eCompila contratos [Solidity](https://soliditylang.org/) usando o [compilador Solidity (solc)](https://docs.soliditylang.org/en/latest/installing-solidity.html), sem isso usavamos o [Remix](https://remix-project.org/) para compilar nossos contratos e gerar os arquivos necessários.\u003c/span\u003e\n - **Deploy de Contratos**: \n  \u003cspan style=\"font-size:0.9em;\"\u003eFacilita o processo de implantação de contratos inteligentes em várias redes [Ethereum](https://ethereum.org/pt-br/), incluindo redes de teste e a rede principal.\u003c/span\u003e  \n - **Testes**: \u003cspan style=\"font-size:0.9em;\"\u003eIntegração com frameworks de teste como Mocha e Chai para escrever e executar testes automatizados para seus contratos inteligentes.\u003c/span\u003e  \n - **Scripts de Execução**: \u003cspan style=\"font-size:0.9em;\"\u003ePermite escrever scripts personalizados para realizar tarefas específicas, como deploy, migrações e interações com contratos.\u003c/span\u003e  \n - **Debugging**: \u003cspan style=\"font-size:0.9em;\"\u003eFerramentas avançadas de debugging que ajudam a identificar e corrigir problemas em seus contratos inteligentes.\u003c/span\u003e  \n - **Hardhat Network**: \u003cspan style=\"font-size:0.9em;\"\u003eUm nó local que pode ser usado para desenvolvimento, permitindo mineração instantânea, contas locais, e uma blockchain que pode ser resetada facilmente.\u003c/span\u003e  \n Dentre outras que podem ser exploradas e veremos aqui neste tutorial.  \n -\u003e Projeto antigo: https://github.com/kauemurakami/etherum-wallet  \n### Iniciando projeto\n\nAntes de iniciar o projeto irei passar minha referência, e serei o mais fiel possível à ela, a própria documentação do [Hardhat doc](https://hardhat.org/docs) e [Hardhat tutorial](https://hardhat.org/hardhat-runner/docs/getting-started#overview)  \n\n#### Então vamos começar!!!\n\nPrimeiro crie um diretório, via [VSCode](https://code.visualstudio.com/), terminal ou pelo explorador de arquivos pro nosso projeto, no meu caso nomeei de `api-ethereum-wallet`, mas pode colocar o nome que desejar.\u003cbr/\u003e\u003cbr/\u003e\n\nAbra esse diretório no [VSCode](https://code.visualstudio.com/), abra um terminal no diretório via Terminal do [VSCode](https://code.visualstudio.com/), ou apenas cliquei com o botão direito sobre a pasta e selecionar a opção `Open in integrated Terminal`.\u003cbr/\u003e\u003cbr/\u003e\n\nVocê verá no terminal algo como `PS C:\\projetos\\api-ethereum-wallet\u003e`, e então tudo estara ok.\u003cbr/\u003e\u003cbr/\u003e\n\nNo terminal vamos começar instalando o [Hardhat](https://hardhat.org/) com o seguinte comando:  \n`npm install --save-dev hardhat`  \u003cbr/\u003e\u003cbr/\u003e\n\nAgora vamos rodar um comando do [Hardhat](https://hardhat.org/) para que gerar a estrutura básica pro nosso projeto, no terminal digite:  \n`npx hardhat init`  \nVocê irá se deparar com essa tela:  \n```shell\n$ npx hardhat init\n888    888                      888 888               888\n888    888                      888 888               888\n888    888                      888 888               888\n8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888\n888    888     \"88b 888P\"  d88\" 888 888 \"88b     \"88b 888\n888    888 .d888888 888    888  888 888  888 .d888888 888\n888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.\n888    888 \"Y888888 888     \"Y88888 888  888 \"Y888888  \"Y888\n\n👷 Welcome to Hardhat v2.22.6 👷‍\n\n? What do you want to do? …\n❯ Create a JavaScript project\n  Create a TypeScript project\n  Create a TypeScript project (with Viem)\n  Create an empty hardhat.config.js\n  Quit\n```  \nSelecione a primeira opção `\u003e Create a JavaScript project`, usaremos `JavaScript` neste tutorial, mas nada impede que faça com `TypeScript` também.\u003cbr/\u003e\u003cbr/\u003e\n\nVocê verá essas mensagens no terminal:  \n```shell\n√ What do you want to do? · Create a JavaScript project  \n? Hardhat project root: » C:\\projetos\\api-ethereum-wallet\n```  \nConfirme    \n\nAgora de um enter e irá se deparar com uma mensagem como:  \n`Create .gitignore` que por padrão vem `y`, tecle `n`, pois o mesmo conteúdo desse `.gitignore` que poderia ser gerado, já é adicionado ao `.gitignore` existente ao instalarmos o [Hardhat](https://hardhat.org/) com `npm`.\u003cbr/\u003e\u003cbr/\u003e\n\nAgora você deve ter uma estrutura parecida com:  \n```go\n- api-ethereum-wallet (ou seu diretório raiz)\n  - contracts/\n  - ignition/\n  - node_modules/\n  - test/\n  - hardhat.config.js \n  ... arquivos padrão do nodejs\n```\nPara ter uma ideia rápida do que está disponível e do que está acontecendo execute `npx hardhat`, o único problema até agora é que devemos rodar esse comando do módulo do [hardhat](https://hardhat.org/) em `node_modules/hardhat`, você pode entrar nesse caminho e testar, mas já trago a solução pro nosso comando não ficar tão extensos e termos que trabalhar de dentro de uma pasta `node_modules` diretamente, pra isso faça:  \n - Vá até o arquivo `package.json`, lá, caso não tenha adicionado outras configurações, o arquivo estará assim:  \n ```json\n {\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^5.0.0\",\n    \"hardhat\": \"^2.22.6\"\n  },\n }\n ```\n - Vamos fazer um alteração, adicionando a seção `scripts` para criar uma script que rode o `npx hardhat` direto de `node_modules/hardhat`:\n ```json\n {\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^5.0.0\",\n    \"hardhat\": \"^2.22.6\"\n  },\n   \"scripts\": {\n    \"hardhat\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat\"\n  }\n}\n ```  \nAgora basta rodar `npm run hardhat`, e o comando `npx hardhat` será executado de dentro de `node_modules/hardhat`, esse comando mostra tudo que está disponível via `npx hardhat`, caso tudo ocorra vem significar que nossa instalação foi um sucesso. Com isso vamos continuar.\u003cbr/\u003e\n\n### Compilando nossos contratos inteligentes\n\n#### Criando contrato e eventos\nRepare que na pasta `/contracts/` já existe um contrato de exemplo `Lock.sol` mas vamos criar nosso próprio `contract` para compila-lo.  \nEm `/contratcs/` crie um arquivo chamado `SimpleWallet.sol` com o seguinte conteúdo:  \n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\n// Uncomment this line to use console.log\n// import \"hardhat/console.sol\";\n\ncontract SimpleWallet {\n    mapping(address =\u003e uint256) private balances;\n    mapping(string =\u003e address) private qrCodeToAddress;\n\n    // Event to log deposits\n    event Deposit(address indexed account, uint256 amount);\n\n    // Event to log withdrawals\n    event Withdrawal(address indexed account, uint256 amount);\n\n    // Event to log charges\n    event Charge(address indexed account, uint256 amount);\n\n    // Event to log sent funds\n    event Sent(address indexed from, address indexed to, uint256 amount);\n\n    // Event emitted when a QR code is linked to an address\n    event QRCodeLinked(string indexed qrCodeHash, address indexed account);\n\n    // Event emitted when a QR code address is retrieved\n    event QRCodeAddressRetrieved(\n        string indexed qrCodeHash,\n        address indexed account\n    );\n\n    // Function to deposit funds\n    function deposit(uint256 _amount) public {\n        require(_amount \u003e 0, \"Deposit amount must be greater than zero\");\n        balances[msg.sender] += _amount  ;\n        //console.log(\"Deposited %s to %s\", _amount, msg.sender);\n        emit Deposit(msg.sender, _amount);\n    }\n\n    // Function to withdraw funds\n    function withdraw(uint256 _amount) public {\n        require(_amount \u003e 0, \"Withdrawal amount must be greater than zero\");\n        require(balances[msg.sender] \u003e= _amount, \"Insufficient balance\");\n        balances[msg.sender] -= _amount;\n        // console.log(\"Withdrew %s from %s\", _amount, msg.sender);\n        emit Withdrawal(msg.sender, _amount);\n    }\n\n    // Function to charge funds (add a balance for specific service)\n    function charge(uint256 _amount) public {\n        require(_amount \u003e 0, \"Charge amount must be greater than zero\");\n        balances[msg.sender] += _amount;\n        // console.log(\"Charged %s to %s\", _amount, msg.sender);\n        emit Charge(msg.sender, _amount);\n    }\n\n    function send(\n        uint256 _amount,\n        address payable _to,\n        string memory _qrCodeHash\n    ) public {\n        require(_amount \u003e 0, \"Send amount must be greater than zero\");\n        require(balances[msg.sender] \u003e= _amount, \"Insufficient balance\");\n\n        address payable recipient = _to;\n\n        if (bytes(_qrCodeHash).length \u003e 0) {\n            recipient = payable(qrCodeToAddress[_qrCodeHash]);\n            require(recipient != address(0), \"Invalid QR code\");\n            balances[msg.sender] -= _amount;\n            (bool success, ) = recipient.call{value: _amount}(\"\");//_amount, gas: gasleft()\n            require(success, \"Transfer failed.\");\n            emit QRCodeAddressRetrieved(_qrCodeHash, recipient);\n        } else {\n            require(\n                recipient != address(0),\n                \"Recipient address must be provided\"\n            );\n            balances[msg.sender] -= _amount;\n            (bool success, ) = recipient.call{value: _amount}(\"\");\n            // require(success, \"Transfer failed.\"); // Esta linha pode ser removida\n            emit Sent(msg.sender, recipient, _amount);\n        }\n    }\n\n    // Send function to send funds to another account or retrieve funds linked to a QR code\n    // function send(uint256 _amount, address payable _to, string memory _qrCodeHash) public {\n    //     require(_amount \u003e 0, \"Send amount must be greater than zero\");\n    //     require(balances[msg.sender] \u003e= _amount, \"Insufficient balance\");\n\n    //     address payable recipient = _to;\n\n    //     if (bytes(_qrCodeHash).length \u003e 0) {\n    //         recipient = payable(qrCodeToAddress[_qrCodeHash]);\n    //         require(recipient != address(0), \"Invalid QR code\");\n    //         balances[msg.sender] -= _amount;\n    //         (bool success, ) = recipient.call{value: _amount}(\"\");\n    //         require(success, \"Transfer failed.\");\n    //         emit QRCodeAddressRetrieved(_qrCodeHash, recipient);\n    //     } else {\n    //         require(recipient != address(0), \"Recipient address must be provided\");\n    //         balances[msg.sender] -= _amount;\n    //         (bool success, ) = recipient.call{value: _amount}(\"\");\n    //         require(success, \"Transfer failed.\");\n    //         emit Sent(msg.sender, recipient, _amount);\n    //     }\n    // }\n\n\n\n    // Function to associate a QR code hash with an address\n    function linkQRCodeToAddress(\n        string memory _qrCodeHash,\n        address _address\n    ) public {\n        require(_address != address(0), \"Invalid address\");\n        qrCodeToAddress[_qrCodeHash] = _address;\n        emit QRCodeLinked(_qrCodeHash, _address);\n    }\n\n    // Function to retrieve the address linked to a QR code hash\n    function getQRCodeAddress(\n        string memory _qrCodeHash\n    ) public view returns (address) {\n        return qrCodeToAddress[_qrCodeHash];\n    }\n\n    // Function to check balance\n    function getBalance() public view returns (uint256) {\n        uint256 balance = balances[msg.sender];\n        // console.log(\"Balance of %s is %s\", msg.sender, balance);\n        return balance;\n    }\n}\n\n```  \nHabilitaremos o console.log do [hardhat](https://hardhat.org/) depois, por enquanto deixe os `console.sol e .log` comentados \u003cbr/\u003e\u003cbr/\u003e\n\nPronto temos um contrato em mãos, agora basta compilarmos ele.\u003cbr/\u003e\u003cbr/\u003e\n\n#### Compilando seu contrato\nAntes de rodarmos o comando no terminal, vamos criar mais dois scripts no `package.json` para encurtar nosso trabalho e não precisar ir para `node_modules/hardhat` e rodar de dentro, criando dois novos `scripts`:\n```json\n{\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^5.0.0\",\n    \"hardhat\": \"^2.22.6\"\n  },\n   \"scripts\": {\n    \"hardhat\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat\",\n    \"hardhat-compile\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat compile\",\n    \"hardhat-compile-v\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat compile --show-stack-traces --verbose\"\n  }\n}\n```\nCriamos dois comandos `npm run hardhat-compile` para compilar o contrato e `npm run hardhat-compile-v` que é um modo verboso do compile com toda stack trace gerada.  \nAqui podemos apagar nosso contrato `Lock.sol`, pra não gerarmos arquivos desnecessários.  \nAgora vamos rodar nosso comando no terminal da raiz do nosso projeto `npm run hardhat-compile`, se tudo ocorrer bem você verá dois novos diretórios sendo eles `cache/` e `artifacts/`, explore esses arquivos para saber mais.\u003cbr/\u003e\u003cbr/\u003e\n\n### Criando nossos testes\nPrimeiro vamos garantir que alguns modulos depreciados não estejam no n osso projeto, rode:  \n`npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers\n`\u003cbr/\u003e\u003cbr/\u003e\n\nAgora vamos garantir que `hardhat-toolbox` esteja instalado, rode:  \n`npm install --save-dev @nomicfoundation/hardhat-toolbox`  \nAgora na pasta `test/` exclua o `Lock.js` e crie o `SimpleWallet.js` arquivo com o seguinte conteúdo:  \n```JavaScript\nconst { expect } = require(\"chai\");\nconst { ethers } = require(\"hardhat\");\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n// const { anyValue } = require(\"@nomicfoundation/hardhat-chai-matchers/withArgs\");\ndescribe(\"SimpleWallet\", function () {\n  let SimpleWallet;\n  let owner;\n  let addr1;\n  let addr2;\n\n  beforeEach(async function () {\n    // get signers\n    [owner, addr1, addr2] = await ethers.getSigners();\n\n    // Load the contract SimpleWallet\n    const SimpleWalletFactory = await ethers.getContractFactory(\"SimpleWallet\");\n    SimpleWallet = await SimpleWalletFactory.deploy();\n    await SimpleWallet.waitForDeployment();\n\n  });\n\n\n  describe(\"deposit\", function () {\n    it(\"Should deposit funds\", async function () {\n      // Doing a deposit\n      await SimpleWallet.deposit(100);\n\n      // Check if balance of the owner address after the deposit\n      const ownerBalance = await SimpleWallet.getBalance();\n      expect(ownerBalance).to.equal(100, \"Owner's balance should be 100 after deposit\");\n    });\n  });\n\n  describe(\"charge\", function () {\n    it(\"Should charge funds\", async function () {\n      const chargeAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).charge(chargeAmount);\n\n      const balance = ethers.parseEther(\"1\");\n      expect(balance).to.equal(chargeAmount, \"Contract balance should be equal to charge amount\");\n    });\n\n    it(\"Should emit a Charge event\", async function () {\n      const chargeAmount = ethers.parseEther(\"1\");\n\n      await expect(SimpleWallet.connect(addr1).charge(chargeAmount))\n        .to.emit(SimpleWallet, \"Charge\")\n        .withArgs(addr1.address, chargeAmount);\n    });\n\n    it(\"Should revert on zero amount charge\", async function () {\n      await expect(SimpleWallet.connect(addr1).charge(0)).to.be.revertedWith(\"Charge amount must be greater than zero\");\n    });\n  });\n\n  describe(\"send\", function () {\n    it(\"Should send funds to another account\", async function () {\n      const initialBalance = await ethers.provider.getBalance(owner.address);\n      const sendAmount = ethers.parseEther(\"1\");\n\n      // Deposit an initial specified balance\n      await SimpleWallet.connect(owner).deposit(initialBalance);\n\n      // Execute the send function to transfer funds\n      await expect(SimpleWallet.connect(owner).send(sendAmount, addr2.address, \"\"))\n        .to.emit(SimpleWallet, \"Sent\")\n        .withArgs(owner.address, addr2.address, sendAmount);\n       \n\n      // Check the balance after the transaction\n      const contractBalance = await SimpleWallet.connect(owner).getBalance();\n      expect(contractBalance).to.equal(initialBalance - sendAmount);\n    });\n\n    it(\"Should emit a Sent event\", async function () {\n      const sendAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).deposit(sendAmount);\n\n      await expect(SimpleWallet.connect(addr1).send(sendAmount, addr2.address, \"\"))\n        .to.emit(SimpleWallet, \"Sent\")\n        .withArgs(addr1.address, addr2.address, sendAmount);\n    });\n\n    it(\"Should revert on insufficient balance\", async function () {\n      const sendAmount = ethers.parseEther(\"1\");\n\n      await expect(SimpleWallet.connect(addr1).send(sendAmount, addr2.address, \"\")).to.be.revertedWith(\"Insufficient balance\");\n    });\n\n    it(\"Should revert on zero amount send\", async function () {\n      await expect(SimpleWallet.connect(addr1).send(0, addr2.address, \"\")).to.be.revertedWith(\"Send amount must be greater than zero\");\n    });\n\n    it(\"Should revert on invalid QR code\", async function () {\n      const sendAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).deposit(sendAmount);\n\n      await expect(SimpleWallet.connect(addr1).send(sendAmount, addr2.address, \"invalidQRCode\")).to.be.revertedWith(\"Invalid QR code\");\n    });\n\n    it(\"Should revert on missing recipient address\", async function () {\n      const sendAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).deposit(sendAmount);\n\n      await expect(SimpleWallet.connect(addr1).send(sendAmount, ethers.ZeroAddress, \"\")).to.be.revertedWith(\"Recipient address must be provided\");\n    });\n\n\n  });\n\n  describe(\"linkQRCodeToAddress\", function () {\n    it(\"Should revert with 'Invalid address' when linking to AddressZero\", async function () {\n      const qrCode = \"exampleQRCode\";\n\n      await expect(\n        SimpleWallet.connect(owner).linkQRCodeToAddress(qrCode, ethers.ZeroAddress)\n      ).to.be.revertedWith(\"Invalid address\");\n    });\n\n    it(\"Should link QR code to a valid address\", async function () {\n      const qrCode = \"exampleQRCode\";\n      const validAddress = addr1.address;\n\n      // Link QR code to a valid address\n      await SimpleWallet.connect(owner).linkQRCodeToAddress(qrCode, validAddress);\n\n      // Check that the QR code is linked to the correct address\n      const linkedAddress = await SimpleWallet.getQRCodeAddress(qrCode);\n      expect(linkedAddress).to.equal(validAddress, \"QR code should be linked to the correct address\");\n    });\n  });\n\n  describe(\"getBalance\", function () {\n    it(\"Should return the correct balance\", async function () {\n      // Check opening balance\n      const initialBalance = await SimpleWallet.getBalance();\n      expect(initialBalance).to.equal(0, \"Initial balance should be 0\");\n\n      // Make a deposit\n      const depositAmount = ethers.parseEther(\"0.3\"); // 0.3 ETH in wei\n      await SimpleWallet.deposit(depositAmount);\n\n      // Check balance after deposit\n      const balanceAfterDeposit = await SimpleWallet.getBalance();\n      expect(balanceAfterDeposit).to.equal(depositAmount, \"Balance should be 0.3 ETH after deposit\");\n    });\n  });\n\n  describe(\"withdraw\", function () {\n    it(\"Should withdraw funds\", async function () {\n      const depositAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).deposit(depositAmount);\n      await SimpleWallet.connect(addr1).withdraw(depositAmount);\n\n      expect(await SimpleWallet.getBalance()).to.equal(0);\n    });\n\n    it(\"Should emit a Withdrawal event\", async function () {\n      const depositAmount = ethers.parseEther(\"1\");\n\n      await SimpleWallet.connect(addr1).deposit(depositAmount);\n\n      await expect(SimpleWallet.connect(addr1).withdraw(depositAmount))\n        .to.emit(SimpleWallet, \"Withdrawal\")\n        .withArgs(addr1.address, depositAmount);\n    });\n\n    it(\"Should revert on insufficient balance\", async function () {\n      const depositAmount = ethers.parseEther(\"1\");\n\n      await expect(SimpleWallet.connect(addr1).withdraw(depositAmount)).to.be.revertedWith(\"Insufficient balance\");\n    });\n\n    it(\"Should revert on zero amount withdrawal\", async function () {\n      await expect(SimpleWallet.connect(addr1).withdraw(0)).to.be.revertedWith(\"Withdrawal amount must be greater than zero\");\n    });\n  });\n});\n```\n\nPronto, os tests são auto explicativos em seus nomes, agora vamos criar dois novos `scripts` em `package.json` para rodar esses tests, em `package.json` adicione mais esses scripts:  \n```json\n\"hardhat-node\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat node\",\n\"hardhat-test\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat test\"\n```\nCom `npm run hardhat-node` vamos criar rodar a rede local do [hardhat](https://hardhat.org/) em um terminal, em outro terminal rode `npm run hardhat-test`, aqui todos os 17 testes devem passar. Você não precisa necessariamente rodar o `node` para rodar o `test`, mas lá você pode ter noção das contas que estamos usamos e conferir se está tudo ok para rodarmos nossa aplicação na rede local do [hardhat](https://hardhat.org/).\u003cbr/\u003e\u003cbr/\u003e\n\n### Fazendo deploy do contrato para rede local via ignition\n\nAgora para fazermos o deploy, primeiramente, na rede local, depois faremos em uma rede teste online via [Infura](https://www.infura.io/) para se conectar à rede testnet da [Sepolia](https://ethereum.org/en/developers/docs/networks/#sepolia), recomendada pela própria [Ethereum.org aqui](https://ethereum.org/en/developers/docs/networks/#sepolia), mas antes vamos fazer o seguinte.  \nPrimeiro crie um arquivo js em `/ignition/modules/` chamado `SimpleWallet.js` com o seguinte conteúdo:\n```JavaScript\nconst { buildModule } = require(\"@nomicfoundation/hardhat-ignition/modules\");\n\nmodule.exports = buildModule(\"SimpleWalletModule\",  (m) =\u003e {\n  const simpleWallet =  m.contract(\"SimpleWallet\", [])\n  return { simpleWallet }\n});\n```\nAgora criaremos outro `script` para rodar `npx hardhat ignition deploy ./ignition/modules/SimpleWallet.js --network localhost` no nosso `package.json`:  \n```json\n\"hardhat-ignition-deploy\": \"cd node_modules/hardhat \u0026\u0026 npx hardhat ignition deploy ../../ignition/modules/SimpleWallet.js --network %npm_config_name%\"\n```\nA única diferença nesse `script` é que ele vai receber o nome da `network` dinâmicamente com `--name=localhost` por exemplo, pra que no futuro possamos usar outra rede caso necessário, você poderia fazer o mesmo definindo outra variável caso possua mais de uma `ignition` e também devemos nos lembrar que o npx roda de dentro de `node_modules/hardhat`, portanto estamos voltando alguns repositórios para encontrar nossa `/ignition`.\u003cbr/\u003e\u003cbr/\u003e\n\nPra esse caso será necessário que a rede esteja rodando em um terminal e você execute o `ignition deploy` em outro.  \nEm um terminal rode : `npm run hardhat-node`  \nEm outro terminal rode : `npm run hardhat-ignition-deploy --name=localhost`\u003cbr/\u003e\u003cbr/\u003e\n\nSe tude ocorrer bem você deve receber uma mensagem no terminal do `node` como:\n```shell\neth_call\n  Contract deployment: SimpleWallet\n  Contract address:    0x5fbdb2315678afecb367f032d93f642f64180aa3    \n  From:                0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266    \n\neth_sendTransaction\n  Contract deployment: SimpleWallet\n  Contract address:    0x5fbdb2315678afecb367f032d93f642f64180aa3    \n  Transaction:         0x106888b066befe7989423edd6d6779dce44cb1f2d0f1598acc977b10dc6460d7\n  From:                0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266    \n  Value:               0 ETH\n  Gas used:            1196395 of 1196395\n  Block #1:            0x147493863adf7f7c17a1628a33dcdd99a41f7d58699d8f2e521ad907ff71b94f\n```\nE um aviso em vermelho `hardhat_setLedgerOutputEnabled - Method not supported` pode ser ignorado com segurança, mas não devemos alertá-lo sobre fazer algo que é totalmente esperado (uma implantação do Ignition) ([comentário](https://github.com/NomicFoundation/hardhat/issues/5406#issuecomment-2178203227)), segundo [essa própria issue](https://github.com/NomicFoundation/hardhat/issues/5406#issuecomment-2178203227) do [NomicFoundation](https://github.com/NomicFoundation) responsável pelo própio [hardhat](https://hardhat.org/).  \n\nE no terminal do `ignition deploy` :  \n`SimpleWalletModule#SimpleWallet - 0x5FbDB2315678afecb367f032d93F642f64180aa3` \u003cbr/\u003e\u003cbr/\u003e\n\n\n### Criando nossos endpoints\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkauemurakami%2Fapi-ethereum-wallet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkauemurakami%2Fapi-ethereum-wallet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkauemurakami%2Fapi-ethereum-wallet/lists"}