WEB3DEV

Cover image for Envio de arquivos para o Arweave com o Irys
Panegali
Panegali

Posted on

Envio de arquivos para o Arweave com o Irys

ÍNDICE

O que é o Irys?

Conhecimentos Prévios

Criando a Aplicação NextJS e Instalando Dependências

Inicializando o Irys

Financiando um Node Irys

Função de Envio de Arquivo

Codificando a Página de Envio de Imagens

Codificando a Rota da API de Envio

Recuperando Arquivos Enviados da Rede Arweave

Exibindo Imagens Enviadas

Considerações Finais


O Arweave permite o armazenamento descentralizado de dados. Os usuários pagam uma taxa única para enviar seus dados e têm garantia de armazenamento permanente. Os mineradores garantem a permanência dos dados armazenando e replicando dados em troca do token AR nativo do Arweave. Você pode pensar no Arweave como um disco rígido global ou um Amazon S3 descentralizado.

Este artigo explica como enviar arquivos para o Arweave usando o IRYS. Você aprenderá o que é o Irys e como ele torna o envio de dados para o Arweave simples. Você criará uma aplicação NextJS simples para enviar e visualizar as imagens enviadas para o Arweave, então relaxe e vamos começar essa aventura.

O que é o Irys?

O Irys, anteriormente conhecido como Bundlr, é uma camada de proveniência no Arweave. Ele escala os envios para o Arweave por meio de agrupamento (bundling), permite que você pague com tokens diferentes do AR e oferece fortes capacidades de proveniência para seus envios.

Proveniência significa a origem dos dados. No caso do Arweave, quem enviou os dados e quando. A proveniência do Irys é forte porque vai até o milissegundo e é imutável e permanente, então, depois que seus dados estão no Arweave, você pode usar as tags de proveniência do Irys para provar que você é o criador.

Também é mais barato e conveniente usar o Irys para envio para o Arweave, pois você não é cobrado por fragmento (chunk) como quando envia diretamente para o Arweave. Se você enviar apenas 1 KB, pagará apenas por isso, não pelo fragmento inteiro de 256 KB usado para armazená-lo.

Ainda assim, a taxa é dinâmica e depende de vários fatores, como o número exato de bytes que você está enviando e o custo do Arweave, que é o custo de armazenar X quantidade de bytes no Arweave usando preços lineares, etc. Você pode aprender como o custo é calculado na documentação do Irys.

As transações enviadas via Irys são consideradas finalizadas assim que são enviadas, pois o Irys garante que os dados sejam enviados para o Arweave. Ao contrário do Arweave, que tem um tempo de bloco de 2 minutos e requer 50 confirmações de bloco para que os dados sejam finalizados e armazenados permanentemente no Arweave, o Irys não tem essas restrições, pois usa finalidade otimista e tenta enviar os dados para o Arweave até que sejam incluídos em um bloco e confirmados. Você pode assumir com segurança que o Irys finaliza qualquer dado enviado pela rede.

Conhecimentos Prévios

Você deve estar familiarizado com JavaScript e saber como criar aplicativos React. Você deve saber como usar o prompt de comando e ser capaz de instalar pacotes NPM via terminal. Você deve instalar o Node.js v16 e o NPM em sua máquina de desenvolvimento e estar familiarizado com uma carteira baseada em EVM, como a MetaMask.

Criando a Aplicação NextJS e Instalando Dependências

Navegue até seu diretório de trabalho, crie um novo diretório e inicie um novo projeto NPM no diretório recém-criado, onde iremos instalar a aplicação NextJS. Execute o seguinte comando no terminal:


npx create-next-app@latest

Enter fullscreen mode Exit fullscreen mode

Este comando cria uma nova aplicação NextJS no diretório. Por favor, mantenha-o simples e evite usar o novo roteador de aplicativos NextJS.

Instale as dependências executando:


npm install @irys/sdk @irys/query axios formidable

Enter fullscreen mode Exit fullscreen mode
  • @irys/sdk é usado para enviar dados via Irys para o Arweave.
  • @irys/query é o pacote de consulta do Irys usado para buscar dados e transações enviadas.
  • axios faz chamadas de rede a partir do navegador.
  • formidable é usado para analisar arquivos enviados no servidor.

Após instalar essas dependências, execute a aplicação digitando no terminal:


npm run dev

Enter fullscreen mode Exit fullscreen mode

A aplicação deve iniciar e rodar em localhost:3000.

