DEV Community

Cover image for Enterprise Blockchain in TypeScript: Real-World Case Studies, Protocol Mappings, MPC, HSM & Post-Quantum Patterns That Actually Run
Pedro Savelis
Pedro Savelis

Posted on

Enterprise Blockchain in TypeScript: Real-World Case Studies, Protocol Mappings, MPC, HSM & Post-Quantum Patterns That Actually Run

Most enterprise blockchain projects die in PoC hell. You've seen it: a flashy demo, some Hyperledger slides, a proof-of-concept that "works on my machine," and then... silence. The pilot never graduates to production. The consortium loses interest. The budget evaporates.

The problem isn't the technology—it's that most repositories show you what blockchain can do without showing you how to actually build it. Where's the code for recall traceability that maps to real chaincode? Where's the privacy pattern that actually projects into Besu privacy groups? Where's the MPC implementation you can run locally without spinning up three cloud VMs?

This repository is different. enterprise-blockchain by @psavelis delivers 20 runnable examples covering four production-grade business scenarios, three protocol adapters (Fabric, Besu, Corda), MPC secret sharing, HSM key management, and NIST-standardized post-quantum cryptography. Everything runs locally. Everything passes CI. Everything is actually useful.

And yes, with quantum computers advancing faster than expected, the PQC examples aren't academic exercises—they're code you might need sooner than you think.

📦 What You'll Get From This Post

  • 4 production case studies with domain models and real code
  • 3 protocol adapters (Hyperledger Fabric, Besu/EVM, R3 Corda)
  • Post-quantum cryptography (NIST FIPS 203/204 compliant)
  • MPC and HSM patterns for off-chain computation and key custody
  • Full local infrastructure (Docker Compose + OpenTelemetry + Jaeger)
  • AI skill files that teach coding assistants the domain

Let's dive in.


🏗️ Repository Overview

Stat Value
Language TypeScript (strict mode)
Examples 20 runnable scenarios
Protocols Hyperledger Fabric, Besu, R3 Corda
Cryptography MPC, HSM, ML-KEM-768, ML-DSA-65
Infrastructure Docker Compose + Terraform
CI GitHub Actions (4 parallel matrix jobs)
Test Runner Node.js native + fast-check property tests
License Apache 2.0

The repository follows hexagonal architecture: domain logic sits at the center, protocol adapters implement ports, and integration clients handle the messy SDK details. This means you can swap Fabric for Besu without rewriting your business rules.

Why does this matter? Most enterprise blockchain projects fail at the integration boundary. The chaincode works, but nobody can figure out how to connect it to the ERP system. The Corda flows run, but the identity mapping to Active Directory is a nightmare. This repository explicitly separates those concerns:

  • Domain layer: Pure business logic. No protocol dependencies. Fully unit-testable.
  • Protocol adapters: Stateless projectors that translate domain events into platform-specific transaction shapes.
  • Integration clients: SDK wrappers with retry policies, circuit breakers, and connection management.
modules/
├── traceability/      # Food recall domain logic
├── privacy/           # Selective disclosure ledger
├── credentialing/     # Hospital staffing clearance
├── aid-settlement/    # Humanitarian voucher reconciliation
├── mpc/               # Secret sharing + post-quantum KEM
├── hsm/               # Envelope encryption + signing
├── protocols/         # Fabric, Besu, Corda adapters
└── integrations/      # SDK clients (Gateway, ethers, REST)
Enter fullscreen mode Exit fullscreen mode

🍎 Case Study #1: Food Recall Response (Fabric)

The Problem: A contaminated lettuce shipment reaches three distribution centers before anyone notices. How do you trace every affected lot, identify which retailers received them, and generate a recall plan—all in under an hour?

The Solution: The TraceabilityLedger domain module models lots, shipments, and telemetry readings. When temperatures breach safe ranges or contamination is detected, the RecallAssessor walks the shipment graph and returns every affected lot.

export class TraceabilityLedger {
  private readonly store: TraceabilityStore;

  registerLot(lot: ProductLot): void {
    this.store.addLot(lot);
  }

  dispatchShipment(shipment: Shipment): void {
    this.store.addShipment(shipment);
  }

  recordTelemetry(reading: TelemetryReading): void {
    this.store.addTelemetry(reading);
  }

