registerDevice
Registers the device authentication key of registration's address. context is the host's authentication context of this request (for example the authenticated account principal), null if the host could not establish one. body is the exact HTTP body the request carried and authentication must be signed with the key being registered. Returns true for a first registration, false if exactly this key was registered before.
A first registration records clock's time as the key's installation time; a repeated registration of the same key keeps the recorded one.
Throws DeviceRegistrationException.InvalidRegistration for a key of the wrong size, DeviceAuthenticationException if the request is not authenticated with that key (nothing is registered), DeviceRegistrationException.Conflict if another key is registered (a registered key is never replaced), DeviceRegistrationException.NotAuthorized if context is null or the host's DeviceRegistrationAuthorizer denied it, and DeviceRegistrationAuthorizationFailedException if the authorizer threw anything but genuine cancellation of the calling coroutine, an OutOfMemoryError or a StackOverflowError (those propagate unchanged), including a kotlinx.coroutines.CancellationException thrown while the coroutine is still active and an Error such as AssertionError, InternalError or NotImplementedError (S1.3, N7). In every failure nothing is registered; only the request's nonce is claimed.
Order: size → authentication (key possession, window, nonce) → existing registration (same key: false without asking the host, so lost-response retries and the recovery/rotation probes need no context; other key: conflict) → context present → host authorization with context (outside every storage transaction) → atomic store. Every first registration of an address, including a user's first device, needs the host's authorization. There is no reset; only recoverDevice, rotateDeviceAuthenticationKey and recoverLastDevice replace a registered key.