Em seguida, navegue até a raiz da sua aplicação NextJS e crie um arquivo de variáveis de ambiente chamado .env-local. Esse arquivo conterá as chaves privadas da sua carteira.

Adicione o arquivo .env-local ao seu arquivo gitignore e nunca o envie para um repositório remoto. É aconselhável usar uma chave de carteira descartável para este exercício. Não use a chave de carteira que contém seus ativos de criptomoeda!

Abra o arquivo .env-local e insira a chave privada da sua carteira.

Private_Key = insira-sua-chave-privada-aqui
Enter fullscreen mode Exit fullscreen mode

Você concluiu a criação de uma aplicação NextJS básica e pode explorar o mundo do Irys para ver como é fácil usá-lo para enviar dados para o Arweave.

Inicializando o Irys

Crie uma nova pasta chamada utils no diretório raiz da sua aplicação. Dentro da pasta utils, crie um arquivo chamado utils.js. Você implementará algumas funções relevantes neste arquivo.

No topo do arquivo utils.js recém-criado, importe o pacote Irys:

import Irys from "@irys/sdk";
Enter fullscreen mode Exit fullscreen mode

Em seguida, copie e cole o seguinte código dentro do arquivo utils.js:

const getIrysClient = () => {

    const irys = new Irys({

        url: "https://devnet.irys.xyz",

        token: "matic",

        key: Private_Key,

        config: {

            providerUrl: "https://rpc-mumbai.maticvigil.com",

        }

    });

    // Imprima o endereço da sua carteira

    console.log(`endereço da carteira = ${irys.address}`);

    return irys;

};
Enter fullscreen mode Exit fullscreen mode

Esse código inicializa o Irys criando um construtor Irys que aceita um objeto com as chaves url, token, key e config. O url é o nó Irys ao qual queremos nos conectar, token é a moeda a ser usada para pagamento, key é a chave privada da carteira e config é necessário apenas se estivermos nos conectando a uma rede de testes, o que estamos fazendo neste tutorial.

Podemos nos conectar a três redes de nós Irys, que são:

As primeiras duas redes listadas são redes principais, que exigem tokens reais para pagamentos antes que você possa usá-las para enviar dados. A última é uma rede de testes, onde você pode usar tokens de teste.

A rede de testes exclui arquivos após 90 dias, enquanto a rede principal garante que seus dados sejam armazenados para sempre no Arweave.

A figura a seguir mostra as moedas suportadas:

Como você está testando coisas, você usará a rede de desenvolvimento com o token Matic Mumbai Polygon para pagamento. Você pode obter um token Matic de teste gratuito aqui.

Financiando um Node Irys

Você pode financiar um Node Irys conectado usando um modelo de pagamento conforme o uso, o que significa que você financia o nó com a quantia necessária para o próximo envio.

Você também pode financiar o nó antecipadamente, mas só pode usar o nó que financiou e também é permitido retirar quaisquer fundos não utilizados do nó.

Abra o arquivo utils/utils.js e crie uma nova função chamada lazyFundNode.

export const lazyFundNode = async (size) => {

    const irys = getIrysClient();

    const price = await irys.getPrice(size);

    await irys.fund(price);

};
Enter fullscreen mode Exit fullscreen mode

A função é async e recebe o tamanho dos dados que você está enviando como parâmetro. Ela chama o método getIrysClient, que definimos anteriormente, para obter um novo cliente Irys que usa Matic Mumbai para pagar pelos envios. Em seguida, você await (aguarda) uma chamada para o método getPrice para obter o preço para enviar uma imagem/dados do tamanho passado como parâmetro. Finalmente, você aguarda irys.fund(price), o que faz com que o token seja retirado da sua carteira para financiar o nó.

Função de Envio de Arquivo

Crie e exporte uma nova função dentro do arquivo utils/utils.js chamada uploadFileToArweave. Essa é uma função simples que faz o envio do arquivo.

No topo do arquivo utils.js, adicione uma instrução de importação para o módulo fs.

import * as fs from "fs";
Enter fullscreen mode Exit fullscreen mode
export const uploadFileToArweave = async (filepath, tags) => {

    const irys = getIrysClient();

    const file = fs.readFileSync(filepath);

    const { id } = await irys.upload(file, { tags });

    console.log("arquivo enviado para ", `https://arweave.net/${id}`);

    return id;

};
Enter fullscreen mode Exit fullscreen mode

