Skip to content

Repository files navigation

Landbou

Decentralized land registration and verification on the Stellar blockchain.

License: MIT Stellar Soroban All Contributors


Overview

Landbou is an open-source, decentralized protocol for registering, verifying, and trading land parcels on the Stellar blockchain. It provides governments, developers, and land owners with a transparent, immutable, and tamper-proof system for managing real-world land records.

By combining Stellar's fast, low-cost infrastructure with Soroban smart contracts, Landbou eliminates the inefficiencies of paper-based land registries and bridges the gap between traditional property law and Web3 ownership.

Key Features

Feature Description
Land Registration Register parcels on-chain with GPS coordinates, area, and land-use metadata
Inspector Workflow Assigned inspectors approve or reject parcels before they can be traded
NFT Ownership Each approved parcel is minted as a non-fungible token (Soroban NFT)
Marketplace List, update, cancel, and purchase land parcels using XLM
Transaction History Full immutable audit trail for every ownership change
Role Management Admin, inspector, and owner roles with on-chain access control
Upgradeable Contracts Admin-gated Wasm upgrade path via Soroban's update_current_contract_wasm

Architecture

Landbou is organized as a monorepo with the following components:

landbou/
├── app/
│   └── client/               # Next.js frontend (Stellar wallet integration)
├── contracts/
│   └── land_registry/        # Soroban smart contracts (Rust)
│       ├── src/
│       │   ├── lib.rs         # Module root & public re-exports
│       │   ├── land_register.rs  # LandRegistry contract
│       │   ├── land_nft.rs    # LandNFT contract
│       │   ├── types.rs       # Shared data structures
│       │   ├── errors.rs      # Error code definitions
│       │   └── utils.rs       # Land ID generation & helpers
│       ├── tests/
│       │   └── test_land_registry.rs
│       └── Cargo.toml
├── docs/                     # Protocol documentation
├── indexers/
│   └── land-registry/        # Blockchain event indexer (Node.js)
├── land-registry-backend/    # REST API backend (Express + PostgreSQL)
├── landing_page/             # Marketing & onboarding site (Next.js)
├── sdk/                      # JavaScript SDK for protocol interaction
└── tools/
    ├── cli/                  # CLI tool for contract interaction (Rust)
    └── explorer/             # Block explorer utility (Rust)

Contract Architecture

┌────────────────────┐       mints / locks / unlocks       ┌──────────────┐
│   LandRegistry     │ ──────────────────────────────────► │   LandNFT    │
│                    │                                      │              │
│  • register_land   │       cross-contract calls           │  • mint      │
│  • approve_land    │ ◄────────────────────────────────── │  • transfer  │
│  • buy_land        │                                      │  • lock      │
│  • …               │                                      │  • unlock    │
└────────────────────┘                                      └──────────────┘
        │
        │ reads / writes
        ▼
  Soroban Persistent Storage
  (lands, listings, inspectors, history)

Smart Contracts

The contracts are written in Rust using the soroban-sdk and live in contracts/land_registry/.

LandRegistry

The central registry contract. It handles the full lifecycle of a land parcel.

Function Access Description
initialize(admin, nft_contract) Once Deploy and wire up the contracts
register_land(caller, location, area, land_use) Any Register a new land parcel; mints a locked NFT
transfer_land(caller, land_id, new_owner) Owner Transfer approved land to a new owner
get_land(land_id) View Fetch a land parcel by ID
get_land_count() View Total number of registered parcels
get_lands_by_owner(owner) View List of land IDs owned by an address
get_all_lands() View Full list of all registered parcels
update_land(caller, land_id, area, land_use, status) Owner Update mutable parcel fields
approve_land(caller, land_id) Inspector Approve a pending parcel; unlocks NFT
reject_land(caller, land_id) Inspector Reject a pending parcel
is_inspector(inspector) View Check if address is a registered inspector
is_land_approved(land_id) View Check if a parcel has been approved
get_land_status(land_id) View Get current LandStatus of a parcel
get_pending_approvals() View List of land IDs awaiting approval
get_land_transaction_history(land_id) View Full ownership history for a parcel
set_land_inspector(caller, land_id, inspector) Admin Assign an inspector to a parcel
get_land_inspector(land_id) View Get the assigned inspector for a parcel
add_inspector(caller, inspector) Admin Register a new inspector address
remove_inspector(caller, inspector) Admin Remove a registered inspector
get_all_inspectors() View List of all registered inspectors
inspector_lands(inspector) View List of parcels assigned to an inspector
get_user_type(user_address) View Returns "admin", "inspector", "owner", or "none"
create_listing(caller, land_id, price) Owner Create a marketplace listing
cancel_listing(caller, listing_id) Seller Cancel an active listing
update_listing_price(caller, listing_id, new_price) Seller Update listing price
buy_land(buyer, listing_id) Any Purchase a listed parcel using XLM
get_listing(listing_id) View Fetch a listing by ID
get_active_listings() View List of all active listing IDs
upgrade(caller, new_hash) Admin Upgrade contract Wasm

