Authentication

Overview

The Rewards Claiming API uses wallet signature verification to authenticate requests. This method ensures that only the actual wallet owner can claim rewards associated with that address.

Traditional authentication methods like API keys or tokens are not used. Instead, users must sign messages with their Solana wallet to prove ownership.

How It Works

The authentication process works as follows:

  1. Generate a timestamp - Create a current Unix timestamp in milliseconds

  2. Sign the timestamp - Use your Solana wallet to sign this timestamp

  3. Include the signature - Send both the timestamp and the signature in the API request headers

Required Headers

For endpoints that require authentication, you must include these headers:

Header
Description

X-Timestamp

The Unix timestamp in milliseconds that was signed

X-Signature

The base58-encoded signature of the timestamp

Timestamp Expiration

For security reasons, signatures are only valid for 5 minutes after the timestamp is created. This helps prevent replay attacks. If the timestamp is older than 5 minutes, the API will return an EXPIRED_SIGNATURE error.

Signature Verification Example

Using @solana/web3.js

import { Keypair } from "@solana/web3.js"
import bs58 from "bs58"
import nacl from "tweetnacl"

// Create the timestamp
const timestamp = Date.now().toString()

// Sign the timestamp with your wallet
const signTimestamp = async (wallet, timestamp) => {
  // Convert string timestamp to Uint8Array
  const messageBytes = new TextEncoder().encode(timestamp)

  // Sign the timestamp (implementation depends on your wallet integration)
  // For a Keypair:
  const signature = nacl.sign.detached(messageBytes, wallet.secretKey)

  // Return the base58-encoded signature
  return bs58.encode(signature)
}

// For wallet adapters like Phantom, Solflare, etc.
const signWithWalletAdapter = async (walletAdapter, timestamp) => {
  // Most wallet adapters provide a signMessage method
  const signature = await walletAdapter.signMessage(new TextEncoder().encode(timestamp))

  return bs58.encode(signature)
}

Common Authentication Errors

Error Code
Description
Solution

MISSING_AUTHENTICATION

Missing signature or timestamp headers

Ensure both X-Signature and X-Timestamp headers are included in your request

INVALID_SIGNATURE

Signature verification failed

Ensure the signature corresponds to the provided timestamp and address

EXPIRED_SIGNATURE

Timestamp is older than 5 minutes

Generate a new timestamp and signature

INVALID_TIMESTAMP

Timestamp is not a valid number

Ensure the timestamp is a valid Unix timestamp in milliseconds

SIGNATURE_VERIFICATION_ERROR

Error during signature verification process

Ensure the signature is properly base58-encoded

Security Best Practices

  1. Generate a fresh timestamp for each request

  2. Never share your private key or seed phrase

  3. Verify that you're connecting to the official API domain

  4. Implement retry logic that regenerates the timestamp if a request fails due to an expired signature

Last updated