THRA
THRA NETWORK
Decentralized P2P Network
👋 Welcome back,
Your Ed25519 key pair is generated in your browser. Your private key is encrypted with your password and never stored in plaintext.
THRA
THRA NETWORK
Decentralized P2P Network
@user
CONNECTING...
THRA
THRA NETWORK
Choose a shard to enter
searching peers… · — THRA
◈ Profile
Username
@—
Node ID
—
Public Key
—
0
DAG Vertices
0
Live Peers
0
Active Tips
NOT STAKING
Stake THRA to join PoS consensus and help validate the network
Crypto Engine Ed25519 + SHA-256
Ledger Type DAG (parallel)
Consensus Proof of Stake
Fee Model 0.01% micro-fee
⬡ Community
0
Online Nodes
0
Transactions
Live Network Transactions
Loading network transactions…
Global Chat Room
Loading messages…
@
◇ Wallet
Public Address
—
0
THRA Balance
0
Staked THRA
💸 Send THRA
+ =
Micro-fee: 0.01% · Ed25519 signed · PoS validated
🔒 Stake THRA

Stake THRA to participate in Proof-of-Stake validation and secure the network.

Password required · Decrypted in browser only · Never leaves your device
Recent Transactions
No transactions yet

🔐 Reveal Private Key

Your private key is encrypted with your password and decrypted entirely in your browser — never sent to any server.

⚠️ Never share your private key. Anyone who has it controls your THRA wallet.
Ed25519 Private Key (PKCS8)
Keep this safe. This is the master key to your THRA wallet.
THRA
DECENTRALIZED P2P NETWORK
⬡ THRA Chain Explorer — Live Network Ledger
—TOTAL VERTICES
—UNIQUE NODES
—TRANSFERS
—THRA VOLUME
Loading chain data…
THRA Network — Technical Whitepaper  ·  v1.0.0
THRA

THRA Network

A Browser-Native Decentralized Peer-to-Peer Computation Network

Version 1.0  ·  Technical Whitepaper

thra.network  ·  2025

Abstract

THRA Network is a browser-native, fully decentralized peer-to-peer computation network in which every browser session constitutes an autonomous cryptographic node. Each node is assigned a unique Ed25519 identity, participates in a SHA-256 secured Directed Acyclic Graph (DAG) ledger, and communicates directly with peers via WebRTC data channels brokered by a lightweight WebSocket signaling layer. The THRA token serves as the native currency, staking asset, and governance unit. Unlike traditional blockchain networks that require heavyweight client software, THRA operates entirely within the constraints of a standards-compliant web browser using the Web Crypto API, requiring no plugins, extensions, or downloads. This paper describes the full technical architecture, consensus mechanism, token economics, developer SDK, and the rationale for each design decision.

Table of Contents

  1. Introduction
  2. Background & Motivation
  3. System Architecture Overview
  4. The Identity Layer — Ed25519 Cryptography
  5. The Ledger — SHA-256 Directed Acyclic Graph
  6. Consensus Protocol — Proof of Stake
  7. THRA Token Economics
  8. Network Architecture — WebRTC P2P Mesh
  9. Transaction Lifecycle
  10. The THRA Developer SDK
  11. Building on THRA
  12. Security Analysis
  13. Performance & Scalability
  14. Use Cases
  15. Conclusion
  16. References

1. Introduction

The internet was originally conceived as a decentralized communication fabric — a network of equal peers exchanging data without a central authority. Over time, economic forces concentrated infrastructure into the hands of a small number of large providers. Today, the majority of web applications depend on centralized servers for authentication, state management, and data persistence. This architecture introduces single points of failure, censorship vectors, and data sovereignty concerns that are incompatible with the original ethos of an open web.

THRA Network re-imagines the web browser not as a thin client consuming centralized services, but as a full network node: an autonomous participant capable of generating cryptographic identities, maintaining a local ledger, transacting directly with peers, and contributing to network consensus — all within the sandboxed environment of a standard web browser.

The design philosophy of THRA is grounded in three principles:

  1. Zero-install participation. Any browser visiting the THRA Network endpoint becomes a node. No wallet extensions, no native applications, no browser plugins. The Web Crypto API provides all necessary cryptographic primitives.
  2. True peer-to-peer topology. Nodes communicate directly via WebRTC RTCDataChannel connections. The WebSocket signaling server facilitates connection establishment but carries no application data — it is architecturally excluded from all transaction flows.
  3. Cryptographic integrity. Every identity is an Ed25519 key pair. Every transaction is a SHA-256 hashed vertex in a Directed Acyclic Graph. Every transfer carries an Ed25519 digital signature. No operation can be forged or repudiated.

THRA is written entirely in TypeScript — both the browser client and the Node.js signaling server — ensuring a unified type system, shared data structures, and a consistent developer experience across the full stack.

