The Effect surface
The same namespaced route tree returning Effect values instead of promises, with a tagged failure channel and interruption wired to the request.
Overview
The Effect entry returns typed effects for Platform API calls. Each call has a DalpRequestError failure channel, and fiber interruption aborts a request that uses the client-provided signal.
The route tree and transport match the promise client. Calls return Effect<A, DalpRequestError> instead of Promise<A>.
import { createDalpEffectClient } from "@settlemint/dalp-sdk/effect";
import * as Effect from "effect/Effect";
const dalp = createDalpEffectClient({
baseUrl: process.env.DALP_API_URL!,
apiKey: process.env.DALP_API_KEY!,
runtime: "server",
});
const program = Effect.gen(function* () {
const tokens = yield* dalp.api.token.list({ page: { limit: 50 } });
return tokens.data;
});effect is an optional peer dependency. Install it only if you use this entry.
npm install effectWhy it is a separate entry
The root package does not import Effect. Import @settlemint/dalp-sdk/effect when your application uses Effect.
Both clients use the same route table and transport.
The failure channel
Every call fails with one type, DalpRequestError, carrying the platform's error contract:
const program = dalp.api.token
.list({ page: { limit: 50 } })
.pipe(Effect.retry({ times: 3, while: (error) => error.retryable }));| Field | What it holds |
|---|---|
_tag | "DalpRequestError", so Effect.catchTag matches it by tag. |
id | The stable DALP identifier when the platform supplied one, otherwise the SDK's own code. |
status | The HTTP status, when there was a response. |
retryable | Whether retrying this exact request can succeed. |
retryAfterSeconds | How long the platform asked you to wait, from Retry-After, when it named a delay. |
routeId | Which route failed, which matters when several are composed in one program. |
The same error type covers route failures. Branch on error.id for domain handling and on error.retryable for retry policy. Response types are compile-time only.
Interruption
Interrupting a fiber aborts the request. The abort controller is wired to the fiber rather than handed to you, so a cancelled fiber does not leave a socket open:
import * as Fiber from "effect/Fiber";
const program = Effect.gen(function* () {
const fiber = yield* Effect.forkChild(dalp.api.token.list({ page: { limit: 50 } }));
yield* Effect.sleep("2 seconds");
yield* Fiber.interrupt(fiber); // the HTTP request is aborted
});A promise wrapper must pass Effect's abort signal into the HTTP request to cancel it. The SDK Effect client creates and connects that signal for you. If you pass your own signal, manage its cancellation yourself.
Composition
Concurrency, retry, and timeout are Effect's, not the SDK's:
const program = Effect.gen(function* () {
const [tokens, users] = yield* Effect.all(
[dalp.api.token.list({ page: { limit: 50 } }), dalp.api.party.users.list({ page: { limit: 50 } })],
{
concurrency: 2,
}
);
return { tokens: tokens.data, users: users.data };
});dalp.api.token.list({ page: { limit: 50 } }).pipe(Effect.timeout("5 seconds"), Effect.retry({ times: 3 }));An Effect.timeout around a call interrupts it, which aborts the request. That composes correctly with settlement: a queue-backed write interrupted mid-wait stops waiting, and the instruction it submitted stays live on the platform exactly as it would if the platform's own wait had run out and answered with a 202 handle. Interrupting the wait is not cancelling the transaction.
Route ids
Dispatch by id, for code that builds its own command surface:
const program = dalp.execute("token/list", { page: { limit: 50 } });An unknown id fails with a DalpRequestError in the error channel rather than throwing, so the failure stays in the type system with every other failure.
What is the same
Everything below the channel. The flat argument split, the response envelope, conditional reads, settlement, the acting-context headers, and the per-call options are identical, and each is documented once on the pages that cover the promise surface. The only difference is what the call hands back.
Next
Command-line access to the same routes: CLI.
React Native
Use the DALP TypeScript SDK from an Expo app: supported versions, the transport to pass, where the session lives, and how passkeys reach the device.
Error catalog overview
Index of DALP's error catalogs and handling guidance. Map an error to the right reference page, find its domain, and choose the next action.