Building an Address-Converter Page for your Polkadot JS Accounts

In this tutorial we’ll build a simple component to convert PolkadotJS addresses from one network’s format to another’s. This is the same functionality you already have in the Polkadot JS extension’s settings, but replicated outside it.

Before we begin, you’ll need to start up Polkadash on your computer here.

Prequisites

Background

In this tutorial, we will be grabbing our Polkadot/Kusama accounts from the Polkadot{js} extension. This will allow us to convert our addresses to different prefixes, such as Edgeware, Substrate, Acala, and others.

The address converter will look something like this:

Screenshot of finished component

In the sidebar, we are able to access the converter from the label ‘Accounts’ where it will pull all your accounts and their associated addresses. The dropdown option will let you select which network you want to convert your account address to, and the data will appear underneath.

Adding Packages

To be able to grab our accounts from the Polkadot{js} extension, we first need to install its package.

yarn add @polkadot/extension-dapp

We also want to install the util crypto package. This will allow us to call certain functions like decodeAddress and encodeAddress, which is useful for the filter component. If you haven’t already installed it from the Address Translation filter tutorial, here is the command:

yarn add @polkadot/util-crypto

Modifying our Filter

Starting with our original filter component from the Address Translation filter tutorial, we want to modify it to support our address converter. We will begin by exporting the prefixes inside /components/Filter/Filter.js:

//NEW: We want to export prefixes 
export const prefixes = {
    polkadot: 0,
    kusama: 2,
    plasm: 5,
    bifrost: 6,
    edgeware: 7,
    karura: 8,
    reynolds: 9,
    acala: 10,
    laminar: 11,
    kulupu: 16,
    darwinia: 18,
    stafi: 20,
    robonomics: 32,
    centrifuge: 36,
    substrate: 42,
};

By including the export keyword, this allows for the object to be accessed by other files using the import statement.

Creating the Address Converter

Now it’s time to create a new page in src/pages. We will call it Accounts.vue and this is where the logic for the converter and the rendered component will be stored.

First, we will add a basic template for our component. You may notice there isn’t much in here yet, we want to add in the logic as we go on.

<template>
  <div class="content">
    <card>
      <template slot="header">
        <h5 class="title">Accounts</h5>
        <p class="category">A component to interact with your accounts</p>
      </template>
      <div class="row">
        <div class="col-lg-12 col-md-3 col-sm-4 col-xs-6 col-xs-6 text-left">
          <card>
          <!-- This is where the address converter data will be displayed -->
          </card>
        </div>
      </div>
    </card>
  </div>
</template>
<script>
import { Card } from "@/components/index";
import { web3Accounts } from "@polkadot/extension-dapp";
import { prefixes } from "../components/Filters/prefix.js";
const dappex = require("@polkadot/extension-dapp");

export default {
  components: {
  },
  data() {
    return {
    };
  },
  methods: {
  },
  created() {
  }
};
</script>

Notice here that we’ve imported a few things into our file:

import { Card } from "@/components/index";
import { web3Accounts } from "@polkadot/extension-dapp";
import { prefixes } from "../components/Filters/Filter.js";
const dappex = require("@polkadot/extension-dapp");

When we import the web3Accounts from the extension-dapp package, this will allow us to connect to our Accounts on the Polkadot{js} extension. We’ve also added in a dappex constant, which will let us access extension-dapp’s features.

If we also remember the export keyword we added to the prefix object in Filter.js, we are now just pulling that in with the import statement.

Let’s add in this new page to the sidebar so that it’s accessible. This is done by modifying two files. In src\pages\Layout\DashboardLayout.vue, add a new <sidebar-link> component instance under the existing ones, like so:

<sidebar-link to="/accounts">
    <i class="tim-icons icon-book-bookmark"></i>
    <p>Accounts</p>
</sidebar-link>

Now we need to modify the src/router.js because this will give the VueJS router a new route for the Accounts page.

{
    path: "accounts",
    name: "Accounts",
    component: () => import("@/pages/Accounts.vue"),
},

Perfect, now we have the basics to begin building our logic for the address converter.

Let’s begin.

Crafting the Logic

First, let’s add in some more code into Accounts.vue. We’ve added in some variables and objects (addresses, onlyChain, and prefixes) and linked our imported components from the import statements (Card and web3Accounts).

components: {
    Card,
    web3Accounts
  },
  data() {
    return {
      addresses: {},
      onlyChain: "",
      prefixes,
    };
  },

Pulling in the Accounts

Let’s begin by connecting our component to the Polkadot{js} extension to grab all our addresses.

Inside our component’s methods, we are going to add the following function:

web3Connect: async function() {
      dappex.web3Enable();
      if (!dappex.isWeb3Injected) {
        alert(
          "You need a Web3 enabled browser to log in with Web3. The easiest solution is probably to install the Polkadot{js} extension."
        );
      } else {
        let allAccounts = await web3Accounts();

        let addressOptions = [];
        allAccounts.forEach(element => {
          addressOptions.push(element.address);
        });
        this.addresses = addressOptions;
      }
    }

The if statement in this function is checking whether or not the Polkadot{js} extension is installed in your browser. If it hasn’t been installed or set up properly, an error message will appear on your screen, prompting you to install it.

Once the check has passed, we now begin pulling all the injected accounts from the extension using the web3Accounts function but only if the user allows the web page to connect to the extension. You can read more about this in the official docs.

We then begin reading in the accounts. If we console.log(allAccounts); we will get the metadata and the address for each account we have in Polkadot{js}.

A screenshot of address objects listed in the console

However, for the purpose of this address converter, we want to convert the address only. So, we push the address data onto an array called addresses, which we declared above inside data().

