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.
Requisitos
Vs Code ou qualquer IDE de sua escolha
Create React App. Isso cria um boilerplate de React
The Reach JS stdlib, cujas informações de instalação estão incluídas abaixo no Conjunto de Projetos - Up. O Reach stdlib fornece uma interface front-end para conexão de carteiras e implantação / anexação a contratos inteligentes Reach.
Executável Reach. O executável Reach depende de make, Docker, e Docker Composer. A melhor maneira de instalar o Docker no Mac e Windows é com Área de trabalho do Docker.
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
Instalação do projeto e instalação do React
Instalação do Reach
Estrutura do projeto
Página principal e estilo
MyAlgo Wallet
Testando o projeto
Estilo da MyAlgo Wallet
AlgoSigner
Estilos de interface do usuário AlgoSigner
Próximo passo
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
Para executar o servidor de desenvolvimento React com a Algorand, você pode chamar:
./reach reactDE=ALGO ./reach react
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
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
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]
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;
index.js
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
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
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;
}
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,
}
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
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 }));
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.
Fig 5 - 2 - 1 Transferir Fundos com a MyAlgo Wallet.
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
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.
Fig 5 - 3 - 1 Carteira de fundos
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
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
MyAlgoWallet / ConnectButton / index.js
import { Button } from "../../Button.styles";
const ConnectButton = ({connectWallet}) => {
return(
<Button onClick ={connectWallet}>
Connect MyAlgo Wallet
</Button>
)
}
export default ConnectButton
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
`
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
`
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;
`
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.
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
Fig 8 - 1 - 1 UI principal do AlgoSigner
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
Fig 8 - 2 - 1 Conexão com a AlgoSigner
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
Fig 8 - 3 - 1 UI de pagamento
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"}
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
Fig 8 - 4 - 1 Criação da interface do usuário do ativo
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
Fig 8 - 5 - 1 Detalhes do ativo AlgoSigner
Fig 8 - 5 - 2 interface do ativo
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
https://purestake.github.io/algosigner-dapp-example/index.html
https://github.com/PureStake/algosigner/blob/develop/docs/dApp-integration.md
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)