@defuse-protocol/outlayer-sdk
v0.5.1
Published
TypeScript gRPC SDK for the Outlayer service
Readme
@defuse-protocol/outlayer-sdk
TypeScript gRPC SDK for the Outlayer
service, built with Connect-ES. Node.js only —
speaks gRPC over HTTP/2 to the worker, and ships the generated message types plus an
execute helper.
Install
The SDK is published publicly to npm:
npm install @defuse-protocol/outlayer-sdkUsage
import { createOutlayerClient } from "@defuse-protocol/outlayer-sdk";
const client = createOutlayerClient("http://localhost:50051");
const res = await client.execute({
app: { appId: "app.near" },
input: new TextEncoder().encode("{}"),
});
if (res.error) {
console.error(res.error, res.fuelConsumed); // WASM run failed (returned as data)
} else {
console.log(new TextDecoder().decode(res.output), res.fuelConsumed);
}Apps can also be executed directly from a URL with either a hexadecimal or raw-byte SHA-256 hash:
const res = await client.execute({
app: {
codeUrl: "https://example.com/app.wasm",
codeHash: "8f2466da...",
},
input: new TextEncoder().encode("{}"),
});execute resolves to { output, logs, fuelConsumed, error? }; output/logs are raw
Uint8Arrays. A populated error means the run reached the worker but the WASM
failed — returned as data, not thrown. Transport failures reject with a ConnectError.
Authentication
A worker behind Google IAM wants a Google ID token. Create a Google token manager and inject it into the client. The manager mints, caches, and refreshes tokens. If the worker rejects a request as unauthenticated, the Google manager invalidates the cached token, generates a fresh one, and retries once:
import {
createGoogleJwtTokenManager,
createOutlayerClient,
type JwtTokenManager,
} from "@defuse-protocol/outlayer-sdk";
const jwtTokenManager = createGoogleJwtTokenManager({
impersonate: "[email protected]",
});
const client = createOutlayerClient({
endpoint: "https://worker.example.com:443",
auth: jwtTokenManager,
});Omit auth for a worker with authentication disabled. With Google,
omit impersonate to use Application Default Credentials directly:
createOutlayerClient("http://localhost:50051");
createGoogleJwtTokenManager();
createGoogleJwtTokenManager({ impersonate });Google auth needs the optional peer dependency google-auth-library. Install it only
when using createGoogleJwtTokenManager.
The audience defaults to outlayer, which is what the worker expects unless its
deployment sets another one. Override it in the manager options:
createGoogleJwtTokenManager({ audience: "another-audience" });Other identity providers can implement the provider-neutral interface:
const jwtTokenManager: JwtTokenManager = {
generateToken: () => myTokenSource(),
invalidateToken: async () => clearMyTokenCache(),
handleAuthError: async (error) => {
throw error;
},
};Call invalidateToken() at any time to force the next request to generate a fresh
token:
jwtTokenManager.invalidateToken();An authToken passed to execute overrides the configured manager for that
request. The override can be a token or a synchronous or asynchronous function:
await client.execute({ app, input }, { authToken: idToken });
await client.execute({ app, input }, { authToken: () => getFreshToken() });Override tokens are sent as given and bypass the manager's retry behavior.
The JWT-protected worker integration test is disabled unless its endpoint or token is configured. Provide both variables to run it:
OUTLAYER_ENDPOINT=https://worker.example.com:443 \
OUTLAYER_JWT_TOKEN="$(get-token)" \
pnpm test:jwt-liveFor inline WASM, a fuel limit, or a custom transport, use the underlying Connect client
at client.raw, or build your own from the re-exported OutlayerService.