Now, if we console.log(this.addresses); we see only the addresses of the injected accounts.

A screenshot of just addresses listed in the console

There’s another thing we need to do in order for this web3Connect function to work: make sure it’s called. Underneath methods, let’s add a created function. By calling web3Connect() inside this created function, it will be called as soon as the page is initialized or loaded. So, instead of calling this function every time we want to convert an address, we call it once when the page is displayed.

created() {
    this.web3Connect();
 }

Inside the Accounts.vue page, your <script> tag should hold the following:

import { Card } from "@/components/index";
import { web3Accounts } from "@polkadot/extension-dapp";
import { prefixes } from "../components/Filters/Filter.js";
const dappex = require("@polkadot/extension-dapp");

export default {
  components: {
    Card,
    web3Accounts
  },
  data() {
    return {
      addresses: {},
      onlyChain: "",
      prefixes,
    };
  },
  methods: {
    web3Connect: async function() {
      dappex.web3Enable();
      if (!dappex.isWeb3Injected) {
        alert(
          "You need a Web3 enabled browser to log in with Web3. The easiest solution is probably to install the Polkadot{js} extension."
        );
      } else {
        let allAccounts = await web3Accounts();

        let addressOptions = [];
        allAccounts.forEach(element => {
          addressOptions.push(element.address);
        });
        this.addresses = addressOptions;
      }
    }
  },
  created() {
    this.web3Connect();
  }
};

Displaying the Data

Finally the part we’ve all been waiting for! Let’s take all our logic from both the Filter.js and the Accounts.vue file, and finish the UI.

Inside our src/pages/Accounts.vue page, let’s add the following inside the card tag inside the Accounts.vue template.

<p v-for="(account, address) in addresses">{{ address }}. Account: {{ account }}</p>
<hr />

This will print out our list of addresses from the Polkadot{js} extension. The v-for directive is used for looping through the addresses array, the account being each account address and the address being the index of the address (0, 1, 2, 3, etc).

If we run yarn serve we should see:

A list of addresses on the page

Now, let’s add a dropdown option for users to be able to pick what address format they’d like to convert to.

Inside our card component, underneath the above code we just created, let’s add:

<p>
  Choose an address to convert to:
  <select
    v-model="onlyChain"
  >
    <option v-for="(value, key) in prefixes" v-bind:value="key">{{ key }} : {{ value }}</option>
  </select>
</p>
<hr />

Note the v-model directive here, it’s set to the onlyChain string variable. We set this here to capture the network name that is selected in the options. Once an option is selected, the onlyChain value will be set.

Taking a look at the option tag, we see that another v-for loop is present. We are now iterating through the prefixes object, which we imported from the Filter.js file.

To learn more about prefixes, the Polkadot Wiki goes into much more depth on this.

One more thing about the code we just placed, the v-bind:value="key". In VueJS, it’s called value binding and is needed to save the selected option from the dropdown. In this case, we save the selected network name (the key) reactively.

The last step: displaying the converted addresses. We want to add in the following code, underneath the dropdown inside the card component:

<p
  v-if="onlyChain"
  v-for="(account, address) in addresses"
>{{ address }}. Address on {{ onlyChain }}: {{ account | prefix(onlyChain) }}</p>

Now we have a v-if directive that checks if onlyChain has a value. In other words, it only appears if an option from the dropdown has been selected. If an option hasn’t been selected from the dropdown, no data will be displayed in the UI. This is also where we utilize the filter component from the Address Translation filter tutorial.

The Final Reveal

Our code inside src/pages/Accounts.vue should now look like this:

<template>
  <div class="content">
    <card>
      <template slot="header">
        <h5 class="title">Accounts</h5>
        <p class="category">A component to interact with your accounts</p>
      </template>
      <div class="row">
        <div class="col-lg-12 col-md-3 col-sm-4 col-xs-6 col-xs-6 text-left">
          <card>
            <p v-for="(account, address) in addresses">{{ address }}. Account: {{ account }}</p>
            <hr />
            <p>
              Choose an address to convert to:
              <select
                v-model="onlyChain"
              >
                <option v-for="(value, key) in prefixes" v-bind:value="key">{{ key }} : {{ value }}</option>
              </select>
            </p>
            <hr />
            <p
              v-if="onlyChain"
              v-for="(account, address) in addresses"
            >{{ address }}. Address on {{ onlyChain }}: {{ account | prefix(onlyChain) }}</p>
          </card>
        </div>
      </div>
    </card>
  </div>
</template>
<script>
import { Card } from "@/components/index";
import { web3Accounts } from "@polkadot/extension-dapp";
import { prefixes } from "../components/Filters/Filter.js";
const dappex = require("@polkadot/extension-dapp");

export default {
  components: {
    Card,
    web3Accounts
  },
  data() {
    return {
      addresses: {},
      onlyChain: "",
      prefixes,
    };
  },
  methods: {
    web3Connect: async function() {
      dappex.web3Enable();
      if (!dappex.isWeb3Injected) {
        alert(
          "You need a Web3 enabled browser to log in with Web3. The easiest solution is probably to install the Polkadot{js} extension."
        );
      } else {
        let allAccounts = await web3Accounts();

        let addressOptions = [];
        allAccounts.forEach(element => {
          addressOptions.push(element.address);
        });
        this.addresses = addressOptions;
      }
    }
  },
  created() {
    this.web3Connect();
  }
};
</script>

Altogether, your UI should look like this:

The completed UI

Congrats! You’ve just built an address converter using VueJS!

You can find the full code of this tutorial in the kirsten_tutorial_address branch of the Polkadash repo.

Remember to subscribe to our newsletter to be kept up to date on new posts and to be kept in the loop about Web 3.0 developments.

Related posts