> For the complete documentation index, see [llms.txt](https://docs.lazai.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lazai.network/data-anchoring-token-dat/developer-implementation/mint-your-dat/mint-your-dat-in-python.md).

# Mint your DAT in Python

This guide walks through the process of setting up your local environment, connecting your wallet, and minting your first Data Anchoring Token (DAT) using the LazAI Python SDK.

It assumes familiarity with Python, basic blockchain interactions, and access to the LazAI Pre-Testnet.\
\
For a guided walkthrough of the entire setup and minting process, watch the official tutorial:\
➡️ <https://youtu.be/YawyZ3aziRE?si=2i104Js04nxJ-oez>

***

### Prerequisites

Ensure the following tools and credentials are available before starting:

| Requirement | Description                                                                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------- |
| Python      | Version 3.10 or later                                                                                         |
| pip         | Latest package manager version                                                                                |
| Wallet      | Funded Pre-Testnet wallet for gas fees                                                                        |
| Credentials | PRIVATE\_KEY — your wallet private key (must start with 0x) IPFS\_JWT — Pinata (or compatible) IPFS JWT token |

***

### Step 1. Project Setup

Create a new working directory and (optionally) set up a virtual environment.

```bash
mkdir lazai-contribution-py
cd lazai-contribution-py

# Optional: create a Python virtual environment
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
```

***

### Step 2. Install Dependencies

Install the LazAI SDK and required libraries.

```bash
python3 -m pip install -U alith requests rsa eth-account
```

If you prefer to load environment variables from a .env file instead of exporting them directly, install:

```bash
python3 -m pip install python-dotenv
```

***

### Step 3. Configure Environment Variables

Set your credentials in the shell environment:

```bash
export PRIVATE_KEY=<your wallet private key>   # must start with 0x
export IPFS_JWT=<your pinata ipfs jwt>
```

If you are using a .env file, include:

```bash
from dotenv import load_dotenv
load_dotenv()
```

at the top of your Python script.

***

### Step 4. Create the Minting Script

Create a file named mint.py and paste the following code.

```python
from alith.lazai import Client, ProofRequest
from alith.data import encrypt
from alith.data.storage import (
    PinataIPFS,
    UploadOptions,
    GetShareLinkOptions,
    StorageError,
)
from eth_account.messages import encode_defunct
from os import getenv
import asyncio
import requests
import rsa
import aiohttp
from pydantic import BaseModel
from typing import Optional


class ActualPinataUploadResponse(BaseModel):
    id: str
    name: str
    cid: str
    size: int
    number_of_files: int
    mime_type: str
    created_at: str
    updated_at: str
    network: str
    streamable: bool
    accept_duplicates: Optional[bool] = None
    is_duplicate: Optional[bool] = None
    group_id: Optional[str] = None


class CustomPinataIPFS(PinataIPFS):
    async def upload(self, opts: UploadOptions):
        url = "https://uploads.pinata.cloud/v3/files"

        form = aiohttp.FormData()
        form.add_field("file", opts.data, filename=opts.name, content_type="text/plain")
        form.add_field("network", "public")

        headers = {"Authorization": f"Bearer {opts.token}"}

        try:
            async with self.client.post(url, data=form, headers=headers) as response:
                if response.status != 200:
                    error_text = await response.text()
                    raise StorageError(f"Pinata IPFS API error: {error_text}")

                data = await response.json()
                pinata_response = ActualPinataUploadResponse(**data["data"])

                from alith.data.storage import FileMetadata
                return FileMetadata(
                    id=pinata_response.cid,
                    name=pinata_response.name,
                    size=pinata_response.size,
                    modified_time=pinata_response.updated_at,
                )
        except aiohttp.ClientError as e:
            raise StorageError(f"Network error: {str(e)}") from e


async def main():
    client = Client()
    ipfs = CustomPinataIPFS()

    try:
        # 1. Prepare and encrypt data
        data_file_name = "your_encrypted_data.txt"
        privacy_data = "Your Privacy Data"
        encryption_seed = "Sign to retrieve your encryption key"

        message = encode_defunct(text=encryption_seed)
        password = client.wallet.sign_message(message).signature.hex()
        encrypted_data = encrypt(privacy_data.encode(), password)

        # 2. Upload to IPFS
        token = getenv("IPFS_JWT", "")
        file_meta = await ipfs.upload(
            UploadOptions(name=data_file_name, data=encrypted_data, token=token)
        )
        url = await ipfs.get_share_link(GetShareLinkOptions(token=token, id=file_meta.id))

        # 3. Register file on LazAI
        file_id = client.get_file_id_by_url(url)
        if file_id == 0:
            file_id = client.add_file(url)

        # 4. Request proof from verified node
        client.request_proof(file_id, 100)
        job_id = client.file_job_ids(file_id)[-1]
        job = client.get_job(job_id)
        node_info = client.get_node(job[-1])

        node_url: str = node_info[1]
        pub_key = node_info[-1]
        encryption_key = rsa.encrypt(
            password.encode(),
            rsa.PublicKey.load_pkcs1(pub_key.strip().encode(), format="PEM"),
        ).hex()

        response = requests.post(
            f"{node_url}/proof",
            json=ProofRequest(
                job_id=job_id,
                file_id=file_id,
                file_url=url,
                encryption_key=encryption_key,
                encryption_seed=encryption_seed,
                proof_url=None,
            ).model_dump(),
        )

        if response.status_code == 200:
            print("Proof request sent successfully.")
        else:
            print("Failed to send proof request:", response.json())

        # 5. Request DAT reward
        client.request_reward(file_id)
        print("Reward requested for file id", file_id)

    except StorageError as e:
        print(f"Storage error: {e}")
    except Exception as e:
        raise e
    finally:
        await ipfs.close()


if __name__ == "__main__":
    asyncio.run(main())
```

***

### Step 5. Run the Script

Execute the minting process.

```bash
python mint.py
```

Expected Output:

```bash
Proof request sent successfully
Reward requested for file id <file_id>
```

***

### Troubleshooting

| Issue                          | Cause                                    | Resolution                                                          |
| ------------------------------ | ---------------------------------------- | ------------------------------------------------------------------- |
| eth\_keys or signing errors    | Invalid private key format               | Ensure PRIVATE\_KEY starts with 0x and Python version ≥ 3.10        |
| 401 / 403 IPFS errors          | Invalid or expired JWT                   | Verify your IPFS\_JWT and permissions in Pinata                     |
| Request or connection failures | Node busy or network timeout             | Wait a minute and retry; confirm your Pre-Testnet RPC configuration |
| StorageError                   | Invalid token or transient network issue | Retry the upload or reinitialize IPFS connection                    |

***

### Summary

This tutorial demonstrated how to:

1. Set up a local LazAI development environment.
2. Encrypt and upload data to IPFS.
3. Register and anchor it on the LazAI Network.
4. Generate verifiable proof and mint a DAT.
5. Request tokenized rewards on-chain.

Once this is running successfully, you can integrate the same workflow into your agent or service pipeline using the Alith SDK for automated data anchoring and reward management.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.lazai.network/data-anchoring-token-dat/developer-implementation/mint-your-dat/mint-your-dat-in-python.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