A função uploadFileToArweave recebe dois parâmetros: o caminho do arquivo (filepath) e tags. A função lê o arquivo do sistema de arquivos usando fs.readFileSync(filepath). Após ler o arquivo em um buffer, ela chama irys.upload, passando o buffer do arquivo e as tags do Arweave.

As tags do Arweave, muitas vezes chamadas apenas de tags, são definidas pelo usuário e são um array de objetos com o seguinte formato:

const tags = [ { name: "...", value: "..."} ];
Enter fullscreen mode Exit fullscreen mode

Você aprenderá a usar essas tags para consultar dados enviados posteriormente.

Codificando a Página de Envio de Imagens

Em seguida, você irá codificar a página para permitir que os usuários selecionem um arquivo de imagem para envio posterior para o servidor para processamento adicional.

Abra o arquivo pages/index.js, remova o conteúdo anterior e substitua-o pelo seguinte conteúdo:

import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

import React, { useState } from "react";

import ImageViewer from '@/components/ImageViewer';

const allowedFiles = (file) => {

  const fileTypes = ["image/png", "image/jpeg", "image/jpg", "image/gif"];

  return fileTypes.includes(file)

}

export default function Home() {

  const [imageSource, setImageSource] = useState(null);

  const [selectedFile, setSelectedFile] = useState(null)

  const [caption, setCaption] = useState("");

  const [description, setDescription] = useState("")

  const [loading, setLoading] = useState(false);

  const [error, setError] = useState(null);

  const fileInputRef = React.useRef();

  const handleImageUpload = (event) => {

    if (event.target.files && event.target.files[0] && allowedFiles(event.target.files[0].type)) {

      setSelectedFile(event.target.files[0])

      const reader = new FileReader();

      reader.onload = function (e) {

        setImageSource(e.target.result);

      };

      reader.readAsDataURL(event.target.files[0]);

    } else {

      setImageSource(null);

    }

  };

  const uploadFileToArweave = async (event) => {

    event.preventDefault();

    try {

      if (selectedFile && caption && description) {

        setLoading(true);

        const formData = new FormData();

        //build the tags

        const applicationName = {

          name: "application-name",

          value: "image-album",

        };

        const applicationType = { name: "Content-Type", value: selectedFile.type }

        const imageCaption = { name: "caption", value: caption };

        const imageDescription = { name: "description", value: description }

        const metadata = [

          applicationName,

          imageCaption,

          imageDescription,

          applicationType

        ]

        formData.append("file", selectedFile);

 formData.append("metadata", JSON.stringify(metadata));

        const response = await fetch("/api/upload", {

          method: "POST",

          body: formData,

        });

       console.log ("response from the method: ",response.data)

      }

    } catch (error) {

      setError(error.message);

      console.log("error ", error);

    } finally {

      setLoading(false);

      setSelectedFile(null);

      setImageSource(null);

      setCaption("");

      setDescription("")

      fileInputRef.current.value = null;

    }

  };

  return (

    <React.Fragment>

    <div className="flex justify-center items-center">

      {error && <p>There was an error: {error}</p>}

      <div className="bg-white m-2 p-8 rounded shadow-md w-1/3">

        <h2 className="text-2xl mb-4">Upload Image</h2>

        <div className='flex-col'>

          <div>

            <label className="block text-sm font-medium text-gray-700 mb-2">Upload an Image</label>

            <input

              type="file"

              className="hidden"

              id="imageInput"

              onChange={handleImageUpload}

              ref={fileInputRef}

              accept=".png, .jpg, .jpeg"

            />

          </div>

          {/*Div para exibir a imagem selecionada */}

          <div className="mt-2">

            {imageSource ? (

              <img className="mt-2 rounded-lg" src={imageSource} alt="Selected" />

            ) : (

              <p className="text-gray-400">No image selected</p>

            )}

          </div>

          <button

            className="mt-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"

            onClick={() => document.getElementById('imageInput').click()}

          >

            Select Image

          </button>

        </div>

      </div>

      {selectedFile &&

        <div className='bg-white m-2 p-8 w-2/3'>

            <div className="bg-white p-8 m-4 rounded shadow-md">

              <h2 className="text-2xl mb-4">Image Details</h2>

              <div className="mb-4">

                <label className="block text-sm font-medium mb-1">Image Caption</label>

                <input

                  value={caption}

                  onChange={(e) => setCaption(e.target.value)}

                  type="text"

                  className="w-full border border-gray-300 px-3 py-2 rounded-md focus:ring focus:ring-blue-300"

                />

              </div>

              <div className="mb-4">

                <label className="block text-sm font-medium mb-1">Image Description</label>

                <textarea

                  value={description}

                  onChange={(e) => setDescription(e.target.value)}

                  className="w-full border border-gray-300 px-3 py-2 rounded-md resize-none focus:ring focus:ring-blue-300"

                  rows= "4"

                ></textarea>

              </div>

              <button

                disabled={loading}

                onClick={uploadFileToArweave}

                className="bg-green-500 text-white px-4 py-2 rounded-md hover:bg-green-600 focus:outline-none focus:ring focus:ring-green-300"

              >

                Upload Image

              </button>

            </div>

        </div>

      }

    </div>

    </React.Fragment>

  )

}
Enter fullscreen mode Exit fullscreen mode

