1import * as machines from "@distilled.cloud/fly-io/machines";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as FetchHttpClient from "effect/http/FetchHttpClient";
5import { CredentialsFromAmbientOrEnv } from "./Credentials.ts";
6import {
7 base64ToBytes,
8 bytesToBase64,
9 makeHttpSecretKeyBinding,
10} from "./SecretKeyHttp.ts";
11import { Sign, type SignRequest } from "./Sign.ts";
12
13/**
14 * HTTP implementation of {@link Sign}. Provide it on the
15 * {@link Service} or Action Effect.
16 *
17 *
18 * ### Provide the layer
19 * **Example:** On a Service
20 * ```typescript
21 * Effect.gen(function* () {
22 * const sign = yield* Fly.Sign(Signing);
23 * // ...
24 * }).pipe(Effect.provide(Fly.SignHttp))
25 * ```
26 *
27 * @layer
28 * @product Secret Key
29 * @provides Fly.Sign
30 */
31export const SignHttp = Layer.effect(
32 Sign,
33 Effect.suspend(() =>
34 makeHttpSecretKeyBinding({
35 makeClient: (auth, appName, secretName) =>
36 Effect.fn("Fly.Sign")(function* (request: SignRequest) {
37 const res = yield* auth.authorize(
38 machines.signSecretKey({
39 app_name: yield* appName,
40 secret_name: yield* secretName,
41 plaintext: bytesToBase64(request.plaintext),
42 }),
43 );
44 return { signature: base64ToBytes(res.signature) };
45 }),
46 }),
47 ),
48).pipe(
49 Layer.provide(FetchHttpClient.layer),
50 Layer.provide(CredentialsFromAmbientOrEnv),
51);