2. Background & Motivation

2.1 Limitations of Existing Blockchain Networks

Existing public blockchain networks such as Bitcoin and Ethereum offer strong cryptographic guarantees but impose significant participation barriers. Running a full Ethereum node requires downloading hundreds of gigabytes of chain data, maintaining synchronized state against a global peer network, and operating specialized client software. Light clients improve accessibility but sacrifice trustlessness, relying on full nodes to serve state proofs.

Smart-contract platforms have demonstrated that programmable value transfer is commercially viable, but their architectures were designed for desktop and server environments. Browser-based dApp frontends interact with the network through centralized RPC providers (Infura, Alchemy) — reintroducing the centralization that blockchain was intended to remove.

2.2 Directed Acyclic Graph Ledgers

Linear blockchain architectures serialize all transactions into a single chain, fundamentally limiting throughput. DAG-based ledgers such as IOTA's Tangle and Nano's Block Lattice permit multiple vertices to be appended in parallel, improving throughput in proportion to network activity. THRA adopts a DAG structure where each vertex references one or more "tip" vertices as parents, creating a partial order over transactions that allows parallel processing while preserving causal integrity.

2.3 The WebRTC Opportunity

The WebRTC standard (RFC 8825) enables browsers to establish low-latency, encrypted peer-to-peer data channels directly, without server mediation. The RTCDataChannel API supports binary and text messaging with sub-100ms round-trip times on local area networks and sub-300ms on intercontinental paths. THRA exploits this to create a mesh network topology in which transaction propagation does not depend on any central relay.

2.4 Design Goals

THRA was designed with the following explicit goals:

  • Node startup in under 3 seconds from page load
  • Transaction confirmation latency under 500ms on a network of up to 1,000 peers
  • A developer SDK with fewer than 10 core methods covering 90% of use cases
  • No dependency on any external library for cryptography — Web Crypto API only
  • Human-readable transaction types: genesis, transfer, profile, stake

3. System Architecture Overview

THRA Network consists of three architectural tiers that operate with clearly defined responsibilities and minimal coupling:

Tier 1: Browser Node Layer
Ed25519 Identity · DAG Ledger · WebRTC Mesh · THRA SDK
↕ WebRTC RTCDataChannel (direct P2P)
Tier 2: Signaling & Persistence Layer
WebSocket Signaling Server (Node.js/TypeScript) · PostgreSQL Ledger Mirror
↕ REST API (Bearer JWT)
Tier 3: Application Layer
Third-party DApps · SDK Integrations · Community Applications

3.1 Browser Node Layer

Each browser session instantiates a DecentralizedNode object — the primary SDK class. This object holds the node's Ed25519 key pair in memory (using the non-extractable CryptoKey type provided by the Web Crypto API), maintains a local DAGLedger instance, and manages the SignalingClient which handles all P2P connectivity. The node is self-sufficient: it can verify balances, sign transactions, and propagate updates entirely without contacting any server.

3.2 Signaling and Persistence Layer

The THRA signaling server (written in TypeScript, running on Node.js) performs two functions: it acts as a WebRTC rendezvous point, relaying ICE offers, answers, and candidates between nodes that cannot yet communicate directly; and it mirrors the DAG ledger to a PostgreSQL database, enabling nodes to retrieve historical transactions on startup, synchronize after offline periods, and serve as light-node data sources. The signaling server never holds private keys and cannot construct or sign transactions.

3.3 Technology Stack

ComponentTechnologyRationale
Client runtimeBrowser (Chrome/Firefox/Safari)Zero-install, universal access
Client languageTypeScript → ES2022Type safety, modern browser targets
Server languageTypeScript (Node.js)Shared types with client SDK
CryptographyWeb Crypto API (Ed25519, SHA-256)Native browser, no external deps
P2P transportWebRTC RTCDataChannelBrowser-native direct P2P
SignalingWebSocket (ws library)Low latency connection brokering
PersistencePostgreSQLACID transactions, JSONB vertex storage
Build toolesbuildSub-second TypeScript bundling
Ledger structureDirected Acyclic GraphParallel transaction processing

4. The Identity Layer — Ed25519 Cryptography

4.1 Key Generation

Upon account creation, THRA generates an Ed25519 key pair using the browser's crypto.subtle.generateKey method with the Ed25519 algorithm. Ed25519 was selected over ECDSA (secp256k1) for the following reasons:

  • Performance. Ed25519 operations (key generation, signing, verification) are significantly faster than equivalent ECDSA operations, reducing node initialization latency.
  • Security. Ed25519 provides approximately 128 bits of security and is resistant to timing side-channel attacks by design, which is critical in a browser execution context where timing information may be observable.
  • Determinism. Ed25519 signatures are fully deterministic — the same message and private key always produce the same signature. This eliminates the risk of nonce reuse vulnerabilities that have historically compromised ECDSA implementations.
  • Compact representations. Ed25519 public keys are 32 bytes and signatures are 64 bytes, minimizing DAG vertex payload size.

