Sovereign, on-premises, never on a cloud.
Air-gapped Offline Signers in a sovereign data center. HSM inside the country’s borders. Every key generation witnessed as a ceremony. Every signature is a four-of-seven quorum.
See our deployment options
Store keys in MPC, HSM, or offline.
Run them in our cloud, yours, or on your metal.
MPC or HSM. Mix them by wallet, entity, or mandate. Our key layer adapts to your risk model.
Managed SaaS, hybrid, or fully on-premises. Same API, same controls, wherever the keys live.
MPC across enclaves, no seed phrases. The key is never assembled and signing never stops.
A single key derives wallets on 100+ networks. Manage access once, apply it everywhere.
Generate your keys with advanced multi-party computation. The key never exists in full.
No mnemonic, no recovery sheet, no HD tree rooted in a single secret an attacker can target.
Each share derives from its enclave's hardware RNG. No shared seed, no correlated randomness.
secp256k1, Ed25519, Stark, Schnorr, covered by KU25 for ECDSA and FROST for Schnorr.
Before any key share participates, the request must be user-signed, policy-cleared, and cryptographically authorized. Compromise one layer and nothing signs.
Quorums, limits, and allowlists are evaluated before a signature exists, not after it settles.
Passkeys authenticate the request; MPC keys authorize the action onchain. They are different.
Sensitive requests carry a WebAuthn signature from the user's device, bound to the exact action.
Key shares span multiple regions. Signer quorums remain available when nodes fail. No whole key exists to rotate, expire, or lose.
MPC doesn't depend on freshness. Rotate the credentials that touch it; leave the key in place.
A region can go dark, the signing quorum carries on. Continent-level failures degrade gracefully.
The threshold tolerates losing nodes and missing shares by reconstituting them under attestation.
Run company wallets and user wallets on the same key management layer. Custody what you hold. Delegate what they hold.
Hold keys for your users. Or delegate signing so they approve, you operate per wallet.
Add user wallets inside your product with a passkey. No seed phrase to manage.
However the key is held, every signature lands in the same signed, timestamped record.
“Thanks to their collaborative team and institutional-grade wallet platform, we've enhanced our operational capabilities and widened our business lines. Our security framework has also been reinforced by their state-of-the-art MPC cryptography.”
Three archetypes. Three configurations. One platform.
Air-gapped Offline Signers in a sovereign data center. HSM inside the country’s borders. Every key generation witnessed as a ceremony. Every signature is a four-of-seven quorum.
See our deployment optionsHextrust runs sub-organizations per client and per jurisdiction. Hybrid deployment matches controls to asset class — SaaS for new chains, on-prem for the assets that demand it.
Discover our integrationsDue provisions non-custodial wallets for tens of thousands of users through DFNS. Passkeys on the user’s device. Co-controlled signing with the neobank’s policy engine.
Read the Due storyGenerate the key. Derive wallets. Govern access. Sign safely. The same primitive whether you have one wallet or ten million.
0 client key losses since 2020 · MPC across enclaved nodes in multiple regions · Curves: secp256k1, Ed25519, Stark, Schnorr · 100+ chains served from one key
One API call. The MPC network generates independent shares across enclaves. No seed phrase produced. No master secret stored. The key is referenced by keyId and never exists in complete form.
// Generate an MPC key — distributed across enclaved signers from the start
const key = await dfnsApi.keys.createKey({
body: {
scheme: "ECDSA", // or "EdDSA", "Schnorr"
curve: "secp256k1", // or "ed25519", "stark"
name: "Treasury Master Key — EU Region"
}
});
// key.id, key.publicKey, key.scheme, key.curve
// The private key is split, sealed, and distributed.
// It has never existed as a complete value, and never will.Reference the same keyId to derive wallets on any compatible network. Same address on every EVM chain. Different address on Bitcoin or Solana, same underlying key. Rotate access once, propagate everywhere.
// Same key — wallets on Ethereum, Polygon, Base, Arbitrum, etc.
const ethereum = await dfnsApi.wallets.createWallet({
body: { network: "Ethereum", signingKey: { id: key.id }, name: "Treasury — ETH" }
});
const polygon = await dfnsApi.wallets.createWallet({
body: { network: "Polygon", signingKey: { id: key.id }, name: "Treasury — MATIC" }
});
// ethereum.address === polygon.address — same key, same EVM address
// On Bitcoin or Solana, different address derivation, same underlying keyPasskeys and API credentials authenticate the request. MPC shares authorize the signature. Compromise of one doesn't compromise the other. Layer policies on top — quorums, limits, allowlists.
// Authenticate the request with a passkey-signed user action
const userActionSignature = await dfnsApi.auth.signUserAction({
challenge,
credential: await navigator.credentials.get({ publicKey: { challenge } })
});
// Sign a payload — the policy engine evaluates BEFORE the MPC network signs
const signature = await dfnsApi.keys.generateSignature({
keyId: key.id,
body: {
kind: "Hash",
hash: "0xabc...def" // 32-byte hash to sign
},
userActionSignature
});
// Authentication credential ≠ signing key. Two domains, two attack surfaces.
// Compromise of either alone signs nothing.Managed SaaS for speed. Hybrid cloud when sovereignty matters. On-premises when regulation requires it. Same MPC protocol, same audited code, your choice of where the enclaves run.
// Managed SaaS — the default. All shares in Dfns enclaves.
const dfnsApi = new DfnsApiClient({
baseUrl: "https://api.dfns.io",
// ...
});
// Hybrid — you hold one or more shares in your own infrastructure
// Configured during onboarding; the signing flow is otherwise identical
// Dfns cannot sign without your share; you cannot sign without Dfns
// On-premises — entire MPC stack inside your data center
// Same SDK, different base URL, full operational control
const onPremApi = new DfnsApiClient({
baseUrl: "https://dfns.your-bank.internal",
// ...
});