README.md

# TelegramMiniappValidation

A library for validating Telegram Mini App initialization data in Elixir.

## Installation

The package can be installed by adding `telegram_miniapp_validation` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:telegram_miniapp_validation, "~> 0.1.0"},
    {:jason, "~> 1.4"} # Required for parsing JSON user data
  ]
end
```

## Usage

This library provides functionality to validate the initialization data received from Telegram Mini Apps. The validation process ensures that the data was indeed sent by Telegram and hasn't been tampered with.

### Basic Usage

```elixir
alias TelegramMiniappValidation, as: Validator

# The init_data is the raw query string received from the Telegram Mini App
init_data = "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%7D&auth_date=1662771648&hash=c501b71e775f74ce10e377dea85a7ea24ecd640b223ea86dfe453e0eaed2e2b2"

# Your Telegram Bot token
bot_token = "YOUR_BOT_TOKEN"

# Validate the init data
case Validator.validate(init_data, bot_token) do
  {:ok, data} ->
    # The data is valid, you can now use it
    IO.inspect(data)
    
  {:error, reason} ->
    # The data is invalid
    IO.puts("Validation failed: #{reason}")
end
```

### Customizing Validation

You can customize the validation by specifying the maximum age of the auth_date parameter:

```elixir
# Set the maximum age to 1 hour (3600 seconds)
case Validator.validate(init_data, bot_token, 3600) do
  {:ok, data} ->
    # The data is valid and not older than 1 hour
    IO.inspect(data)
    
  {:error, reason} ->
    # The data is invalid or too old
    IO.puts("Validation failed: #{reason}")
end
```

### Additional Functions

The library also provides these public functions that can be used individually:

```elixir
# Parse the initialization data and extract the hash
{:ok, {data_map, hash}} = Validator.parse_and_extract_hash(init_data)

# Validate just the auth_date (86400 seconds = 24 hours)
:ok = Validator.validate_auth_date(data_map, 86400)

# Validate just the hash
true = Validator.valid_hash?(init_data, hash, bot_token)
```

## Validation Process

The validation process follows these steps:

1. Parse the query string into key-value pairs
2. Extract the hash value and remove it from the pairs
3. Sort the remaining pairs alphabetically
4. Create a data check string by joining the pairs with newlines
5. Create an HMAC-SHA256 signature of the bot token using "WebAppData" as the key
6. Create an HMAC-SHA256 signature of the data check string using the result from step 5 as the key
7. Compare the calculated hash with the provided hash

This implementation follows the official Telegram Mini Apps documentation: [Validating Init Data](https://docs.telegram-mini-apps.com/platform/init-data#validating).

## Examples

For more comprehensive examples, see the `examples/validate_init_data.exs` file in the repository.

If you want to have a simple function for validating the hash check out `examples/validator.ex` file in the repository

## License

This project is licensed under the MIT License - see the LICENSE file for details.