# `@wrnexus/rpc` Define a service contract in a shared workspace package, then import that same contract from the caller and callee. ```ts import { defineService, implement, inProcessTransport, procedure, serviceClient, } from "@wrnexus/rpc"; import { v } from "@wrnexus/validation"; const greeter = defineService({ name: "greeter", procedures: { greet: procedure .input(v.object({ name: v.string() })) .output<{ message: string }>() .build(), }, }); const service = implement( greeter, { greet: async ({ name }) => ({ message: `Hello, ${name}` }) }, { selfApp: "greeter" }, ); const client = serviceClient(greeter, { app: "greeter", transport: inProcessTransport({ "greeter/greet": (input, identity) => service.invoke("greet", input, identity), }), }); await client.greet({ name: "Ada" }); ``` Service files default-export `implement(...)` from `app/services`. The development server mounts them under the private `/__wrnexus/rpc` prefix. Pass `{ as: ctx }` to `serviceClient` to propagate the subject. The signed token contains only subject and tenant identifiers; permissions are always checked by the callee. Set `WRNEXUS_RPC_SECRET` in every app, use at least 32 characters, and never reuse the session secret. Calls time out by default. Retrying is intentionally deferred; when introduced, only procedures marked `.idempotent()` may be retried.