Using Context Tags for Key Management in Schema Transformations

Is this the recommended way to get the keys inside the schema?

import { Effect, Schema as S, ParseResult, Context } from "effect";
import * as crypto from "./index.ts";

class EncodingKeys extends Context.Tag("EncodingKeys")<
  EncodingKeys,
  {
    sender_secret: Uint8Array;
    recipient_public: Uint8Array;
  }
>() {}

class DecodingKeys extends Context.Tag("DecodingKeys")<
  DecodingKeys,
  {
    recipient_secret: Uint8Array;
    sender_public: Uint8Array;
  }
>() {}

const Schema = S.transformOrFail(S.Uint8ArrayFromSelf, S.Uint8ArrayFromSelf, {
  strict: true,

  encode: (input: Uint8Array, _options, ast) =>
    Effect.gen(function* () {
      const keys = yield* EncodingKeys;
      const result = yield* ParseResult.try({
        try: (): Uint8Array =>
          crypto.asymmetric.encrypt(
            input,
            keys.sender_secret,
            keys.recipient_public,
          ),
        catch: (error) =>
          new ParseResult.Type(
            ast,
            input,
            error instanceof Error ? error.message : "Failed to encode",
          ),
      });

      return result;
    }),

  decode: (input: Uint8Array, _options, ast) =>
    Effect.gen(function* () {
      const keys = yield* DecodingKeys;
      const result = yield* ParseResult.try({
        try: (): Uint8Array =>
          crypto.asymmetric.decrypt(
            input,
            keys.recipient_secret,
            keys.sender_public,
          ),
        catch: (error) =>
          new ParseResult.Type(
            ast,
            input,
            error instanceof Error ? error.message : "Failed to decode",
          ),
      });

      return result;
    }),
});
Was this page helpful?