Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Global frontend-only verification system for web3 dapps.


Demo dapp using SkyID login:

Read security logs in

Getting started


Just copy this code to your HTML:

// get portal url from response header
fetch("", {method: 'HEAD'})
.then( response => response.headers)
.then( headers => {
	let portal = headers.get('skynet-portal-api');
	let devMode = false;
	if (!portal){
		// if no header, default to
		portal = ""
		devMode = true;

	let portalNoProtocol = portal.replace(/^https?\:\/\//i, "");

	// path for sky-id, easier than subdomain logic
	let path = 'https://sky-id.hns.' + portalNoProtocol;

	// create script tag
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.src = path+"/skyid.js";
	script.onload = ()=>{initSkyID(path, devMode)}; //once loaded, call method to run code that relies on it


var initSkyID = function(path){
	var skyid = new SkyID('App Name', null, {customSkyidUrl:path});

Initialize with options and callback (optional)

// detect if app is opened on localhost for development
if (window.location.hostname == 'idtest.local' || window.location.hostname == 'localhost' || window.location.protocol == 'file:') {
	var devMode = true
} else {
	var devMode = false

var opts = { 'devMode': devMode  }
var skyid = new SkyID('App name', skyidEventCallback, opts)

function skyidEventCallback(message) {
	switch (message) {
		case 'login_fail':
			console.log('Login failed')
		case 'login_success':
			console.log('Login succeeded!')
		case 'destroy':
			console.log('Logout succeeded!')

Available options:

Option default
devMode false
disableLoadingScreen false
customSkyidUrl null
onUploadProgress null

Start session (login)


Destroy session (logout)


Display classes

If you want, you can use special HTML classes, so you don't need to listen to SkyID callbacks.

  • show-if-logged-in - Set display to '' if user logged in

  • hide-if-logged-in - Set display to none if user logged in

  • show-if-initialized - Set display to '' if SkyID initialized

  • hide-if-initialized - Set display to none if SkyID initialized


<div class="show-if-logged-in"> You are logged in! </div>

You can also combine these classes:

<div class="hide-if-initialized">Loading...</div>

<div class="show-if-initialized hide-if-logged-in" style="display:none"> Loaded and you are not logged in :( </div>

<div class="show-if-initialized show-if-logged-in" style="display:none"> Loaded and you are logged in! </div>

It is important to use style="display:none" and not a CSS class the display property (bad example class="display-none") because SkyID will only reset the display attribute and not the CSS class



SkyID uses SkyDB under the hood to save, modify, and fetch files. The only difference is that you don't need to remember for your secret key - SkyID generates deterministic keypairs instead.

let yourObject = { key1: 'value1' }
skyid.setJSON('filename', yourObject, function(response) {
	if (response != true) {
		alert('Sorry, skyid.setFile failed :(')

You can store any JSON data, for example notes, settings, or a list of your uploaded files.


skyid.getJSON('filename', function(response) {
	if (response == false) {
		alert('Sorry, skyid.getFile failed :(')

Set registry entry

skyid.setRegistry('filename', 'IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ', function(success) {
	if (success == false) {
		alert('Sorry, skyid.setRegistry failed :(')

Get registry entry

skyid.getRegistry('filename', function(entry) {
	if (entry == false) {
		alert('Sorry, skyid.getRegistry failed :(')

Get registry URL

skydbFile = skyid.getRegistryUrl('filename')

Upload directory

<input id="my_input" type="file" multiple="" webkitdirectory="true">
let files = document.getElementById['my_input'].files
skyid.uploadDirectory(files, function(skylink) {
	console.log('File uploaded:', skylink)

Upload encrypted file

let file = document.getElementById['my_input'].files[0]
skyid.uploadEncryptedFile(file, 'derivationPath', function(skylink) {
	console.log('Uploaded:', skylink)

derivationPath can be any string. It will be hashed with the user's app-seed, no need to make it long since the app-seed is not public. It is recommended to use unique derivationPath to each file, so users can share decription keys for one file without revealing the other files

You can put a callback function to the onUploadProgress option both for upload and download.

Download encrypted file

let skylink = 'sia:/...'
skyid.downloadEncryptedFile(skylink, 'derivationPath', function(blobUrl){
	console.log('File downloaded', blobUrl)


Used libraries:

Skynet-js Sia-js



Thank you!

Brainstorm participants & helpers:

Taek, wkibbler, redsolver, Nemo, pjbrone, kreelud, Mortal-Killer, RBZL


Install development dependencies

cd SkyID

npm install

Compiling Javascript

You need to compile your node-js files (from the src folder) to a web-browser friendly javascript. Type

npx webpack

You'll see 3 new .js file in the dist folder. If you want to edit javascript, you can make changes inside the src folder and run npx webpack again. (Of course you can use npx webpack --watch so it will watch and compile automatically if you change something.

Open in browser

You can just open the /dist/index.html in your browser.

If you're using the file:// protocol (or idtest.local as localhost domain), SkyID will recognise you're in development mode and will be used as default Skynet portal.

Chrome won't save cookies with file:// protocol. You can use Firefox, use idtest.local as localhost domain, or upload the dist folder to Skynet.

Testing with example dapp

We have a SkyID-example-note-dapp, so you can clone it. Don't forget to change the source of skyid.js if you want to test with self-hosted SkyID (open image)

To be able to test cross-domain things, you need to setup two local virtual-host domains. If you have Wamp.NET installed (what I really recommend), this will be easy. You just need to create two sites pointing to your local SkyID projects: idtest.local for SkyID and skynote.local for the example dapp (open image).