No description
  • JavaScript 45.6%
  • Shell 35.5%
  • HTML 13.1%
  • Solidity 5.8%
Find a file
Clayton Rabenda d4944a8038 2nd transport pathway to dequic
fix many bugs in dequic
fix scripts
2026-09-17 18:57:01 +08:00
contracts declaw 2026-08-21 14:28:36 +08:00
dapps 2nd transport pathway to dequic 2026-09-17 18:57:01 +08:00
docs fix pricing for media 2026-09-15 12:25:21 +08:00
scripts 2nd transport pathway to dequic 2026-09-17 18:57:01 +08:00
.gitignore feat: better deployment scripts 2026-06-17 18:11:56 +08:00
.gitmodules chore: drop deployments submodule (single copy lives in LitheumCore) 2026-08-21 17:36:03 +08:00
dappstore-address.txt feat: dapp store upgrades and deployment scripts 2026-06-12 15:48:55 +08:00
README.md fix pricing for media 2026-09-15 12:25:21 +08:00
testdapp-address.txt feat: dapp store upgrades and deployment scripts 2026-06-12 15:48:55 +08:00

Litheum DappStore

This repository contains the DappStore smart contracts and deployment tools for the Litheum blockchain.

Overview

The DappStore is a decentralized registry for applications on Litheum. It provides:

  • On-chain registration of dapps
  • Approval system for quality control
  • Integration with Litheum's media storage for dapp hosting
  • Standardized interface (IDapp) for all applications

Note: This repository uses a local implementation of Ownable.sol to avoid external dependencies like OpenZeppelin.