4.2 Node Identity

A node's identity is defined as the SHA-256 hash of its DER-encoded public key, represented as a 64-character lowercase hexadecimal string. This Node ID serves as the node's primary identifier across all network operations. It is stable for the lifetime of the key pair and can be recomputed from the public key at any time.

nodeId = SHA-256( DER-encode( Ed25519PublicKey ) ).toHex()

4.3 Wallet Address

The wallet address is derived as a prefix-checksum of the node ID, providing a shorter human-readable identifier for token transfer operations:

walletAddress = "thra" + nodeId.substring(0, 40)

4.4 Key Storage

The private key is exported in PKCS#8 DER format, encrypted with the user's password using AES-GCM (256-bit key derived via PBKDF2 with 100,000 iterations and SHA-256), and stored in the server-side PostgreSQL database. The plaintext private key is never transmitted over the network and exists only in browser memory during an active session. The Web Crypto API's extractable: false flag prevents raw key extraction via JavaScript reflection after the key is imported.

4.5 Transaction Signing

Every transfer vertex includes an Ed25519 digital signature over the transaction payload string:

signingPayload = "transfer:" + fromNodeId + ":" + toNodeId + ":" + amount + ":" + timestamp
signature = Ed25519.sign( signingPayload, privateKey )

The signature and a SHA-256 hash of the signing payload are embedded in the vertex's data field, enabling any participant to verify authenticity without trusting the sender.

5. The Ledger — SHA-256 Directed Acyclic Graph

5.1 Vertex Structure

The THRA ledger is a Directed Acyclic Graph in which each node is a vertex with the following structure:

interface DagVertex {
  id:        string        // Unique vertex identifier
  parentIds: string[]      // References to parent vertex IDs (tips at creation time)
  type:      VertexType    // 'genesis' | 'transfer' | 'profile' | 'stake'
  timestamp: number        // Unix milliseconds
  from:      string        // Originating node ID
  to?:       string        // Destination node ID (transfers only)
  amount?:   number        // THRA amount (genesis/transfer/stake)
  data?:     object        // Type-specific metadata
  hash:      string        // SHA-256 of canonical JSON representation
}

5.2 Vertex Hashing

Each vertex's integrity hash is computed as the SHA-256 of the canonical JSON representation of all fields except hash itself:

hashInput = JSON.stringify({
  id, parentIds, type, timestamp, from, to, amount, data
})
vertex.hash = await crypto.subtle.digest('SHA-256', encode(hashInput))

This hash serves as a content address: any mutation of the vertex data, however small, produces a completely different hash, making tampering immediately detectable.

5.3 Vertex Types

TypeDescriptionParentsAmount
genesisInitial allocation — created once per node on first initialization[] (none)50 THRA
transferValue transfer between two nodes; carries Ed25519 signatureCurrent DAG tipsArbitrary
profileNode identity metadata update (display name, etc.)Current DAG tipsNone
stakeCommits THRA balance to the validator stake poolCurrent DAG tipsStaked amount

5.4 DAG Tip Selection

A tip is a vertex that has not yet been referenced as a parent by any subsequent vertex. When creating a new vertex, the node attaches it to all current tips. This mechanism ensures:

  • Confirmation propagation: Each new vertex implicitly confirms all vertices in its ancestry chain.
  • Parallel throughput: Multiple vertices can become tips simultaneously, allowing concurrent transactions from different nodes without serialization.
  • Eventual convergence: As the network grows and vertices reference tips, the DAG converges toward a consistent global ordering.

5.5 Balance Computation

Account balances are computed by traversing the entire local DAG and summing credits and debits:

balance(nodeId) = Σ genesis.amount  [where genesis.from == nodeId]
               + Σ transfer.amount [where transfer.to   == nodeId]
               − Σ transfer.amount [where transfer.from == nodeId]

Staked amounts are tracked separately and do not reduce the spendable balance (they represent a locked commitment). Fee amounts are deducted from the sender's spendable balance at the time of transfer creation and distributed to the network treasury.

5.6 DAG Persistence

Vertices are persisted in two locations: the browser's localStorage (via the storage module) and the server-side PostgreSQL database. The PostgreSQL schema stores vertices as rows with JSONB fields for flexible structured data, enabling efficient queries by node ID, vertex type, and timestamp. On node startup, the SDK fetches all vertices involving the current node from the server to reconstruct any transactions that occurred while the node was offline.

6. Consensus Protocol — Proof of Stake

6.1 Overview

