Next.js server actions
Server actions are a perfect place for Eda: they’re where your UI triggers real side effects. The SDK is zero-dependency and edge-safe, so it works in both the Node and Edge runtimes.
Construct the client once
lib/eda.ts
import { Eda } from "@eda-holding-inc/sdk";
export const eda = new Eda({ apiKey: process.env.EDA_API_KEY! });Gate the action
app/actions/refund.ts
"use server";
import { eda } from "@/lib/eda";
import { auth } from "@/lib/auth";
export async function refundAction(customerId: string, amount: number) {
const { userId } = await auth();
const decision = await eda.check({
agent: "dashboard-user",
action: "refund_customer",
params: { amount, customerId },
metadata: { userId }, // who triggered it, for the audit log
});
if (decision.status !== "approved") {
return { ok: false, reason: decision.reason, status: decision.status };
}
await stripe.refunds.create({ customer: customerId, amount });
return { ok: true };
}Handle the pending case in the UI
app/refund-button.tsx
"use client";
import { refundAction } from "@/app/actions/refund";
export function RefundButton({ customerId, amount }: { customerId: string; amount: number }) {
async function onClick() {
const res = await refundAction(customerId, amount);
if (res.status === "pending") toast("Sent for approval — you'll be notified.");
else if (!res.ok) toast.error(res.reason);
else toast.success("Refunded.");
}
return <button onClick={onClick}>Refund ${amount}</button>;
}Edge runtime
The SDK uses only the standard fetch, so it runs unchanged on the edge:
export const runtime = "edge";If you run in an environment with a non-global fetch, inject one:
const eda = new Eda({ apiKey: process.env.EDA_API_KEY!, fetch: myFetch });Set EDA_API_KEY in your hosting provider’s environment (Vercel/Amplify/…), not in
the client bundle. The SDK reads it server-side only.
Fail posture
For a dashboard action, failMode: "closed" (the default) is usually right — if Eda
is unreachable, the refund simply doesn’t run and the user can retry. Flip to
"open" only for actions where a missed gate is acceptable.