Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/django_server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sqlite3
168 changes: 168 additions & 0 deletions examples/django_server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Django JSON-RPC Server for py-wallet-toolbox

This Django project provides a JSON-RPC HTTP server for BRC-100 wallet operations using py-wallet-toolbox.

## Features

- **JSON-RPC 2.0 API**: Standard JSON-RPC protocol for wallet operations
- **StorageProvider Integration**: Auto-registered StorageProvider methods (28 methods)
- **TypeScript Compatibility**: Compatible with ts-wallet-toolbox StorageClient
- **Django Integration**: Full Django middleware and configuration support

## Quick Start

### 1. Install Dependencies

```bash
# Install core dependencies
pip install -r requirements.txt

# Optional: Install development dependencies
pip install -r requirements-dev.txt

# Optional: Install database backends
pip install -r requirements-db.txt
```

### 2. Run Migrations

```bash
python manage.py migrate
```

### 3. Start Development Server

```bash
python manage.py runserver
```

The server will start at `http://127.0.0.1:8000/`

## API Endpoints

### JSON-RPC Endpoint
- **URL**: `POST /` (TypeScript StorageServer parity)
- **Content-Type**: `application/json`
- **Protocol**: JSON-RPC 2.0
- **Admin**: `GET /admin/` (Django admin interface)

### Available Methods

The server exposes all StorageProvider methods as JSON-RPC endpoints:

- `createAction`, `internalizeAction`, `findCertificatesAuth`
- `setActive`, `getSyncChunk`, `processSyncChunk`
- And 22 other StorageProvider methods

## Usage Examples

### Create Action

```bash
curl -X POST http://127.0.0.1:8000/ \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "createAction",
"params": {
"auth": {"identityKey": "your-identity-key"},
"args": {
"description": "Test transaction",
"outputs": [
{
"satoshis": 1000,
"lockingScript": "76a914000000000000000000000000000000000000000088ac"
}
],
"options": {
"returnTXIDOnly": false
}
}
},
"id": 1
}'
```

### Available Methods

The server exposes all StorageProvider methods as JSON-RPC endpoints:

- `createAction`, `internalizeAction`, `findCertificatesAuth`
- `setActive`, `getSyncChunk`, `processSyncChunk`
- And 22 other StorageProvider methods

Note: BRC-100 Wallet methods like `getVersion` are not available via JSON-RPC.
They are implemented in the Wallet class but not exposed through the StorageProvider interface.

## Configuration

### Settings

The Django settings are configured in `wallet_server/settings.py`:

- **DEBUG**: Development mode enabled
- **ALLOWED_HOSTS**: Localhost access allowed
- **INSTALLED_APPS**: `wallet_app` and `rest_framework` included
- **REST_FRAMEWORK**: JSON-only configuration

### CORS Support

For cross-origin requests, install `django-cors-headers`:

```bash
pip install django-cors-headers
```

Then uncomment CORS settings in `settings.py`.

## Development

### Running Tests

```bash
# Install test dependencies
pip install -r requirements-dev.txt

# Run Django tests
python manage.py test

# Run with pytest
pytest
```

### Code Quality

```bash
# Format code
black .

# Lint code
ruff check .

# Type check
mypy .
```

## Architecture

```
wallet_server/
├── wallet_app/
│ ├── views.py # JSON-RPC endpoint
│ ├── services.py # JsonRpcServer integration
│ └── urls.py # URL configuration
├── settings.py # Django configuration
└── urls.py # Main URL routing
```

## TypeScript Compatibility

This server is designed to be compatible with `ts-wallet-toolbox` StorageClient:

- Same JSON-RPC method names (camelCase)
- Compatible request/response formats
- TypeScript StorageServer.ts equivalent functionality

## License

Same as py-wallet-toolbox project.
22 changes: 22 additions & 0 deletions examples/django_server/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wallet_server.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()
8 changes: 8 additions & 0 deletions examples/django_server/requirements-db.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Database backends for Django JSON-RPC server
# SQLite is included with Python by default