THRA uses a Proof-of-Stake consensus model in which validators are nodes that have committed THRA tokens to the stake pool via a stake vertex. Any node with a staked balance greater than zero qualifies as a validator. The staking commitment is recorded immutably on the DAG, making it transparent and verifiable by all network participants.

6.2 Validator Selection

In the current THRA v1.0 implementation, validator status is binary: a node either has a positive staked amount (and is a validator) or does not. Future protocol versions will implement a weighted selection algorithm where the probability of being selected as block proposer is proportional to the node's staked balance relative to total staked supply:

P(selection) = staked_amount / total_staked_supply

6.3 Staking Mechanics

To become a validator, a node broadcasts a stake vertex to the network:

  1. The node verifies it holds sufficient spendable balance.
  2. A stake vertex is created with the staked amount, the current DAG tips as parents, and the cumulative staked total in the data field.
  3. The vertex is hashed, stored locally, saved to the server, and broadcast to all peers.
  4. The node's isValidator() flag becomes true.

6.4 Validator Incentives

Validator nodes participate in network governance and are eligible for a proportional share of protocol fees. The fee structure (described in Section 7) collects 0.01% of each transfer, accumulated in the protocol treasury. Future releases will distribute treasury rewards to validators pro-rata to their stake weight at a configurable epoch boundary.

6.5 Slashing (Planned)

THRA v2.0 will introduce slashing conditions: validators that sign conflicting vertices (double-spend attempts) will have a portion of their staked THRA burned. The slashing protocol will use cryptographic proofs of equivocation that can be submitted by any honest node, creating a permissionless fraud-proof mechanism.

7. THRA Token Economics

7.1 Token Overview

THRA is the native utility token of the THRA Network. It serves three purposes: (1) a medium of exchange for peer-to-peer value transfer, (2) a staking asset for validator participation, and (3) a governance token for protocol parameter decisions in future releases.

7.2 Initial Distribution

Every newly registered node receives a genesis allocation of 50 THRA credited via a genesis vertex on first initialization. This design ensures every participant has sufficient tokens to explore the network, execute transfers, and experiment with staking without requiring a token sale or faucet request. The genesis allocation is a protocol constant and is verified by any node that receives and validates the genesis vertex.

7.3 Fee Structure

Transfer transactions carry a network fee computed as:

fee = max(0.001, amount × 0.0001)

This represents a maximum fee rate of 0.01% with a minimum floor of 0.001 THRA. At this rate, a transfer of 100 THRA costs 0.01 THRA in fees. The fee floor prevents dust transactions (transfers of negligible value) from consuming network resources without appropriate compensation. The fee is deducted from the sender's balance at the time of vertex creation and is visible to the sender as a pre-flight preview before confirmation.

7.4 Supply Model

THRA does not have a fixed maximum supply in the v1.0 protocol. Each new network participant receives 50 THRA, meaning total supply grows linearly with network participation. This inflationary genesis model prioritizes network bootstrapping and broad participation over speculative scarcity. Future protocol versions may introduce a fee-burn mechanism to create deflationary pressure as transaction volume grows.

ParameterValue
Genesis allocation per node50 THRA
Transfer fee rate0.01% (0.0001)
Minimum transfer fee0.001 THRA
Supply modelLinear expansion per new node
Token decimals3 (minimum unit: 0.001 THRA)
Staking minimumAny positive amount

8. Network Architecture — WebRTC P2P Mesh

8.1 Network Topology

THRA forms a fully connected mesh topology among all simultaneously online nodes. Each node attempts to establish a direct RTCDataChannel connection with every other known peer. In practice, NAT traversal constraints limit the proportion of directly connected pairs, but the mesh density increases as node count grows and as peer discovery matures.

8.2 Signaling Protocol

Connection establishment uses the following WebSocket signaling exchange:

  1. Register: Node connects to the WebSocket endpoint and sends { type: "register", from: nodeId }.
  2. Peer list: The server responds with { type: "peer-list", peers: string[] } listing all currently registered nodes.
  3. Offer/Answer: The initiating node creates an RTCPeerConnection, generates an SDP offer, and relays it through the signaling server to the target peer. The target responds with an SDP answer.
  4. ICE Candidates: Both peers exchange ICE candidates via the signaling server until a viable connectivity path is found.
  5. Direct channel: Once the RTCDataChannel is open, all subsequent communication is peer-to-peer. The signaling server plays no further role.

8.3 Message Types

Message TypeDirectionDescription
dag-vertexPeer → PeerPropagate a newly created DAG vertex to all connected peers
profile-updatePeer → PeerBroadcast an updated node profile to the network
sync-requestPeer → PeerRequest the last 20 vertices from a peer for DAG reconciliation
chat-messageServer → NodeServer-relayed global chat message (falls through signaling layer)
broadcastNode → Server → PeersFallback broadcast when no direct P2P channel is available

8.4 Fallback Relay

