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

Alex Yevseyevich
May 11, 2019 · 4 min read
Image for post
Image for post
Image by Stefan Keller from Pixabay

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.

Image for post
Image for post

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.

Image for post
Image for post

Thanks for reading; please stay tuned for other articles for this blog series.

Better Programming

Advice for programmers.

Sign up for The Best of Better Programming

By Better Programming

A weekly newsletter sent every Friday with the best articles we published that week. Code tutorials, advice, career opportunities, and more! Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Alex Yevseyevich

Written by

Enjoy studying modern web and blockchain smart contract technologies. The current focus of interest: Angular, NgRx, Ethereum DApps

Better Programming

Advice for programmers.

Alex Yevseyevich

Written by

Enjoy studying modern web and blockchain smart contract technologies. The current focus of interest: Angular, NgRx, Ethereum DApps

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store