Handshake + Skynet tutorial

How to use Handshake and Skynet together through the Namebase API

Sia and Namebase teams have partnered together for the Own the Internet Hackathon — a 3-week hackathon from July 29th to Aug 19th to build decentralized applications that are censorship-resistant and truly in your control. There are more than $4000 SC and HNS in prizes, and every participant gets a free Handshake domain and an Own the Internet T-shirt!

Additional details and registration link: https://gitcoin.co/hackathon/own-the-internet/onboard

Setup

Get Namebase API key

Login to your Namebase account and go to https://namebase.io/pro/keys.

Click NEW API KEY in the top right.

Record the Access Key and Secret Key.

To authenticate your API calls, you’ll need to create an authentication header to send with the HTTP request. Here’s what the steps look like in javascript:

const credentials = Buffer.from(`${ACCESS_KEY}:${SECRET_KEY}`);
const encodedCredentials = credentials.toString('base64');
const authorization = `Basic ${encodedCredentials}`;

Then add Authorization: authorization as a header.

Here’s a script that simplifies the HTTP requests into a command line interface. To set it up, set the ACCESS_KEY and SECRET_KEY with the keys you recorded earlier. The full documentation on the API can be found here (https://github.com/namebasehq/api-documentation).

const fetch = require('node-fetch');
const ACCESS_KEY = '';
const SECRET_KEY = '';
const credentials = Buffer.from(`${ACCESS_KEY}:${SECRET_KEY}`);
const encodedCredentials = credentials.toString('base64');
const authorization = `Basic ${encodedCredentials}`;
async function get(endpoint, body = null) {
const options = {
method: 'GET',
headers: {
Authorization: authorization,
Accept: 'application/json',
'Content-Type': 'application/json',
},
};
const url = `https://namebase.io${endpoint}`;
return fetch(url, options)
.then(res => res.json())
.catch(err => err);
}
async function put(endpoint, body) {
const options = {
method: 'PUT',
body: body,
headers: {
Authorization: authorization,
Accept: 'application/json',
'Content-Type': 'application/json',
},
};
const url = `https://namebase.io${endpoint}`;
return fetch(url, options)
.then(res => res.json())
.catch(err => err);
}
async function main() {
const args = process.argv.slice(2);
let func, path, data;
const domain = args[2];
if (args[0] === 'get') {
func = get;
} else if (args[0] === 'put') {
func = put;
if (args.length < 4) throw new Error('Put requires 4 arguments');
data = args[3];
} else {
throw new Error("Method should be either 'get' or 'put'");
}
if (args[1] === 'blockchain') {
path = `/api/v0/dns/domains/${domain}`;
} else if (args[1] === 'blockchain-advanced') {
path = `/api/v0/dns/domains/${domain}/advanced`;
} else if (args[1] === 'nameserver') {
path = `/api/v0/dns/domains/${domain}/nameserver`;
} else {
throw new Error("Service should be 'blockchain', 'blockchain-advanced' or 'nameserver'");
}
return func(path, data);
}
main().then(res => {
console.log(res);
});

Using the Script

Now that your API calls are authenticated, you can test out the queries. The script call looks like:

node ./namebaseApi.js METHOD SERVICE DOMAIN RECORD_DATA

where

METHOD = get (retrieving records) or put (adding/updating records)

SERVICE = which DNS settings you want to add, the three options are:

  1. blockchain — for Handshake records that are ‘DS’, ‘TXT’, or ‘NS’

  2. blockchain-advanced — Handshake accepts some additional record types, in order to send these create a Handshake resource record and send the hex as the RECORD_DATA (more documentation can be found here https://hsd-dev.org/guides/resource-records.html )

  3. nameserver — Namebase’s own nameservers which enables users to set ‘A’, ‘CNAME’, ‘ALIAS’, ‘NS’, ‘DS’, and ‘TXT’ records either on the root or a subdomain. All names won on Namebase should have this connected by default. There’s an explanation on how to check if this is configured below.

DOMAIN = your Handshake domain

RECORD_DATA = only necessary for METHOD=’put’; the json format varies slightly based on the SERVICE, be sure to double check with the full documentation.

Keep in mind that the blockchain endpoints will replace all existing records with the new json that is sent. So, if you only want to add another record, you have to get the current records and send them along with the new one. For deleting, you would need to resend all the current records except for the one you want to delete.

The nameserver records are slightly different. It will only replace records if a record with the same type and host is specified. For example, if I have a TXT record set on foo.example, adding another TXT record on bar.example will not replace it.

Setting Records

Now that you know the details of the API, let’s run through some examples.

Connecting Namebase’s Nameservers

Retrieve your name’s Handshake records:

node ./namebaseApi.js get blockchain YOUR_DOMAIN

This calls the GET /api/v0/dns/domains/YOUR_DOMAIN endpoint.

If your response contains the following json in the records array, then the nameserver is connected:

{ ttl: 10800, type: ‘NS’, host: ‘ns1’, value: ‘44.231.6.183’ }

If it’s not run the following command to set the record:

node ./namebaseApi.js put blockchain YOUR_DOMAIN ‘{“records”: [{ “ttl”: 10800, “type”: “NS”, “host”: “ns1”, “value”: “44.231.6.183” }] }’

This calls the PUT /api/v0/dns/domains/YOUR_DOMAIN endpoint.

You’ll have to wait until the update gets mined before it’s ready to use. If you’re not sure, run the command to retrieve the Handshake records again. The upToDate value will indicate if Handshake has updated.

Connecting to Skynet

For an extended tutorial on setting up a site hosted on Sia's Skynet and connecting it to Handshake via their Skynet Portal, their Skynet 🤝 Handshake blog post is extremely helpful. Ivaylo explains how to send your content to the decentralized cloud and how to set your Handshake DNS records through Namebase’s UI in order to access your content through the portal. The following is how you would set those records through the Namebase API.

For setting up the Skynet Portal, all you’ll need is to set a TXT record with the skylink for your app. Here’s what the call should look like:

node namebaseApi.js put blockchain YOUR_DOMAIN ‘{ “records”: [{ “type”: “TXT”, “host”: “”, “value”: “[YOUR_SKYLINK]”, “ttl”: 0 }] }’

Other Examples

Update blockchain Skylink

node namebaseApi.js put blockchain example ‘{ “records”: [{ “type”: “TXT”, “host”: “”, “value”: “[YOUR_SKYLINK]”, “ttl”: 0 }] }’

Delete all TXT records on foo.example

node namebaseApi.js put nameserver example ‘{ “records”: [], “deleteRecords”: [{ “type”: “TXT”, “host”: “foo” }] }’