When no direct RTCDataChannel connection is available to a peer (e.g., before ICE negotiation completes, or in restrictive NAT environments), the SDK falls back to relaying broadcast messages through the WebSocket signaling server. This ensures message delivery is never blocked by connectivity issues, at the cost of server bandwidth proportional to the broadcast payload. The fallback is automatically bypassed once a direct channel becomes available.

8.5 Reconnection

The SignalingClient implements automatic reconnection with a 3-second backoff: if the WebSocket connection drops, the client re-establishes it and re-registers with the signaling server. Existing RTCDataChannel connections to peers are unaffected by signaling server disconnections, as they operate independently over ICE-negotiated paths.

9. Transaction Lifecycle

A complete transfer transaction follows these steps from initiation to confirmation across the network:

  1. Pre-flight validation. The SDK checks that the sender's balance (computed from the local DAG) is ≥ amount + fee. A balance error is thrown synchronously without any network I/O.
  2. Signature generation. The signing payload string is constructed from sender, recipient, amount, and timestamp. The payload is signed with the sender's non-extractable Ed25519 private key using crypto.subtle.sign.
  3. TX hash computation. A SHA-256 hash of the signing payload is computed and stored as the transaction's content address.
  4. Vertex construction. A transfer vertex is assembled with the current DAG tips as parents, embedding the signature and TX hash in the data field.
  5. Vertex hashing. The complete vertex (excluding the hash field) is serialized to canonical JSON and SHA-256 hashed, producing the vertex's integrity hash.
  6. Local commit. The vertex is added to the local DAGLedger and persisted to localStorage immediately. The sender's local balance is updated at this point.
  7. Server persistence. The vertex is transmitted to the server via authenticated REST API call (POST /api/auth/dag/vertex) for inclusion in the PostgreSQL ledger mirror.
  8. P2P broadcast. The vertex is broadcast to all directly connected peers via RTCDataChannel. Peers without direct connections receive it via the signaling server fallback.
  9. Recipient sync. When the recipient node next connects (or on their next sync cycle), they receive the transfer vertex from the server and update their local balance accordingly.

Total latency from step 1 to step 7 on a modern browser is under 50ms. Peer propagation (step 8) completes within 100–300ms depending on network conditions and peer count.

10. The THRA Developer SDK

The THRA SDK is structured as three TypeScript modules that can be consumed independently or as an integrated stack:

ModuleFileDescription
DecentralizedNodesrc/sdk/node.tsPrimary node lifecycle, transaction, and staking APIs
DAGLedgersrc/sdk/dag.tsLocal DAG data structure, vertex management, balance computation
SignalingClientsrc/sdk/network.tsWebSocket signaling + WebRTC P2P mesh management

10.1 DecentralizedNode API

The DecentralizedNode class is the primary entry point for all THRA network interactions.

Constructor

const node = new DecentralizedNode()

node.initialize(user, privateKey, token)

await node.initialize(
  user: AuthUser,       // { nodeId, publicKey, walletAddress, username, stakedAmount }
  privateKey: string,   // PKCS8 hex-encoded Ed25519 private key
  token: string         // JWT bearer token for server API authentication
): Promise<void>

Initializes the node: imports the key pair, loads the local DAG from storage, syncs missing vertices from the server, creates a genesis vertex if none exists, and connects to the signaling server. Must be called before any other method.

node.transferCoin(toNodeId, amount)

await node.transferCoin(
  toNodeId: string,   // Recipient node ID (64-char hex)
  amount: number      // Amount in THRA (minimum: fee floor)
): Promise<DagVertex>

Creates a signed transfer vertex, commits it to the local DAG, persists to server, and broadcasts to peers. Throws if balance is insufficient or amount is non-positive.

node.stakeCoin(amount)

await node.stakeCoin(
  amount: number   // THRA to commit to validator stake pool
): Promise<DagVertex>

Creates a stake vertex committing the specified amount to the stake pool. The node becomes a validator immediately. Staked amount is reflected in node.getStakedAmount() and node.isValidator().

node.createProfile(displayName)

await node.createProfile(
  displayName: string   // Human-readable display name for this node
): Promise<DagVertex>

Broadcasts a profile vertex associating a display name with the node's public key and wallet address. Profile vertices are propagated to all peers, populating the network's distributed identity directory.

node.getFee(amount)

node.getFee(amount: number): number
// Returns: max(0.001, amount × 0.0001)

Computes the network fee for a transfer of the specified amount. Use for pre-flight cost display without committing a transaction.

node.getDagTips()

node.getDagTips(): string[]
// Returns: array of current tip vertex IDs

Returns the current set of unreferenced vertices (tips) in the local DAG. Useful for applications that construct custom vertices or need to inspect DAG frontier state.

node.isValidator()

