Identity

Makechain identity is address-native. The owner_address is the sole account identifier, delegated Ed25519 keys sign ordinary messages, and an AccountKeychain custody model authorizes key management. The canonical reference is protocol/SPECIFICATION.md (AccountKeychain custody, ERC-1271 removal, chain wipe).

Canonical identity

owner_address is the sole canonical account identifier in Makechain.

  • It is a raw 20-byte EVM-style address.
  • Any valid 20-byte address is a valid Makechain principal, even if it has never submitted a message.
  • Missing account state means default-zero bookkeeping, not invalid identity.

Makechain has no registry-backed account creation, protocol-level ownership transfer, or protocol-level recovery flow.

Delegated protocol keys

Protocol signing keys are Ed25519-only in Makechain.

Each delegated key is attached to an owner_address and has one of these scopes:

ScopeMeaning
OWNERHighest privilege
SIGNINGOrdinary account and project administration
AGENTProject-scoped automated actions

AGENT keys may be constrained by allowed_projects. OWNER and SIGNING keys ignore allowed_projects.

AccountKeychain custody

Account administration is controlled by an owner-scoped AccountKeychain.

  • The root owner_address is an implicit admin forever. It is never stored as a custody key, and KEYCHAIN_AUTHORIZE rejects key_id == owner_address.
  • KEYCHAIN_AUTHORIZE adds a custody key when authorized by the root or an active admin custody key. It carries an explicit signature_type and public_key for the key being added, and verifies that key_id is derived from that public key.
  • KEYCHAIN_REVOKE permanently revokes a custody key. The revoked row is retained as a tombstone (is_revoked = true, revoked_at set); it is never deleted.
  • Admin custody keys must not expire. Non-admin custody keys may exist in state but are inert in Makechain.
  • custody_nonce is the monotonic replay guard for successful keychain and signer-management mutations. The account being mutated burns its own nonce; the request_owner of an attribution signature never has its nonce burned.

Custody keys follow a three-state lifecycle — never seen → active → revoked — and revocation is permanent: re-authorizing a previously revoked key_id fails closed.

Custody and envelope keys share one owner-scoped keyspace, discriminated by a family byte:

0x06 | owner_address:20 | family:1 | key_id
  family 0x00 = envelope (Ed25519 signer, key_id = pubkey:32)
  family 0x01 = custody  (EVM-derived address, key_id = 20 bytes)

A custody authorization signature uses a self-describing envelope selected by its first byte or total length; nested wrappers are rejected:

65 bytes             secp256k1 direct
0x01 | ...           P256 direct        (r:32 | s:32 | pub_x:32 | pub_y:32 | pre_hash:1)
0x02 | ...           WebAuthn P256       (authenticatorData || clientDataJSON | sig:64 | pub_x:32 | pub_y:32)
0x03 | account:20 | …  AccountKeychain wrapper (one level only)

There are no custody_key_type, request_key_type, or validation-block-hash fields in signer-management messages.

This was a clean protocol break. Existing chain history and state from the ERC-1271 custody model are not replay-compatible with the AccountKeychain model.

In Makechain, custody-key management is an advanced surface: the root owner_address is the implicit admin and non-admin custody keys are inert, so most accounts never authorize a custody key. KEYCHAIN_AUTHORIZE and KEYCHAIN_REVOKE are first-class across the stack:

  • High-level writes: @makechain/viem client.custody.authorize(...) / client.custody.revoke(...) (with computeAuthorizeHash / computeRevokeHash), and the @makechain/wagmi Hooks.custody useAuthorize / useRevoke.
  • Low-level: compute the AccountKeychain digest with keychainAuthorizeSigningHash / keychainRevokeSigningHash, sign it with the admin (or root) key, then encode and submit the body with @makechain/sdk (encodeKeychainAuthorizeBody / encodeKeychainRevokeBody, or buildKeychainAuthorize / buildKeychainRevoke).
  • Operator CLI: mkch-node keys keychain-authorize / keychain-revoke / list-custody / get-custody, and the makechain-client keychain_authorize / keychain_revoke helpers.
  • Reads: GetCustodyKey / ListCustodyKeys (gRPC), GET /v1/accounts/:owner/custody-keys[/:key_id] (REST), client.custodyKeys.list / get (viem), and GetAccount exposes a custody_keys snapshot.

The signer-management surfaces (SIGNER_ADD / SIGNER_REMOVE) remain first-class everywhere.

Try it

Connect a passkey to act as the root owner_address, authorize an admin custody key, read it back from the node, then revoke it. Your passkey signs the native AccountKeychain digests (the digest is the WebAuthn challenge) and each KEYCHAIN_AUTHORIZE / KEYCHAIN_REVOKE is submitted to testnet — the same live flow as the other demos.

Signer management

SIGNER_ADD and SIGNER_REMOVE are the only delegated signer-management paths in Makechain.

  • Both are user-submitted messages with valid Ed25519 envelopes.
  • The envelope signer provides transport integrity only.
  • Authorization comes from verify_keychain_admin(owner_address, digest, custody_signature).

App attribution

Every SIGNER_ADD includes app attribution.

  • request_owner_address is a 20-byte external wallet address.
  • It is not a Makechain account lookup key.
  • request_signature is authorized by verify_keychain_admin(request_owner_address, SIGNER_REQUEST digest, request_signature) — the request owner's root key signing directly, or an active admin custody key of the request owner signing through a keychain wrapper.
  • Self-request is represented by request_owner_address == owner_address.

The request signature signs the native SIGNER_REQUEST AccountKeychain digest for the request owner, key, validity window, and Makechain network.

Signed digests

The custody and attribution payloads are native AccountKeychain digests in Makechain:

0x01 KEYCHAIN_AUTHORIZE
0x02 KEYCHAIN_REVOKE
0x03 SIGNER_ADD
0x04 SIGNER_REMOVE
0x05 SIGNER_REQUEST

Each digest commits to the operation byte, the target key family (custody 0x01 or envelope 0x00), Makechain network, account or request owner, target key, validity window, nonce when applicable, and operation-specific fields. It is not an EIP-712 typed-data hash.

External address verification

VERIFICATION_ADD and VERIFICATION_REMOVE link external addresses to an owner_address.

For ETH verification, the outer claim signature is self-describing (secp256k1 ECDSA, P256, or WebAuthn P256, parsed with the same unified envelope as custody signatures). The signed payload is still the EIP-712 VerificationClaim typed-data hash bound to the Makechain domain. Consensus verifies the signature locally from those bytes — there is no ERC-1271 contract call.

For SOL verification, the signed challenge string is:

makechain:verify:<network>:<owner_address_hex>

owner_address_hex is lowercase hex, exactly 40 characters, with no 0x prefix.

Removed concepts

These do not exist in Makechain semantics:

  • registry-based account allocation
  • onchain registry-based account creation
  • protocol-level ownership transfer
  • protocol-level recovery
  • host-chain-driven identity ingress
  • relay-derived signer authorization
  • ERC-1271 custody or verification