LandNFT

Non-fungible token contract representing land parcel ownership.

Function Access Description
initialize(admin, registry_contract) Once Deploy and configure the NFT contract
mint(to, token_id) Registry Mint a locked NFT for a new parcel
transfer(from, to, token_id) Registry / Owner Transfer an unlocked token
lock(token_id) Registry Lock a token (prevents transfer)
unlock(token_id) Registry Unlock a token (after approval)
set_base_uri(new_base_uri, updater) Admin Update metadata base URI
owner_of(token_id) View Get the current token owner
is_locked(token_id) View Check if a token is locked
base_uri() View Get the current metadata base URI

Data Structures

pub struct Land {
    pub land_id:                    u64,
    pub owner:                      Address,
    pub location:                   Location,
    pub area:                       u64,        // square metres
    pub land_use:                   String,
    pub status:                     LandStatus,
    pub last_transaction_timestamp: u64,        // ledger timestamp
    pub inspector:                  Address,
}

pub struct Location {
    pub latitude:  i64,  // fixed-point × 1_000_000
    pub longitude: i64,
}

pub enum LandStatus { Pending, Approved, Rejected }

pub struct Listing {
    pub listing_id: u64,
    pub land_id:    u64,
    pub seller:     Address,
    pub price:      i128,   // stroops (1 XLM = 10_000_000 stroops)
    pub status:     ListingStatus,
    pub created_at: u64,
    pub updated_at: u64,
}

pub enum ListingStatus { Active, Sold, Cancelled }

Getting Started

Prerequisites

Tool Version Purpose
Rust ≥ 1.78 Contract compilation
Stellar CLI ≥ 21.x Deploy & interact with contracts
Node.js ≥ 20 Frontend & backend
pnpm ≥ 10 Monorepo package manager
PostgreSQL ≥ 15 Backend database

Installation

# 1. Clone the repository
git clone https://github.com/NoshonNetworks/landbou.git
cd landbou

# 2. Install Node.js dependencies
pnpm install

Build the Smart Contracts

cd contracts/land_registry

# Add the Soroban WASM target (first time only)
rustup target add wasm32-unknown-unknown

# Build optimized contract WASM
cargo build --target wasm32-unknown-unknown --release

Run Contract Tests

cd contracts/land_registry
cargo test

Deploy to Stellar Testnet

# Configure the Stellar CLI (first time)
stellar keys generate --global alice --network testnet

# Deploy the LandNFT contract
stellar contract deploy \
  --wasm target/wasm32-unknown-unknown/release/land_nft.wasm \
  --source alice \
  --network testnet

# Deploy the LandRegistry contract
stellar contract deploy \
  --wasm target/wasm32-unknown-unknown/release/land_registry.wasm \
  --source alice \
  --network testnet

# Initialize the contracts (replace CONTRACT_IDs with deployed addresses)
stellar contract invoke \
  --id <REGISTRY_CONTRACT_ID> \
  --source alice \
  --network testnet \
  -- initialize \
  --admin <ADMIN_ADDRESS> \
  --nft_contract <NFT_CONTRACT_ID>

Run the Frontend Client

# From the repository root
pnpm run client

The client starts on http://localhost:3000.

Run the Backend API

cd land-registry-backend
npm install
npm run dev

Run the Landing Page

# From the repository root
pnpm run landing