node.isValidator(): boolean
// Returns: true if node.stakedAmount > 0

node.getStakedAmount()

node.getStakedAmount(): number
// Returns: total THRA staked by this node

node.getBalance()

node.getBalance(): number
// Returns: spendable THRA balance

node.getState()

node.getState(): NodeState
// Returns: { nodeId, publicKey, walletAddress, username, balance,
//            stakedAmount, peerCount, profile, ledgerSize }

node.onStateChange(handler)

node.onStateChange((state: NodeState) => void): void

Registers a callback that fires whenever the node state changes (new vertex added, peer connected/disconnected, profile updated). Use this to reactively update application UI.

10.2 DAGLedger API

The DAGLedger class manages the local in-memory DAG. It is accessible via node.getDag().

dag.addVertex(vertexData)

await dag.addVertex(
  vertex: Omit<DagVertex, 'hash'>
): Promise<DagVertex>

Adds a vertex to the DAG, computes its SHA-256 hash, updates the tip set, and fires change callbacks. Returns the complete vertex including its hash.

dag.getBalance(nodeId)

dag.getBalance(nodeId: string): number

dag.getTips()

dag.getTips(): string[]

dag.getAllVertices()

dag.getAllVertices(): DagVertex[]
// Returns vertices sorted ascending by timestamp

dag.hasVertex(id)

dag.hasVertex(id: string): boolean

10.3 SignalingClient API

The SignalingClient manages WebSocket signaling and WebRTC peer connections. It is accessible via node.getNetwork().

network.broadcast(type, data)

network.broadcast(
  type: string,            // Message type identifier
  data: Record<string, unknown>  // Message payload
): void

Sends a message to all directly connected peers via RTCDataChannel. Falls back to server relay if no direct channels are available.

network.on(type, handler)

network.on(
  type: string,
  handler: (msg: Record<string, unknown>, fromPeerId?: string) => void
): void

Registers a handler for incoming messages of a given type from any peer.

network.getConnectedPeerCount()

network.getConnectedPeerCount(): number

11. Building on THRA

11.1 Getting Started

The THRA SDK is distributed as TypeScript source modules and compiled to standard ES2022 JavaScript. To integrate THRA into your application, import the modules directly:

import { DecentralizedNode } from './sdk/node.js'
import { DAGLedger, DagVertex } from './sdk/dag.js'
import { SignalingClient } from './sdk/network.js'

The SDK has zero external runtime dependencies. All cryptographic operations use the browser's built-in Web Crypto API. All networking uses the browser's WebRTC and WebSocket APIs. You can add the SDK to any web project without modifying your build pipeline beyond adding the TypeScript source files.

11.2 Initializing a Node

// 1. Authenticate with the THRA server
const response = await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username, password })
})
const { user, token, privateKey } = await response.json()

// 2. Create and initialize a node
const node = new DecentralizedNode()
await node.initialize(user, privateKey, token)

// 3. Subscribe to state changes
node.onStateChange(state => {
  console.log('Balance:', state.balance, 'THRA')
  console.log('Peers:', state.peerCount)
  console.log('Ledger size:', state.ledgerSize, 'vertices')
})

11.3 Sending a Transfer

// Check balance before sending
const fee = node.getFee(10)
console.log(`Sending 10 THRA. Fee: ${fee}. Total: ${10 + fee}`)

// Execute transfer
try {
  const vertex = await node.transferCoin(recipientNodeId, 10)
  console.log('Transfer confirmed:', vertex.hash)
  console.log('TX ID:', vertex.id)
  console.log('Parents:', vertex.parentIds)
} catch (err) {
  console.error('Transfer failed:', err.message)
}

11.4 Staking and Becoming a Validator

// Stake 5 THRA to become a validator
const stakeVertex = await node.stakeCoin(5)
console.log('Staked successfully. Vertex:', stakeVertex.id)
console.log('Is validator:', node.isValidator())         // true
console.log('Staked amount:', node.getStakedAmount())    // 5

11.5 Building a Custom Message Protocol

const network = node.getNetwork()

// Register a custom message handler
network.on('my-app-event', (msg, fromPeerId) => {
  console.log('Received from', fromPeerId, ':', msg)
  // Handle application-level message
})

// Broadcast a custom message to all peers
network.broadcast('my-app-event', {
  type: 'my-app-event',
  payload: { action: 'ping', data: 'hello network' }
})

11.6 Querying the DAG

const dag = node.getDag()

// Get all vertices
const all = dag.getAllVertices()
console.log('Total vertices:', all.length)

// Filter transfers involving this node
const myNodeId = node.getNodeId()
const myTransfers = all.filter(v =>
  v.type === 'transfer' &&
  (v.from === myNodeId || v.to === myNodeId)
)

// Get current DAG tips
const tips = dag.getTips()
console.log('Active tips:', tips.length)

