Keys and signing
Three schemes
One key generation and coordination stack, three signing schemes, selected per request with a curve parameter.
| Curve | Algorithm | Verified by | Signature |
|---|---|---|---|
| frost_secp256k1 | FROST Schnorr (RFC 9591) | A verifier library, via a smart account | 65 bytes — R.x ‖ z ‖ v |
| ecdsa_secp256k1 | Threshold ECDSA | ecrecover | 65 bytes — r ‖ s ‖ v |
| frost_ed25519 | FROST Schnorr over Ed25519 | Native Ed25519 verifiers | 64 bytes |
The curve is part of a key's identity
curve explicitly; the node never guesses.Which one to pick
For anything that needs to look like an ordinary Ethereum signature — EIP-712, EIP-3009, anything a contract verifies with ecrecover — use ecdsa_secp256k1. For a smart account whose validator is Signet’s own, use frost_secp256k1. For Solana and other chains with native Ed25519, use frost_ed25519.
Key lifecycle
- Generate — a distributed round; every operator ends with a share.
- Disable — the kill switch. The key refuses to sign and refuses to mint delegations. Enforced by every operator, not by any one of them.
- Enable — reverses a disable.
- Delete — removes the shares. There is no undo, and no recovery.
await fetch(`${NODE_URL}/v1/keys/disable`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
group_id: GROUP_ADDRESS,
key_id: KEY_ID,
curve: "ecdsa_secp256k1",
...signedRequest,
}),
});Listing what your group holds
POST /admin/keys returns the inventory for a group. It requires a signature from an authorization key the group trusts, which is why the console asks you to sync it rather than fetching it on your behalf — this platform deliberately holds no credential your operators would accept.
Reshare
Calling requestReshare on your group contract emits an event; the nodes elect a leader and run the protocol. Public keys and addresses are unchanged throughout, so nothing your users hold has to move. Worth doing after an operator leaves, and worth scheduling if you want a stolen share to expire on its own.