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​