// Compute balance for any node
const balance = dag.getBalance(someOtherNodeId)

11.7 Listening for Profile Updates

// Profiles are propagated via P2P broadcast
// The SDK handles incoming 'profile-update' messages automatically
// Access profiles via:
const profiles = node.getAllProfiles()
profiles.forEach(p => {
  console.log(p.displayName, '-', p.nodeId.substring(0, 12))
})

11.8 Server API Reference

The THRA server exposes a REST API for account management and ledger access:

EndpointMethodAuthDescription
/api/auth/registerPOSTNoneCreate account. Body: {username, password}. Returns user + token.
/api/auth/loginPOSTNoneAuthenticate. Body: {username, password}. Returns user + token + privateKey.
/api/auth/meGETBearer JWTReturns authenticated user object.
/api/auth/profilesGETNoneReturns all registered node profiles.
/api/auth/dag/vertexPOSTBearer JWTPersist a DAG vertex. Body: vertex object.
/api/auth/dag/verticesGETNoneFetch vertices. Query: ?nodeId=xxx to filter by node.
/api/chat/messagesGETNoneFetch last 12 global chat messages.
/api/chat/messagesPOSTBearer JWTPost a chat message. Body: {message}.

11.9 WebSocket Protocol Reference

The WebSocket endpoint at ws://host (or wss://host over TLS) accepts the following message types:

MessageDirectionPayload
registerClient → Server{type, from: nodeId}
registeredServer → Client{type}
peer-listServer → Client{type, peers: string[]}
offerClient → Server → Client{type, from, to, data: RTCSdpInit}
answerClient → Server → Client{type, from, to, data: RTCSdpInit}
ice-candidateClient → Server → Client{type, from, to, data: RTCIceCandidateInit}
broadcastClient → Server → All Clients{type, from, data: {type, ...payload}}

12. Security Analysis

12.1 Cryptographic Assumptions

THRA's security relies on the hardness of two well-studied problems:

  • Ed25519 discrete logarithm: Given a public key, it is computationally infeasible to derive the corresponding private key. This assumption underlies all identity and transaction signing guarantees.
  • SHA-256 preimage resistance: Given a hash, it is computationally infeasible to construct an input that produces that hash. This underpins the integrity of all DAG vertices.

Both assumptions are broadly accepted and underpin the security of major production systems (TLS, Bitcoin, Signal Protocol).

12.2 Threat Model

ThreatMitigation
Private key theftKeys stored server-side as AES-GCM encrypted blobs; in-browser keys use non-extractable CryptoKey type
Transaction forgeryEd25519 signature on every transfer; signature verified by recipients before acceptance
Double spendDAG append-only; conflicting spends detectable via parent-chain analysis; slashing planned for v2.0
Replay attackTimestamp and unique TX hash in every vertex; duplicate IDs rejected by DAG
Vertex tamperingSHA-256 content hash over full vertex body; any mutation invalidates hash
Sybil attackStake-weighted consensus; validator weight proportional to staked THRA
Signaling server compromiseServer handles only connection brokering; cannot forge transactions; all data is verifiably signed
Man-in-the-middle (WS)Production deployment uses WSS (WebSocket over TLS); ICE candidates authenticated via DTLS-SRTP

12.3 Key Management Recommendations

For production deployments on THRA, application developers should:

  • Enforce strong password requirements (12+ chars, mixed case, symbols) to increase AES-GCM key derivation resistance
  • Implement session timeouts with automatic in-memory key disposal
  • Consider hardware-backed key storage via WebAuthn/FIDO2 for high-value nodes
  • Never log or transmit the plaintext private key outside the initialization flow

13. Performance & Scalability

13.1 Transaction Throughput

The THRA DAG permits parallel vertex appending from multiple nodes simultaneously. In a network of N concurrently active nodes, each capable of submitting transactions at rate r, the theoretical maximum throughput is:

TPS_max = N × r (unbounded by serialization)

In practice, WebRTC data channel throughput on a modern system exceeds 100 Mbps on a local network, supporting thousands of vertex messages per second per channel. The primary bottleneck for large networks is the O(N²) mesh topology — each node maintains direct connections to all other nodes, which becomes impractical beyond ~500 simultaneous peers. THRA v2.0 will introduce a structured overlay topology (DHT-based routing) to address this.

13.2 Confirmation Latency

PhaseTypical Latency
Pre-flight validation (local)< 1ms
Ed25519 signing (Web Crypto API)1–5ms
SHA-256 hashing (vertex + TX)0.5–2ms
Local DAG commit + storage2–10ms
Server persistence (REST API)20–100ms
P2P broadcast to connected peers50–300ms (RTT dependent)
Total (local confirmation)< 20ms
Total (network propagation)< 500ms

13.3 Storage Scalability

