Name Server protocol
====================

The protocol used by Jami to query and register a name is based on an
HTTP
[REST](https://en.wikipedia.org/wiki/Representational_state_transfer)
API answering requests with JSON documents and regular HTTP status
codes.

The public nameserver is hosted at `ns.jami.net` and uses a blockchain
as its backend.  Another implementation could use any other database
or directory service making the nameserver protocol reusable.

If you run your own nameserver, looking up a username in the form of
`username@example.com` will look up the name `username` with the
nameserver at `example.com`.  (There is no need to add `@ns.jami.net`
to use the default nameserver.)

Rules on name formatting
------------------------

Usernames are checked by a regex to ensure some rules about their
format:

-   Length must be between 3 and 32 characters
-   Those characters must be alphanumerical with dashes `-` being
    also accepted.

Querying a name
---------------

This is the main service provided by a name server.  It enables
getting the Jami ID corresponding to a username.

### Request

A request for the name `foobar` is a `GET` request with
`/name/`*`foobar`* as the URI.

### Response (Success)

If the name is found, a response with status code `200` `OK` must be
sent to the client with a `Content-type` field set as
`application/json`.

The body is a JSON documents with 2 string attributes : `name` and
`addr`.  `name` is equal to the one requested and `addr` is an
hexadecimal representation of the Jami ID prefixed with `0x`.

In our example, the JSON answer would be:

```javascript
{
    "name":"foobar",
    "addr":"0x29347542eb07159f316577e1ae16243d152f6b7b"
}
```

### Response (Not found)

If the name is not found, a response with status code `404` `Not`
`Found` must be sent to the client with a `Content-type` field set as
`application/json`.

The body is a JSON documents with 1 string attribute : `error`.  This
attribute is filled with an error message that explains the error (and
could be displayed in the client in the future).

On the reference implementation, the returned document is:

```javascript
{
    "error":"name not registred"
}
```

Querying an address
-------------------

This service is a reverse lookup.  You query for an address and a
username is returned if one is registered on the name server.

### Request

A request for the ID `jami:29347542eb07159f316577e1ae16243d152f6b7b`
is a `GET` request with
`/addr/`*`29347542eb07159f316577e1ae16243d152f6b7b`* as the URI.

### Response (Success)

If the address corresponds to a username, a response with status code
`200` `OK` must be sent to the client with a `Content-type` field set
as `application/json`.

The body is a JSON documents with 1 string attribute : `name`.  The
value of this field is the name registered to this address

In our example, the JSON answer would be:

```javascript
{
    "name":"foobar"
}
```

### Response (Not found)

If the address is not found, a response with status code `404` `Not`
`Found` must be sent to the client with a `Content-type` field set as
`application/json`.

The body is a JSON documents with 1 string attribute : `error`.  This
attribute is filled with an error message that explains the error (and
could be displayed in the client in the future).

On the reference implementation, the returned document is:

```javascript
{
    "error":"address not registred"
}
```

Registering a name
------------------

This part of the protocol is used to register a new name/address pair.
It is used on the main public registry but may be optional in a custom
implementation.

### Request

A request for registering the name `foobar` is a `POST` request with
`/name/`*`foobar`* as the URI. The header attribute `Content-type` must
be set to `application/json`.

The body of the request is a JSON document with 2 string attributes:
`addr` and `owner`.  `addr` contains the Jami ID prefixed with `0x`
and `owner` is the name to be registered.

An example for `foobar` could be:

```javascript
{
    "addr":"0x29347542eb07159f316577e1ae16243d152f6b7b",
    "owner":"foobar"
}
```

### Response (Success)

If the name/address pair is successfully registered, a response with
status code `200` `OK` must be sent to the client with a `Content-type`
field set as `application/json`.

The body contain a JSON document with 1 boolean attribute `success` set
to `true`.

As an example:

```javascript
{
    "success":true
}
```

Further attempts to query the name or the address should then be
successful.

### Response (Bad request)

If the registration cannot be achieved because of an error in the
request (formatting, missing attribute, etc.), a response with status
code `400` `Bad` `Request` must be sent to the client with a
`Content-type` field set as `application/json`.

The body is a JSON documents with 2 attributes: `success` which is a
boolean and `error` which is a string.  `success` is set to `false`
and `error` is filled with an error message that explains the error
(and could be displayed in the client in the future).

For an invalid formatting of the username, the body could be:

```javascript
{
    "success": false,
    "error": "invalid name"
}
```

### Response (Forbidden)

If the registration cannot be achieved because the name is already
taken, a response with status code `403` `Forbidden` must be sent to
the client with a `Content-type` field set as `application/json`.

The body is a JSON documents with 3 attributes: `success` which is a
boolean set to `false`, `name` and `addr` which are both strings
replicated from the original request.

Registering `foobar`, with it being already registered, would lead to
the following response:

```javascript
{
    "success": false,
    "name":"foobar",
    "addr":"0x29347542eb07159fdeadbeefae16243d152f6b7b"
}
```

Some links
----------

- {gitlab-project}`jami-nameservice`: reference NodeJS implementation
  used by `ns.jami.net` and querying an Ethereum node.