Esta página contém um componente de envio de arquivo para selecionar imagens do computador do usuário. Vamos analisar as funções importantes deste componente.

Os estados do React que armazenam dados, como a imagem selecionada, a legenda da imagem e a descrição.

A função handleImageUpload está vinculada ao evento onChanged do carregador de arquivo.

A função handleImageUpload verifica se o usuário selecionou um arquivo e se o tipo de arquivo está entre os tipos permitidos.

A função allowedFiles verifica se o tipo MIME é "image/png", "image/jpeg", "image/jpg" ou "image/gif". Essa verificação garante simplicidade, pois a melhor maneira de verificar o conteúdo e o tipo de um arquivo é no lado do servidor.

A classe FileReader do navegador lê o arquivo selecionado e salva o resultado no estado React chamado imageSource. O arquivo de imagem é salvo em outro estado chamado selectedFile. A imagem selecionada é exibida com uma tag de imagem. Após a seleção da imagem, um formulário é indicado para que o usuário insira uma legenda e uma descrição para a imagem. A legenda e a descrição são salvas em um estado React chamado caption e description.

A função uploadFileToArweave está vinculada ao manipulador de eventos click do botão UploadImage do formulário de detalhes da imagem. A função verifica a existência de uma imagem selecionada, legenda e descrição. Você cria um novo FormData() para ser passado para o servidor. A imagem selecionada e os metadados são anexados ao FormData().

Você está criando três tags descrevendo a imagem e uma tag descrevendo o nome da aplicação. Você pode definir um número arbitrário de tags; a única restrição é que o tamanho total das tags não deve ultrapassar 2KB. Ao definir as tags, podemos incluir o criador dos dados específicos, que então fica associado a esse pedaço de dados.

const applicationName = { name: "application-name",value: "image-album"};

 const applicationType = { name: "Content-Type", value: selectedFile.type }

 const imageCaption = { name: "caption", value: caption };

 const imageDescription = { name: "description", value: description }
Enter fullscreen mode Exit fullscreen mode

As tags são inseridas em um array que é anexado aos dados do formulário com uma chave de metadata.

formData.append("file", selectedFile);

formData.append("metadata", JSON.stringify(metadata));
Enter fullscreen mode Exit fullscreen mode

Finalmente, você chama o ponto de extremidade da API no servidor usando o axios, passando o formData no corpo da solicitação.

const resposta = await fetch("/api/upload", {

    method: "POST",

    body: formData,

});
Enter fullscreen mode Exit fullscreen mode

Em seguida, você criará o ponto de extremidade para receber e processar o arquivo para posterior upload para o Arweave.

Codificando a Rota da API de Envio

Crie um novo arquivo pages/api/upload.js. Lembre-se de que o nome do arquivo deve corresponder ao ponto de extremidade. No topo do arquivo upload.js, importe o seguinte:

   import formidable from "formidable";

   import path from "path";

   import * as fs from "fs";

   import { lazyFundNode, uploadFileToArweave } from "../../utils/utils";
Enter fullscreen mode Exit fullscreen mode

O pacote formidable é utilizado para processar o arquivo enviado pelo cliente. Você também importou as funções utilitárias que criamos anteriormente: lazyFundNode e uploadFileToArweave.

Em seguida, você exporta um objeto config para configurar o NextJS para não analisar automaticamente as solicitações provenientes da rota da API.

export const config = {

    api: {

        bodyParser: false,

    },

};
Enter fullscreen mode Exit fullscreen mode

