diff --git a/src/at/did_document.gleam b/src/at/did_document.gleam index 13f8a5b..0b453f0 100644 --- a/src/at/did_document.gleam +++ b/src/at/did_document.gleam @@ -2,7 +2,9 @@ import at/did.{type Did} import at/handle.{type Handle} +import at/internal/encoding import gleam/dynamic/decode.{type Decoder} +import gleam/json.{type Json} import gleam/list import gleam/option.{type Option, None, Some} import gleam/uri.{type Uri, Uri} @@ -33,7 +35,7 @@ import ywt/verify_key.{type VerifyKey} /// specification but isn't given any special meaning by atproto. /// pub type DidDocument { - Document( + DidDocument( id: Did, controller: List(Did), also_known_as: List(Handle), @@ -142,7 +144,7 @@ pub fn decoder() -> Decoder(DidDocument) { decode.list(service_endpoint_decoder()) }) - decode.success(Document( + decode.success(DidDocument( id:, controller:, also_known_as:, @@ -255,3 +257,79 @@ pub fn signing_key(document: DidDocument) -> Result(String, Nil) { _ -> Error(Nil) } } + +// CONVERSIONS ----------------------------------------------------------------- + +pub fn to_json(document: DidDocument) -> Json { + json.object([ + #("id", did.to_json(document.id)), + #("controller", json.array(document.controller, did.to_json)), + #("alsoKnownAs", json.array(document.also_known_as, handle.to_json)), + #("verificationMethod", { + json.array(document.verification_method, { + embedded_verification_method_to_json + }) + }), + #("authentication", { + json.array(document.authentication, verification_method_to_json) + }), + #("assertionMethod", { + json.array(document.assertion_method, verification_method_to_json) + }), + #("keyAgreement", { + json.array(document.key_agreement, verification_method_to_json) + }), + #("capabilityInvocation", { + json.array(document.capability_invocation, verification_method_to_json) + }), + #("capabilityDelegation", { + json.array(document.capability_delegation, verification_method_to_json) + }), + #("service", { json.array(document.service, service_endpoint_to_json) }), + ]) +} + +fn embedded_verification_method_to_json( + embedded_verification_method: EmbeddedVerificationMethod, +) -> Json { + encoding.optional_object( + [ + #("id", did.url_to_json(embedded_verification_method.id)), + #("controller", did.to_json(embedded_verification_method.controller)), + #("type", json.string(embedded_verification_method.type_)), + ], + [ + encoding.optional_field( + "publicKeyJwt", + embedded_verification_method.public_key_jwk, + verify_key.to_jwk, + ), + encoding.optional_field( + "publicKeyMultibase", + embedded_verification_method.public_key_multibase, + json.string, + ), + ], + ) +} + +fn verification_method_to_json( + verification_method: VerificationMethod, +) -> Json { + case verification_method { + Reference(url) -> did.url_to_json(url) + Embedded(embedded_verification_method) -> + embedded_verification_method_to_json(embedded_verification_method) + } +} + +fn service_endpoint_to_json(service_endpoint: ServiceEndpoint) -> Json { + json.object([ + #("id", did.url_to_json(service_endpoint.id)), + #("type", json.string(service_endpoint.type_)), + #( + "serviceEndpoint", + json.string(uri.to_string(service_endpoint.service_endpoint)), + ), + ]) +}