Basics 5: Nimiq Identicons
TL;DR? Run the demo.
Building on the tutorial Basics 4: Extended Transactions, we can add one of Nimiq’s unique features: Nimiq Identicons.
Identicons help users identify and verify addresses,
for example helping them to make sure that the address they entered is the correct address of the recipient.
Here is an example: the Identicon in the following screen corresponds to the address NQ45 RGMN JG3R MQ4S TS19 M1YM 46KS Q7D2 15EE
.
First, let’s import the Nimiq Identicons library at the top of our script:
import Identicons from "https://unpkg.com/@nimiq/identicons@1.5/dist/identicons.bundle.min.js";
Note: Nimiq Identicons were named “Iqons” before. Older documents, blog posts or some members of the Nimiq Community might refer to them also as Nimiqons or Avatars.
For this to work we take advantage of the module
type definition by changing the <script>
tag to:
<script type="module">
An Identicon for our own wallet address
To use the lib, we get the user-friendly address of our wallet and create an Identicon for it.
It’s three new lines of code in start()
:
const address = wallet.address.toUserFriendlyAddress();
$('address').textContent = address;
await Identicons.render(address, $('identicon'));
This code will create an Identicon as an SVG and place it into a `#identicon’ element that we now add to our HTML:
...
<div class="nq-card-body">
<h2><span>Wallet</span></h2>
<div id="identicon"></div> <!-- just this line -->
<p>
<span class="nq-label">Address: </span>
<span id="address">loading…</span></p>
<p>
...
Now, when reloading the web-app, an Identicon will appear there. Of course a different one for you, because the address of your wallet is different.
Identicons for sending transactions
In the “Send Transaction” section of our app, let’s add a part that visualizes the transaction by showing an Identicon for the sender, the amount being transferred and another Identicon for the receiver.
First step, some HTML markup just before the tx_send
button:
<div id="transaction">
...
<p id="tx_overview">
<span id="tx_overview_sender"></span>
<span> ⇢ </span>
<span id="tx_overview_amount"></span>
<span> ⇢ </span>
<span id="tx_overview_recipient"></span>
</p>
...
</div>
Add a new function to generate the “transaction overview”. It extracts the data entered into the transaction form and renders it into the HTML section we added before. The function will also check if the entered values are valid. If so, the overview will be shown and the “send” button becomes enabled.
async function transactionOverview() {
let ready = false;
try {
// Test if recipient address is valid by converting it forth and back
const recipientAddress = Nimiq.Address
.fromUserFriendlyAddress($('tx_recipient').value.trim())
.toUserFriendlyAddress();
// Render our own wallet's address as Identicon
await Identicons.render(nimiq.address, $('tx_overview_sender'));
// Show the amount to be sent
const amount = parseFloat($('tx_amount').value || '0');
$('tx_overview_amount').textContent = `${amount} NIM`;
// Render the recipient address as Identicon
await Identicons.render(recipientAddress, $('tx_overview_recipient'));
// If everything worked until here and a positive amount is set
// we're ready to show the overview
ready = amount > 0;
} catch (error) {
// a good place to add some proper error handling later on :)
}
// Show overview and and enable the send button if ready
$('transaction').classList.toggle('ready', ready);
$('tx_send').disabled = !ready;
}
Next step, call the transactionOverview()
function each time
the user enters something into the amount or recipient box
of the transaction form by adding two input
listeners
at the end of start()
:
$('tx_amount').addEventListener('input', transactionOverview);
$('tx_recipient').addEventListener('input', transactionOverview);
Finally, making it nice with some CSS to a) show the transaction form only when consensus has been established and b) show the overview if the entered transactions data is valid. By folding and unfolding the sections using a little animation:
#transaction {
max-height: 0;
overflow: hidden;
transition: max-height .3s;
}
.consensus-established #transaction {
max-height: 63rem;
}
#tx_overview {
/* ... */
max-height: 0;
overflow: hidden;
transition: max-height 1s;
}
#transaction.ready #tx_overview {
max-height: 21rem;
}
Now update the onConsensusChanged(...)
method so that it adds the consensus-established
class to show the transaction form:
function onConsensusChanged(consensus) {
const established = consensus == Nimiq.Client.ConsensusState.ESTABLISHED;
status(established
? 'Consensus established.'
: 'Establishing consensus...');
// Add or remove the class depending if consensus is established or not.
document.body.classList.toggle('consensus-established', established);
}
Awesome!
You are now an official Nimiq Basics Code Nimja (that is not a typo), having mastered the ancient skills of
- Establishing consensus
- Listening to blockchain events
- Sending both types of transactions
- Last but not least, creating Identicons
As a Nimiq Basics Code Nimja, you can now proudly wear the golden belt of honor!
Find more help and documentation in the Nimiq Developer Center. Share your ideas and feedback on the Nimiq Community Forum, you’ll also find a dedicated section for discussions and ideas. Or get in touch at sven@nimiq.com.