Search by name, SuiNS, address, digest, object ID, coin type or checkpoint.

API
zklogin.proof

zklogin.proof

A zkLogin proof for an ephemeral key, ready to sign Sui transactions.

Details

Endpoint
POST /v1/zklogin/proof
Credits
varies
Pricing
Depends on the input and the size of the result. The description says how.
Rate class
None. Never limited by class.

Proves that the signed-in user owns the ephemeral key: send the ID token, the ephemeral public key, maxEpoch and the randomness used for the nonce. Leave out salt to use the user's salt from zklogin.salt. Returns the proof inputs for getZkLoginSignature, with addressSeed filled in. The same request again comes from the cache and is free. 50,000 new proofs a month are free per app, then 1,000 credits each. Takes a few seconds.

Parameters

NameTypeDescription
jwtrequiredstringThe ID token (JWT). Its nonce must be generateNonce(ephemeral public key, maxEpoch, randomness).
extendedEphemeralPublicKeyrequiredstringBase64 Sui public key of the ephemeral key pair, flag byte first (getExtendedEphemeralPublicKey).
maxEpochrequiredinteger or stringThe last epoch the proof is valid for, as used in the nonce.
randomnessrequiredstringThe randomness used in the nonce (decimal). jwtRandomness is accepted too.
saltstringOptional: the user's salt (decimal, below 2^128). Default: the salt zklogin.salt returns.

Request

Send your key in the x-api-key header, or leave it out to use the keyless tier.

curl
curl -X POST "https://api.tide.ad/v1/zklogin/proof" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  -d '{
  "jwt": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiIxMjM0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTEwMDAwMDAwMDAwMDAwMDAwMDAwIiwibm9uY2UiOiIuLi4ifQ.signature",
  "extendedEphemeralPublicKey": "AL3dKmKOGLWGv+Av8dcZOt9DOJzCXZ7Bo6E4FQIJYCvv",
  "maxEpoch": 940,
  "randomness": "100681567828351849884072155819400689117"
}'
TypeScript
const res = await fetch("https://api.tide.ad/v1/zklogin/proof", {
  method: "POST",
  headers: {
    "x-api-key": process.env.TIDE_API_KEY!,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "jwt": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiIxMjM0LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTEwMDAwMDAwMDAwMDAwMDAwMDAwIiwibm9uY2UiOiIuLi4ifQ.signature",
    "extendedEphemeralPublicKey": "AL3dKmKOGLWGv+Av8dcZOt9DOJzCXZ7Bo6E4FQIJYCvv",
    "maxEpoch": 940,
    "randomness": "100681567828351849884072155819400689117"
  }),
});
const data = await res.json();

Response

JSON
{
  "proofPoints": {
    "a": [
      "...",
      "...",
      "1"
    ],
    "b": [
      [
        "...",
        "..."
      ],
      [
        "...",
        "..."
      ],
      [
        "1",
        "0"
      ]
    ],
    "c": [
      "...",
      "...",
      "1"
    ]
  },
  "issBase64Details": {
    "value": "yJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLC",
    "indexMod4": 1
  },
  "headerBase64": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9",
  "addressSeed": "1356...",
  "address": "0x1c5d8a7a1f2b2b3e9d3b0e3f6a1d0c2b4e5f60718293a4b5c6d7e8f9a0b1c2d3",
  "cached": false,
  "credits": 0
}