# Authentication

## Overview

While our protocol is fully open, all communications with our API will require authentication. If you're more interested in just reading the data to build something, you can use our subgraphs.&#x20;

> A Raft token (NFT) is the authorization token needed to create badges withing your account. Please fill out [this](https://forms.otterspace.xyz/get-started) form to apply for a Raft token and one of our team members will contact you ASAP and help you get setup.&#x20;

## Integration types

### Server-side integrations

Once you have obtained a Raft Token, you can generate an API key via the settings page of your Raft.&#x20;

#### Generating an API Key

* Sign in to <https://beta.otterspace.xyz/> and navigate to your Raft's settings page via the drop-down menu.&#x20;
* Click the edit icon to access Raft settings.
* Go to "API" tab
* Enter a name for your app and then click "Generate key"
* Note that this key is only viewable/copy-able only once i.e., upon generation. If you lose it, you would need to generate a new one and delete the old one

> **IMPORTANT:** you should do everything to secure your API key and it should be easily accessible to exposed unauthorized parties

<figure><img src="https://2226074966-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FAzd5KglFXWJXBKKKNfoX%2Fuploads%2FeWjVvGV59XqtzsNfk9qQ%2Fimage.png?alt=media&#x26;token=9d9c3a26-d920-45eb-a0cc-8fc3d06d53df" alt=""><figcaption><p>Your raft's API settings page</p></figcaption></figure>

Note that only the API routes under `/external` are accessible with this API key for server side integrations. You will need to provide a header ‘***Authorization***’ that contains an API key as a Base64 string. Using the raw string of the API key from the UI will not work, unless it is base64 encoded. You can use this [tool](https://base64.guru/converter/encode) to help convert it.&#x20;

```bash
curl "https://staging.otterspace.xyz/api" \
		 -H "Authorization: <API key as base64 encoded string>"
```

### Client-side integrations

If you're building a client-side integration i.e., a web application without a server-side componenet for instance, you will need to use a different authentication flow called SIWE or [Sign-in With Ethereum](https://eips.ethereum.org/EIPS/eip-4361).&#x20;

> Note: API access for client-side integrations not fully open. Please contact us via email or discord to discuss your requirements and your access.

#### Step 1: Retrieve a nonce

Request

```bash
$ curl -X GET "https://staging.otterspace.xyz/api/auth/nonce" \
       -H "Content-Type: application/json"
```

Response

```json
{ "nonce": "<random nonce>" }
```

#### Step 2: Sign-in

Request

{% code fullWidth="false" %}

```bash
$ curl -X POST "https://staging.otterspace.xyz/api/auth/sign_in" \
			 -H "Content-Type: application/json" \
       -H "Accept: application/json" \
			 -d '{ "signature": "<signed message>", "message": "<message object>" }'
```

{% endcode %}

*Response*

```bash
{ "<siweMessage>" }
HTTP/1.1 200 OK
Date: Mon, 18 Aug 2022 13:08:53 GMT
...
Set-Cookie: "<created cookie for this specific user>"
```

***message*** field in the request is composed standardised off-chain authentication message proposed in [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361). It is an object that have certain fields like `address`, `chainId`, `nonce`, `domain` etc. This standardised message is of type `SiweMessage` from the [`siwe`](https://github.com/spruceid/siwe) library.

```typescript
const siweMessage = new siwe.SiweMessage({
  domain: "<string>",
  address: "<string>",
  statement: "<string>",
  uri: "<string>",
  version: "<string>",
  nonce: '<received nonce from previous step>',
  issuedAt: "<YYYY-MM-DDTHH:MM:SS.000Z>",
  chainId: "<number>",
  ...
});
```

***signature*** field in the request body is signed version of the `message` created by the wallet of the user. Simply put a `message` is signed by the user's private key and then `signature` is verified on the API side using user's public key. Concept is called [elliptic curve cryptography](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography). ***For a programmatic message signing please check the section*** [***below***](https://docs.otterspace.xyz/developer-docs/otterspace-platform-api-docs#d2229317fcb847698a7a2243c76520bd)***.***

> **IMPORTANT:** For authentication of further requests to API please provide **`Cookie`** HTTP Header. You can extract the cookie from response’s header **`Set-Cookie`**.

#### ✍🏼 Programmatic message generation and signing with siwe/ethers.js

```javascript
// import necessary dependencies
import {
	Wallet
} from "ethers";
import {
	SiweMessage
} from "siwe";

async function main() {
	// provide a private key for your existing wallet (you can also create a random one: Wallet.createRandom())
	const wallet = new Wallet(privateKey);

	// generate a Siwe message
	const siweMsg = new SiweMessage({
		domain: "<>", // RFC 4501 dns authority that is requesting the signing.
		wallet.address, // wallet address of the user
		statement: "<>", // Human-readable ASCII assertion that the user will sign,
		uri: "<>", // RFC 3986 URI referring to the resource that is the subject of the signing
		version: "1", // Current version of the message.
		chainId: 10, // EIP-155 Chain ID to which the session is bound, and the network where Contract Accounts must be resolved.
		nonce, // the nonce you acquired
		issuedAt: new Date().toISOString(),
	});

	// parse all the fields in the object and creates a sign message according with the type defined
	const message = siweMsg.prepareMessage();

	// sign the message with your wallet
	const signature = await wallet.signMessage(message.toString());

	return {
		signature: signature,
		message: message
	};
}
```
