WEB3DEV

Cover image for Crie uma interface de carteira da Web do Algorand usando Reach e React
Adriano P. Araujo
Adriano P. Araujo

Posted on • Atualizado em

Crie uma interface de carteira da Web do Algorand usando Reach e React

Crie uma interface de carteira da Web do Algorand usando Reach e React

 

O valor comercial deste tutorial é ensinar como usar o front-end Reach para conectar-se a uma carteira da Algorand e assinar transações usando a MyAlgo Wallet e Algosigner com o React. O motivo da escolha do Reach e React para este projeto é porque o Reach é a maneira mais rápida e fácil de criar DApps que podem ser implantados em várias plataformas, e o React é uma das bibliotecas de front-end mais populares de escolha para a maioria dos desenvolvedores e organizações.

Conectar  uma carteira é um requisito importante para a maioria dos desenvolvedores de DApp, uma vez que terão que integrá-la em seu aplicativo ao criar um DApp na Blockchain Algorand.

Este tutorial o guiará na conexão do seu DApp a uma carteira da Algorand usando a  MyAlgo Wallet ou o  AlgoSigner. O tutorial e a solução de código são divididos em duas seções. A conexão da MyAlgo Wallet  com Reach e Algosigner independente do Reach.

A conexão com a MyAlgo Wallet faz parte da integração integrada no Reach, que fornece um fallback para conectar-se à carteira. O AlgoSigner não está integrado ao Reach e, portanto, a integração do AlgoSigner no seu DApp não requer o Reach.

Para obter o código completo,  aqui está o repositório no github  e aqui está o link para o Demo na netlify.

https://youtu.be/7fIDHOjlUvw

Requisitos

Antecedentes

O Reach é uma linguagem específica de domínio  para a criação de aplicativos descentralizados ( DApps ).Reach é uma linguagem de programação agnóstica de blockchain - que possui sintaxe semelhante à do JavaScript. Reach verifica automaticamente os contratos inteligentes a um custo menor e compila-os em várias blockchains. Atualmente, o Reach compila para Algorand, Ethereum e Conflux, e planeja expandir-se mais em breve.

O Reach também criou uma biblioteca front-end - para conectar-se a carteiras devnet ou diretamente ao Algosigner, MyAlgo Wallet ou Metamask se estiver implantando na blockchain Etherum. Este projeto usa a biblioteca front-end com React para criar uma interface simples da carteira Algorand. Este tutorial utiliza o Algorand TestNet para permitir que o usuário verifique o saldo da conta, financie a conta e transfira fundos para outra conta usando Reach and React. O usuário pode se conectar a MyAlgo Wallet ou ao AlgoSigner.

MyAlgo Wallet é uma carteira  Web e o AlgoSigner é uma extensão do navegador Chrome, usada para conectar os DAPs para assinar transações na blockchain de Algorand.

Nota

O AlgoSigner não está integrado ao Reach, nós o adicionaremos manualmente se quisermos assinar transações com o AlgoSigner.

Para mais informações sobre o Reach, confira o site do Reach, a documentação, e o Discord.

No final deste tutorial, a interface do usuário deve ficar assim.

Fig 0 - 1 UI do aplicativo

Etapas

  1. Instalação do projeto e instalação do React

  2. Instalação do Reach

  3. Estrutura do projeto

  4. Página principal e estilo

  5. MyAlgo Wallet

  6. Testando o projeto

  7. Estilo da MyAlgo Wallet

  8. AlgoSigner

  9. Estilos de interface do usuário AlgoSigner

  10. Próximo passo

  11. Estudo adicional

1.Instalação do projeto e instalação do React

Para criar um aplicativo com o React , primeiro você precisa ter instalado node para então instalar o react globalmente, se você o está instalando pela primeira vez por precaução instale o react sempre que precisar com o create react app.

Fig 1 - 1 ajuda a confirmar que o node está instalado.

Fig 1 - 1 Versão npm do node

npm install -g create-react-app

Isso instalará o react global em sua máquina. A próxima coisa a fazer é inserir este comando

Fig 1 - 2 Criando uma aplicação React

Fig 1 - 3  Criando os arquivos de uma aplicação React

create-react-app reach-react-wallet. Isso criará um boilerplate do aplicativo React com o nome reach-react. Depois disso, navegue na pasta do projeto fazendo cd reach-react. Parabéns, seu aplicativo react está pronto, você pode executá-lo usando este comando npm start

Fig 1 - 4 UI da aplicação React

Para este tutorial, usaremos o styled component para escrever nosso css. Para usar o styled component, precisamos instalá-lo.

Digite no seu terminal npm install --save styled-components. Com isso, podemos configurar nosso css usando o styled component. Aqui está o link para aprender mais sobre o styled component.

Nota

O Reach possui funcionalidades incorporadas ao React. Para ter acesso ao React enquanto usa o Reach, basta fazer o seguinte;

Como conveniência para executar o servidor de desenvolvimento React, você pode chamar:

./reach react
Enter fullscreen mode Exit fullscreen mode

