WEB3DEV

Cover image for Construindo seus próprios Plugins Hardhat Customizados a partir do zero (DEV)
Rafael Ojeda
Rafael Ojeda

Posted on

Construindo seus próprios Plugins Hardhat Customizados a partir do zero (DEV)

Construindo seus próprios Plugins Hardhat Customizados a partir do zero

Se você costuma usar o Hardhat, pode haver situações em que você tenha algumas tarefas que realiza regularmente (por exemplo, remover console.log do seu código). Nesse caso, seria realmente útil criar algumas tarefas ou alguns plugins para reutilizar mais tarde.

Image description

Então, neste artigo, vamos caminhar através de como podemos criar um novo plugin de hardhat personalizado a partir do zero (realmente a partir do zero).

O que vamos criar

Neste artigo, abordarei como escrever um plugin personalizado chamado hardhat-laika, que é o plugin que vai sincronizar a Interface Binária de Aplicativos (ABI) dos artefatos gerados pelo Hardhat com uma aplicação chamada Laika.

Se você não sabe o que é Laika, Laika é uma ferramenta de desenvolvimento Blockchain que ajuda você a solicitar contratos inteligentes sem ter o incômodo de escrever uma única linha de código - um carteiro para a web3!

Como funciona?

Como a hardhat-laika vai funcionar é realmente simples. Funciona da seguinte maneira.

  • obtém os artefatos compilados a partir de contratos específicos

  • envia sua ABI para https://api.getlaika.app

  • obtém uma resposta e gera uma nova URL para que o usuário possa acessar seu próprio contrato através da Laika

Muito bem, como você pode ver o propósito é bastante específico (não é muito simples ou muito complicado, então eu acho que seria um bom exemplo para caminharmos juntos).

Portanto, quero encorajá-los a pensar em algo que vocês mesmos queiram fazer e seguir em frente.

E de qualquer forma, não sou especialista em construir um plugin Hardhat personalizado, então se vocês quiserem acrescentar algumas sugestões, isso é realmente bem-vindo!

O que são exatamente plugins Hardhat?

De acordo com https://hardhat.org/advanced/building-plugins.html

Plugins Hardhat são configurações reutilizáveis ou qualquer coisa que você possa adicionar ao seu arquivo de configuração que possa juntar tudo para criar outro plugin.

Sim, então a maneira mais fácil de construir um plugin Hardhat é começar no seu hardhat.config.js!

Então, o que você pode fazer com o plugin Hardhat?

Como dito na documentação, você pode fazer o que quiser em seu arquivo de configuração.
Vamos listá-los para que possamos ter uma idéia.

e é isso!

Vamos montar nosso plugin no arquivo de configuração

Antes de mais nada, vamos criar um novo projeto de Hardhat usando o comando

npx hardhat init

Então, configure-a como quiser, mas para mim, vou usar esta configuração.

√ O que você quer fazer? - Criar um projeto básico de amostra
√ Raiz do projeto Hardhat: · /path/to/project/
√ Você quer adicionar um .gitignore? (y/n) - y
√ Você quer instalar as dependências deste projeto modelo com npm (...)? (y/n) - y

Porque eu quero meu plugin hardhat-laika para que quando eu o instalar eu seja capaz de fazer algo como.

npx hardhat laika-sync --contract <name> --address <address>

Obviamente, a primeira coisa que tenho que fazer é criar uma nova tarefa para isso.

const open = require(" open");
const fetch = require("node-fetch")

…

// Definindo uma nova tarefa chamada laika-sync
tarefa("laika-sync", "Sync your ABIs with Laika")
  .addParam("contrato", "nome do contrato para sincronizar") // adicionar parâmetros do contrato
  .addOptionalParam( // adicionar parâmetros de endereço opcionais
    "endereço",
    "Endereço desse contrato específico",
    "", // valor padrão
    types.string
  )
  .setAction(async (taskArgs, hre) => {
const { contract, address: contractAddress } = taskArgs;
    const { abi } = await hre.artifacts.readArtifact( contract);
    console.log(`Syncing the ABI of ${contracto} contract...`);

const response = await fetch(
      "https://api.getlaika.app/abi-storages",
      {
        method: "POST",
        body: JSON.stringify({ abi, contractAddress }),
        headers: {"Content-Type": "aplicação/json" },
      }
    );

const publicUrl = await response.text();
    const endpoint = `https://web.getlaika.app/evm/collections/import/${
      publicUrl.split("/")[4].split(".")[0]
    }`;

    console.log(`Check out your request at ${endpoint}`);
    open(endpoint);
  });
Enter fullscreen mode Exit fullscreen mode

As coisas que estamos fazendo com esta tarefa são realmente simples e a questão é que isto é tudo o que temos que fazer para a tarefa que eu quero. Obtemos a ABI e o endereço do contrato para carregá-lo no backend da Laika e então geramos um novo URL para que os usuários possam acessá-lo através dos navegadores.

Note que eu tenho usado "open" (para abrir o navegador) e node-fetch, então não se esqueça de instalá-lo!

Muito bem, vamos tentar :))

Primeiro eu uso o comando

Image description

Então o plugin irá abrir o navegador e veremos a coleção que vai ser importada.

Image description

Legal!

Tente olhar ao redor do repo para ver como as coisas se encaixam.

Outra ótima maneira de explorar como as coisas se encaixam é olhando ao redor de outros plugins se você estiver realmente começando. Há muitos plugins pequenos que você poderia ver ao redor.

