Ethereum DApp With Ethers.js and IPFS Using Angular, Angular Material and NgRx. Part II

In the second part of this blog series, we will continue building the NgRx powered DApp for the FleaMarket Smart Contract.
In part I, we started implementing the root state and introduced the Ethers.js Web3 provider to interact with the Ethereum blockchain.
In this section, we will continue extending the global state and we’ll focus on the process of setting up the communication with the IPFS on Infura using Angular NgRx. We will take advantage of the IPFS network to upload and store image files that are used to advertise our merchandise in the virtual flea market booth DApp we build.
Extending Functionality of the Web3 Provider State
Let’s look at how we can leverage the use of the NgRx store, to display the user account and the current balance information. The balance and account properties are defined in the web3Provider
state, which is a part of the global state tree.
We’re also taking advantage of new creator functions recently introduced in the NgRx v8 to construct actions, reducers, and effects.
After we’ve successfully set up the connection with the Ethereum blockchain, we dispatch the '[Web3/Provider] Init Success’
action. In the Web3ProviderEffects
class, we define two effects that are listening out for this action:
In the Web3ProviderEffects
constructor, we also inject the ProviderService
, which allows us to retrieve the address and balance of the current account by invoking the corresponding API from Ethers.js library:
Upon receiving the '[Web3/Provider] Init Success'
notification, both effects will trigger the call to the service to retrieve a corresponding value from the blockchain wrapped in the Promise
.
We then convert it to an observable using the RxJS from
operator, and flatten it using the map
operator, to create and dispatch the balanceSuccess
and account
actions back to the store.
In the component Nav
, we use the selector and the async pipe functions, so we can retrieve the account and balance properties of the global state.
this.account$ = this.store.pipe(select(fromRoot.getAccount));
this.balance$ = this.store.pipe(select(fromRoot.getBalance));
Essentially, once the user confirms the connection to the blockchain, the selectors will emit the current account and balance state values, which then get observed and displayed on the toolbar.

Manage the IPFS Daemon on Infura With Angular NgRx
The Safe Remote Purchase smart contract defines a state variable ipfsHash
that stores the product image file’s IPFS hash value.
The important advantage of using IPFS is that it is assured that both file, and its corresponding hash code that is stored on the IPFS network, are immutable. Which means that it is impossible to change an image file without changing its hash.
We use Infura to access the IPFS. To be able to communicate with a remote IPFS node hosted on the Infura network we need to install the IPFS HTTP client library ipfs-http-client.
This requires creating a custom webpack configuration file webpack.config.js
to tell angular to include in compilation the cryptographic node
modules.
Start by installing the custom Webpack builder:
npm install -save-dev @angular-builders/custom-webpack
Then, we add an extra-webpack.config.js
file to the project with the following context:
Finally, modify the angular.js
file to include the custom builders:
Next let’s setup the connection to the IPFS node that runs on Infura. Create a new InjectionToken
with the factory function that instantiates the IpfsHttpClient
object.
The ipfsToken
token is getting passed to the IpfsDaemonService
service class. We declare a method to validate the connection to an IPFS node by retrieving its version
object.
We also need to inject the service in the Effect
class.
In the onConnectEffect
effect, we use the ROOT_EFFECTS_INIT
lifecycle hook, which is triggered after all the root effects have been added.
Upon successful verification that the IPFS node is ready, we dispatch the [IPFS/Daemon] Connect Success
action and update the global state property connectStatus
to true
:
export interface IpfsDaemonState {
connectStatus: boolean;
}
This change will be automatically picked up by the corresponding selector from the store reducer, and the async pipe from the Nav
component will update the IPFS Infura connection status on the toolbar.

Thanks for reading; please stay tuned for other articles for this blog series.
References:
- Architecture Ethereum DApp with Angular, Angular Material and NgRx, (Available at http://www.amazon.co.uk/kindlestore 5 March 2020) by Alex Yevseyevich