Connecting to the Bounties API

If you want to use the Off-chain auth API, follow this guide to authenticate your Ethereum address.

No gas and no transactions are required to follow the steps below. If you do want to try transactions without paying real gas, use the rinkeby test net. The StandardBounties smart contract is deployed to:

Only this API requires auth:

These API's don't require auth:

Note: Unless you are familiar with terms like off chain and on chain, web3, mainnet and rinkeby, we recommend taking a quick look at the Useful terms before you get started.

Step 1: Get the nonce

As we described in the Useful terms section, a nonce is a unique and random message. We use a nonce as a way to verify that the person making the request is actually the owner of the Ethereum address.

First, let's request the nonce from the server with the address:

// Let's assume we have the Bounties API running on our local host
const api = 'http://rinkeby.api.bounties.network/auth/'

// This is a made up address, but you would use a real one: 
const address = '0xe42f8C6AB127ecDFD5cbf031f74A584aD2fC494b'

// Putting it all together, we have the endpoint we want to call:
const endpoint = api + address + '/nonce/'

// Let's call the endpoint to get the nonce:
let nonce = ''
fetch(endpoint).then(function(response) {
	// First promise resolved, we have the data but json() returns another promise
  return response.json()
}).then(function(json) {
  // Second promise resolved, we have the nonce!
  nonce = json.nonce
})

Now we have our nonce, and we can move on to the signing step.

Step 2: Sign with web3

Next, we can easily call the sign function using web3, asking the user to approve the nonce we got above. Let's request a signature to verify the Etherum address:

let signature = ''

web3.personal.sign(
  web3.fromUtf8('Hi there! Your special nonce: ' + nonce),
  web3.eth.accounts[0],
  function(error, response){
  	signature = response
  }
)

Step 3: Sign in with JWT (JSON Web Tokens)

Now that we have signed and received the signature, we are ready to sign in. The preferred method is using JWT, but this does require you to keep track of the JWT yourself. In this example, we save it to token.

Note: The JWT token is only valid for 2 weeks. At that time it expires and it won't be usable, and a new login is necessary.

Once we successfully sign in, we get the user data:

let user
let token

fetch('http://rinkeby.api.bounties.network/auth/login/jwt/', {
  method: 'post',
  credentials: 'include',
  body: JSON.stringify({
    public_address: '0xe66f8C6AB127ecDFD5cbf031f74A584aD2fC494b',
    signature: signature // The signature we requested above
  }),
  headers: {
    'content-type': 'application/json'
  }
}).then(function(response) {
  return response.json()
}).then(function(json) {
  user = json.user
  token = json.token
})

Any subsequent calls that require authentication must now follow this format, adding headers that use the JWT token we received above:

fetch('http://rinkeby.api.bounties.network/auth/user/', {
  method: 'get',
  headers: {
    'content-type': 'application/json',
    'Authentication': token
  },
}).then(function(response) {
  return response.json()
}).then(function(json) {
  user = json
})

Alternative Step 3: Session based sign in

Although using JWT is the recommended way, you can also use sessions. This might break in more secure browsers that are strict about cookies, and staying logged in could be a problem. We strongly recommend using JWT.

Following a similar flow as with JWT, we log in using the signature and the address from before:

let user

fetch('http://rinkeby.api.bounties.network/auth/login/', {
  method: 'post',
  credentials: 'include',
  body: JSON.stringify({
    public_address: '0xe42f8C6AB127ecDFD5cbf031f74A584aD2fC494b',
    signature: signature
  }),
  headers: {
    'content-type': 'application/json'
  }
}).then(function(response) {
 	// First promise resolved, but json() returns another promise
  return response.json()
}).then(function(json) {
  // Second promise resolved, we have the user!
  user = json
})

And that's all there is to it!

Subsequent calls will have the cookie set, and not require authentication again. From here on out, you can access the Bounties API for the user you have authenticated.

We hope this guide was useful, and that you were able to follow the steps without any issues! If you found anything wrong with these steps, please click "Suggest Edits" in the upper right corner. We would truly appreciate it, and it would make the experience better for everyone.