The landing page starts on http://localhost:3001.

Run the Indexer

cd indexers/land-registry
npm install
npm start

User Flow

┌─────────────────────────────────────────────────────────────────────┐
│                         Landbou Flow                                │
│                                                                     │
│  1. Connect Freighter (Stellar) wallet                              │
│  2. Select role → Land Owner  |  Land Inspector                     │
│                                                                     │
│  Land Owner Dashboard                                               │
│  ├── Register Land → provide GPS, area, land_use                    │
│  │     └── On-chain: LandRegistry::register_land                    │
│  │           └── LandNFT minted (locked, status = Pending)          │
│  │                                                                  │
│  ├── My Collections → view registered parcels                       │
│  ├── Marketplace → browse, list, and purchase land                  │
│  │     ├── create_listing → list an approved parcel                 │
│  │     └── buy_land → purchase via XLM payment                      │
│  └── Notifications → real-time status updates                       │
│                                                                     │
│  Inspector Dashboard                                                │
│  ├── Pending Queue → lands awaiting approval                        │
│  ├── Approve / Reject → approve_land | reject_land                  │
│  │     └── On approval: NFT unlocked, status = Approved             │
│  ├── Transfer Oversight → verify ownership transfers                │
│  └── Reports & Logs → transaction history per parcel               │
│                                                                     │
│  Off-chain data (metadata, search) served by the backend API.       │
└─────────────────────────────────────────────────────────────────────┘

Development

Project Scripts

pnpm run client     # Start the frontend client (dev mode)
pnpm run landing    # Start the landing page (dev mode)
pnpm run build      # Build all packages for production

Environment Variables

Create a .env file in land-registry-backend/:

DATABASE_URL=postgresql://user:password@localhost:5432/landbou
JWT_SECRET=your_jwt_secret_here
PORT=4000
STELLAR_NETWORK=testnet
REGISTRY_CONTRACT_ID=CXXX...
NFT_CONTRACT_ID=CYYY...

Create a .env.local file in app/client/:

NEXT_PUBLIC_STELLAR_NETWORK=testnet
NEXT_PUBLIC_REGISTRY_CONTRACT_ID=CXXX...
NEXT_PUBLIC_NFT_CONTRACT_ID=CYYY...

Code Quality

This project uses ESLint and Husky pre-commit hooks to enforce code quality.

# Lint all JS/TS files
pnpm exec eslint --fix "**/*.{js,ts,tsx}"

# Rust formatting and linting
cd contracts/land_registry
cargo fmt
cargo clippy

Contributing

We welcome contributions from the community. Please read the guidelines below before opening a pull request.

  1. Fork the repository and create your branch from develop.
  2. Follow the existing code style (ESLint for TypeScript, rustfmt for Rust).
  3. Write tests for any new contract functions.
  4. Open a PR against the develop branch with a clear description of your changes.
  5. Ensure all CI checks pass before requesting a review.

See .github/PULL_REQUEST_TEMPLATE.md for the PR template.


Documentation

Document Description
docs/getting_started.md Detailed setup and usage guide
docs/land_registry.md Land Registry contract reference
docs/land_nft.md Land NFT contract reference
docs/api.md Backend REST API reference
docs/Design.md UI/UX design specifications

Contributors

Fishon Amos
Fishon Amos

💻 👀
Solomonsolomonsolomon
Solomonsolomonsolomon

💻 🚇
Stephanie Nwankwo
Stephanie Nwankwo

💻
RAJI ABDUL
RAJI ABDUL

📖
Yusuf Habib
Yusuf Habib

💻
Akinshola
Akinshola

💻
Sagar Rana
Sagar Rana

💻
saimeunt
saimeunt

💻
Echefula Ndukwe
Echefula Ndukwe

💻
Poulav Bhowmick
Poulav Bhowmick

💻
Asher
Asher

💻
Santiago Villarreal Arley
Santiago Villarreal Arley

💻
Abdulsamad sadiq
Abdulsamad sadiq

💻
Caleb
Caleb

🎨 📖
Oshioke Salaki
Oshioke Salaki

💻

License

This project is licensed under the MIT License. See LICENSE for details.


Contact

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages