# Integration

To illustrate how apps can be decentralized with the Zellular Sequencer, let’s look at a basic order book created using Python with Flask for handling user orders and SQLite for data storage. This example is streamlined, focusing solely on demonstrating the practical integration with the Zellular Sequencer, and does not include the extensive features of a full-scale implementation.

### Python Code for a Simple Order-Book[](https://docs.zellular.xyz/integration.html#python-code-for-a-simple-order-book)

The complete code for the sample order book is available at [this link](https://github.com/zelluar_xy/zsequencer/blob/18ba23dda29813820d658c5033ad945784f88b31/docs/codes/order_book.py). Below is a brief overview of the code structure:

#### Setting up the Environment[](https://docs.zellular.xyz/integration.html#setting-up-the-environment)

This section sets up the basic Flask application and the database:

```python
from flask import Flask, request, session, jsonify
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import check_password_hash

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///orders.db'
app.config['SECRET_KEY'] = 'your_secret_key'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(120), nullable=False)

class Balance(db.Model):
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    token = db.Column(db.String(50), primary_key=True)
    amount = db.Column(db.Float, nullable=False)

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    base_token = db.Column(db.String(50), nullable=False)
    quote_token = db.Column(db.String(50), nullable=False)
    order_type = db.Column(db.String(10), nullable=False)
    quantity = db.Column(db.Float, nullable=False)
    price = db.Column(db.Float, nullable=False)
    matched = db.Column(db.Boolean, default=False, nullable=False)

@app.before_first_request
def create_tables():
    db.create_all()
```

#### User Authentication[](https://docs.zellular.xyz/integration.html#user-authentication)

This section adds a login route to authenticate users:

```python
@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password_hash, password):
        session['user_id'] = user.id
        return jsonify({"message": "Logged in successfully"}), 200
    return jsonify({"message": "Invalid username or password"}), 401
```

#### Order Submission[](https://docs.zellular.xyz/integration.html#order-submission)

`place_order` adds a route to the server to enable users submitting buy and sell orders if they have logged in and have a session:

```python
@app.route('/order', methods=['POST'])
def place_order():
    if 'user_id' not in session:
        return jsonify({"message": "Please log in"}), 401

    order_type = request.form['order_type']
    base_token = request.form['base_token']
    quote_token = request.form['quote_token']
    quantity = float(request.form['quantity'])
    price = float(request.form['price'])

    ...
```

#### Order Matching[](https://docs.zellular.xyz/integration.html#order-matching)

`match_order` and `update_balances` implement the core logic of matching orders and updating users balances:

```python
def match_order(new_order):
    # Logic to find and process matching orders
    ...


def update_balances(new_order, matched_order, trade_quantity):
    # Logic to update balances after matching orders
    ...
```

### Applying Signature-based Authentication[](https://docs.zellular.xyz/integration.html#applying-signature-based-authentication)

To decentralize an app like the order-book using the Zellular Sequencer, start by switching to a signature-based authentication system. Here’s how to do it:

#### Identifying Users by their Public Keys[](https://docs.zellular.xyz/integration.html#identifying-users-by-their-public-keys)

Since username and password are no longer needed for authentication, the `User` table can be eliminated. Additionally, update the `user_id` field in the `Order` and `Balance` table to reference the user’s `public_key`, which serves as the user identifier in the new version.

```python
class Balance(db.Model):
    public_key = db.Column(db.String(500), primary_key=True)
    ...

class Order(db.Model):
    ...
    public_key = db.Column(db.String(500), nullable=False)
    ...
```

#### Authorising Users by their Signatures[](https://docs.zellular.xyz/integration.html#authorising-users-by-their-signatures)

Remove the login function, as session-based authentication is no longer used, and users sign every request. Add a signature parameter to the `place_order` function, using this signature to verify access authorization instead of relying on user sessions.

```python
from ecdsa import VerifyingKey, SECP256k1, BadSignatureError
...

def verify_order(order):
    # Serialize the data from the form fields
    keys = ['order_type', 'base_token', 'quote_token', 'quantity', 'price']
    message = ','.join([order[key] for key in keys]).encode('utf-8')

    # Verify the signature
    try:
        public_key = base64.b64decode(order['public_key'])
        signature = base64.b64decode(order['signature'])
        vk = VerifyingKey.from_string(public_key, curve=SECP256k1)
        vk.verify(signature, message)
    except (BadSignatureError, ValueError):
        return False
    return True

@app.route('/order', methods=['POST'])
def place_order():
    if not verify_order(request.form):
        return jsonify({"message": "Invalid signature"}), 403

    ...
```

### Sequencing orders before applying them[](https://docs.zellular.xyz/integration.html#sequencing-orders-before-applying-them)

The next step in decentralizing the app is to send user-signed orders to the Zellular Sequencer before applying them to the database and update the database after receiving them back from the sequencer. This helps all the nodes running the app apply the requests in a consistent order. Here’s how it should be done:

#### Sending orders to the Sequencer[](https://docs.zellular.xyz/integration.html#sending-orders-to-the-sequencer)

After signature verification, the place\_order function uses the `POST /node/{app}/batches` endpoint of the Zellular Sequencer service to send the orders to the sequencer before applying them into the database.

```python
zsequencer_url = 'http://5.161.230.186:6001/node/orderbook/batches'
...

@app.route('/order', methods=['POST'])
def place_order():
    if not verify_order(request.form):
        return jsonify({"message": "Invalid signature"}), 403

    keys = ['order_type', 'base_token', 'quote_token', 'quantity', 'price', 'signature']
    txs = [{key: request.form[key] for key in keys}]
    requests.put(zsequencer_url, json=txs)
    return { 'success': True }
```

#### Receiving sequenced orders from the sequencer[](https://docs.zellular.xyz/integration.html#receiving-sequenced-orders-from-the-sequencer)

Add a thread to continuously retrieve finalized, sequenced orders and apply the same routine used in the `place_order` function to process these orders. [Zellular SDK](https://github.com/zellular-xyz/zellular.py) can be used to pull the finalized sequence of transaction batches from the Zellular network.

```python
import zellular

def process_loop():
    verifier = zellular.Verifier("orderbook", "http://5.161.230.186:6001")
    for batch, index in verifier.batches():
        txs = json.loads(batch)
        for i, tx in enumerate(txs):
            place_order(tx)

def __place_order(order):
    if not verify_order(order):
        print("Invalid signature:", order)
        return
    ...

if __name__ == '__main__':
    Thread(target=process_loop).start()
    app.run(debug=True)
```

The complete code for the decentralized version of the sample order book can be accessed [here](https://github.com/zellular-xyz/zsequencer/blob/main/docs/codes/order_book.py). Additionally, you can view the GitHub comparison between the centralized and decentralized versions [here](https://github.com/zellular-xyz/zsequencer/compare/18ba23d..39a1a42). As demonstrated, integrating the Zellular Sequencer into your apps is straightforward and accessible for any Python developer, without requiring deep expertise in blockchain or smart contracts.


---

# 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://zellular.gitbook.io/zellular-docs/technical-documentation/integration.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.
