Construisons notre propre dApp
Ne serait-il pas cool de créer votre propre dApp qui vous permette d’échanger toutes sortes de jetons sans avoir à écrire une seule ligne de code Solidity ? Eh bien, avec le SDK Uniswap, vous pouvez utiliser les contrats intelligents d’Uniswap pour échanger tout un tas de jetons ERC20 avec votre propre interface personnalisée.
Dans ce didacticiel, nous allons créer une dApp React qui vous permet d’échanger ETH contre UNI.
Le didacticiel se concentre sur la logique réelle et sur la manière de s’y connecter à partir de l’interface utilisateur avec l’agent utilisateur CSS par défaut. Il ne contient aucun style personnalisé. Cependant, j’ai également créé une version stylée du dApp.
Si vous êtes intéressé par la façon dont cela a été fait, rendez-vous au bas de la page où j’ai lié le référentiel et le site Web réel.
Afin de suivre le tutoriel connaissance de base de npm, React, ethers.js et wagmi.sh
est nécessaire.
Tout d’abord, nous devons créer notre React dApp. Nous utiliserons TypeScript pour ce projet. Alors ouvrez votre terminal et écrivez :
npx create-react-app uniswap-dapp --template typescript
Ensuite, changez le répertoire pour celui que vous venez de créer et installez les dépendances :
cd uniswap-dapp
npm install ethers wagmi @uniswap/v3-sdk @uniswap/sdk-core
Démarrez maintenant le serveur de développement.
npm start
Votre navigateur Web par défaut devrait s’ouvrir et afficher le tristement célèbre écran React.
Ensuite, ouvrez le projet nouvellement créé dans votre éditeur de code préféré. Pour commencer avec une configuration propre, supprimez tout le code passe-partout. Supprimer tout des fichiers index.css
et App.css
. Supprimer le logo.svg
fichier et supprimer la plupart des choses à l’intérieur du App.tsx
fichier donc il ressemble à ceci:
Maintenant, nous pouvons commencer !
Nous allons utiliser la bibliothèque wagmi.sh
pour une connexion facile du portefeuille à MetaMask. Si vous savez déjà comment configurer une connexion de portefeuille avec MetaMask et wagmi.sh
n’hésitez pas à sauter cette section.
Afin de connecter notre application à un nœud Ethereum et de pouvoir accéder aux informations liées à la blockchain depuis n’importe où dans notre application, nous devons envelopper notre application entière avec le WagmiConfig
fournisseur et transmettre ses options de configuration. Dirigez-vous vers App.tsx
et changez le fichier comme ceci:
Pour cette démonstration, nous utiliserons le testnet Goerli. Nous utilisons également un fournisseur public car nous n’avons pas à envoyer beaucoup de transactions. Si votre dApp dépasse les limites de débit du fournisseur public, vous devez utiliser des services comme Alchemy ou Infura à la place.
Avec cela, nous sommes connectés avec succès à un nœud Ethereum et pouvons déjà lire les données de la blockchain. Cependant, pour effectuer des transactions et modifier l’état de la blockchain, nous devons connecter notre dApp à un portefeuille.
Nous allons implémenter notre bouton de connexion de portefeuille et notre logique dans l’en-tête de la dApp. Créer un nouveau Header
composant à l’intérieur d’un nouveau répertoire appelé components
avec le contenu suivant :
La InjectedConnector
fait référence à l’extension MetaMask et nous nous assurons que MetaMask utilise Goerli comme chaîne en passant le chainId
propriété avec sa valeur définie sur l’identifiant de Goerli. Nous devrions maintenant pouvoir connecter notre portefeuille MetaMask à la dApp avec ce beau bouton qui est apparu sur la page :
Après une connexion réussie, le bouton se transforme en adresse du portefeuille actuellement connecté.
Maintenant que la connexion au portefeuille a été prise en charge, nous pouvons nous concentrer sur le sujet même de cet article : Comment utiliser Uniswap pour échanger des jetons depuis votre propre interface personnalisée. Nous allons commencer par créer un nouveau crochet personnalisé appelé useSwap
dans un nouveau répertoire appelé hooks
.
Afin de récupérer les prix des jetons, nous devons interagir avec le contrat d’un pool qui inclut cette paire de jetons. Comme dit au début, nous allons interagir avec le pool ETH-UNI. En interne, ETH est traité comme Ether enveloppé ou WETH en bref car Uniswap ne peut gérer que les jetons ERC20 et ETH lui-même n’est pas un jeton mais une monnaie. Donc la piscine que nous recherchons est en fait une piscine WETH-UNI. J’expliquerai cela plus en détail plus tard. Pour l’instant, nous allons obtenir une référence au contrat de piscine comme suit :
Étant donné que nous ne lirons que ce contrat et n’effectuerons aucune transaction, il suffit d’utiliser un fournisseur plutôt qu’un signataire (un fournisseur auquel un portefeuille est connecté).
Ensuite, nous créons deux interfaces Immutables
et State
modéliser les données de pool en chaîne dont nous avons besoin.
Nous créons deux fonctions getPoolImmutables
et getPoolState
qui effectuent la récupération des données réelles et renvoient les données correspondant à leur interface respective.
Avec cela, nous avons déjà toutes les données blockchain dont nous avons besoin pour faire un devis.
Nous ajoutons deux autres constantes en haut du fichier.
Et maintenant, nous pouvons mettre en œuvre le getQuote
fonction qui renvoie la quantité d’UNI que nous obtenons pour une quantité spécifique d’ETH.
La fonction appelle les deux autres fonctions que nous avons définies précédemment afin d’obtenir les données actuelles de la blockchain. Ce qui est intéressant à noter ici, c’est que le token0
du pool est UNI et le token1 du pool est WETH. Après cela, Uniswap Token
et Pool
les classes sont instanciées avec les données renvoyées. Enfin, nous obtenons le devis en multipliant le montant d’ETH par le prix d’UNI par rapport à ETH.
Assembler toutes les pièces et remettre le getQuote
fonction du composant, votre fichier devrait maintenant ressembler à ceci :
Nous pouvons maintenant commencer à construire l’interface utilisateur qui appelle la fonction et se met à jour en fonction de la citation renvoyée. Créer un nouveau composant nommé SwapCard
avec le contenu suivant :
Maintenant, si vous tapez un nombre dans le champ de saisie pour ETH, la quantité attendue d’UNI que vous obtiendriez si vous deviez exécuter le swap s’affiche dans le deuxième champ de saisie. Votre site Web devrait maintenant ressembler à ceci :
Maintenant, avant de pouvoir demander au routeur Uniswap v3 d’échanger notre ETH contre UNI, nous devons convertir notre ETH en WETH et autoriser le contrat de routeur à utiliser WETH en notre nom. Comme je l’ai mentionné plus tôt, il n’y a en fait aucun pool qui inclut directement l’ETH. Uniswap fonctionne uniquement avec les jetons ERC20, c’est pourquoi nous devons convertir notre ETH en jeton ERC20 qui représente ETH c’est-à-dire WETH.
Nous commençons donc par créer un nouveau fichier appelé useWETH.tsx
qui est un crochet React personnalisé, tout comme useSwap
.
Ensuite, nous voulons créer l’instance de contrat du jeton WETH. Pour cela, nous avons besoin du jeton ABI. Créez un nouveau répertoire appelé abis
et un nouveau fichier appelé WETH.json
dans le répertoire avec ce contenu :
Vous pouvez également copier l’ABI directement depuis Étherscan.
Nous sommes maintenant prêts à instancier le contrat comme ceci :
Nous ajoutons une constante supplémentaire en haut qui représente le nombre de décimales du jeton WETH.
Ensuite, nous créons une fonction appelée deposit
qui analyse le montant d’entrée et appelle la fonction de dépôt sur le contrat WETH. À l’aide de cette fonction, nous convertissons notre ETH natif en jetons WETH que nous pouvons ensuite utiliser pour l’échange de jetons.
Il ne nous reste plus qu’à créer une fonction supplémentaire et nous avons tous les prérequis pour pouvoir exécuter un swap. Créer le approve
fonction. Pour que le contrat de routeur Uniswap puisse accéder à notre WETH, il doit avoir l’autorisation de le faire.
Au sein de notre approve
nous appelons la fonction d’approbation du contrat WETH et définissons le nombre de jetons auxquels le routeur peut accéder.
Nous sommes maintenant prêts à écrire la logique du swap.
Dirigez-vous vers le useSwap.tsx
fichier et ajoutez cette importation :
Maintenant, ajoutez cette constante en haut du fichier :
Et le suivant sous le déjà existant useProvider
accrocher:
Parce que nous allons changer l’état de la blockchain, nous avons besoin d’un signataire plutôt que d’un fournisseur pour le contrat de routeur. De plus, nous importons les fonctions que nous avons écrites dans le useWETH
accrocher.
Maintenant, créez enfin le swap
fonction qui exécute le swap.
Cette fonction accepte le montant en ETH qui doit être échangé comme argument. Il convertit ensuite ETH en WETH avec le deposit
fonction que nous avons définie précédemment et approuve le routeur Uniswap v3 pour accéder exactement à ce montant en WETH à l’aide du approve
fonction.
Il obtient ensuite les données de pool nécessaires (adresses de jeton, frais) avec le getPoolImmutables
fonction et construit un objet params qui sera passé en argument à la transaction.
Enfin, nous appelons le exactInputSingle
fonction sur le contrat de routeur Uniswap qui exécute le swap. Une limite de gaz personnalisée doit être définie car MetaMask ne peut pas estimer les frais de gaz sur cette transaction.
Vous pouvez maintenant ajouter la fonction swap à l’instruction return et votre fichier devrait ressembler à ceci :
Dirigez-vous maintenant vers le SwapCard.tsx
composant, ajoutez la logique pour enregistrer la valeur de l’entrée dans l’état et ajoutez un bouton qui initie l’échange avec ledit montant. Votre fichier devrait maintenant ressembler à ceci :
De plus, j’ai ajouté le comportement selon lequel le bouton d’échange n’est activé que si un portefeuille est connecté.
Rendez-vous maintenant sur localhost:3000 pour le tester car tout devrait fonctionner maintenant. Assurez-vous simplement que vous avez suffisamment d’ETH sur le réseau Goerli.
Si vous avez besoin de plus de tests ETH, rendez-vous chez Goerli robinet comme celui d’Alchemy. De plus, gardez à l’esprit que l’extraction des 3 transactions peut prendre un certain temps et que nous n’avons aucun retour d’utilisateur sur l’état actuel de la transaction pour le moment.
Pour voir directement combien d’ETH vous pouvez échanger et obtenir une sorte de retour sur le résultat de l’échange, il serait bien d’afficher le solde actuel. Heureusement, avec wagmi.sh, il est incroyablement facile de le faire.
Ajoutez cette constante en haut de la SwapCard.tsx
dossier:
Ensuite, ajoutez ceci sous le useAccount
accrocher:
La watch
propriété s’assure que notre solde est toujours à jour en vérifiant si le solde a changé après chaque nouveau bloc. Maintenant, last but not least, nous ajoutons une petite note dans le modèle pour les deux jetons comme celui-ci pour ETH :
Maintenant, en mettant toutes les choses ensemble, votre fichier devrait ressembler un peu à ceci :
Notre dApp sans style devrait maintenant ressembler à ceci :
Si vous essayez d’échanger des jetons maintenant, vous verrez qu’après un échange réussi, le solde des deux jetons change en conséquence.