How Tetrapolar Generates Keys: The Custody Question

A slightly technical post about how things are wired in the Tetrapolar stack.

Share
How Tetrapolar Generates Keys: The Custody Question

In the past couple of days, hardware wallet maker Coldcard lost an estimated 1,082 BTC — roughly $70 million — in 41 minutes. The culprit was not a leaked seed phrase, a phishing email, or a kidnapped founder. It was a flaw in random number generation at the firmware level. Battle-tested hardware. A brand security professionals trust. Undermined by entropy that was not random enough.

For any company holding, brokering, or settling bitcoin transactions, the Coldcard incident asks a question that is easy to dodge and dangerous to ignore: Who generates your keys, where, and how?

This post explains our answer.

The Wrong Framing

Most custody conversations start in the wrong place.

  • Hot wallet or cold storage?
  • Singlesig or multisig?
  • Hardware device or software?

These are implementation details. They matter, but they come later. What matters first is the moment before any of those choices exist: the moment a random number becomes a private key. If that moment is compromised, every downstream defense is cosmetic.

Coldcard shows that hardware alone is not a solution. Hardware shifts the trust boundary from your laptop to a dedicated device. But if the device itself generates weak entropy, the hardware boundary becomes a liability: it concentrates the secret in a place where the flaw is harder to inspect and slower to discover.

At the moment, there is only one way to generate keys in your Tetrapolar account. Our client does not delegate key generation to a hardware device, and it does not bundle a heavyweight wallet framework inside the browser. Instead, it generates keys inside a minimal, auditable signer using well-known, open-source cryptographic primitives. The goal is to reduce surface area, increase inspectability, and ensure that no single point of failure ever holds enough power to move funds alone.

Three Layers, One Custody Model

Tetrapolar's architecture separates key generation, transaction orchestration, and business logic into three layers.

This separation matters for two reasons.

First, it means a compromise of any single layer is insufficient to steal funds. A stolen laptop, a breached API, or a compromised coordinator node all leave the attacker with only a partial view. Because Tetrapolar uses 2-of-3 multisig with timelock recovery, extracting a single key — even a fully private key — does not grant spend authority.

Second, it means each layer can be optimized for exactly what it does, without inheriting the complexity of a full wallet stack. The browser client is a signer, not a wallet. It does not sync a blockchain, select coins, or manage UTXOs. It generates entropy, derives keys, applies a signature when instructed, and keeps the seed in memory only inside an isolated Web Worker.

BDK at the Core, Primitives in the Browser

BDK (Bitcoin Development Kit) and its companion LWK (Liquid Wallet Kit) are widely adopted Bitcoin and Liquid wallet frameworks in the industry. Written in Rust, they provide reliable blockchain synchronization, descriptor-based wallet management, coin selection, transaction building, and PSBT/PSET orchestration. Any serious Bitcoin project needs these capabilities somewhere in the stack — and Tetrapolar is no exception. We use them in our Coordinator layer.

Coordinator: BDK and LWK

Tetrapolar's Coordinator runs BDK for Bitcoin and LWK for Liquid. The reason is straightforward: the Coordinator is where the full framework belongs.

BDK and LWK provide:

  • Blockchain synchronization against light backends (Esplora and Electrum)
  • Descriptor-based wallet management, including multi-path descriptors and, on Liquid, confidential (blinded) descriptors
  • Miniscript support for timelocked escrow policies (CSV and CLTV)
  • Coin selection, with the option for clients to pin exact UTXOs
  • PSBT and PSET construction and finalization

That is exactly what the Coordinator needs. It is a server-side function that composes transactions, manages UTXOs, constructs PSBTs and PSETs from descriptors, and handles broadcast. Crucially, it does all of this statelessly: wallets are rebuilt on demand from descriptors on every request, with no database and no persistent wallet state — keys never touch the server, and signing stays on the client. BDK and LWK are the right tools for that profile — and they perform excellently.

However, this is not where client keys are generated and where the conversation about entropy applies.

Client: Primitives by Design

The browser client, by contrast, is intentionally thin. It does not sync a chain. It does not select coins. It does not manage UTXOs. It does not create or manage descriptors. It is a signer without chain state — it holds only your encrypted key.

What it does need:

  1. A secure source of randomness.
  2. A standard way to turn that randomness into a hierarchical key tree.
  3. The ability to parse and sign a partially-signed transaction (PSBT / PSET).
  4. Blinding support for confidential assets on Liquid.

Everything else — blockchain data, wallet state, deal logic, rate feeds, messaging — lives in the Coordinator or the Product API, where it is managed server-side with the operational tools appropriate to such infrastructure.

What the Browser Client Actually Uses

The client is built from the most widely deployed open-source JavaScript Bitcoin libraries. These packages underpin many of the wallets and services that have been in production since the early 2010s.

Before any key generation, the client probes the runtime: it proves crypto.getRandomValues exists, fills the buffer, and verifies the output does not repeat. If the probe fails, key generation aborts with an error — it never produces a weak key.

The seed and blinding secret never leave the Web Worker. Only xpubs, fingerprints, and signatures cross the thread boundary. The encrypted vault in IndexedDB can only be unlocked inside the worker. This structure is the right fit for a browser signer: minimal, inspectable, and targeted at exactly the operations a thin client needs to perform.

The Real Threat Model

The Coldcard incident shifted the conversation from devices to entropy. At Tetrapolar, the equivalent concern is not which library we use. Rather, it is the environment in which the library runs.

A browser is a hostile environment. Extensions can monkey-patch global objects. Compromised build pipelines can swap dependencies. XSS can leak data from the renderer process. We treat all of these as real risks, not theoretical concerns. Our defensive posture includes:

  • Fail-closed entropy validation. Before generating any key material, the client probes the browser's randomness source. If the probe fails, the application refuses to proceed. There is no silent fallback.
  • Dependency lockfile verification. The build pipeline pins exact versions of every cryptographic dependency and audits the lockfile for unexpected changes.
  • Web Worker isolation. The mnemonic and seed material are handled inside a dedicated Web Worker, separate from the main application thread. This does not make extraction impossible, but it raises the bar significantly over standard DOM-based storage.
  • No single-key authority. Even if every one of the defenses above were defeated, the attacker would walk away with one key in a 2-of-3 multisig setup. That key alone cannot move funds.

What This Means for Tetrapolar's Clients

If you are a business using Tetrapolar to escrow or settle BTC and USDT transactions, this architecture translates into three practical guarantees.

  1. You hold part of the multisig yourself. Unlike traditional custodians, Tetrapolar never has unilateral authority over your funds. Your key is generated in your browser and backed up on your own terms.
  2. There is no single vendor to trust blindly. The client is built from widely audited open-source libraries. The protocol is transparent. The threat models have been audited. You do not need to trust Tetrapolar's hardware, our firmware, or our entropy source. You need only trust the mathematics and the 2-of-3 quorum you participate in.
  3. An exploit at any single layer is survivable. A bad library, a compromised server, or a browser extension cannot independently drain funds because no single actor ever holds a complete signing quorum.

Final Takeaway

Coldcard taught a hard lesson: the most expensive failures happen where nobody is looking. In hardware wallets, that place was entropy generation. In web-based Bitcoin services, it is often the gap between "we use famous libraries" and "we understand how they are exposed in a browser."

Tetrapolar's architecture is designed to be minimal and structurally resilient: a thin, auditable signer in the browser, a coordinator that never touches private keys, and a multisig model where compromise of any single point is insufficient.


Sources