  assessRecall(rule: RecallRule): RecallAssessment {
    return new RecallAssessor(this.store).assess(rule);
  }
}
Enter fullscreen mode Exit fullscreen mode

The Fabric adapter projects this into chaincode invocations:

export class FabricTraceabilityAdapter {
  createLotCommand(lot: ProductLot): FabricInvocation {
    return {
      contract: "FoodTraceContract",
      transaction: "CreateProduct",
      args: [lot.id, lot.originCountry, lot.supplier, lot.harvestDate],
      endorsementPolicyHint: "AND('RetailerMSP.peer','SupplierMSP.peer')",
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

Pro tip: The endorsementPolicyHint tells you which organizations must co-sign. This is operational gold—it forces you to think about governance before you write the chaincode.

The pattern here is powerful: domain logic knows nothing about Fabric. The TraceabilityLedger could just as easily project to Besu or Corda. The adapter layer handles the translation, and the endorsement policy hints are documentation—not runtime dependencies.

Run it yourself:

npm run example:food-recall
npm run example:fabric-projection
Enter fullscreen mode Exit fullscreen mode

🔐 Case Study #2: Consortium Order Sharing (Besu)

The Problem: A buyer, a bank financing the purchase, a logistics provider, and a regulator all need to see a purchase order—but each should see only their relevant slice. The buyer sees pricing. The bank sees credit terms. The regulator sees compliance flags. Nobody sees everything.

The Solution: The SelectiveDisclosureLedger creates audience-specific projections from a canonical order, each cryptographically committed so any party can verify their view derives from the same source.

export class SelectiveDisclosureLedger {
  publishOrder(order: PurchaseOrder): void {
    this.repo.addOrder(order);
  }

  createView(orderId: string, audience: Audience): SharedOrderView {
    return this.projector.createView(orderId, audience);
  }
}
Enter fullscreen mode Exit fullscreen mode

The Besu adapter maps this to privacy-group scoped contract calls. Different audiences get different privacy groups, but the canonical hash anchors everyone to the same truth.

Watch out: Privacy groups aren't magic. If your public contract reads private state, you've just leaked data. The adapter enforces this boundary—use it.

The selective disclosure pattern is increasingly critical as regulations like GDPR and CCPA demand data minimization. The canonical order exists. The views are derived. The audit proofs are cryptographic. This is how you share data across organizational boundaries without oversharing.

npm run example:order-sharing
npm run example:besu-projection
Enter fullscreen mode Exit fullscreen mode

🏥 Case Study #3: Hospital Staffing Clearance (Corda)

The Problem: Before a traveling nurse can work a shift, you need to verify their license, check for sanctions, confirm malpractice insurance, and get hospital sign-off. This involves the staffing agency, the hospital, the state licensing board, and potentially CMS.

The Solution: Corda's point-to-point model fits perfectly. Each party only sees the transactions they're involved in. The ProviderClearanceState captures the clearance decision, and the flow collects signatures from exactly the required participants.

The Corda adapter generates flow invocation payloads:

{
  flow: "IssueProviderClearanceFlow",
  participants: ["Hospital-A", "StaffingAgency-X", "LicenseBoard-CA"],
  state: {
    providerId: "NP-12345",
    clearanceStatus: "APPROVED",
    validUntil: "2026-06-30"
  }
}
Enter fullscreen mode Exit fullscreen mode

Why Corda here? The healthcare staffing workflow is fundamentally bilateral—the hospital and the staffing agency need to agree, with the licensing board providing attestation. Corda's "need-to-know" model means the hospital's competitor down the street never sees this transaction. That's not a bug, it's the core feature.

npm run example:staffing-clearance
npm run example:corda-projection
Enter fullscreen mode Exit fullscreen mode

💰 Case Study #4: Aid Voucher Reconciliation (Besu/Fabric)

The Problem: Multiple humanitarian agencies issue digital vouchers to beneficiaries. Merchants redeem them for payment. But without coordination, beneficiaries double-dip, merchants submit fake invoices, and settlement takes months.

The Solution: The AidSettlementLedger validates claims against grant rules (budget caps, category restrictions, expiry dates) and generates reconciliation reports. The Solidity contract mirrors these rules on-chain:

function submitClaim(
    bytes32 claimId,
    bytes32 grantId,
    address merchantId,
    uint8 merchantCategory,
    bytes32 invoiceReference,
    uint256 amountUsd100
) external {
    Grant storage g = grants[grantId];
    require(block.timestamp < g.expiresAt, "Grant expired");
    require(g.consumedUsd + amountUsd100 <= g.amountUsd, "Budget exceeded");
    require(!usedInvoices[grantId][invoiceReference], "Duplicate invoice");
    // ... emit ClaimSettled or ClaimRejected
}
Enter fullscreen mode Exit fullscreen mode

Pro tip: The validation rules are expressed in both TypeScript and Solidity. This is the one place hexagonal purity yields to platform reality: EVM enforcement requires on-chain logic. The TypeScript domain model remains the source of truth for design, but Besu deployments maintain parallel validation in Solidity. Fabric deployments can keep everything in TypeScript chaincode.


🔗 Protocol Adapters: One Domain, Three Platforms

The protocol adapter layer is where this repository shines. Instead of writing three separate applications, you write domain logic once and project it to multiple platforms:

Domain Event Fabric Besu Corda
Register lot CreateProduct chaincode registerLot(bytes32) IssueLotState flow
Record shipment RecordShipment + transient data Privacy group contract call RecordShipmentFlow
Submit claim Endorsement by agency + merchant Public contract with budget check SubmitClaimFlow

The adapters are stateless. They take domain objects and return platform-specific command shapes. No network calls, no SDK dependencies, no environment configuration. You can unit test them in isolation.

This is the key insight: protocol selection is a deployment decision, not an architectural one. Your domain model should survive a platform migration. The caveat: EVM-based platforms (Besu) require on-chain enforcement in Solidity, so you'll maintain parallel validation logic there. Fabric's TypeScript chaincode keeps everything in one language. The domain layer remains the design authority either way—contract code is derived from it, not the other way around.


🤫 Off-Chain Cryptography: MPC Secret Sharing

Some computations shouldn't happen on-chain. Sealed-bid auctions, joint risk analysis, and threshold signatures all require parties to collaborate without revealing their inputs.

The MPCEngine implements additive secret sharing:

export class MPCEngine {
  /**
   * Split `secret` into `partyIds.length` additive shares.
   * Any strict subset reveals nothing; summing all shares
   * reconstructs the original value.
   */
  splitSecret(secret: number, partyIds: string[]): SecretShare[] {
    const shares: SecretShare[] = [];
    let remaining = secret;

    for (let i = 0; i < partyIds.length - 1; i++) {
      const value = randomInt(-(2 ** 47) + 1, 2 ** 47);
      remaining -= value;
      const nonce = randomBytes(16).toString("hex"); // Fresh nonce per share
      shares.push({
        partyId: partyIds[i],
        shareIndex: i,
        value,
        nonce,
        commitment: commitShare(partyIds[i], i, value, nonce),
      });
    }
    // Last share gets the remainder to ensure sum = original secret
    return shares;
  }
}
Enter fullscreen mode Exit fullscreen mode

The compute() method reconstructs the aggregate without any party learning individual inputs:

npm run example:mpc-auction      # Sealed-bid procurement
npm run example:mpc-risk-analysis # Cross-institution credit analysis
Enter fullscreen mode Exit fullscreen mode

The repository also includes QuantumResistantVault for Shamir k-of-n threshold secret sharing:

// Distribute a key across 5 custodians, requiring any 3 to reconstruct
const shares = vault.distributeSecret(masterKey, parties, 3);
const reconstructed = vault.reconstructSecret(threeShares, 3);
Enter fullscreen mode Exit fullscreen mode

This pattern is essential for key custody ceremonies where no single party should hold the complete key.


🔐 HSM Key Management: Envelope Encryption

Production blockchain deployments use hardware security modules. The HsmClient simulates PKCS#11 semantics—private keys never leave the "hardware boundary":

export class HsmClient {
  generateKeyPair(keyLabel: string): HsmKeyPair;
  sign(keyLabel: string, data: string): HsmSignatureResult;

  // Envelope encryption: DEK wrapped by KEK
  encryptWithEnvelope(kekLabel: string, plaintext: string): {
    encryptedRecord: EncryptedRecord;
    wrappedDek: WrappedKey;
  };
}
Enter fullscreen mode Exit fullscreen mode

Three examples demonstrate real patterns:

  • hsm-transaction-signing: ECDSA-SHA256 for equity trade orders
  • hsm-key-ceremony: Root key ceremony with 3-of-5 Shamir threshold
  • hsm-envelope-encryption: DEK/KEK for sensitive trade documents

Watch out: The simulated HSM uses in-memory storage. In production, you'd connect to AWS CloudHSM, Azure Dedicated HSM, or an on-prem Thales Luna via PKCS#11.


⚛️ Post-Quantum Cryptography: Future-Proofing Now

Here's the thing about "harvest now, decrypt later" attacks: adversaries are already collecting your encrypted traffic. When CRQCs arrive (NIST estimates 2030-2035), they'll decrypt everything you sent today.

If your data has 10+ year confidentiality requirements—financial records, healthcare, trade secrets—you need post-quantum cryptography now.

The repository implements NIST FIPS 203 (ML-KEM-768) and FIPS 204 (ML-DSA-65) with hybrid constructions for defense-in-depth:

export class HybridKem {
  /**
   * Combine X25519 (classical) + ML-KEM-768 (post-quantum).
   * Breaking this requires breaking BOTH algorithms.
   */
  encapsulate(
    recipientX25519PublicKey: KeyObject,
    recipientMlKemPublicKey: Uint8Array,  // FIPS 203 naming
  ): HybridEncapsulation {
    // Classical channel
    const x25519SharedSecret = diffieHellman({ /* ... */ });

    // Post-quantum channel (ML-KEM-768, formerly "Kyber")
    const { cipherText, sharedSecret: mlKemSharedSecret } =
      ml_kem768.encapsulate(recipientMlKemPublicKey);

    // Combine via HKDF
    const combinedKey = hkdfSync(
      "sha256",
      Buffer.concat([x25519SharedSecret, mlKemSharedSecret]),
      HKDF_SALT,
      "hybrid-kem-v1",
      32,
    );
    return { combinedKey, /* ... */ };
  }
}
Enter fullscreen mode Exit fullscreen mode

This matches how Chrome and Cloudflare deployed post-quantum TLS (X25519Kyber768). Run the examples:

npm run example:kyber-kem          # Pure ML-KEM-768
npm run example:hybrid-kem         # X25519 + ML-KEM hybrid
npm run example:quantum-safe-payment # End-to-end PQ payment flow
Enter fullscreen mode Exit fullscreen mode

🐳 Infrastructure: Docker Compose + Observability

The repository includes a complete local development stack:

services:
  besu-validator-1:    # Hyperledger Besu node
  besu-validator-2:
  fabric-peer:         # Hyperledger Fabric peer
  fabric-orderer:
  otel-collector:      # OpenTelemetry Collector
  jaeger:              # Distributed tracing UI
  prometheus:          # Metrics collection
Enter fullscreen mode Exit fullscreen mode

Security follows CIS Docker Benchmark:

  • Resource limits (CPU/memory) on all containers
  • no-new-privileges: true blocks privilege escalation
  • Log rotation prevents disk exhaustion
  • All ports bound to 127.0.0.1

Run it:

make up              # Start everything
make smoke           # Run health checks
open http://localhost:16686  # Jaeger traces
open http://localhost:9090   # Prometheus metrics
Enter fullscreen mode Exit fullscreen mode

Want to see distributed traces for your blockchain operations? Just set the environment variables:

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_SERVICE_NAME=food-recall-service
npm run example:food-recall
Enter fullscreen mode Exit fullscreen mode

Then open Jaeger and watch the spans flow through your traceability ledger operations.


✅ Quality Gates: Property-Based Testing

Enterprise blockchain systems demand correctness guarantees that exceed typical application standards. Cryptographic operations produce silent failures—no exception, just compromised security.

The repository uses fast-check for property-based testing of cryptographic invariants:

// HSM envelope encryption round-trip
test("envelope encryption: decrypt(encrypt(x)) === x", () => {
  fc.assert(
    fc.property(
      fc.string({ minLength: 1, maxLength: 10000, unit: "binary-ascii" }),
      (plaintext) => {
        const { encryptedRecord, wrappedDek } = hsm.encryptWithEnvelope(kekLabel, plaintext);
        const decrypted = hsm.decryptWithEnvelope(wrappedDek, encryptedRecord);
        return decrypted === plaintext;
      },
    ),
  );
});
Enter fullscreen mode Exit fullscreen mode

These tests catch edge cases that unit tests miss:

  • Off-by-one errors in field arithmetic
  • IV reuse across encryptions
  • Implicit rejection failures in post-quantum KEMs

Run the property tests:

npm test                           # All tests
npm test -- tests/hsm.property.test.ts  # HSM-specific
npm test -- tests/mpc.property.test.ts  # MPC-specific
Enter fullscreen mode Exit fullscreen mode

⚡ Run Everything in 5 Minutes

git clone --recursive https://github.com/psavelis/enterprise-blockchain.git
cd enterprise-blockchain
npm install
npm run verify        # format + lint + typecheck + tests + 20 examples
make up               # start infrastructure (optional)
npm run examples      # run all business scenarios
Enter fullscreen mode Exit fullscreen mode

That's it. Every example runs. Every test passes. No external services required.

Want to verify everything passes CI? Run the full quality gate:

npm run verify   # format:check + lint + typecheck + test + all examples
Enter fullscreen mode Exit fullscreen mode

This is the same command CI runs. If it passes locally, it passes in GitHub Actions. No surprises.


📚 Lessons Learned

After reviewing dozens of enterprise blockchain deployments, some patterns emerge:

  1. Platform selection follows trust, not throughput. Feature matrices are noise. Teams pick Fabric because they have Java developers. They pick Besu because they know EVM. They pick Corda because R3 has regulatory relationships. Throughput differences matter only after trust assumptions narrow the field.

  2. Privacy is architecture, not configuration. Every platform offers privacy mechanisms. None of them work without deliberate design. If your public contract queries private state, you've leaked data.

  3. Off-chain is not optional. Every production deployment stores bulk data off-chain. The blockchain stores commitments, not content. Plan for this from day one.

  4. Integration complexity dominates. Chaincode development is 20-30% of the project. Identity integration, legacy system bridges, and operational tooling consume the rest.

  5. Governance evolves faster than code. Consortium agreements written at kickoff become obsolete. New members require endorsement policy changes. Regulatory requirements mandate audit observer nodes. Design for governance evolution from day one.

  6. Consensus selection follows trust, not throughput. Marketing materials emphasize throughput differences. Production deployments choose based on trust assumptions. Raft (CFT) for aligned incentives. QBFT (BFT) for competing parties. The throughput numbers are noise.


🤖 AI Skills: Teaching Your Coding Assistant

The skills/ folder contains structured knowledge files designed for AI coding assistants:

Skill When to Use
platform-selection.md Choosing between Fabric, Besu, Corda
hsm-key-management.md Implementing PKCS#11 key operations
mpc-secret-sharing.md Building threshold cryptography
selective-disclosure.md Privacy-preserving data sharing
infrastructure-reference.md Docker Compose and CI configuration

Each skill follows a consistent structure: when to use, when NOT to use, key concepts, must-preserve invariants, and anti-patterns to avoid. Feed these to Claude, Copilot, or your favorite coding assistant for context-aware suggestions.


🌟 Who Should Star This Repo?

  • Blockchain architects evaluating Fabric vs Besu vs Corda
  • Security engineers implementing MPC, HSM, or post-quantum patterns
  • Protocol researchers studying transaction shape mappings
  • Teams in PoC purgatory who need production-grade examples
  • Anyone who's tired of blockchain demos that don't actually run
  • Developers learning enterprise blockchain who want working examples, not slides

Whether you're building a supply chain traceability system, a consortium data sharing platform, or exploring post-quantum cryptography for your organization's future security posture—this repository has runnable code that demonstrates the pattern.


🚀 Call to Action

Star the repoFork itRun the examplesOpen an issue with your use case

The code is Apache 2.0. Take what you need. Adapt it to your consortium. And if you build something cool, let us know in the issues—we love seeing what people create with these patterns.


📖 Further Reading


Built by @psavelis. If this helped you ship something real, drop a star.

Top comments (0)