Otterspace Docs
  • Overview
    • 🦦Intro to Otterspace
    • πŸ”‘Key Concepts
      • πŸ”₯Burning and revocation
      • ⏳Expiration
      • πŸ€“Metadata schemas
    • ❓F.A.Q
  • Documentation
    • πŸ”ŒAPI
      • πŸ”Authentication
    • πŸ™Subgraph
    • πŸ› οΈContracts
      • 🎨Create a Badge Spec
      • πŸͺ‚Airdrop a Badge
      • βœ…Adding to allowlist
      • 🀝Minting allowlisted Badges
      • βž•Add/Remove Admins
  • Guides
    • πŸ”Token-gating using badges
  • Integrations
    • Using badges with Snapshot
    • Guild.xyz for token gating
    • Using with Gnosis Safe
    • On OpenSea, Metamask etc
  • Get Help
    • πŸ•ΊDiscord/Twitter
Powered by GitBook
On this page
  • Overview
  • Integration types
  • Server-side integrations
  • Client-side integrations

Was this helpful?

  1. Documentation
  2. API

Authentication

PreviousAPINextSubgraph

Last updated 1 year ago

Was this helpful?

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.

A Raft token (NFT) is the authorization token needed to create badges withing your account. Please fill out form to apply for a Raft token and one of our team members will contact you ASAP and help you get setup.

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.

Generating an API Key

  • Sign in to and navigate to your Raft's settings page via the drop-down menu.

  • 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

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

Client-side integrations

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

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

Response

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

Step 2: Sign-in

Request

$ 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>" }'

Response

{ "<siweMessage>" }
HTTP/1.1 200 OK
Date: Mon, 18 Aug 2022 13:08:53 GMT
...
Set-Cookie: "<created cookie for this specific user>"
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>",
  ...
});

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

// 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
	};
}

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 to help convert it.

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 .

message field in the request is composed standardised off-chain authentication message proposed in . It is an object that have certain fields like address, chainId, nonce, domain etc. This standardised message is of type SiweMessage from the library.

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 . For a programmatic message signing please check the section .

πŸ”Œ
πŸ”
tool
Sign-in With Ethereum
EIP-4361
siwe
elliptic curve cryptography
below
this
https://beta.otterspace.xyz/
Your raft's API settings page