Hello HiveDevs,
I want to share another weekend project called Random Hive. It's a minimalistic Hive frontend that shows a random, recently-published post. This site is meant to be useful for discovering new content and authors on Hive.
My main goal for this project is to learn how to do Hive Keychain integration. It was surprisingly easy to pull off, and I'll go into details below.
Here's what Random Hive looks like:

To try Random Hive you can visit here: https://hiveuprss.github.io/randomhive/
The source code is free and open on GitHub here: https://github.com/hiveuprss/hiveuprss.github.io/tree/master/randomhive
Components
- Languages: HTML and JavaScript (all client side)
- GitHub pages is used as an easy way to host the HTML, JS, and CSS content.
- I'm using @mahdiyari's hive-tx-js again for calling Hive condenser APIs
- Showdown.js is used to convert markdown into HTML
- Bootstrap and FontAwesome are used for all of the UI components. It feels like cheating.
- jQuery is included as a dependency but I don't use jQuery directly
- @stoodkev's Hive Keychain is used to sign in and send Upvotes
How it works
On page load, Random Hive calls condenser_api.get_discussions_by_created to grab 100 recent posts. It filters out short posts and nsfw posts before it selects one of the remaining at random to be displayed on the page. Reloading the page or clicking 'Next' button repeats this selection process.
After a random post is chosen, showdown.js is invoked to convert from Markdown to HTML. Some extra transformations are done to handle weird off-spec stuff. For example, Hive frontends allow users to insert images by just including the raw URL of the image without Markdown syntax. Showdown doesn't handle this, so I added some fancy regex to find and replace these with the correct markdown. Trying to fix the rendering ate up the most time for this project, and it's still imperfect.
The conversion itself is pretty simple, I used some non-default option to try to render more edge cases. I think it's still messing up when rendering tables.
Simple showdown.js usage:
var converter = new showdown.Converter()
converter.setFlavor('github')
converter.setOption('openLinksInNewWindow', true)
converter.setOption('simplifiedAutoLink', true)
var html = converter.makeHtml(text)`
When the 'Next' button is clicked, the current post permlink is fed as an input to condenser_api.get_discussions_by_created. By using the paginated API this way, the next post is drawn from another pool of 100 posts. This improves the randomness, so if you click the 'Next' button over and over you aren't likely to see the same post again.
Hive keychain integration
Learning Hive Keychain integration was my main goal for this project. It was surprisingly easy. As a developer, what is very nice about Hive Keychain is I don't have to worry about key management. And I don't need to ask you to give me your keys.
This is what happens when you enter your Hive account name and click the sign-in button. No data/request is sent to the server. Random Hive's index.js first sends a handshake to make sure Hive Keychain is present. If Keychain isn't installed, this will throw an exception and bail out. Ideally I would add some error handling here to warn the user.
Then, it sends a requestSignBuffer() to Hive Keychain with the account name. It asks to sign a test message with the account's Posting key, to make sure the key is present in the keychain. Again, error handling needed to warn the user when their keys aren't right.
Here's a code snippet which demonstrates the sign-in process
hive_keychain.requestHandshake(function() {
console.log("Handshake received!");})
hive_keychain.requestSignBuffer(accountName, 'test', 'Posting',
(response) => {
console.log(response)
if (response.success) {
// all is well!
}}
If all is well, the code uses 'localStorage' to save the account name. This means you will stay 'signed in' if you refresh the page, and until you sign out. The only thing stored is the name of the account. And it's stored locally, hence 'localStorage'. So no data is sent to the server (unlike what happens for cookies). localStorage is very simple to use, like the below examples.
// sign in
window.localStorage.setItem('hiveaccount', accountName)
if (!window.localStorage.getItem('hiveaccount')) {
// not logged in yet
}
// sign out
window.localStage.removeItem('hiveaccount')
Similar to the sign in process, Hive Keychain offers a requestVote API for voting on Hive posts. By using this API our code doesn't need to do anything extra to create and broadcast the transaction.
One liner for broadcasting an Upvote via hive keychain:
hive_keychain.requestVote( accountName, permlink, author, weight, function(response) { console.log(response); } )
Note:The Hive Keychain GitHub repo includes some very helpful example code for all of the supported APIs.
Wrapping Up
Random Hive includes some helpful buttons for jumping to PeakD or Hive.blog, if you want interact with the post in a full-featured front end. It also has a 'Follow' and a 'Reblog' button which aren't wired up yet.
That's about it! I had fun learning about Hive Keychain, and even more fun sharing the fruits of my learning with you. So, I hope this is helpful. I'm looking forward to sharing next week's project.
If you use Random Hive, enjoy discovering some unexpected, excellent content created by the talented Hive community. 😎
Shoutouts
- Thank you again to @mahdiyari for creating hive-tx-js
- Thank you @stoodkev for creating hive keychain

Brought to you by @HiveTrending

@customcog was asking about this. Thank you.
For rendering, I'd recommend using
remarkable(https://www.npmjs.com/package/remarkable) to get a feel closer to condenser. Its what they use for markdown parsing.Thanks for the tip @rishi556!