# 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

```javascript
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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.something.cool/rewards-claiming/auth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
