Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use Vue.js To Generate Cold Storage Paper Wallets For DigiByte DGB Coins

TwitterFacebookRedditLinkedInHacker News

To continue on my technical journey of cryptocurrency coin management, I figured it would be a good idea to share how to create a paper wallet for DigiByte DGB coins. A few weeks back I had written a tutorial titled, Generate Cold Storage Paper Wallets for Ripple XRP Coins with Angular, but we all know Ripple isn’t the only technology on the block.

In case you’re unfamiliar with paper wallets, they are nothing more than printouts that contain your private and public key information. It is separated from the internet and the paper wallets can be placed in a cold storage location like a locked safe or a bank.

We’re going to see how to use JavaScript and the Vue.js framework to generate DigiByte DGB wallet information that includes QR codes for easy scanning.

So what do we hope to accomplish by the end of this guide? Take the image below for example:

DigiByte DGB Paper Wallet with Vue.js

As you can see, we have four different QR codes and four different hash values. The private values should be heavily protected while the public values can be shared. You’d hit the generate button and then print the page.

Creating a New Vue.js Web Application with Dependencies

The easiest way to create a Vue.js web application is by using the CLI. However, because we won’t be using Webpack in this example, it doesn’t really matter as it will be simple regardless. You’ll see by the end of this guide how easy it was.

From the Vue CLI, execute the following:

vue init simple dgb-paper-wallet

The above command will leave you with a project and a single index.html file when you’re done.

When generating a wallet, it is a bad idea to be connected to the internet. You never know what kind of malware is lingering around on your computer or the server you’re trying to run from. For this reason, we need to download a pre-built Vue.js rather than use the CDN.

Download Vue.js and include the vue.js file in your project.

The next dependency we need is for QR code generation. The easiest library I could find is called qrcode.js. Download the qrcode.min.js file from the GitHub repository and include it in your project.

The last remaining dependency is the most complicated. We need to use the DigiByte JavaScript library, however, we have to build a browser compatible version of it.

From your computer, outside the Vue.js project, execute the following commands:

git clone https://github.com/digibyte/digibyte-lib
cd digibyte-lib
npm install
gulp browser

The above commands will clone the repository, install all the necessary build dependencies, and then build a browser bundle of the project. In theory, a digibyte.min.js file should be generated, but I was only able to get a digibyte.js file. For this project, it doesn’t really matter. Copy the digibyte.js file into your Vue.js project.

At this time your project directory should look like the following:

index.html
qrcode.min.js
digibyte.js
vue.js

Before we start some actual development, let’s include the dependencies in our index.html file. Open it and include the following within the <head> tags:

<script src="digibyte.js"></script>
<script src="qrcode.min.js"></script>
<script src="vue.js"></script>

Remember, we’ve swapped out pkg.com/vue with the local vue.js file. Ready to start the development of your paper wallet?

Generating DigiByte Wallet Information with JavaScript

There is a lot of stuff to cover, but it really isn’t difficult. With any Vue.js project you’re going to have a <script> section, a <style> section and then a bunch of HTML markup. While this is all in the index.html file, let’s start with the <script> content:

<script>
    const digibyte = require("digibyte");

    var app = new Vue({
        el: '#app',
        data() {
            return {
                privateKey: "",
                wifKey: "",
                publicKey: "",
                address: ""
            }
        },
        mounted() {
            this.generate();
        },
        methods: {
            generate() {
                var dgb = new digibyte.PrivateKey();
                this.privateKey = dgb.toString();
                this.wifKey = dgb.toWIF();
                this.publicKey = dgb.toPublicKey().toString();
                this.address = dgb.toAddress().toString();
                if(!this.qrPrivateKey) {
                    this.qrPrivateWIFKey = new QRCode(this.$refs.qrPrivateWIFKeyImg, {
                        text: this.wifKey,
                        width: 150,
                        height: 150
                    });
                    this.qrPrivateKey = new QRCode(this.$refs.qrPrivateKeyImg, {
                        text: this.privateKey,
                        width: 150,
                        height: 150
                    });
                    this.qrPublicKey = new QRCode(this.$refs.qrPublicKeyImg, {
                        text: this.publicKey,
                        width: 150,
                        height: 150
                    });
                    this.qrPublicAddress = new QRCode(this.$refs.qrPublicAddressImg, {
                        text: this.address,
                        width: 150,
                        height: 150
                    });
                } else {
                    this.qrPrivateWIFKey.clear();
                    this.qrPrivateWIFKey.makeCode(this.wifKey);
                    this.qrPrivateKey.clear();
                    this.qrPrivateKey.makeCode(this.privateKey);
                    this.qrPublicKey.clear();
                    this.qrPublicKey.makeCode(this.publicKey);
                    this.qrPublicAddress.clear();
                    this.qrPublicAddress.makeCode(this.address);
                }
            }
        }
    })