Prerequisites

  • Litheum node running locally (default: http://localhost:8001)
  • lcli (Litheum CLI) configured with wallet
  • Solidity compiler (solc)
  • Basic shell utilities (bash, grep, awk)

Directory Structure

  • contracts/ - Smart contracts for dapps
    • IDapp.sol - Interface that all dapps must implement
    • IDappStore.sol - Interface for dapp store contracts
    • DappStore.sol - Main dapp store implementation
    • TestDapp.sol - Example dapp implementation
    • Ownable.sol - Local implementation of access control
  • dapps/ - HTML/JS dapp frontends
    • dapp-store.html - Dapp store UI
    • dapp-store.js - Dapp store JavaScript
    • test.html - Test dapp UI
    • test.js - Test dapp JavaScript
  • scripts/ - Deployment and utility scripts
    • deploy-dappstore.sh - Deploys DappStore contract (saves to ~/.litheum/chaindata/dappstore)
    • deploy-testdapp.sh - Deploys TestDapp with media publishing
  • docs/ - Additional documentation
    • media-publishing.md - Details on Litheum's media storage

DappStore Architecture

The DappStore follows the specification in the Litheum E2E Dapps design:

  1. IDapp Interface - All dapps must implement:

    • getEntrypoint() - Returns media hash of the dapp's HTML
    • getName() - Returns dapp name (max 30 chars)
    • getIcon() - Returns media hash of the dapp's icon
    • getDescription() - Returns description (max 500 chars)
  2. DappStore Contract - Manages dapp registry:

    • Submit dapps for approval
    • Owner can approve/remove dapps
    • Set ranking for featured ordering
    • Pagination support for listing
  3. Media Storage Integration - Dapps are stored on-chain:

    • HTML/JS/CSS published as media transactions
    • Retrieved via /media/{hash} endpoint
    • Wallet loads dapps in sandboxed iframes

Quick Start

1. Clone and Setup

git clone [repository-url] litheum-dapps
cd litheum-dapps

# Make scripts executable
chmod +x scripts/*.sh

2. Deploy DappStore

./scripts/deploy-dappstore.sh

This will compile and deploy the DappStore contract. Note the deployed address.

3. Deploy a Test Dapp

./scripts/deploy-testdapp.sh

This script will:

  • Publish test.html to media storage using lcli
  • Deploy the TestDapp contract with the media hash
  • Submit the dapp to DappStore for approval

4. Approve the Dapp

As the DappStore owner, approve the submitted dapp:

# Replace addresses with actual values from deployment
lcli send-transaction \
  --to [DAPPSTORE_ADDRESS] \
  --data "0x8a3e645a[TESTDAPP_ADDRESS_PADDED]" \
  --gas-limit 200000

5. Configure Wallet

In LitheumWallet, configure the DappStore address to see your dapps.

Deployment Instructions (Manual)

1. Deploy DappStore Contract

Using the deployment script:

# Run the DappStore deployment script
./scripts/deploy-dappstore.sh

Or manually using lcli:

# First, compile the contracts
cd contracts
solc --abi --bin --optimize Ownable.sol -o ../build --overwrite
solc --abi --bin --optimize IDapp.sol -o ../build --overwrite
solc --abi --bin --optimize IDappStore.sol -o ../build --overwrite
solc --abi --bin --optimize DappStore.sol -o ../build --overwrite

# Deploy DappStore
lcli send-transaction \
  --bytecode ../build/DappStore.bin \
  --gas-limit 3000000 \
  --constructor-args ""

Save the deployed contract address from the output - you'll need it for the wallet configuration.

2. Deploy a Test Dapp

The deployment script now handles media publishing automatically:

# Run the TestDapp deployment script
./scripts/deploy-testdapp.sh

Or manually:

# Compile TestDapp
cd contracts
solc --abi --bin --optimize TestDapp.sol -o ../build --overwrite

# First, publish the test dapp HTML to media storage
lcli send-transaction \
  --media-file ../dapps/test.html \
  --content-type "text/html" \
  --bytehours 8760  # 1 year

# Note the media hash from the output (e.g., 0xabcd...1234)
# Deploy TestDapp contract with the media hash
lcli send-transaction \
  --bytecode ../build/TestDapp.bin \
  --gas-limit 1000000 \
  --constructor-args "0xabcd...1234"  # Use actual media hash

# Submit the TestDapp to DappStore
# Function selector for submitDapp(address): 0x7e5fb2f7
lcli send-transaction \
  --to [DAPP_STORE_ADDRESS] \
  --data "0x7e5fb2f7[TESTDAPP_ADDRESS_PADDED_TO_64_CHARS]" \
  --gas-limit 200000

3. Approve the Dapp (as DappStore owner)

# Function selector for approveDapp(address): 0x8a3e645a
lcli send-transaction \
  --to [DAPP_STORE_ADDRESS] \
  --data "0x8a3e645a[DAPP_ADDRESS_PADDED_TO_64_CHARS]" \
  --gas-limit 200000

4. Verify Deployment

# Check owner
lcli eth-call --to [DAPP_STORE_ADDRESS] --data 0x8da5cb5b

# Check dapp count
lcli eth-call --to [DAPP_STORE_ADDRESS] --data 0x4dfa8e41

# Check if a dapp is listed
# Function selector for isListed(address): 0x821b99ba
lcli eth-call --to [DAPP_STORE_ADDRESS] --data "0x821b99ba[DAPP_ADDRESS_PADDED]"

Media Publishing with lcli

lcli now supports publishing files to Litheum's media storage:

# Publish an HTML file
lcli send-transaction \
  --media-file path/to/file.html \
  --content-type "text/html" \
  --bytehours 8760 \
  --media-name "My Dapp" \
  --max-payment 250000000  # Payment for storage

# Publish an image (larger file = higher payment needed)
lcli send-transaction \
  --media-file logo.png \
  --content-type "image/png" \
  --bytehours 87600 \
  --max-payment 5000000000  # Adjust based on file size

The command returns:

  • Media hash (SHA256 of content)
  • Transaction hash
  • Access URL (/media/{hash})

Bytehours Calculation

Storage cost is based on file size × hours:

  • 1 KB for 1 year = 1,024 × 8,760 = 8,972,640 bytehours
  • 1 MB for 1 month = 1,048,576 × 720 = 755,497,472 bytehours

Important: For media transactions, the --max-payment parameter sets the payment amount (a U256 carried inside the media message — no u64 ceiling). The network calculates the required payment based on current storage costs; set this value high enough to cover the total bytehours cost. The legacy --max-gas-price payment (u64) is still accepted but capped.

Wallet Integration

The LitheumWallet automatically discovers DappStore addresses from multiple sources:

Automatic Discovery

  1. Chaindata: Deployment scripts save addresses to ~/.litheum/chaindata/dappstore/
  2. Default Stores: Known DappStore addresses are pre-configured for each network
  3. User Stores: Additional stores can be added through the wallet UI

DappStore Tab Features

  • Store Selector: Switch between multiple DappStores
  • Add New Store: Configure additional DappStore contracts
  • Auto-import: Stores saved by deployment scripts appear automatically
  • Persistent Storage: User preferences saved locally

The wallet displays approved dapps and loads them from media storage when selected.

Chaindata Integration

Contract addresses are automatically saved to ~/.litheum/chaindata/ during deployment:

  • ~/.litheum/chaindata/dappstore - Contains the deployed DappStore address
  • ~/.litheum/chaindata/servicemarketplace - Contains the ServiceMarketplace address (when deployed)

These addresses are compiled into the LitheumWallet's WASM module at build time, making them available to the wallet automatically.

Creating a New Dapp

Step 1: Implement the IDapp Interface

contract MyDapp is IDapp {
    bytes32 private _entrypoint;
    
    constructor(bytes32 entrypointHash) {
        _entrypoint = entrypointHash;
    }
    
    function getEntrypoint() external view returns (bytes32) {
        return _entrypoint;
    }
    
    function getName() external pure returns (string memory) {
        return "My Awesome Dapp";
    }
    
    function getIcon() external pure returns (bytes32) {
        return bytes32(0); // Optional icon hash
    }
    
    function getDescription() external pure returns (string memory) {
        return "Description of what my dapp does";
    }
}

Step 2: Create Your Frontend

<!DOCTYPE html>
<html>
<head>
    <title>My Dapp</title>
    <script src="https://cdn.jsdelivr.net/npm/web3@1.9.0/dist/web3.min.js"></script>
</head>
<body>
    <h1>My Dapp</h1>
    <script src="mydapp.js"></script>
</body>
</html>

Step 3: Deploy

# 1. Publish HTML
lcli send-transaction \
  --media-file mydapp.html \
  --content-type "text/html" \
  --bytehours 8760

# 2. Note the media hash (e.g., 0xabc...123)

# 3. Deploy contract with media hash
lcli send-transaction \
  --bytecode MyDapp.bin \
  --constructor-args "0xabc...123" \
  --gas-limit 1000000

# 4. Submit to DappStore
lcli send-transaction \
  --to [DAPPSTORE_ADDRESS] \
  --data "0x7e5fb2f7[MYDAPP_ADDRESS_PADDED]" \
  --gas-limit 200000

Security Considerations

  • All dapps run in sandboxed iframes in the wallet
  • Dapps communicate with the wallet via postMessage API
  • Users must explicitly approve transactions
  • DappStore owners curate listings for quality/safety
  • Media storage is immutable - plan your deployments carefully

Troubleshooting

Common Issues

  1. "File not found" when running scripts

    • Make sure you're in the repository root directory
    • Check that scripts have execute permissions: chmod +x scripts/*.sh
  2. "No wallet configured" error

    • Ensure lcli has access to a wallet: lcli address
    • Create a wallet if needed: lcli create-wallet
  3. "Insufficient funds" for transactions

    • Check balance: lcli balance
    • Media publishing requires ions for bytehours
  4. DappStore shows no dapps

    • Verify DappStore address is correct
    • Check if dapp is approved: lcli eth-call --to [STORE] --data "0x821b99ba[DAPP_PADDED]"
    • Ensure wallet is connected to correct network

Examples

  • TestDapp.sol - Minimal dapp implementation
  • test.html/test.js - Simple dapp frontend
  • DappStore.sol - Full dapp registry implementation