Para executar o servidor de desenvolvimento React com a Algorand, você pode chamar:

./reach reactDE=ALGO ./reach react
Enter fullscreen mode Exit fullscreen mode

Mas, para este tutorial, estamos executando react do zero e excluiremos alguns dos arquivos do boilerplate.

Fig 1 - 4 Estrutura do projeto Boilerplate

Neste ponto, sua estrutura de projeto atualmente se parece com isso. Exclua tudo da pasta de origem, exceto App.js e index.js, então na pasta pública exclua tudo do index.jsl

Após excluir esses arquivos, sua estrutura de arquivos deve ficar assim.

Fig 1 - 5 Estrutura modificada do projeto Boilerplate

Para evitar erros após excluir esses arquivos, abra index.js e index.js e remova as importações não utilizadas.

Por enquanto, seu arquivo App.js deve ficar assim

Fig 1 - 6 App.js

E  arquivo index.js deve ficar assim

Fig 1 - 7 index.js

A estrutura do projeto será atualizada na etapa 3.

2. Instalação do Reach

Nota

Esta configuração guia será importante ao configurar o Reach. Verifique se a composição make, docker e docker estão todos instalados. Para garantir que eles estejam instalados, você pode verificar a versão deles no terminal fazendo o seguinte;

make --version  
docker --version  
docker-compose --version
Enter fullscreen mode Exit fullscreen mode

Fig 2 - 1 make, docker and docker-compose

Fig 2 - 1 Confirme que o código da imagem acima foi instalado com sucesso.

Depois de ter certeza de que eles estão instalados, faça o download do Reach executando

curl https://docs.reach.sh/reach -o reach ; chmod +x reach

Fig 2 - 2 download do Reach 

Para começar a usar a biblioteca padrão Reach JavaScript, você precisa instalar o Reach usando este comando. Primeiro navegue / cd até a pasta src para executar

npm install @reach-sh/stdlib
Enter fullscreen mode Exit fullscreen mode

Fig 2 - 3 Instalação do pacote Reach JavaScript 

Então rode ./reach update ( isso fará o download das bibliotecas )

3. Estrutura do projeto

![[Pasted image 20221008205410.png]]
Fig 3 - 1 Estrutura do projeto

Para o tutorial, sua estrutura de projeto deve se parecer com a Fig 3 - 1 acima.

Aqui está uma rápida discriminação da estrutura de pastas / arquivos. Para manter as coisas arrumadas e modulares, decidi separar os arquivos. Um aspecto da codificação limpa envolve a separação de assuntos .

A pasta Asset cuida de imagens e da pasta css. A pasta Component cuida dos componentes que contêm a pasta AlgoSigner, a pasta Header, a pasta MyAlgoWallet, o Button.Styles.js e o Form.style.js.

App.js, constants.js, index.js, Main.styles.js estão diretamente dentro da pasta raiz(src). A pasta Assets e Components também está dentro da pasta src. O Reach também está dentro da pasta src.

4. Página principal e estilo

App.js

/*global AlgoSigner*/  
import React from 'react'  
import Header from './components/Header/header'  
import MyAlgoWallet from './components/MyAlgoWallet/MyAlgoWallet'  
import AlgoSigner from './components/AlgoSigner/AlgoSigner'  
import { Main, MainBody } from './Main.styles'  
import './assets/css/app.css'  

function App(){  
        return(  

            <MainBody>  
                <Header/>  
                <Main>  
                    <MyAlgoWallet/>  
                    <AlgoSigner/>          
                </Main>  
            </MainBody>  
        )  
}  

export default App]
Enter fullscreen mode Exit fullscreen mode

Main.styles.js

import styled from "styled-components"  

export const Main = styled.div`  
    display : flex;  
    justify-content : space-evenly;  

    @media(max-width : 560px){  
        flex-direction   : column;  
        align-content : center;  
        align-items : center;  
    }  
`  

export const MainBody = styled.div`  
    background-color : #F8F9FF;  
    height : 100vh;  

Enter fullscreen mode Exit fullscreen mode

index.js

 

ReactDOM.render(  
  <React.StrictMode>  
    <App />  
  </React.StrictMode>,  
  document.getElementById('root')  
);

Enter fullscreen mode Exit fullscreen mode

header.js

import React from 'react'  
import { MainHeader, HeaderText } from './MainHeader.styles'  
const Header = () => {  
    return(  
      <MainHeader>  
          <HeaderText>Welcome to Algorand Wallet Connect</HeaderText>  
        </MainHeader>  
    )  
}  

export default Header
Enter fullscreen mode Exit fullscreen mode

MainHeader.styles.js

import styled from "styled-components";  

export const MainHeader  = styled.header `  
    padding : 20px;  
    margin : 0;  
    background-color : #F4F1FE;  
`  


export const HeaderText = styled.h3`  
    text-align : center;  
    font-family : 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif  
`

src / ativos / css / app.css



body {  
    background: #F8F9FF;  
}
Enter fullscreen mode Exit fullscreen mode

constants.js

const ALGOD_SERVER = 'https://testnet-algorand.api.purestake.io/ps2'  
const INDEXER_SERVER = 'https://testnet-algorand.api.purestake.io/idx2'  
const TOKEN = { 'X-API-Key': 'YOUR PURESTAKE API KEY' }  
const PORT = '443';  


module.exports = {  
    ALGOD_SERVER,  
    INDEXER_SERVER,  
    TOKEN,  
    PORT,  
}
Enter fullscreen mode Exit fullscreen mode

5. MyAlgo Wallet

MyAlgo é uma carteira de Algorand que permite interagir livremente com a blockchain da Algorand.

A MyAlgo fornece a maneira mais simples e segura de enviar e receber Algos e tokens, organizar e rastrear todas as suas carteiras de Algorand, gerenciar seus ativos e muito mais.

Esta seção cuidará da conexão com a My Algo Wallet e da realização de transações usando o Reach. Para começar a usar a MyAlgo Wallet, você precisará criar uma conta na Algorand TestNet à qual você se conectará mais tarde nesse tutorial. Aqui está o link para obter essa configuração.

5.1 Conecte-se à MyAlgo Wallet 

Para se conectar à Carteira MyAlgo, seu código deve ficar assim. Este código cobre a conexão e recuperação do saldo da conta. Isso também inclui a interface do usuário da MyAlgo Wallet, que cuida do financiamento e transferência de fundos.

Nota

Aqui estão algumas coisas a serem observadas sobre o useRef e useState por que eles são usados neste tutorial. O hook useRef retorna um objeto que possui uma propriedade atual, e armazena o valor real, já o hook useState permite o desenvolvimento do estado do componente para componentes funcionais.

Para obter a conta de usuário usando Reach, esse método será chamado: reach.getDefaultAccount() e para obter o saldo da conta do usuário será chamado: reach.balanceOf() , isso conduzirá em um argumento a conta do usuário.

Fig 5 - 1 - 1 MyAlgo Wallet Connect

Fig 5 - 1 - 2 Conta e saldo da MyAlgo Wallet.

import React, {useState, useRef} from 'react'  
import { loadStdlib } from '@reach-sh/stdlib'  
import MyAlgoConnect from '@reach-sh/stdlib/ALGO_MyAlgoConnect';  
import ConnectWalletButton from './ConnectButton/ConnectWalletBtn';  
import TransferFund from './Transferfund';  
import FundAccount from './FundWallet';  
import myalgo from '../../assets/images/myaglo-logo.png'



import { MyAlgoWalletMain } from './MyAlgoWallet.styles';  

const reach = loadStdlib("ALGO")  

reach.setWalletFallback(reach.walletFallback({  
  providerEnv: 'TestNet', MyAlgoConnect }));  

const MyAlgoWallet = () => {  

    const account = useRef()  
    const balance = useRef()  


    const [accountBal, setAccountBal] = useState(0);  
    const [accountAddress, setAccountAddress] = useState('');  


    const connectWallet = async () =>{  
        try{  
            await getAccount()  
            await getBalance()  

        }catch(err){  
            console.log(err)  
        }  
    }  

    const getAccount = async () => {  
        try{  
          account.current = await reach.getDefaultAccount()  
            setAccountAddress(account.current.networkAccount.addr)  
            console.log("Account :" + account.current.networkAccount.addr)  
        }catch(err){  
            console.log(err)  
        }  
    }  

    const getBalance = async () => {  
        try{  
              let rawBalance = await reach.balanceOf(account.current)  
                balance.current = reach.formatCurrency(rawBalance, 4)  
                setAccountBal(balance.current)  
            console.log("Balance :" + balance.current)  
        }catch(err){  
            console.log(err)  
        }  

    }  

    return(  
        <MyAlgoWalletMain>  
            <img src= {myalgo} alt="My Algo" height= "70px"/>  
            <ConnectWalletButton accountAddress={accountAddress} connectWallet = {connectWallet} accountBal = {accountBal}/>  
            <TransferFund account = {account} getBalance = {getBalance} />  
            <FundAccount account = {account} getBalance = {getBalance}/>  
        </MyAlgoWalletMain>  
    )  
}  

export default MyAlgoWallet
Enter fullscreen mode Exit fullscreen mode

Nota

Ao usar o Reach, é importante especificar a rede à qual você deseja se conectar. Caso contrário, a conexão será padronizada pela Metamask, se você a tiver instalada.

No código acima, ao tentar se conectar à rede Algorand usando a MyAlgo Wallet, essas linhas são importantes.

import MyAlgoConnect from '@reach-sh/stdlib/ALGO_MyAlgoConnect';  
const reach = loadStdlib("ALGO")  

reach.setWalletFallback(reach.walletFallback({  
  providerEnv: 'TestNet', MyAlgoConnect })); 
Enter fullscreen mode Exit fullscreen mode

5.2 Transferir recursos

Isso lida com a transferência de fundos para a conta especificada. Para transferir fundos, essa função será chamada por reach.transfer() isso requer três argumentos: a conta, o destinatário e o valor.

EditorImages / 2021/11/18 02:32 / Screenshot_2021 - 11 - 18_at_03.30.14.png

Fig 5 - 2 - 1 Transferir Fundos com a MyAlgo Wallet.

EditorImages / 2021/11/18 02:33 / Screenshot_2021 - 11 - 18_at_03.30.50.png

Fig 5 - 2 - 2 UI da transferência de fundos

 

import React, {useRef, useState} from "react";  
import { loadStdlib } from '@reach-sh/stdlib'  
import { FormStyle } from "../Form.style";  
import { Button, TransactionButton } from "../Button.styles";  
import { BodyText } from "./MyAlgoWallet.styles";  

const reach = loadStdlib("ALGO")  

const TransferFund = ({account, getBalance}) => {  
    const transferAmount = useRef()  
    const receiverAddress = useRef()  
    const [isLoading, setLoading] = useState(false)  

    const transferFund = async () =>{  
        try{  
        setLoading(true)  
        const receiver = await reach.connectAccount({  
            addr: receiverAddress.current  
        })  
        console.log(receiver)  

        await reach.transfer(account.current, receiver, reach.parseCurrency(transferAmount.current))  
        await getBalance()



      setLoading(false)  
        }catch(err){  
            console.log(err)  
            setLoading(false)  
        }  


    }  

    return(  
        <div>  
            <br/>  
            <BodyText>Transfer Fund</BodyText>  
            <FormStyle onChange = {(e) => receiverAddress.current = e.target.value} placeholder="Receiver address" /><br/>  
            <FormStyle onChange = {(e) => transferAmount.current = e.target.value} placeholder="Amount" /><br/>



            <TransactionButton onClick ={transferFund}>{isLoading ? "loading...": "Transfer Fund"}</TransactionButton>  
        </div>  
    )  
}  

export default TransferFund
Enter fullscreen mode Exit fullscreen mode

5.3 Carteira de Fundos

Isso lida com o financiamento da conta da faucet Reach Dev. Ao usar a faceut do Dev para financiar a carteira, esse método será chamado reach.fundFromFaucet(),  isso leva dois argumentos: a conta e o valor.

Nota

O saldo da conta no dev faceut é limitado a carteira de fundos que você pode usar na Algorand TestNet Dispenser para financiar sua carteira.

EditorImages / 2021/11/18 03:14 / Screenshot_2021 - 11 - 12_at_23.28.15.png

Fig 5 - 3 - 1 Carteira de fundos

EditorImages / 2021/11/18 02:36 / Screenshot_2021 - 11 - 18_at_03.35.56.png

Fig 5 - 3 - 2 UI da carteira de fundos

import React, {useState} from "react";  
import { loadStdlib } from '@reach-sh/stdlib'  
import { FormStyle } from "../Form.style";  
import {  TransactionButton } from "../Button.styles";  
const reach = loadStdlib("ALGO")  

const FundAccount = ({account, getBalance}) =>{  
    const [isLoading, setLoading] = useState(false)  
    const [amount, setAmount] = useState("")  

    const fundAccount = async () =>{  
        try{  
            setLoading(true)  
            await reach.fundFromFaucet(account.current, reach.parseCurrency(+amount))  
            await getBalance()  
            setLoading(false)  
            setAmount("")  
        }catch(err){  
            setLoading(false)  
            console.log(err)  
        }  

    }  

    return(  
        <div>  
        <FormStyle onChange = {(e) => setAmount(e.target.value)} placeholder="Enter amount" />   
            <TransactionButton onClick ={fundAccount} > {isLoading ? "loading...": "Fund Account"}  
        </TransactionButton>  
        </div>  
    )  
}  

export default FundAccount

Enter fullscreen mode Exit fullscreen mode

6. Testando o projeto

No terminal , rode

REACH_CONNECTOR_MODE=ALGO ./reach/reach devnet isso definirá o modo de conectar com Algo.

Em seguida rode npm start em outro terminal para executar o aplicativo

7. Estilo da MyAlgo Wallet

Esta seção lida com o estilo de interface do usuário da página MyAlgo Wallet. Usando o styled component.

ConnectWalletBtn.js

import React from 'react'  
import { loadStdlib } from '@reach-sh/stdlib'  
import MyAlgoConnect from '@reach-sh/stdlib/ALGO_MyAlgoConnect';  
import ConnectButton from '.';  
import { BodyText } from '../MyAlgoWallet.styles';  
const reach = loadStdlib("ALGO")  
reach.setWalletFallback(reach.walletFallback({  
    providerEnv: 'TestNet', MyAlgoConnect }));  


const ConnectWalletButton = ({connectWallet,accountAddress, accountBal }) => {  

    return(  
        <div>  
            <ConnectButton connectWallet = {connectWallet}/>  
                <BodyText>Account Address: {accountAddress} </BodyText>  
                <BodyText>Account Balance: {accountBal}</BodyText>  
        </div>  
    )  
}  

export default ConnectWalletButton  
Enter fullscreen mode Exit fullscreen mode

MyAlgoWallet / ConnectButton / index.js

import { Button } from "../../Button.styles";  

const ConnectButton = ({connectWallet}) => {  
    return(  
        <Button onClick ={connectWallet}>  
          Connect MyAlgo Wallet  
        </Button>  
    )  
}  

export default ConnectButton
Enter fullscreen mode Exit fullscreen mode

MyAlgoWallet.styles.js

import styled from "styled-components";  

export const MyAlgoWalletMain = styled.div`  
    margin-top : 20px;  
