Developer SDKs
Two SDKs.
One platform.
@zafeguard/caller-sdk triggers workflows and components on the platform. @zafeguard/mpc-sdk lets your app hold an MPC share and participate in threshold ceremonies itself. Use them independently or together.
Install whichever you need
Caller SDKTrigger workflows & components
npm install @zafeguard/caller-sdkMPC SDKHold an MPC share client-side
npm install @zafeguard/mpc-sdkWorks with pnpm and yarn too. The MPC SDK ships native binaries for every major Node.js platform plus a WebAssembly fallback that runs in browsers, Expo, and Workers.
@zafeguard/caller-sdkExecute components.
Execute components.
Trigger workflows.
- Typed ComponentModule enumEvery component has a typed input + output schema. Pass the enum value, get back the exact result shape — no manual casts.
- .promise() — wait for resultOpens an SSE stream to the platform and resolves with the typed result on completion. No polling.
- .execute() — fire and trackReturns immediately with an execution record. Pair with a callbackUrl for webhook delivery, or poll/stream the status separately.
- WorkflowClientTrigger a configured workflow, wait for the run, or stream stage-by-stage progress in real time.
- Synchronous input validationInputs are validated against the component's Zod schema before any network call. Throws synchronously — no await needed to catch.
- Signed callback verificationComponent executions can deliver results to your endpoint with an HMAC-signed callback header — confirm authenticity in one line.
workspace.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { WorkspaceClient, ComponentModule } from '@zafeguard/caller-sdk'
const workspace = new WorkspaceClient({
apiKey: process.env.ZAFEGUARD_API_KEY!,
apiSecret: process.env.ZAFEGUARD_API_SECRET!,
})
// Typed input → typed output, no polling
const { balance } = await workspace
.call(ComponentModule.GET_EVM_ACCOUNT_BALANCE, {
jsonRpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/KEY',
tokenAddress: '0x0000000000000000000000000000000000000000',
account: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
})
.promise()
console.log(balance) // "1000000000000000000"@zafeguard/mpc-sdkHold an MPC share.
Hold an MPC share.
Sign without exposing keys.
- EmbeddedSignerHigh-level facade for the warm-cold wallet shape — one device share, N cloud-agent shares, threshold signing across the cohort. Five methods cover the whole lifecycle.
- MPCAgentLower-level surface — direct cluster client for institutional setups that want server-side custody with no embedded device party.
- Presignature poolMint signatures in batches so the device can keep signing offline between agent round-trips. Manual or auto-refill.
- Pluggable storageIn-memory, file, or hardware-wrapped adapters. Pair with iOS Secure Enclave or Android Keystore to seal the device share.
- Recovery + reshareSealed recovery bundles, cloud-agent reshare, sign-pack export for cold-storage flows. Root public key is preserved end-to-end.
- Universal runtimeNative binaries on Node.js (macOS + Linux glibc + Linux musl); WASM on browsers, Expo, Cloudflare Workers, Deno, Bun. Same API across all four.
signer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
import { EmbeddedSigner, Curve, RecoveryKind } from '@zafeguard/mpc-sdk'
const signer = new EmbeddedSigner({
agent: [{ baseUrl: 'https://node-1.example', apiKey: '...' }],
threshold: 2,
curve: Curve.Secp256k1,
})
// Generate the wallet — device holds share[0], agent holds share[1]
const loaded = await signer.create({ signerId, recovery: { kind: RecoveryKind.Noop } })
// Sign — combines device + threshold-many agent partials offline
const sig = await loaded.sign({ messageHash })Direct REST API too
Skip the SDK and hit the API directly. Every request needs three headers — API key, timestamp, and an Ed25519 signature — so even compromised network paths can't replay or tamper.
The TypeScript SDKs handle signing for you; this is what they call under the hood.
POST
/v1/sdk/componentsExecute a componentGET
/v1/sdk/components/executions/{executionId}Get component statusSSE
/v1/sdk/components/executions/{executionId}/streamStream component eventsPOST
/v1/sdk/workflows/{workflowId}Trigger a workflow runGET
/v1/sdk/workflows/executions/{runId}Get run statusSSE
/v1/sdk/workflows/executions/{runId}/streamStream run events