Name | zellular JSON |
Version |
0.2.8
JSON |
| download |
home_page | None |
Summary | SDK package for zellular sequencer |
upload_time | 2025-07-12 15:45:12 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.7.2 |
license | MIT |
keywords |
sdk
sequencer
blockchain
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# zellular.py
A Python SDK for interacting with the Zellular network.
## Dependencies
To use zelluar.py, you'll need to install the [MCL](https://github.com/herumi/mcl) native library. Follow these steps to install it:
```
$ sudo apt install libgmp3-dev
$ wget https://github.com/herumi/mcl/archive/refs/tags/v1.93.zip
$ unzip v1.93.zip
$ cd mcl-1.93
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install
```
## Installation
Install the zelluar.py package via pip:
```
pip install zellular
```
## Usage
### Network Architectures
Zellular supports multiple network architectures:
1. **EigenlayerNetwork**: For interacting with Zellular deployed on EigenLayer.
2. **StaticNetwork**: For local testing or proof-of-authority deployments with a fixed set of operators.
### Setting Up With EigenLayer Network
```python
from zellular import Zellular, EigenlayerNetwork
# Create the network instance
network = EigenlayerNetwork(
subgraph_url="https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3",
threshold_percent=67 # Default threshold for consensus
)
# Create the Zellular client
app_name = "simple_app"
zellular = Zellular(app_name, network)
```
### Setting Up With Static Network
```python
import json
from zellular import Zellular, StaticNetwork
# Load node data from a JSON file
with open("nodes.json") as f:
nodes_data = json.load(f)
# Create the network instance
network = StaticNetwork(nodes_data, threshold_percent=67)
# Create the Zellular client
app_name = "simple_app"
zellular = Zellular(app_name, network)
```
### Active Operators and Gateway Selection
When initializing a Zellular client, you can optionally specify a `gateway` parameter to connect to a specific operator. If you don't provide a gateway, Zellular automatically selects a random active operator for your application:
```python
from zellular import Zellular, EigenlayerNetwork
network = EigenlayerNetwork(
subgraph_url="https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3",
threshold_percent=67
)
# Without gateway parameter - automatically selects a random active operator
zellular_auto = Zellular("simple_app", network)
# With custom gateway parameter - uses the specified operator
custom_gateway = "http://your-custom-operator:6001"
zellular_custom = Zellular("simple_app", network, gateway=custom_gateway)
```
You can also manually find operators that are actively participating in consensus for a specific app using the `get_active_operators` method:
```python
import asyncio
from pprint import pprint
from zellular import Zellular, EigenlayerNetwork
network = EigenlayerNetwork(
subgraph_url="https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3",
threshold_percent=67
)
zellular = Zellular("simple_app", network)
# Get active operators - returns operators running latest version with up-to-date consensus state
active_operators = asyncio.run(zellular.get_active_operators("simple_app"))
pprint(active_operators)
# Manually select a random active operator if needed
if active_operators:
random_operator = active_operators[0]
print(f"Selected operator: {random_operator.socket}")
```
Active operator selection is particularly useful when you need to:
- Find healthy nodes for your application
- Ensure you're connecting to operators running the latest version
- Select a node with an up-to-date view of the consensus state
### Posting Transactions
Zellular sequences transactions in batches. You can send a batch of transactions like this:
```python
import time
from uuid import uuid4
from zellular import Zellular, EigenlayerNetwork
network = EigenlayerNetwork(
subgraph_url="https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3",
threshold_percent=67
)
app_name = "simple_app"
zellular = Zellular(app_name, network)
t = int(time.time())
txs = [{"operation": "foo", "tx_id": str(uuid4()), "t": t} for _ in range(5)]
index = zellular.send(txs, blocking=True)
```
When setting `blocking=True`, the method waits for the batch to be sequenced and returns the index.
> [!TIP]
> You can add your app to zellular test network using:
> `curl -X POST https://www.zellular.xyz/testnet/apps -H "Content-Type: application/json" -d '{"app_name": "your-app-name"}'`
### Fetching and Verifying Transactions
Unlike reading from a traditional blockchain, where you must trust the node you're connected to, Zellular allows trustless reading of sequenced transactions. This is achieved through an aggregated BLS signature that verifies if the sequence of transaction batches is approved by the majority of Zellular nodes. The Zellular SDK abstracts the complexities of verifying these signatures, providing a simple way to constantly pull the latest finalized transaction batches:
```python
import json
from zellular import Zellular, EigenlayerNetwork
network = EigenlayerNetwork(
subgraph_url="https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3",
threshold_percent=67
)
app_name = "simple_app"
zellular = Zellular(app_name, network)
for batch, index in zellular.batches(after=0):
txs = json.loads(batch)
for i, tx in enumerate(txs):
print(index, i, tx)
```
Example output:
```
app: simple_app, index: 1, result: True
app: simple_app, index: 2, result: True
583 0 {'tx_id': '7eaa...2101', 'operation': 'foo', 't': 1725363009}
583 1 {'tx_id': '5839...6f5e', 'operation': 'foo', 't': 1725363009}
583 2 {'tx_id': '0a1a...05cb', 'operation': 'foo', 't': 1725363009}
583 3 {'tx_id': '6339...cc08', 'operation': 'foo', 't': 1725363009}
583 4 {'tx_id': 'cf4a...fc19', 'operation': 'foo', 't': 1725363009}
...
```
If you want to start reading batches from the latest finalized batch rather than from the beginning, you can achieve this by specifying the `after` parameter with the latest index. Here's an example of how to do this:
```python
index = zellular.get_last_finalized()["index"]
for batch, index in zellular.batches(after=index):
...
```
## Testing
To test the Zellular SDK locally, you need to simulate a Zellular network environment. This is done using the [zsequencer](https://github.com/zellular-xyz/zsequencer/) repository.
### Step 1: Clone and Run the ZSequencer Simulation
Follow the instructions in the [zsequencer test section](https://github.com/zellular-xyz/zsequencer/#testing) to run a local Zellular network simulation. This includes spinning up a simulation netowrk of operator nodes:
```bash
git clone https://github.com/zellular-xyz/zsequencer.git
cd zsequencer
docker compose build
uv run -m tests.e2e.run start
```
### Step 2: Clone and Install Zellular SDK in Dev Mode
In a separate terminal:
```bash
git clone https://github.com/zellular-xyz/zellular.py.git
cd zellular.py
pip install -e .[dev]
```
### Step 3: Run the Tests
With the simulation network running, you can now run the test suite:
```bash
pytest tests/test_zellular_static.py
```
Raw data
{
"_id": null,
"home_page": null,
"name": "zellular",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7.2",
"maintainer_email": null,
"keywords": "sdk, sequencer, blockchain",
"author": null,
"author_email": "Mahdi <mahdi@zellular.xyz>",
"download_url": "https://files.pythonhosted.org/packages/d1/eb/a4e387363e855d72995d60366a9248e1610df9ec119056ca7a0e97854b5d/zellular-0.2.8.tar.gz",
"platform": null,
"description": "# zellular.py\n\nA Python SDK for interacting with the Zellular network.\n\n## Dependencies\n\nTo use zelluar.py, you'll need to install the [MCL](https://github.com/herumi/mcl) native library. Follow these steps to install it:\n\n```\n$ sudo apt install libgmp3-dev\n$ wget https://github.com/herumi/mcl/archive/refs/tags/v1.93.zip\n$ unzip v1.93.zip\n$ cd mcl-1.93\n$ mkdir build\n$ cd build\n$ cmake ..\n$ make\n$ make install\n```\n\n## Installation\n\nInstall the zelluar.py package via pip:\n\n```\npip install zellular\n```\n\n## Usage\n\n### Network Architectures\n\nZellular supports multiple network architectures:\n\n1. **EigenlayerNetwork**: For interacting with Zellular deployed on EigenLayer.\n2. **StaticNetwork**: For local testing or proof-of-authority deployments with a fixed set of operators.\n\n### Setting Up With EigenLayer Network\n\n```python\nfrom zellular import Zellular, EigenlayerNetwork\n\n# Create the network instance\nnetwork = EigenlayerNetwork(\n subgraph_url=\"https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3\",\n threshold_percent=67 # Default threshold for consensus\n)\n\n# Create the Zellular client\napp_name = \"simple_app\"\nzellular = Zellular(app_name, network)\n```\n\n### Setting Up With Static Network\n\n```python\nimport json\nfrom zellular import Zellular, StaticNetwork\n\n# Load node data from a JSON file\nwith open(\"nodes.json\") as f:\n nodes_data = json.load(f)\n\n# Create the network instance\nnetwork = StaticNetwork(nodes_data, threshold_percent=67)\n\n# Create the Zellular client\napp_name = \"simple_app\"\nzellular = Zellular(app_name, network)\n```\n\n### Active Operators and Gateway Selection\n\nWhen initializing a Zellular client, you can optionally specify a `gateway` parameter to connect to a specific operator. If you don't provide a gateway, Zellular automatically selects a random active operator for your application:\n\n```python\nfrom zellular import Zellular, EigenlayerNetwork\n\nnetwork = EigenlayerNetwork(\n subgraph_url=\"https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3\",\n threshold_percent=67\n)\n\n# Without gateway parameter - automatically selects a random active operator\nzellular_auto = Zellular(\"simple_app\", network)\n\n# With custom gateway parameter - uses the specified operator\ncustom_gateway = \"http://your-custom-operator:6001\"\nzellular_custom = Zellular(\"simple_app\", network, gateway=custom_gateway)\n```\n\nYou can also manually find operators that are actively participating in consensus for a specific app using the `get_active_operators` method:\n\n```python\nimport asyncio\nfrom pprint import pprint\nfrom zellular import Zellular, EigenlayerNetwork\n\nnetwork = EigenlayerNetwork(\n subgraph_url=\"https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3\",\n threshold_percent=67\n)\n\nzellular = Zellular(\"simple_app\", network)\n\n# Get active operators - returns operators running latest version with up-to-date consensus state\nactive_operators = asyncio.run(zellular.get_active_operators(\"simple_app\"))\npprint(active_operators)\n\n# Manually select a random active operator if needed\nif active_operators:\n random_operator = active_operators[0]\n print(f\"Selected operator: {random_operator.socket}\")\n```\n\nActive operator selection is particularly useful when you need to:\n- Find healthy nodes for your application\n- Ensure you're connecting to operators running the latest version\n- Select a node with an up-to-date view of the consensus state\n\n### Posting Transactions\n\nZellular sequences transactions in batches. You can send a batch of transactions like this:\n\n```python\nimport time\nfrom uuid import uuid4\nfrom zellular import Zellular, EigenlayerNetwork\n\nnetwork = EigenlayerNetwork(\n subgraph_url=\"https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3\",\n threshold_percent=67\n)\n\napp_name = \"simple_app\"\nzellular = Zellular(app_name, network)\n\nt = int(time.time())\ntxs = [{\"operation\": \"foo\", \"tx_id\": str(uuid4()), \"t\": t} for _ in range(5)]\n\nindex = zellular.send(txs, blocking=True)\n```\n\nWhen setting `blocking=True`, the method waits for the batch to be sequenced and returns the index.\n\n> [!TIP]\n> You can add your app to zellular test network using:\n> `curl -X POST https://www.zellular.xyz/testnet/apps -H \"Content-Type: application/json\" -d '{\"app_name\": \"your-app-name\"}'`\n\n\n### Fetching and Verifying Transactions\n\nUnlike reading from a traditional blockchain, where you must trust the node you're connected to, Zellular allows trustless reading of sequenced transactions. This is achieved through an aggregated BLS signature that verifies if the sequence of transaction batches is approved by the majority of Zellular nodes. The Zellular SDK abstracts the complexities of verifying these signatures, providing a simple way to constantly pull the latest finalized transaction batches:\n\n```python\nimport json\nfrom zellular import Zellular, EigenlayerNetwork\n\nnetwork = EigenlayerNetwork(\n subgraph_url=\"https://api.studio.thegraph.com/query/95922/avs-subgraph/v0.0.3\",\n threshold_percent=67\n)\n\napp_name = \"simple_app\"\nzellular = Zellular(app_name, network)\n\nfor batch, index in zellular.batches(after=0):\n txs = json.loads(batch)\n for i, tx in enumerate(txs):\n print(index, i, tx)\n```\nExample output:\n\n```\napp: simple_app, index: 1, result: True\napp: simple_app, index: 2, result: True\n583 0 {'tx_id': '7eaa...2101', 'operation': 'foo', 't': 1725363009}\n583 1 {'tx_id': '5839...6f5e', 'operation': 'foo', 't': 1725363009}\n583 2 {'tx_id': '0a1a...05cb', 'operation': 'foo', 't': 1725363009}\n583 3 {'tx_id': '6339...cc08', 'operation': 'foo', 't': 1725363009}\n583 4 {'tx_id': 'cf4a...fc19', 'operation': 'foo', 't': 1725363009}\n...\n```\n\nIf you want to start reading batches from the latest finalized batch rather than from the beginning, you can achieve this by specifying the `after` parameter with the latest index. Here's an example of how to do this:\n\n```python\nindex = zellular.get_last_finalized()[\"index\"]\nfor batch, index in zellular.batches(after=index):\n ...\n```\n\n## Testing\n\nTo test the Zellular SDK locally, you need to simulate a Zellular network environment. This is done using the [zsequencer](https://github.com/zellular-xyz/zsequencer/) repository.\n\n### Step 1: Clone and Run the ZSequencer Simulation\n\nFollow the instructions in the [zsequencer test section](https://github.com/zellular-xyz/zsequencer/#testing) to run a local Zellular network simulation. This includes spinning up a simulation netowrk of operator nodes:\n\n```bash\ngit clone https://github.com/zellular-xyz/zsequencer.git\ncd zsequencer\ndocker compose build\nuv run -m tests.e2e.run start\n```\n\n### Step 2: Clone and Install Zellular SDK in Dev Mode\n\nIn a separate terminal:\n\n```bash\ngit clone https://github.com/zellular-xyz/zellular.py.git\ncd zellular.py\npip install -e .[dev]\n```\n\n### Step 3: Run the Tests\n\nWith the simulation network running, you can now run the test suite:\n\n```bash\npytest tests/test_zellular_static.py\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "SDK package for zellular sequencer",
"version": "0.2.8",
"project_urls": {
"Homepage": "https://github.com/zellular-xyz/zellular.py"
},
"split_keywords": [
"sdk",
" sequencer",
" blockchain"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7d8f2b4c8f86d94dbd352ee6d1aa2ce028253e400fdeeeafe0e4e1b0000e9977",
"md5": "86750166d3b8f26eb05e3379bd5dd99c",
"sha256": "b096b56a82ed337caf8be1e273989f7ebd0eed945ec531c7174ae5ca21cdc27e"
},
"downloads": -1,
"filename": "zellular-0.2.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "86750166d3b8f26eb05e3379bd5dd99c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7.2",
"size": 11569,
"upload_time": "2025-07-12T15:45:10",
"upload_time_iso_8601": "2025-07-12T15:45:10.724280Z",
"url": "https://files.pythonhosted.org/packages/7d/8f/2b4c8f86d94dbd352ee6d1aa2ce028253e400fdeeeafe0e4e1b0000e9977/zellular-0.2.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d1eba4e387363e855d72995d60366a9248e1610df9ec119056ca7a0e97854b5d",
"md5": "901d7dbc13bc05f5d8eda69912955cc0",
"sha256": "9c2258fa2007aac13bae91b8671875249f1a84c6e49726ad4094f92f61ae990d"
},
"downloads": -1,
"filename": "zellular-0.2.8.tar.gz",
"has_sig": false,
"md5_digest": "901d7dbc13bc05f5d8eda69912955cc0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7.2",
"size": 12989,
"upload_time": "2025-07-12T15:45:12",
"upload_time_iso_8601": "2025-07-12T15:45:12.994419Z",
"url": "https://files.pythonhosted.org/packages/d1/eb/a4e387363e855d72995d60366a9248e1610df9ec119056ca7a0e97854b5d/zellular-0.2.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-12 15:45:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "zellular-xyz",
"github_project": "zellular.py",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "zellular"
}