`  

export const BodyText = styled.h5`  
    font-family : -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif  
`  
Enter fullscreen mode Exit fullscreen mode

Button.styles.js

import styled from "styled-components";  


export const Button = styled.button`  
    background-color : ${({backgroundColor}) => backgroundColor  ? '#E13E00' : '#245EC7' };  
    color: white;  
    padding : 16px;  
    border-radius: 10px;  
    border-color : transparent;  
    margin : 20px 0;  
    font-family : 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif  

`  

export const TransactionButton = styled.button`  
    background-color : #F8F9FF;  
    color: ${({backgroundColor}) => backgroundColor  ? '#E13E00' : '#245EC7' };  
    padding : 10px;  
    border-radius: 5px;  
    border-color : ${({backgroundColor}) => backgroundColor  ? '#E13E00' : '#245EC7' };  
    margin : 20px 10px;  
    font-family : 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif  
`

Enter fullscreen mode Exit fullscreen mode

Form.style.js

import styled from "styled-components";  

export const FormStyle = styled.input`  
    margin-bottom : 20px;  
    width : 200px;  
    padding : 10px;  
    border-radius : 5px;  
    border-color : #245EC7;  
`
Enter fullscreen mode Exit fullscreen mode

8. AlgoSigner

O AlgoSigner desempenha uma função semelhante à MyAlgo Wallet. A principal diferença é que o AlgoSigner possui uma extensão da Web como a Metamask para assinar transações na blockchain da Algorand.

O AlgoSigner injeta uma biblioteca JavaScript em todas as páginas da web visitadas pelo usuário do navegador, o que permite que o site interaja com a extensão. O dApp pode usar a biblioteca injetada para se conectar à carteira do usuário, descobrir os endereços que a conta possui, consultar o Network ( para fazer chamadas para AlgoD v2 ou Indexador ) e solicitar ao AlgoSigner que solicite ao usuário que assine uma transação iniciada pelo aplicativo. Todos os métodos da biblioteca injetada retornam uma Promise que precisa ser tratada pelo dApp.

Para começar a usar o AlgoSigner. Você precisará instalar a extensão do navegador chrome AlgoSigner, e configurar sua conta TestNet. Também vai precisar ir para a seção de configurações da extensão para configurar sua rede.

EditorImages / 2021/11/18 02:59 / Screenshot_2021 - 11 - 16_at_06.32.25.png

Fig 8 - 1 Configurações do AlgoSigner

8.1 Página principal do AlgoSigner

Nota

É importante incluir /global AlgoSigner/ no nível superior do seu projeto para permitir que você tenha acesso ao Algod SDK para evitar erros.

/*global AlgoSigner*/  
import React, {useRef} from "react";  
import ConnectAlgoSigner from "./ConnectAlgoSigner";  
import SignPayTransaction from "./SignPayTransaction";  
import algoSignerlogo from '../../assets/images/algosigner.jpeg'  
import { AlgoSignerMain } from "./AlgoSigner.styles";  
import CreateAsset from "./CreateAsset";  
import AssetOptin from "./AssetOptin"  

const AlgoSigner =  ()  =>{  
    const userAccount = useRef()  
    const receipient = useRef()  
    const amount = useRef()  


    return(  




        <AlgoSignerMain>  
            <img src= {algoSignerlogo} alt ="AlgoSigner Logo" height= "70px"/>  
            <ConnectAlgoSigner userAccount = {userAccount}/>            
            <SignPayTransaction userAccount = {userAccount} amount = {amount} receipient = {receipient} />  
            <CreateAsset userAccount = {userAccount} />  
            <AssetOptin userAccount = {userAccount} />  
        </AlgoSignerMain>  
    )  
}



export default AlgoSigner
Enter fullscreen mode Exit fullscreen mode

EditorImages / 2021/11/18 02:38 / Screenshot_2021 - 11 - 16_at_06.38.20.png

Fig 8 - 1 - 1 UI principal do AlgoSigner

EditorImages / 2021/11/18 02:39 / Screenshot_2021 - 11 - 16_at_06.38.30.png

Fig 8 - 1 - 2 UI principal do AlgoSigner

8.2 Conecte-se ao AlgoSigner

Isso lida com a conexão da extensão web AlgoSigner. Isso falhará se o AlgoSigner não estiver instalado.

O AlgoSigner.connect() é uma função necessária para conectar-se ao AlgoSigner e AlgoSigner.accounts({ledger: 'TestNet'})  é a função usada para obter a conta de usuário na TestNet.

/*global AlgoSigner*/  

import React from "react";  
import { Button } from "../Button.styles";  

const ConnectAlgoSigner = ({userAccount}) => {  

    const connectAlgoSigner = async () =>{  
        let resp = await AlgoSigner.connect()  
        console.log(resp)  
        getUserAccount()  
      }  

      const getUserAccount = async () =>{  
        userAccount.current =  await AlgoSigner.accounts({  
              ledger: 'TestNet'  
            })  
      // console.log(userAccount.current[0]['address'])  
      console.log(userAccount.current)  

      }  
      return(  
        <div>  
          <Button backgroundColor='blue' onClick={connectAlgoSigner}>  
          Connect Algo Signer  
          </Button>  
        </div>  

      )  
}  

export default ConnectAlgoSigner
Enter fullscreen mode Exit fullscreen mode

EditorImages / 2021/11/18 02:40 / Screenshot_2021 - 11 - 15_at_15.28.46.png

Fig 8 - 2 - 1 Conexão com a AlgoSigner

EditorImages / 2021/11/18 02:42 / Screenshot_2021 - 11 - 18_at_03.41.41.png

Fig 8 - 2 - 2 Acesso a carteira de subsídios

8.3 Assinatura de Transação de pagamento

Isso lida com a assinatura de transações de pagamento. Para lidar com o pagamento usando o algosdk, essa função será chamada algosdk.makePaymentTxnWithSuggestedParamsFromObject() isso requer alguns argumentos como o proprietário da conta,  o destinatário,e o amount - o montante a transferir, note  a descrição da transferência opcional e suggestedParams, isso é obtido após a instalação do cliente. Isso é obtido chamando essa função client.getTransactionParams().do().

Após efetuar o pagamento, a transação será assinada e enviada à rede.

/*global AlgoSigner*/  

import React,{useState, useRef} from "react";  
import { FormStyle } from "../Form.style";  
import { TransactionButton } from "../Button.styles";  
import { BodyText } from "../MyAlgoWallet/MyAlgoWallet.styles";  
import { TOKEN, ALGOD_SERVER, PORT } from "../../constants";  
const algosdk = require("algosdk");  

const SignPayTransaction = ({userAccount, amount, receipient}) => {  
    const [isLoading, setLoading] = useState(false)  

    const MICROALGOS_TO_ALGOS_RATIO = 1e6;  
    const INVALID_MICROALGOS_ERROR_MSG =  
    'Microalgos should be positive and less than 2^53 - 1.';  

    /**  
    * microalgosToAlgos converte microalgos em algos  
    * @param microalgos - number  
    * @returns number  
    */  
    const  microalgosToAlgos = (microalgos ) => {  
    if (microalgos < 0 || !Number.isSafeInteger(microalgos)) {  
        throw new Error(INVALID_MICROALGOS_ERROR_MSG);  
    }  
    return microalgos / MICROALGOS_TO_ALGOS_RATIO;  
    }



  /**  
    * algosToMicroalgos converte algos para microalgos  
    * @param algos - number  
    * @returns number  
    */  
    const algosToMicroalgos = (algos) => {  
    const microalgos = algos * MICROALGOS_TO_ALGOS_RATIO;  
    return Math.round(microalgos);  
    }  

    const signPayTransaction = async () =>{  
        // espera AlgoSigner.connect();  
        setLoading(true)  
        let client = new algosdk.Algodv2(TOKEN, ALGOD_SERVER, PORT)  

        //Query Algod para obter parâmetros sugeridos da testnet  
        let suggestedParams = await client.getTransactionParams().do()  

        try{  
            const txn = await new algosdk.makePaymentTxnWithSuggestedParamsFromObject({  
                from:  userAccount.current[0].address,  
                to: receipient.current,  
                amount:parseInt(amount.current),  
                // note: "document.getElementById('note').value",  
                suggestedParams: {...suggestedParams}  
              });  

            // Uso da biblioteca de codificação AlgoSigner para fazer as transações base64  
              let txn_b64 = AlgoSigner.encoding.msgpackToBase64(txn.toByte());  

            let signedTxs = await AlgoSigner.signTxn([{txn: txn_b64}])  

            // Obtendo a transação assinada codificada em base64 e convertendo-a em binário  
            let binarySignedTx = AlgoSigner.encoding.base64ToMsgpack(signedTxs[0].blob);  

            // Envio da transação por meio do cliente SDK  
            let id = await client.sendRawTransaction(binarySignedTx).do();  
                console.log(id)



                setLoading(false)  
        }catch(err){  
            console.log(err)  
            setLoading(false)  
        }   
    }  

    return(  
    <div>  
        <div>  
            <BodyText>Make Payment</BodyText>  
            <FormStyle onChange = {(e) => amount.current = e.target.value} placeholder="Amount" /><br/>  
            <FormStyle onChange = {(e) => receipient.current = e.target.value} placeholder="Receiver address" /><br/>  
            <TransactionButton backgroundColor onClick ={signPayTransaction}>{isLoading ? "loading...": "Sign Transaction"}</TransactionButton>  
        </div>  
    </div>  
    )  
}  

export default SignPayTransaction

Enter fullscreen mode Exit fullscreen mode

EditorImages / 2021/11/18 02:50 / Screenshot_2021 - 11 - 18_at_03.49.21.png

Fig 8 - 3 - 1 UI de pagamento

EditorImages / 2021/11/18 02:47 / Screenshot_2021 - 11 - 18_at_03.46.06.png

Fig 8 - 3 - 2 Assinatura de Transação de pagamento

Depois que a transação for assinada e enviada para a rede, você receberá o ID da transação

{txId: "5PHUOS7F6OAFGMFKOZIBURKWTH2CDYK6DGM7L44Q7QX6S7PZYQTA"}

EditorImages / 2021/11/18 03:17 / Screenshot_2021 - 11 - 18_at_04.17.14.png

Fig 8 - 3 - 2 Detalhe da transação do AlgoExplorer

8.4 Criar ativo padrão Algorand ( ASA )

O código abaixo é usado para criar um ativo do AlgoSigner. Para criar um ativo, essa função será chamada algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject() isso leva em alguns argumentos assetName - o nome do ativo, unitName - o nome da unidade total , que é a unidade total do ativo, decimals - os decimais, note e suggestedParams são como explicado no ponto 5.3.

Após a criação do ativo, a transação será assinada e enviada à rede.

/*global AlgoSigner*/  
import React, {useRef, useState} from "react";  
import { FormStyle } from "../Form.style";  
import { TransactionButton } from "../Button.styles";  
import { BodyText } from "../MyAlgoWallet/MyAlgoWallet.styles";  
import { TOKEN, ALGOD_SERVER, PORT, RECEIVER } from "../../constants";  
const algosdk = require("algosdk");  

const CreateAsset = ({userAccount}) => {  

    const assetName = useRef()  
    const unitName = useRef()  
    const totalUnit = useRef()  
    const note = useRef()  
    const decimals = useRef()  
    const [isLoading, setLoading] = useState(false)  

    const createAsset = async () =>{  
        // espera o AlgoSigner.connect();  
        setLoading(true)  
        let client =   new algosdk.Algodv2(TOKEN, ALGOD_SERVER, PORT)  

        //Query Algod to get testnet suggested params  
        let txParamsJS = await client.getTransactionParams().do()  

        try{  

            const txn = await new algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({

      from: userAccount.current[0].address,  
                assetName: assetName.current,  
                unitName: unitName.current,  
                total: +totalUnit.current,  
                decimals: +decimals.current,  
                note: AlgoSigner.encoding.stringToByteArray(note.current),  
                suggestedParams: {...txParamsJS}  
              });  

            const txn_b64 = await AlgoSigner.encoding.msgpackToBase64(txn.toByte());  

            let signedTxs  = await AlgoSigner.signTxn([{txn: txn_b64}])  
              console.log(signedTxs)  

              // Obtendo a transação assinada codificada em base64 e convertendo-a em binário  
            let binarySignedTx = await AlgoSigner.encoding.base64ToMsgpack(signedTxs[0].blob);  

            // Envio da transação por meio do cliente SDK            let id = await client.sendRawTransaction(binarySignedTx).do();  
                console.log(id)  
                setLoading(false)  

        }catch(err){  
            console.log(err)  
            setLoading(false)  
        }  
    }  

    return(  
    <div>  
        <div>  
            <BodyText>Create Asset</BodyText>  
            <FormStyle onChange = {(e) => assetName.current = e.target.value} placeholder="Asset name" /><br/>  
            <FormStyle onChange = {(e) => unitName.current = e.target.value} placeholder="Unit name" /><br/>  
            <FormStyle onChange = {(e) => totalUnit.current = e.target.value} placeholder="Total units" /><br/>

      <FormStyle onChange = {(e) => decimals.current = e.target.value} placeholder="Decimals" /><br/>  
            <FormStyle onChange = {(e) => note.current = e.target.value} placeholder="Enter note" /><br/>  
            <TransactionButton backgroundColor onClick ={createAsset}>{isLoading ? "loading...": "Sign Create Asset"}</TransactionButton>  
        </div>  
    </div>  
    )  
}  

export default CreateAsset
Enter fullscreen mode Exit fullscreen mode

EditorImages / 2021/11/18 02:54 / Screenshot_2021 - 11 - 18_at_03.53.57.png

Fig 8 - 4 - 1 Criação da interface do usuário do ativo

EditorImages / 2021/11/18 02:54 / Screenshot_2021 - 11 - 18_at_03.53.20.png

Fig 8 - 4 - 2 Assinatura do ativo

Depois que a transação for assinada. Ela retornará o ID da transação para verificar os detalhes da transação no algoexplorer.io.

{txId: "BZSBJ2A2RAV22SNLQVR25BECX4GX3CTDIAJKJX73PU7DUHQ3SIZQ"}

8.5 Optar por um ativo

Essa função permite que um usuário opte por um ativo. Somente o usuário / endereço optin pode receber um ativo.

Para optar por um ativo, essa função será chamada algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject() isso requer alguns argumentos como from - o criador da conta, to -o destinatário, assetIndex - o número do índice gerado quando o ativo foi criado, note, amount e suggestedParams que são como explicado no ponto 5.3.

Após a opção, a transação será assinada e enviada para a rede.

/*global AlgoSigner*/  
import React, { useRef, useState } from "react";  
import { FormStyle } from "../Form.style";  
import { TransactionButton } from "../Button.styles";  
import { BodyText } from "../MyAlgoWallet/MyAlgoWallet.styles";  
import { TOKEN, ALGOD_SERVER, PORT } from "../../constants";  
const algosdk = require("algosdk");  

const CreateAsset = ({userAccount}) => {  
    const receiver = useRef()  
    const assetIndex = useRef()  
    const note = useRef()  
    const [isLoading, setLoading] = useState(false)  


    const optInToAnAsset = async () =>{  
        setLoading(true)  
        let client =   new algosdk.Algodv2(TOKEN, ALGOD_SERVER, PORT)  

        //Consulta do Algod para obter os parâmetros sugeridos da testnet  
        let txParamsJS = await client.getTransactionParams().do()  
      try{  
          const txn = await new algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({  
              from: userAccount.current[0].address,  
              to: receiver.current,  
              assetIndex: +assetIndex.current,  
              note: AlgoSigner.encoding.stringToByteArray(note.current),  
              amount: 0,  
              suggestedParams: {...txParamsJS}  
            });  

            // Uso da biblioteca de codificação AlgoSigner para fazer as transações base64  
            const txn_b64 = AlgoSigner.encoding.msgpackToBase64(txn.toByte());  

          const signedTxs = await AlgoSigner.signTxn([{txn: txn_b64}])  
            console.log(signedTxs)  

            // Obtendo a transação assinada codificada em base64 e convertendo-a em binário  
            let binarySignedTx = await AlgoSigner.encoding.base64ToMsgpack(signedTxs[0].blob);  

            // Envio da transação por meio do cliente SDK  
          let id = await client.sendRawTransaction(binarySignedTx).do();  
              console.log(id)  
              setLoading(false)  
      }catch(err){  
          console.log(err)  
          setLoading(false)  
      }  
  }  

    return(  
    <div>  
        <div>  
            <BodyText>Asset Optin</BodyText>  
            <FormStyle onChange = {(e) => receiver.current = e.target.value} placeholder="Receiver address" /><br/>  
            <FormStyle onChange = {(e) => assetIndex.current = e.target.value} placeholder="Asset index" /><br/>  
            <FormStyle onChange = {(e) => note.current = e.target.value} placeholder="Note" /><br/>  
            <TransactionButton backgroundColor onClick ={optInToAnAsset}>{isLoading ? "loading...": "Sign Asset Optin"}</TransactionButton>  
        </div>  
    </div>  
    )  
}  

export default CreateAsset
Enter fullscreen mode Exit fullscreen mode

EditorImages / 2021/11/18 03:06 / Screenshot_2021 - 11 - 18_at_04.02.51.png

Fig 8 - 5 - 1 Detalhes do ativo AlgoSigner

EditorImages / 2021/11/18 03:05 / Screenshot_2021 - 11 - 18_at_04.03.02.png

Fig 8 - 5 - 2 interface do ativo

EditorImages / 2021/11/18 03:05 / Screenshot_2021 - 11 - 18_at_04.03.24.png

Fig 8 - 5 - 3 Transação de sinalização

ID da transação optin do ativo {txId: "4AV3LRS743XBN4SSJG6M2MMSHXLZKLRUKKGYXBSGNW25MCSWESNA"}

9. Estilos de interface do usuário AlgoSigner

Isso lida com o estilo de interface do usuário do AlgoSigner usando o styled-components 

AlgoSigner.styles.js

import styled from "styled-components";

export const AlgoSignerMain = styled.div
    margin-top : 20px;
    @media(max-width : 767px) {
        width : 90%;
        margin : 36px auto;
    }

10. Próximo passo

  • Áreas não cobertas neste tutorial, como outros recursos do ASA que podem ser feitos com o AlgoSigner, incluindo transferência atômica e criação de contas multisig. Serão trabalhados em um futuro tutorial.

  • Também haverá uma análise mais profunda do Reach para criar exemplos de contratos inteligentes usando reach tanto no back-end quanto no front-end.

11. Estudo adicional

Aviso

Este tutorial destina-se apenas a fins de aprendizado. Não cobre verificação de erros e outros casos. Portanto, não deve ser usado para criação de uma  aplicação de produção.


Este artigo foi escrito por Glory Agatevure e traduzido por Adriano P. de Araujo. O original  em inglês pode ser encontrado aqui.

Latest comments (0)