</script>

The above <script> block probably looks a bit scary, but it really isn’t. There is just a lot of repetition. In the data section we are defining all variables that can be bound to the HTML. When the application loads and the mounted method is triggered, it will call our generate method.

var dgb = new digibyte.PrivateKey();
this.privateKey = dgb.toString();
this.wifKey = dgb.toWIF();
this.publicKey = dgb.toPublicKey().toString();
this.address = dgb.toAddress().toString();

In the above code we are creating a new random private key, the WIF standard version of it, and public address information to be shared with people.

Because of how the QR code generator works, we need to be concerned about if the codes already exist. If the QR codes have never been initialized, we have the following:

this.qrPrivateWIFKey = new QRCode(this.$refs.qrPrivateWIFKeyImg, {
    text: this.wifKey,
    width: 150,
    height: 150
});
this.qrPrivateKey = new QRCode(this.$refs.qrPrivateKeyImg, {
    text: this.privateKey,
    width: 150,
    height: 150
});
this.qrPublicKey = new QRCode(this.$refs.qrPublicKeyImg, {
    text: this.publicKey,
    width: 150,
    height: 150
});
this.qrPublicAddress = new QRCode(this.$refs.qrPublicAddressImg, {
    text: this.address,
    width: 150,
    height: 150
});

Each QR code will be bound to a DOM element via the $refs object. With the DOM element and the generated wallet value, we can create a QR code that will be automatically rendered on the screen.

If the QR codes had already been initialized, we would run the following:

this.qrPrivateWIFKey.clear();
this.qrPrivateWIFKey.makeCode(this.wifKey);
this.qrPrivateKey.clear();
this.qrPrivateKey.makeCode(this.privateKey);
this.qrPublicKey.clear();
this.qrPublicKey.makeCode(this.publicKey);
this.qrPublicAddress.clear();
this.qrPublicAddress.makeCode(this.address);

The above code clears our currently QR code image and regenerates it with new information.

With the JavaScript logic out of the way, what does the render code look like? Within the project’s index.html file, take a look at the following HTML markup:

<div id="app">
    <p><button type="button" v-on:click="generate()">Generate</button>
    <p>Only share information marked as public!</p>
    <table>
        <tr>
            <td>
                <h2>Private WIF Key</h2>
                <div ref="qrPrivateWIFKeyImg"></div>
                <p>{{ wifKey }}</p>
            </td>
            <td>
                <h2>Public Address</h2>
                <div ref="qrPublicAddressImg"></div>
                <p>{{ address }}</p>
            </td>
        </tr>
        <tr>
            <td>
                <h2>Private Key</h2>
                <div ref="qrPrivateKeyImg"></div>
                <p>{{ privateKey }}</p>
            </td>
            <td>
                <h2>Public Key</h2>
                <div ref="qrPublicKeyImg"></div>
                <p>{{ publicKey }}</p>
            </td>
        </tr>
    </table>
</div>

We can call the generate method by clicking the button and each variable can be rendered to the screen. Remember the $refs object? There are four <div> tags that have a ref attribute with a matching name. This is how we are able to interact with the DOM.

Finally, we have the <style> section, which isn’t truly necessary in this example because we don’t need it to look attractive, we only need it printable.

<style>
    table {
        border: 1px solid black;
        padding: 20px;
        width: 100%;
    }
    h2 {
        margin: 0;
        margin-bottom: 20px;
    }
</style>

The CSS above will give our table a nice border and fill the screen. Again, it isn’t anything that we absolutely needed, but it doesn’t hurt us.

The full code to the project that we created can be seen below:

<!DOCTYPE html>
<html>
    <head>
        <title>DigiByte DGB Paper Wallet</title>
        <script src="digibyte.js"></script>
        <script src="qrcode.min.js"></script>
        <script src="vue.js"></script>
        <style>
            table {
                border: 1px solid black;
                padding: 20px;
                width: 100%;
            }
            h2 {
                margin: 0;
                margin-bottom: 20px;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <p><button type="button" v-on:click="generate()">Generate</button>
            <p>Only share information marked as public!</p>
            <table>
                <tr>
                    <td>
                        <h2>Private WIF Key</h2>
                        <div ref="qrPrivateWIFKeyImg"></div>
                        <p>{{ wifKey }}</p>
                    </td>
                    <td>
                        <h2>Public Address</h2>
                        <div ref="qrPublicAddressImg"></div>
                        <p>{{ address }}</p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <h2>Private Key</h2>
                        <div ref="qrPrivateKeyImg"></div>
                        <p>{{ privateKey }}</p>
                    </td>
                    <td>
                        <h2>Public Key</h2>
                        <div ref="qrPublicKeyImg"></div>
                        <p>{{ publicKey }}</p>
                    </td>
                </tr>
            </table>
        </div>

        <script>
            const digibyte = require("digibyte");

            var app = new Vue({
                el: '#app',
                data() {
                    return {
                        privateKey: "",
                        wifKey: "",
                        publicKey: "",
                        address: ""
                    }
                },
                mounted() {
                    this.generate();
                },
                methods: {
                    generate() {
                        var dgb = new digibyte.PrivateKey();
                        this.privateKey = dgb.toString();
                        this.wifKey = dgb.toWIF();
                        this.publicKey = dgb.toPublicKey().toString();
                        this.address = dgb.toAddress().toString();
                        if(!this.qrPrivateKey) {
                            this.qrPrivateWIFKey = new QRCode(this.$refs.qrPrivateWIFKeyImg, {
                                text: this.wifKey,
                                width: 150,
                                height: 150
                            });
                            this.qrPrivateKey = new QRCode(this.$refs.qrPrivateKeyImg, {
                                text: this.privateKey,
                                width: 150,
                                height: 150
                            });
                            this.qrPublicKey = new QRCode(this.$refs.qrPublicKeyImg, {
                                text: this.publicKey,
                                width: 150,
                                height: 150
                            });
                            this.qrPublicAddress = new QRCode(this.$refs.qrPublicAddressImg, {
                                text: this.address,
                                width: 150,
                                height: 150
                            });
                        } else {
                            this.qrPrivateWIFKey.clear();
                            this.qrPrivateWIFKey.makeCode(this.wifKey);
                            this.qrPrivateKey.clear();
                            this.qrPrivateKey.makeCode(this.privateKey);
                            this.qrPublicKey.clear();
                            this.qrPublicKey.makeCode(this.publicKey);
                            this.qrPublicAddress.clear();
                            this.qrPublicAddress.makeCode(this.address);
                        }
                    }
                }
            })
        </script>
    </body>
</html>

Remember, even though it seemed like a lot was going on, the reality is that it didn’t take much to generate wallet information and display QR codes for it with Vue.js. If you wanted to be a minimalist, this could have been done in just a few lines of code for printed text.

Conclusion

You just saw how to create a cold storage wallet for holding all your DigiByte DGB coins. This wallet, while nothing fancy, was created using only JavaScript and the Vue.js framework.

If you wanted to create something a little more fancy, check out my tutorial titled, Create a Cross-Platform Desktop DigiByte DGB Wallet with Angular and Electron, which focuses on the development of a wallet for computers.

If you’re holding DGB coins and found this tutorial useful, consider donating to my address at D9Ms9hnm32q9nceN2b9jNshuZhWcobrmQm.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.