
Loom Worker
Weaving Your Threads, Together.
A Deno-based worker implementation for the Loom protocol - a decentralized generic compute marketplace built on Nostr.
Overview
Loom Worker enables you to offer compute resources and earn sats by executing commands for clients over the Nostr network. It features:
Pluggable Execution Backends: Shell, Docker, VMs, or custom implementations
Cashu Payment Integration: Automatic payment validation and change generation
Blossom File Storage: Decentralized stdout/stderr storage
Real-time Status Updates: Live job progress via Nostr events
Access Control: Optional NIP-51 whitelist support
Resource Management: Concurrent job execution with queue management
Motivation
Traditional compute platforms require centralized infrastructure and complex billing systems. Loom Worker provides a simple way to monetize spare compute capacity while maintaining full control over:
Who can use your worker
How much you charge
Where jobs are executed
Quick Start
Prerequisites
Deno 2.x or later
A Nostr keypair (nsec format)
A Cashu mint URL
A Blossom server for file uploads
Installation
# Clone the repository
git clone https://github.com/loomprotocol/loom-worker
cd loom-worker
# Copy environment template
cp .env.example .env
# Edit configuration
nano .envConfiguration
Edit .env with your settings:
# Nostr Configuration
NOSTR_PRIVATE_KEY=nsec1...
NOSTR_RELAYS=wss://relay.damus.io,wss://relay.nostr.band
# Cashu Configuration
CASHU_MINT_URL=https://mint.example.com
# Blossom Configuration
BLOSSOM_SERVER_URL=https://blossom.example.com
BLOSSOM_AUTH_KEY=your_auth_key
# Worker Configuration
MAX_CONCURRENT_JOBS=3
MIN_JOB_DURATION=10
MAX_JOB_DURATION=3600
PRICE_PER_SECOND=10
PRICE_UNIT=sat
# Optional: Whitelist (NIP-51 list naddr)
WHITELIST=naddr1...Running
# Run with all permissions
deno run --allow-all main.ts
# Or use the task
deno task startOptional: Geohash Location
GEOHASH=9q8yyk8yurvw # San FranciscoArchitecture
Execution Backends
Loom uses pluggable execution backends. The default is shell execution, but operators can implement custom backends:
import { ExecutionBackend, ExecutionResult } from "./src/execution/interface.ts";
class DockerBackend implements ExecutionBackend {
async execute(stdin: string, env: Record<string, string>, maxSeconds: number): Promise<ExecutionResult> {
// Your Docker execution logic
}
async isAvailable(): Promise<boolean> {
// Check if Docker is available
}
getName(): string {
return "docker";
}
}
// Use custom backend
const executionService = new ExecutionService(new DockerBackend());Job Flow
Advertisement: Worker publishes capabilities (software, pricing, location)
Job Request: Customer submits stdin command with ENV variables and payment
Validation: Worker checks whitelist and validates payment
Execution: Command runs with configured backend
Result: Stdout/stderr uploaded to Blossom, change token returned
Payment Model
Prepayment: Customer pays upfront based on estimated execution time
Time-based:
cost = price_per_second * execution_timeChange: Unused payment returned as Cashu token
No Timeout: Payment determines max execution time, no artificial limits
Event Kinds
10100: Worker Advertisement (Replaceable)
5100: Job Request (Regular)
30100: Job Status Update (Parameterized Replaceable)
5101: Job Result (Regular)
5102: Job Cancellation Request (Regular)
Security
Whitelist
Enabled by default for security
Uses NIP-51 lists for easy management
Real-time updates via Nostr subscription
Only whitelisted pubkeys can submit jobs
Payment Validation
Cashu tokens validated before execution
Insufficient payments rejected immediately
Change calculated and returned automatically
Resource Limits
Maximum concurrent jobs configurable
Minimum/maximum duration limits
Queue depth monitoring
Monitoring
Worker logs include:
Job requests and validations
Execution progress and results
Payment processing
Whitelist updates
Advertisement publishing
Troubleshooting
Worker Won't Start
Check
NOSTR_PRIVATE_KEYformat (must be nsec...)Verify
CASHU_MINT_URLis accessibleIf whitelist enabled, ensure
WHITELIST_EVENT_IDis provided
Jobs Being Rejected
Check whitelist configuration
Verify customer pubkey is in whitelist
Check payment amount meets minimum duration
Execution Failures
Verify advertised software is actually installed
Check software paths in
ADVERTISED_SOFTWAREEnsure default shell is available
Development
Project Structure
loom-worker/
├── main.ts # Main worker entry point
├── src/
│ ├── config/ # Configuration
│ ├── types/ # TypeScript types
│ ├── execution/ # Execution backends
│ ├── nostr/ # Nostr service
│ ├── cashu/ # Cashu wallet
│ ├── blossom/ # File storage
│ └── whitelist/ # Access control
└── deno.json # Deno configurationAdding Custom Backends
Implement
ExecutionBackendinterfaceCreate backend class in
src/execution/Update
main.tsto use custom backendTest with various commands
License
MIT
Support
For issues and questions, contact via Nostr using the protocol repository.