Por exemplo.

clone de git https://github.com/nomiclabs/hardhat-ts-plugin-boilerplate.git

Depois, vamos então digitar as extensões (acho mais fácil para mim, configurar as coisas como elas devem ser primeiro)

Vou colocar este código naquele arquivo.

// Se seu plugin estende tipos a partir de outro plugin, você deve importar o plugin aqui.

// Para estender um dos tipos de Hardhat, você precisa importar o módulo onde ele foi definido, e declará-lo novamente.
import "hardhat/types/config";
import "hardhat/types/config"; importar "hardhat/types/runtime";

declarar o módulo "hardhat/types/runtime" {
export interface HardhatRuntimeEnvironment {
    laikaSync: (
      hre: HardhatRuntimeEnvironmental,
      contract: cordel,
      contractAddress: string
    ) => Promise<void>;
  }
}
Enter fullscreen mode Exit fullscreen mode

Este pedaço de código é onde descrevo a interface da tarefa que criei (laikaSync)

A seguir, vamos passar nossa tarefa para o plugin. Vou criar uma nova pasta chamada tarefas e criar um novo arquivo nessa pasta laika-sync.ts (Então, quando tivermos mais e mais tarefas, elas não serão misturadas no index.ts)

import { HardhatRuntimeEnvironment } from "hardhat/types";
import { task, types } from "hardhat/config";
import open from "open";

import { endpointUrls } from "../config";

/**
 *Ele pega um contrato da ABI e o envia para o backend, que retorna um URL público. Em seguida, gera um
 * novo URL para interagir com contratos inteligentes através da Laika
 * @param {HardhatRuntimeEnvironment} hre - HardhatRuntimeEnvironment
 * @param {string} contract - O nome do contrato que você deseja sincronizar.
 * @param {string} contractAddress - O endereço desse contrato específico.
 */
const laikaSync = async (hre: HardhatRuntimeEnvironment, contract: string, contractAddress: string) => {
  const { abi } = await hre.artifacts.readArtifact(contract);
  console.log(`Syncing the ABI of ${contract} contract...`);

  const { default: fetch } = await import("node-fetch");
  const response = await fetch(
    `${endpointUrls.services}/abi-storages`,
    {
      method: "POST",
      body: JSON.stringify({ abi, contractAddress }),
      headers: { "Content-Type": "application/json" },
    }
  );

  const publicUrl = await response.text();
  const endpoint = `${endpointUrls.interface}/evm/collections/import/${
    publicUrl.split("/")[4].split(".")[0]
  }`;

  console.log(`Check out your request at ${endpoint}`);
  open(endpoint);
};

task("laika-sync", "Sync your ABIs with Laika")
  .addParam("contract", "Contract name to sync")
  .addOptionalParam(
    "address",
    "Address of that specific contract",
    "",
    types.string
  )
  .setAction(async (taskArgs, hre) => {
    const { contract, address: contractAddress } = taskArgs;
    await laikaSync(hre, contract, contractAddress);
  });

export default laikaSync;
Enter fullscreen mode Exit fullscreen mode

Eu passo a tarefa do hardhat.config.js para cá. Você pode notar que mudei um pouco a estrutura do código para torná-lo mais versátil (eu espero rs). Além disso, você pode notar que eu importei o URL do endpoint do config.config.js

Então, vamos criá-lo.

const endpointUrls = {
  interface: "https://web.getlaika.app",
  services: "https://api.getlaika.app",
};

export { endpointUrls };
Enter fullscreen mode Exit fullscreen mode

Sim, isto é bastante simples. Agora passemos ao nosso index.ts

import { extendEnvironment } from "hardhat/config";
import laikaSync from "./tasks/laika-sync";
import "./tasks/laika-sync";

import "./type-extensions";

extendEnvironment((hre) => {
  hre.laikaSync = laikaSync;
});
Enter fullscreen mode Exit fullscreen mode

Aliás, muito simples haha. Nesse arquivo, eu apenas estendo o ambiente adicionando laikaSync ao hre. E é sobre isso! seu plugin está pronto 👀

Vamos testá-lo e publicar

Como nosso plugin está escrito em Typescript, então não se esqueça de construí-lo!

Depois de clonar o boilerplate, mude o nome para hardhat-laika

Image description

Portanto, quando for usá-lo, terei de acrescentar a função require ("./hardhat-laika") ao meu hardhat.config.js (a raiz do projeto um)

Image description

Sim! Ainda está funcionando como o esperado! De qualquer forma, seria uma ótima idéia se escrevêssemos um roteiro de teste para isso, mas esse é um tópico para outro artigo! 👀

Se você quiser publicar para npm e nunca tenha feito antes, basta ir a https://docs.npmjs.com/cli/v8/commands/npm-publish para obter mais informações.

Ufa, isso foi bastante coisa. Muito obrigado pela leitura até aqui! Espero que você tenha conseguido entender como construir um novo plugin Hardhat.

De qualquer forma, se você tiver tempo, eu realmente o encorajo a tentar hardhat-laika com Laika aqui fora: https://www.npmjs.com/package/hardhat-laika

Certamente teremos mais artigos sobre como usar hardhat-laika em breve. Fique atento!

Até a próxima 😃

Este artigo foi escrito por Nonthakon Jitchiranant e traduzido para o português por Rafael Ojeda

Você pode o artigo original em inglês aqui

Latest comments (0)