Você analisa manualmente a solicitação do cliente usando formidable. Lembre-se, como a solicitação conterá o arquivo enviado e os campos de metadados, você definirá uma handler function para processar a solicitação do cliente.

  const handler = async (req, res) => {

    try {

        fs.mkdirSync(path.join(process.cwd() + "/uploads", "/images"), {

            recursive: true,

        });

        const { fields, files } = await readFile(req);

        const filepath = files.file[0].filepath;

        //obter o tamanho do arquivo que queremos carregar

        const { size } = fs.statSync(filepath);

        //financiar o Nó

        await lazyFundNode(size);

        //enviar o arquivo para o Arweave

        const transId = await uploadFileToArweave(filepath,    JSON.parse(fields.metadata));

        fs.unlinkSync(filepath);

        res.status(200).json(transId);

    } catch (error) {

        console.log("error ", error)

        res.status(400).json({ error: error });

    }

};

export default handler;
Enter fullscreen mode Exit fullscreen mode

O handler é asynchronous e recebe um request e um objeto response como parâmetros. No topo do arquivo, criamos um diretório para armazenar a imagem enviada. O diretório é criado se não existir dentro da pasta da sua aplicação.

fs.mkdirSync(path.join(process.cwd() + "/uploads", "/images"), {

    recursive: true,

});
Enter fullscreen mode Exit fullscreen mode

path.join adiciona o diretório de trabalho atual ao diretório recém-criado "uploads/images" para obter um caminho absoluto. A função readFile processa o arquivo e retorna o objeto de arquivo e os campos enviados pelo cliente. Copie o código abaixo e cole-o no arquivo upload.js.

const readFile = (req) => {

    const options = {};

    options.uploadDir = path.join(process.cwd(), "/uploads/images");

    options.filename = (name, ext, path, form) => {

        return Date.now().toString() + "_" + path.originalFilename;

    };

    options.maxFileSize = 4000 * 1024 * 1024;

    const form = formidable(options);

    return new Promise((resolve, reject) => {

        form.parse(req, (err, fields, files) => {

            if (err) reject(err);

            resolve({ fields, files });

        });

    });

};
Enter fullscreen mode Exit fullscreen mode

A função readFile retorna uma Promise, que é resolvida para os campos (fields) e arquivos (files). Você cria um objeto de opções vazio para configurar formidable. Primeiro, você define o uploadDir, que corresponde ao diretório upload/images que você criou anteriormente. Você também define filename e o tamanho máximo do arquivo que deseja enviar para o servidor, neste caso, 4 MB.

Você cria uma instância formidable passando essas opções:

const form = formidable(options);
Enter fullscreen mode Exit fullscreen mode

A Promise é resolvida com os arquivos e campos se for bem-sucedida ou rejeitada com um erro. Após ler e processar o arquivo, obtemos o tamanho do arquivo usando o método fs.statsSync, passando o caminho do arquivo como argumento.

const { size } = fs.statSync(filepath);
Enter fullscreen mode Exit fullscreen mode

Você deve financiar o nó Irys com a quantidade de token necessária para enviar o arquivo. Neste exemplo, você está usando um método de pagamento conforme o uso. Você aguarda o resultado da função lazyFundNode(size). Lembre-se, esta é uma das funções utilitárias criadas anteriormente que aceita um parâmetro de tamanho para financiar um nó.

Em seguida, você chama a função uploadFileToArweave, passando o caminho do arquivo e os metadados. Essa função foi criada anteriormente e processa e envia o arquivo para o Arweave.

const transId = await uploadFileToArweave(filepath, JSON.parse(fields.metadata));
Enter fullscreen mode Exit fullscreen mode

Se tudo correr bem, você obtém o ID da transação do Arweave. O arquivo enviado é então excluído do sistema de arquivos do servidor.

fs.unlinkSync(filepath);
Enter fullscreen mode Exit fullscreen mode

A função handler da API retorna o ID da transação para o cliente como response.

Recuperando Arquivos Enviados da Rede Arweave

Até agora, você aprendeu como configurar o Irys e utilizá-lo para enviar dados para o Arweave. Agora, você vai avançar e ver como recuperar dados enviados para o Arweave.

Vamos usar o pacote de consulta Irys para recuperar dados em vez de usar o GraphQL. Crie um novo arquivo na raiz da pasta do seu projeto chamado queries.js. Dentro do arquivo queries.js recém-criado, vamos criar e exportar uma instância do pacote de consulta; essa instância exportada será usada em toda a nossa aplicação.

