Skip to main content

Architecture

Urblock is a multi-tenant SaaS platform that abstracts blockchain complexity behind a REST API. It handles signing, gas estimation, nonce management, and on-chain confirmation so your application can integrate blockchain flows without operating its own transaction pipeline.

System Overview

┌─────────────────────────────────────────────────────────────────────────┐
│ Client (SDK / curl) │
└──────────────────────────────────┬──────────────────────────────────────┘
│ HTTPS
┌──────────────────────────────────▼──────────────────────────────────────┐
│ API Platform │
│ ┌─────────┐ ┌────────────┐ ┌────────────┐ ┌───────────────────┐ │
│ │ Auth │ │ Validation │ │ Services │ │ Data Layer │ │
│ │ Guard │ │ │ │ (Logic) │ │ │ │
│ └────┬────┘ └─────┬──────┘ └─────┬──────┘ └────────┬──────────┘ │
│ │ │ │ │ │
│ Rate Limiter class-validator Orchestration tenant_id scope │
└──────────────────────────┬──────────────────────────────────────────────┘

┌────────────────┼────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────────┐
│ Data Store │ │ Cache │ │ Async Jobs │
│ │ │ │ │ │
└────────────┘ └────────────┘ └──────┬───────┘

┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│tx-submit │ │tx-confirm│ │ webhook-send │
│ worker │ │ worker │ │ worker │
└────┬─────┘ └────┬─────┘ └──────┬───────┘
│ │ │
▼ ▼ ▼
Blockchain Blockchain Tenant's
RPC RPC webhook URL

Request Flow

Client Request
→ API Gateway (rate limiting, auth)
→ API controller (input validation)
→ Service (business logic, orchestration)
→ Data layer
→ Async job queue (for blockchain operations)
→ Response: { status: "pending", id: "tx_..." }

Background Workers
→ tx-submit: build, sign, submit transaction to RPC
→ tx-confirm: wait for on-chain confirmation
→ webhook-send: notify tenant via HTTP callback

Example: Token Deploy

  1. POST /v1/tokens → Controller validates DTO
  2. Service computes constructor args and encoded bytecode
  3. Repository saves token record (status: "deploying") and transaction record (status: "pending")
  4. Async job enqueued for submission
  5. API returns { id: "tok_abc123", status: "deploying" } immediately
  6. tx-submit worker: resolves nonce, estimates gas, signs with HD wallet, sends to RPC
  7. tx-confirm worker: polls for receipt, updates status: "confirmed", sets contract_address
  8. webhook-send worker: fires token.deployed event to registered webhooks

Async-First Design

All blockchain operations are asynchronous. The API returns immediately with a pending status, and the actual on-chain execution happens in background workers.

Transaction Lifecycle

StatusMeaning
pendingSaved to DB, queued for submission
submittedSent to the blockchain RPC, has a tx_hash
confirmedIncluded in a block, has block_number and gas_used
failedTransaction reverted or timed out

Component Stack

LayerTechnology ClassRole
APIHTTP application layerRequest handling, validation, routing
DatabaseRelational storagePersistent resource and transaction state
CacheIn-memory coordinationRate limiting, caching, short-lived state
QueueBackground processingSubmission, confirmation, retries
BlockchainEVM interaction layerRPC communication and transaction lifecycle
Smart ContractsAudited token and protocol contractsOn-chain execution surface
ObservabilityLogs, traces, metricsOperability and incident visibility

Multi-Tenant Isolation

Every request and resource lookup is scoped to a tenant context. Data does not cross tenant boundaries.

  • Each API key belongs to exactly one tenant
  • Resource access is resolved in tenant context
  • Signing and transaction state stay isolated per tenant
  • Background processing preserves tenant ownership metadata

Security Model

AssetProtection
Wallet root materialManaged server-side and never returned by the API
Private keysAES-256-GCM encrypted at rest
API keysbcrypt hashed in DB, plain key shown only at creation
Inputsclass-validator on every DTO
Rate limitingPer tenant, 100 req/min (configurable)
Sensitive headersNever logged

Idempotency

All write operations accept an idempotency_key. If the same key is submitted twice, the second request returns the original result without re-executing. This prevents double-spends and duplicate deploys.

Background Jobs

JobRetriesBackoffPriority
tx-submit3Exponential 5sHigh
tx-confirm10Exponential 10sHigh
webhook-send5Exponential 30sMedium
contract-deploy3Exponential 10sHigh

Dead Letter Queue

Jobs that exhaust all retries move into an inspection path for internal recovery workflows. Failed webhook deliveries are also recorded so tenants can diagnose delivery outcomes.

Observability

SignalImplementation
LogsStructured application logs
TracesRequest and background-job tracing
MetricsRequest, queue, and transaction health metrics
HealthGET /health (liveness) + GET /v1/status (dependency-aware status)

Next Steps