Tenzro
Custody and wallet

Passkey onboarding.

The default consumer wallet on Tenzro is a passkey-bound ERC-4337 smart account. The signing key lives in the user’s hardware secure element (Apple Secure Enclave, Windows Hello / TPM, Android StrongBox, YubiKey). No seed phrase. Rotation, recovery, and agent delegation all happen on-chain through ERC-7579 modular validators.
STATUS
Testnet
CRATE
tenzro-node
STABILITY
Stable
REFERENCE
passkey-onboarding
01

The model

Three pillars: the smart account address is the identity, not the signing key. Keys rotate without the address changing. Custody is enforced on-chain at signing time through composable ERC-7579 validator modules.

Reference implementations Tenzro is aligned with: Coinbase Smart Wallet, Daimo, Privy, Safe with modular validators, Argent on StarkNet. All share the same shape — passkey primary + guardian quorum recovery + session keys for app grants.

02

Substrate

tenzro-crypto::p256              # P-256 keypair, signer, verifier
tenzro-crypto::webauthn         # full WebAuthn assertion verifier
tenzro-vm precompile 0x100      # EIP-7951 / RIP-7212 P256VERIFY
tenzro-vm::WebAuthnValidator    # ERC-7579 primary validator
tenzro-vm::SocialRecoveryValidator   # 0x101d N-of-M guardians
tenzro-vm::SessionKeyValidator       # 0x101e scoped session keys
tenzro-vm::SpendingLimitValidator    # 0x101f per-tx + daily caps
tenzro-vm::AccountFactory       # ERC-4337 v0.8 EntryPoint compatible
03

Enrollment

The client acquires a WebAuthn registration credential from the platform authenticator and passes the P-256 public key + opaque credential ID + ML-DSA-65 verifying key (for the post-quantum leg) to tenzro_enrollPasskey. The node creates a TDIP human identity, deploys a smart account via the shared AccountFactory, installs WebAuthnValidator as the primary signer, and persists everything to CF_AGENTS + CF_VALIDATOR_MODULES.

POST https://rpc.tenzro.network
{
  "jsonrpc": "2.0",
  "method": "tenzro_enrollPasskey",
  "params": {
    "display_name": "Hilal's iPhone",
    "passkey_public_key_hex": "0x04...",
    "credential_id_hex": "0x...",
    "ml_dsa_public_key_hex": "0x..."
  },
  "id": 1
}
04

Signing

The client builds a UserOperation, hashes it per ERC-4337 v0.8, calls navigator.credentials.get() with the hash as the challenge, and submits the resulting WebAuthn assertion + ML-DSA-65 signature to tenzro_signWithPasskey. The node verifies the challenge matches the op hash, the P-256 leg validates against the registered public key, and the PQ leg validates against the registered ML-DSA verifying key.

For production transactions, the same hybrid signature packed as HybridWebAuthnSignature is supplied as the userOp.signature field on the standard eth_sendRawTransaction / ERC-4337 EntryPoint path. The on-chain WebAuthnValidator runs the same verification through the 0x100 P256VERIFY precompile.

05

Social recovery

When the user enrolls, they nominate guardians — typically family members, a recovery service, or a backup hardware key. Each guardian holds an Ed25519 + ML-DSA-65 composite key. To rotate the account to a new passkey (after device loss), the user enrolls a new passkey on a new device, calls tenzro_initiateRecovery, and shares the returned recovery_op_hash with the guardians. Each guardian signs and submits via tenzro_submitRecoverySignature. Once quorum is reached, the user calls tenzro_finalizeRecoveryand the node installs the new passkey as the smart account’s primary validator. The smart account address never changes.

tenzro_addGuardian                  # register one guardian
tenzro_initiateRecovery             # open the rotation ceremony
tenzro_submitRecoverySignature      # one per guardian
tenzro_finalizeRecovery             # install new passkey on quorum
tenzro_listPendingRecoveries        # observe ceremony state
06

Session keys for agents

Agents never hold the human’s passkey. The human grants the agent a scoped session key: tenzro_grantSessionKey installs a SessionKeyValidator config with allowed function selectors, target contracts, per-call value cap, cumulative lifetime cap, and validity window. The agent uses its own Ed25519 key to sign user ops within the scope; anything outside the scope is refused at the on-chain validator.

Revocation is one call: tenzro_revokeSessionKey. The session validator disengages immediately and the agent loses signing authority.

07

Hardware signers

Power users layer a Ledger / Trezor / GridPlus / YubiKey as an additional ANDed validator: tenzro_addHardwareSigner installs a hardware validator module that the EntryPoint AND-combines with the primary passkey validator. Configure required_always: true for a hardware second factor on every operation, or set required_above_wei for a value threshold above which the hardware key is mandatory.

08

Surfaces

The passkey RPCs map 1:1 to client surfaces:

  • Rust SDK: TenzroClient::passkey_rpc() returns a PasskeyClient.
  • TypeScript SDK: TenzroClient.passkeyRpc.
  • CLI: tenzro passkey enroll | add-guardian | initiate-recovery | grant-session-key | add-hardware-signer | list-accounts
  • MCP tools: enroll_passkey, sign_with_passkey, add_passkey_guardian, initiate_passkey_recovery, submit_recovery_signature, finalize_passkey_recovery, grant_session_key, revoke_session_key, set_spending_limit, add_hardware_signer, get_smart_account, list_smart_accounts, list_pending_recoveries.
  • A2A: passkey-wallet skill.
09

Hybrid post-quantum

Every passkey-bound smart account on Tenzro carries a hybrid PQ leg in addition to the classical P-256. The WebAuthnValidatorAND-combines the two — both must verify for the user op to validate. The PQ key (ML-DSA-65, 1952-byte vk, 3309-byte sig) lives alongside the passkey in the user’s key store and is enrolled at the same time as the passkey. This aligns Tenzro with the genesis v3 PQ-hybrid posture: classical + ML-DSA on every validator and identity.

Related
← All docs