Skip to content

Wallets (end-user)

All routes mounted under /v1/wallets. Auth header convention:

X-Sigil-Publishable-Key: pk_live_xxx
Authorization: Bearer <end-user-jwt> # except where noted

POST /v1/wallets/auth/email-otp/start

Start the Sigil-hosted email-OTP login. Publishable key only — the user doesn’t have a JWT yet.

{ "email": "alice@example.com" }

Returns 204 No Content regardless of whether the email is registered (no enumeration leak). The email arrives at alice@example.com via Resend.

POST /v1/wallets/auth/email-otp/verify

Exchange an OTP for a JWT. Publishable key only.

{ "email": "alice@example.com", "code": "449922" }

Response:

{
"data": {
"token": "eyJhbGciOi…",
"user_identity_id": "00000000-…",
"email": "alice@example.com"
},
"error": null
}

Stash the token; every subsequent call uses it as Authorization: Bearer.

POST /v1/wallets/identify

Canary — confirms publishable key + JWT line up and a user_identity exists.

{
"data": {
"organization_id": "",
"user_identity_id": "",
"auth_provider": "sigil",
"provider_user_id": "alice@example.com",
"email": "alice@example.com"
},
"error": null
}

GET /v1/wallets/me

Return the active wallet for the authenticated end user, or 404 if they don’t have one yet (the iframe then prompts wallet creation).

POST /v1/wallets

Create a wallet. The iframe sends:

{
"address": "0x…",
"public_key": "04…",
"chain_type": "evm",
"provider_share": "base64",
"provider_share_index": 2,
"recovery_share": "base64",
"recovery_share_index": 3
}

Sigil envelope-encrypts the provider share via Cloud KMS, dispatches the recovery share to your webhook (or stores it under a separate KMS purpose in Sigil-managed mode), and returns the wallet record.

Idempotent on (organization_id, user_identity_id). A duplicate returns 409 wallet_exists.

POST /v1/wallets/me/shares/provider

Return the cleartext provider share so the iframe can sign. The iframe combines it with its device share, reconstructs the key in memory, signs, and wipes.

{ "data": { "wallet_id": "", "provider_share": "base64", "share_index": 2 }, "error": null }

Recovery sub-lane

Three endpoints — see Recovery.