Each DAG vertex requires approximately 400–800 bytes of JSON storage (including hash, signature, and metadata). A node performing 10 transactions per day for a year accumulates approximately 1.5 MB of local storage — well within browser localStorage quotas (typically 5–10 MB per origin). The PostgreSQL ledger mirror scales independently using standard horizontal partitioning by node ID or timestamp range.

13.4 Network Initialization Time

Cold-start node initialization (first visit) completes in under 3 seconds on a typical broadband connection:

  • Key pair import: ~50ms
  • Server vertex sync: 100–500ms (network dependent)
  • Genesis vertex creation: ~10ms
  • WebSocket + ICE negotiation: 500–2000ms (peer dependent)

Warm-start (returning user) completes in under 1 second, as the local DAG is already populated from localStorage.

14. Use Cases

14.1 Peer-to-Peer Micropayments

THRA's 0.01% fee rate and sub-20ms local confirmation make it well-suited for micropayment channels — tipping content creators, pay-per-request API billing, in-game economies, and real-time content monetization. Unlike payment networks that require pre-opened state channels or liquidity deposits, THRA transfers complete in a single round of cryptographic operations.

14.2 Decentralized Identity

The Ed25519 node ID provides a self-sovereign identity anchor. The profile vertex type allows nodes to publish human-readable identities, credentials, and metadata without relying on a centralized directory. Applications can build DID (Decentralized Identifier) resolvers on top of the THRA profile layer.

14.3 Browser-Based DeFi Primitives

The staking mechanism provides the foundation for yield-generating protocols. Future THRA protocol extensions will support: liquidity pools (multi-party stake vertices), atomic swaps (time-locked conditional transfer vertices), and decentralized lending (collateral-backed genesis allocations).

14.4 Collaborative Applications

The custom message protocol (network.on / network.broadcast) enables applications to build real-time collaborative features entirely over the P2P mesh: multiplayer games, shared whiteboards, collaborative documents, and live event coordination — all without a central server mediating the data flow.

14.5 Verifiable Credential Exchange

Since every THRA node has an Ed25519 identity, nodes can issue and verify Verifiable Credentials (W3C VC standard) directly. An educational institution running a THRA node can sign a credential vertex attesting to a user's qualification; any recipient can verify the credential by checking the issuer's public key against the THRA identity layer.

15. Conclusion

THRA Network demonstrates that a fully functional decentralized peer-to-peer network — with cryptographic identity, parallel DAG ledger, Proof-of-Stake consensus, and a native token economy — can operate entirely within the constraints of a modern web browser, requiring no external software installation. By building on the Web Crypto API for cryptographic primitives and WebRTC for peer transport, THRA inherits the security model of the browser platform while eliminating its traditional dependency on centralized application servers.

The THRA SDK provides developers with a minimal, composable API surface — fewer than 15 core methods — that covers the full lifecycle of a decentralized application: identity generation, value transfer, staking, custom message protocols, and DAG querying. The TypeScript implementation ensures type safety and IDE tooling support across the full stack.

The most meaningful measure of THRA's success is not throughput metrics or token valuation, but adoption: every browser tab that loads THRA Network and stays connected is a node that strengthens the mesh, improves transaction propagation, and contributes to a network that requires no corporation, server farm, or central authority to function. The network is its users.

THRA Network is open-source software. Contributions, protocol improvement proposals, and community governance are welcome.

References

  1. Nakamoto, S. (2008). Bitcoin: A Peer-to-Peer Electronic Cash System. bitcoin.org/bitcoin.pdf
  2. Buterin, V. (2014). Ethereum: A Next-Generation Smart Contract and Decentralised Application Platform. ethereum.org/whitepaper
  3. Bernstein, D.J., et al. (2011). High-speed high-security signatures. Journal of Cryptographic Engineering, 2(2), 77–89.
  4. W3C Web Crypto API Specification. (2017). w3.org/TR/WebCryptoAPI
  5. IETF RFC 8825 — Overview: Real Time Protocols for Browser-Based Applications. (2021).
  6. IOTA Foundation. (2018). The Tangle. assets.ctfassets.net/r1dr6vzfxhev/2t4uxvsIqk0h/9c100f7ea3a9bed1c56ef5e79a6cd6b1/iota1_4_3.pdf
  7. LeMahieu, C. (2018). Nano: A Feeless Distributed Cryptocurrency Network. nano.org/en/whitepaper
  8. W3C Decentralized Identifiers (DIDs) v1.0. (2022). w3.org/TR/did-core
  9. MDN Web Docs. Ed25519 — Web Crypto API. developer.mozilla.org
  10. PostgreSQL Global Development Group. (2024). PostgreSQL Documentation. postgresql.org/docs
THRA THRA Network  ·  Technical Whitepaper v1.0  ·  thra.network