Copie e cole o código dentro do arquivo queries.js.

importação de Consulta de "@irys/query";

export const minhaConsulta = () => {

    const minhaConsulta = new Query({ url: "https://devnet.irys.xyz/graphql" });

    return minhaConsulta;

}
Enter fullscreen mode Exit fullscreen mode

O objeto Query recebe um objeto com a chave url; esta chave é o nó que queremos consultar. myQuery é retornada a partir da função acima. É isso que vamos usar para consultar nossos dados enviados.

Exibindo Imagens Enviadas

Crie uma nova pasta chamada components no diretório raiz do projeto. Crie um novo arquivo dentro da pasta components chamado ImageViewer.js. Copie e cole o código abaixo no arquivo.

import React, { useEffect, useState } from "react";

import { myQuery } from "@/queries";

const ImageViewer = () => {

    const [data, setData] = useState([]);

    const [loading, setLoading] = useState(false)

    const loadUploadedData = async () => {

        setLoading(true)

        const query = myQuery();

        const results = await query.search("irys:transactions").tags([{ name: "application-name", values: ["image-album"] }]).sort("ASC");

        console.log("the result of the transactions: ", results)

        setData(results);

        setLoading(false);

    }

    useEffect(() => {

        loadUploadedData()

    }, [])

    if (loading) {

        return <div>Loading...........</div>

    }

    return <div className="flex flex-wrap">

        {data &&

            data.map(({ tags, id, }) => (

                <div className="w-1/5 p-4" key={id}>

                    <img src={`https://arweave.net/${id}`} className="w-full h-auto rounded"

                        width={300}

                        height={300}

                        alt=""

                    />

                    {tags.map(({ name, value }) => {

                        if (name == "caption") {

                            return <h3 className="mt-2 text-lg font-semibold" key={value}>{value}</h3>

                        } else if (name == "description") {

                            return <p className="text-gray-500" key={value}>{value}</p>

                        }

                    })}

                </div>

            ))}

    </div>

}

export default ImageViewer
Enter fullscreen mode Exit fullscreen mode

No topo do arquivo, você importou coisas padrão do React como useState e useEffect. Em seguida, importamos a instância do pacote de consulta do Irys que foi exportada do arquivo queries.js.

import { myQuery } from "@/queries";

const loadUploadedData = async () => {

    setLoading(true);

    const query = myQuery();

    const results = await query.search("irys:transactions").tags([{ name: "application-name", values: ["image-album"] }]).sort("ASC");

    console.log("o resultado das transações: ", results);

    setData(results);

    setLoading(false);

}
Enter fullscreen mode Exit fullscreen mode

Definimos uma função assíncrona loadUploadedData. Esta função usa o pacote de consulta para recuperar dados. No topo do arquivo, estamos alterando o estado de carregamento para verdadeiro e estamos recuperando a instância do pacote de consulta que definimos.

Em seguida, fazemos uma pesquisa nas transações de dados enviados, limitando-a a transações com uma tag de "application-name" com um valor de "image-album". Isso nos dá a imagem enviada através da nossa aplicação de exemplo, ordenada em ordem ascendente.

const results = await query.search("irys:transactions").tags([{ name: "application-name", values: ["image-album"] }]).sort("ASC");
Enter fullscreen mode Exit fullscreen mode

O resultado retornado é salvo no estado do React e, definimos o estado de carregamento do aplicativo como falso.

A função loadUploadedData é chamada dentro de um gancho useEffect com um array de dependências vazia, o que significa que queremos chamar a função apenas uma vez.

Os dados retornados do nó são desestruturados para obter a imagem enviada com a legenda e a descrição exibidas na página. Abra a página index.js e adicione o componente ImageViewer à página. Adicione o ImageViewer antes do fechamento de </React.Fragment>.

Execute a aplicaçãoe envie uma imagem; quando a imagem for enviada, atualize a página para ver a imagem enviada.

Pensamentos Finais

Este post mostrou como enviar dados para a rede Arweave via Irys. Você construiu uma aplicação de trabalho de exemplo que pode ser personalizada para atender às suas necessidades.

Agradeço por permanecer na causa e chegar ao final deste post. Você pode encontrar o código do post no GitHub.


Artigo escrito por Osikhena Oshomah. Traduzido por Marcelo Panegali.

Top comments (0)