import type { Services } from '../../../services/mod.js' import type { Timestamp } from '../../../domain/timestamp.js' import type { DecodedDeviceRegistrationManifest, DeviceRegistrationManifest, EncodeDeviceRegistrationManifestError, } from '../../../domain/device-registration-manifest.js' import type { DeviceAlreadyRegisteredError, DeviceQuotaExceededError, DeviceRegistrationEligibilityError, InvalidDeviceRegistrationCodeError, InvalidDeviceRegistrationWindowError, RegisterDeviceClientError, RegisterDevicePlatformError, } from '../../../services/platform/licensing/register-device/errors.js' import type { CreateEncryptionKeypairError } from '../../../services/crypto/create-keypair.js' import type { CreateSigningKeypairError } from '../../../services/signing/create-keypair.js' import type { GatherDeviceInformationError } from '../../../services/device/gather.js' import type { Result } from '../../../framework/types/result.js' import { isError, unwrapResult } from '../../../framework/types/result.js' import { encodeDeviceRegistrationManifest } from '../../../domain/device-registration-manifest.js' interface Options { deps: { services: Services } } export function buildRegister(options: Options) { return async function register( dto: Readonly<{ code: string }>, ): Promise> { const { deps: { services }, } = options const encryptionKeypairResult = await services.crypto.createKeypair() if (isError(encryptionKeypairResult)) { return encryptionKeypairResult } const encryptionKeypair = unwrapResult(encryptionKeypairResult) const signingKeypairResult = await services.signing.createKeypair() if (isError(signingKeypairResult)) { return signingKeypairResult } const signingKeypair = unwrapResult(signingKeypairResult) const gatherDeviceResult = await services.device.gather() if (isError(gatherDeviceResult)) { return gatherDeviceResult } const device = unwrapResult(gatherDeviceResult) const registrationResult = await services.platform.licensing.registerDevice( { code: dto.code, nonce: Date.now() as Timestamp, device, encryption: { publicKey: encryptionKeypair.publicKey, }, signing: { publicKey: signingKeypair.publicKey, }, }, ) if (isError(registrationResult)) { return registrationResult } const registration = unwrapResult(registrationResult) const manifest: DecodedDeviceRegistrationManifest = { _tag: 'DeviceRegistrationManifest', encryption: { keypair: encryptionKeypair, }, signing: { keypair: signingKeypair, }, registration, } return encodeDeviceRegistrationManifest(manifest) } } export type RegisterDeviceError = | RegisterDeviceClientError | RegisterDevicePlatformError | DeviceQuotaExceededError | InvalidDeviceRegistrationCodeError | InvalidDeviceRegistrationWindowError | DeviceAlreadyRegisteredError | DeviceRegistrationEligibilityError | EncodeDeviceRegistrationManifestError | CreateEncryptionKeypairError | CreateSigningKeypairError | GatherDeviceInformationError