avatarGrandSchtroumpf

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

2272

Abstract

ere is to extends the <code>Signer</code> so we can display something to the user when we send a transaction. The <code>Signer</code> is an abstract class that requires three methods to be implemented :</p><ul><li><code>getAddress</code> : Return the address of the current account.</li><li><code>signMessage</code> : Sign a message or transaction.</li><li><code>sendTransaction</code> : Send a transaction to the network.</li></ul><p id="8689">We’ll need to login with a private key. To make it easier, let’s assume that the <a href="https://docs.ethers.io/ethers.js/html/api-wallet.html#encrypted-json-wallets">Encrypted JSON</a> is in the <code>localstorage.</code></p> <figure id="3fba"> <div> <div>

            <iframe class="gist-iframe" src="/gist/GrandSchtroumpf/50036b68960cce9544d7a798f9c9c4fe.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><blockquote id="4765"><p>For now we’ll use the <code>Wallet</code> class because <code>ethers</code> doesn’t expose all the needed methods to create a custom wallet on Angular (see <a href="https://github.com/ethers-io/ethers.js/issues/479">#issue479</a>). But it should be possible with version 5.</p></blockquote><h1 id="1290">Contract</h1><p id="df2d">Now that we have our Injectable Signer we can build injectable contract ! For that we only need to extends the <code>Contract</code> class :</p>
    <figure id="c5fe">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/GrandSchtroumpf/8c2e36ab38694a43df7ab440ac4911bf.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><blockquote id="a631"><p>I use the example of the <a href="https://docs.ethers.io/ethers.js/html/api-contract.html">ethers documentation</a>.</p></blockquote><p id="a515">Here I store ENS name - or the address - of the contract in the environment. In the case of addresses this gives me fine grained control depending on the network.</p><p id="7f25">Now we can import the contract from any component

Options

:</p> <figure id="6ff6"> <div> <div>

            <iframe class="gist-iframe" src="/gist/GrandSchtroumpf/a8d12c4fbed5f3f63c555ad80cef6bd8.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h2 id="bd5b">Limitations</h2><p id="56cf">In this case we suppose that you know the address of the contract <i>a priori</i>. If you need the input of the user to know the address (e.g. ERC1077), you cannot use this method.</p><h1 id="c9e5">[Bonus] Web3 Provider</h1><p id="13f1">Let’s try use the Web3Provider instead of the <code>BaseProvider</code> :</p>
    <figure id="2987">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/GrandSchtroumpf/696cef021956469a1a45bad338d8dcf6.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="ae6e">First we create an <code>InjectionToken</code> around the web3 provider. Then we inject it inside our constructor. Note that in this case we extends the class <code>Web3Provider.</code></p><p id="8a89">But this is not enough, MetaMask requires that you <code>enable()</code> the provider before using it. The esaiest way to manage that is to provide the <code>APP_INITIALIZER</code> in the <code>AppModule</code> :</p>
    <figure id="6725">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/GrandSchtroumpf/16abdceaea50439b4f461877e419d5d0.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="956f">But this would open a new MetaMask window at load time. Which is poor User Experience…</p><p id="3299">Another solution would be to add a <code>enable()</code> method on the Injectable Provider. But this might leads to poor/hard error handling.</p><p id="4cc4">If you have an elegant way of managing this <code>enable()</code> method in Angular please leave a comment, I’d love to read it 😃.</p></article></body>

Ethers and Angular

Ethereum with Dependancy Injection

ethers.js is by far the best javascript library to interact with an Ethereum network. Let’s see how we can use it the right way with Angular.

Before all …

⚠️ : Don’t use deep import from ethers with Angular or it would try to use node modules, and you’ll get errors : - ⛔️: import { BaseProvider } from 'ethers/providers' -✅ : import { providers } from 'ethers' // providers.BaseProvider

Provider

First we need to create an Injectable Provider. For that there is two methods :

  • Create an InjectionToken.
  • Extends the BaseProvider.

The Provider requires a network name. In this case we’ll keep it in the environment. Like that we can use different networks if we are in test (goerli), staging (ropsten) or production (mainnet).

Example with the InjectionToken :

Example by extending the BaseProvider :

The InjectionToken is simplest, but somethings you’ll need to extends a Provider from ethers.

Signer

Now that we have a provider we need to make our Signer injectable too.

The idea here is to extends the Signer so we can display something to the user when we send a transaction. The Signer is an abstract class that requires three methods to be implemented :

  • getAddress : Return the address of the current account.
  • signMessage : Sign a message or transaction.
  • sendTransaction : Send a transaction to the network.

We’ll need to login with a private key. To make it easier, let’s assume that the Encrypted JSON is in the localstorage.

For now we’ll use the Wallet class because ethers doesn’t expose all the needed methods to create a custom wallet on Angular (see #issue479). But it should be possible with version 5.

Contract

Now that we have our Injectable Signer we can build injectable contract ! For that we only need to extends the Contract class :

I use the example of the ethers documentation.

Here I store ENS name - or the address - of the contract in the environment. In the case of addresses this gives me fine grained control depending on the network.

Now we can import the contract from any component :

Limitations

In this case we suppose that you know the address of the contract a priori. If you need the input of the user to know the address (e.g. ERC1077), you cannot use this method.

[Bonus] Web3 Provider

Let’s try use the Web3Provider instead of the BaseProvider :

First we create an InjectionToken around the web3 provider. Then we inject it inside our constructor. Note that in this case we extends the class Web3Provider.

But this is not enough, MetaMask requires that you enable() the provider before using it. The esaiest way to manage that is to provide the APP_INITIALIZER in the AppModule :

But this would open a new MetaMask window at load time. Which is poor User Experience…

Another solution would be to add a enable() method on the Injectable Provider. But this might leads to poor/hard error handling.

If you have an elegant way of managing this enable() method in Angular please leave a comment, I’d love to read it 😃.

Ethereum
Angular
Blockchain
Dependency Injection
Recommended from ReadMedium