# PostgreSQL
psycopg2-binary>=2.9.0

# MySQL
pymysql>=1.1.0
11 changes: 11 additions & 0 deletions examples/django_server/requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Development dependencies for Django JSON-RPC server
# Install with: pip install -r requirements-dev.txt

# Testing
pytest>=7.0.0
pytest-django>=4.5.0

# Code quality
black>=23.0.0
ruff>=0.1.0
mypy>=1.0.0
9 changes: 9 additions & 0 deletions examples/django_server/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Django JSON-RPC HTTP Server for py-wallet-toolbox
# Requirements for Django project providing JSON-RPC endpoints for BRC-100 wallet operations

# Core dependencies
Django>=4.2.0
djangorestframework>=3.14.0

# Local py-wallet-toolbox (with PushDrop fix)
-e ../..
Empty file.
3 changes: 3 additions & 0 deletions examples/django_server/wallet_app/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions examples/django_server/wallet_app/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class WalletAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'wallet_app'
Empty file.
3 changes: 3 additions & 0 deletions examples/django_server/wallet_app/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
76 changes: 76 additions & 0 deletions examples/django_server/wallet_app/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
Services for wallet_app.

This module provides service layer integration with py-wallet-toolbox,
specifically the JsonRpcServer for handling JSON-RPC requests.
"""

import logging
import os
from typing import Optional

from sqlalchemy import create_engine
from bsv_wallet_toolbox.rpc import JsonRpcServer
from bsv_wallet_toolbox.storage import StorageProvider

logger = logging.getLogger(__name__)

# Global JsonRpcServer instance
_json_rpc_server: Optional[JsonRpcServer] = None


def get_json_rpc_server() -> JsonRpcServer:
"""
Get or create the global JsonRpcServer instance.

This function ensures we have a single JsonRpcServer instance
that is configured with StorageProvider methods.

Returns:
JsonRpcServer: Configured JSON-RPC server instance
"""
global _json_rpc_server

if _json_rpc_server is None:
logger.info("Initializing JsonRpcServer with StorageProvider")

# Initialize StorageProvider with SQLite database
# Create database file in the project directory
db_path = os.path.join(os.path.dirname(__file__), '..', 'wallet_storage.sqlite3')
db_url = f'sqlite:///{db_path}'

# Create SQLAlchemy engine for SQLite
engine = create_engine(db_url, echo=False) # Set echo=True for SQL logging in development

# Initialize StorageProvider with SQLite configuration
storage_provider = StorageProvider(
engine=engine,
chain='test', # Use testnet for development
storage_identity_key='django-wallet-server'
)

# Initialize the database by calling make_available
# This creates tables and sets up the storage
try:
storage_provider.make_available()
logger.info("StorageProvider database initialized successfully")
except Exception as e:
logger.warning(f"StorageProvider make_available failed (may already be initialized): {e}")

# Create JsonRpcServer with StorageProvider auto-registration
_json_rpc_server = JsonRpcServer(storage_provider=storage_provider)

logger.info(f"JsonRpcServer initialized with SQLite database: {db_path}")

return _json_rpc_server


def reset_json_rpc_server():
"""
Reset the global JsonRpcServer instance.

Useful for testing or reconfiguration.
"""
global _json_rpc_server
_json_rpc_server = None
logger.info("JsonRpcServer instance reset")
3 changes: 3 additions & 0 deletions examples/django_server/wallet_app/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
11 changes: 11 additions & 0 deletions examples/django_server/wallet_app/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""
URL configuration for wallet_app.

Note: JSON-RPC endpoint is now configured at the root URL (/) in the main urls.py
for TypeScript StorageServer parity. This file is kept for future extensions.
"""

# JSON-RPC endpoint moved to root URL in main urls.py
# urlpatterns = [
# path('json-rpc/', views.json_rpc_endpoint, name='json_rpc'),
# ]
Loading