Open-source, Turnkey-compatible signing infrastructure — EVM and Solana.
Kryard is a remote key-signing service: create private keys and wallets, define signing policies, and request signatures — secp256k1 (EVM) and ed25519 (Solana) — over a Turnkey-wire-compatible API, without your application ever touching private key material. Private keys are generated inside an isolated signer and encrypted at rest with envelope encryption; the API tier can never decrypt them.
It's a drop-in for Turnkey's secp256k1 EVM signing: cutover is a single
TURNKEY_BASE_URL swap.
Client / SDK / Dashboard
→ api/ Turnkey-compatible API (Cloudflare Worker, Hono) — activity + policy engine
→ signer/ Isolated signer (Go) — the only component that decrypts keys
→ KMS AWS KMS or local provider — envelope encryption
→ Postgres — activities, audit, policy, encrypted keys
| Path | What |
|---|---|
api/ |
The Turnkey-compatible HTTP API — activities, idempotency, X-Stamp auth, a deterministic policy engine, and EVM transaction / raw-payload signing. Cloudflare Worker (Hono) over Postgres. |
signer/ |
The isolated Go signer. Generates secp256k1 (EVM) and ed25519 (Solana) keys; signs EVM transactions (legacy / EIP-1559 / EIP-7702), raw payloads, and ed25519 messages; does KMS envelope encryption. Audited crypto only (go-ethereum; ed25519 from the Go stdlib). |
dashboard/ |
A React console — keys, wallets, policies, activities, and a signing playground. Runs locally with no auth. |
infra/aws-dev/ |
Terraform for a dev profile: a KMS key + the signer as an AWS Lambda behind an IAM-auth Function URL. |
- The API never decrypts keys. Only the signer holds KMS decrypt permission, on a surface with no public ingress. A compromise of the application tier cannot expose a private key.
- Every operation is an auditable activity, with
SHA-256(canonical_json(body))idempotency scoped per organization. - Signing is policy-bound. A deterministic, fail-closed policy engine gates every signature; the signer re-verifies the policy decision before signing.
- No hand-rolled crypto. secp256k1, ECDSA, Keccak-256, RLP, and EVM address derivation come from go-ethereum; ed25519 is the Go standard library.
- Runs with no cloud. The signer ships an in-process KMS provider, so the whole stack runs on your laptop — and the same code path runs against real AWS KMS in production.
Run the full stack locally — no AWS account required:
docker compose up -d # Postgres
cd signer && KMS_PROVIDER=local KMS_MASTER_KEY=$(openssl rand -hex 32) go run ./cmd/signer &
cd api && pnpm install \
&& DATABASE_URL=postgres://kryard:kryard@localhost:5432/kryard pnpm migrate \
&& SIGNER_BASE_URL=http://localhost:8081 DEV_ADMIN_ENABLED=true pnpm dev &
cd dashboard && npm install \
&& printf 'VITE_LOCAL=true\nVITE_API_BASE=http://localhost:8787\n' > .env.local \
&& npm run devOpen http://localhost:5173. Full walkthrough: docs/local-development.md.
The signer speaks the Turnkey-compatible activity API, so the published
@kryard/sdk talks to your local
signer the same way it talks to the hosted one — point baseUrl at your API. Every
call is X-Stamp-authenticated and org-scoped (the same path runs in production), but
in dev mode you don't need a managed account: bootstrapLocalClient mints a throwaway
org + API key through the unauthenticated dev bootstrap and hands back a ready client.
import { bootstrapLocalClient } from "@kryard/sdk"; // >= 0.3.0
const { client } = await bootstrapLocalClient(); // http://localhost:8787
const { addresses } = await client.createPrivateKey({
name: "local-evm",
curve: "CURVE_SECP256K1",
});
// Signing additionally needs the API run with POLICY_BYPASS_ALLOWED=true (or a policy):
const { signedTransaction } = await client.signTransaction({
signWith: addresses[0].address,
unsignedTransaction: "0x02ef…",
});Self-mint the same credentials by hand with two POSTs (/admin/dev/org →
/admin/dev/api-key) — see docs/local-development.md.
- Architecture — components, invariants, the KMS seam, the API surface.
- Local development — run everything locally; the local-kms emulator option.
- Component READMEs:
api/·signer/·dashboard/·infra/aws-dev/.
This repository is the signing core. The hosted Kryard product adds capabilities on top (a managed EIP-7702 relay for gasless transactions, billing, and more) that are not part of this repository.
@kryard/sdk— the Kryard SDK. Its signing client (KryardClient) works against this self-hosted signer (see above); its relay/sponsor helpers target the hosted managed-relay tier.
Contributions are welcome — see CONTRIBUTING.md. We require a signed Contributor License Agreement (a one-time comment on your first PR); this lets us include your work both here and in the hosted product under an open-core model.
Apache-2.0. See NOTICE for third-party attributions (the signer depends on go-ethereum, LGPL-3.0, as an unmodified dependency).