Skip to main content
Privy’s SDKs offer abstractions that allow you to automatically sign requests to the Privy API when invoking SDK methods. With this level of abstraction, your application does not need to handle directly signing requests or including the signature in request headers.

Client-side SDKs

For user-owned wallets, Privy’s client-side SDKs (React, React Native, iOS, etc.) automatically sign requests to the Privy API when invoking SDK methods. Under the hood, Privy’s SDK will fetch an ephemeral user signing key, sign the request with it, and include the signature in the request headers when you invoke an SDK method. When using Privy’s client-side SDKs, you do not need to implement any additional logic to sign requests to the Privy API.

Server-side SDKs

Privy’s server-side SDKs offer an abstraction called the authorization context to enable automatic request signing. When an SDK method may require request signing (e.g. sending a transaction), your application can pass the authorization context to the SDK method with relevant inputs needed to sign the request. Concretely, this includes:
  • Authorization private keys. For authorization key-based signatures, the SDK will directly use these keys to compute P256 signatures over the request
  • User JWTs. For user-based signatures, the SDK will request user signing keys given the provided JWTs and compute P256 signatures over the request.
  • Custom signing function. If your application logic requires signing to occur in a separate service (e.g. KMS), you can pass a custom signing function that the SDK will invoke to sign requests.
  • Signatures. If you compute signatures in your application separately from calling Privy’s SDK, you can pass these signatures directly into the authorization context.
The SDK will compute all signatures given the parameters passed in the authorization context, and include all signatures in the underlying request to Privy’s API.

Using the authorization context

At a high-level, there are two steps to using the authorization context.
1

Build the authorization context

Build the authorization context with the private key(s), user(s), custom sign function that you’d like to sign your request. Include any signatures that you have already computed in the context as well.
2

Pass the authorization context to SDK methods

Once you’ve built the authorization context, pass the populated context to SDK methods that may require signatures, such as updating wallets or policies or sending transactions.

1. Build the authorization context

To build the authorization context with your signing inputs, follow the instructions below depending on your setup.
To sign a request with an authorization key, get the private key(s) that you saved locally when creating your signer in the Privy API or Dashboard.See the guide on authorization keys for more details.Then, add the private key(s) to the authorization context to automatically have them sign requests to the Privy API.
AuthorizationContext authorizationContext = AuthorizationContext.builder()
    .addAuthorizationPrivateKey("authorization-key")
    .build();
To sign requests with a user, add the user’s valid JWT to the authorization context. The SDK will automatically request a signing key for the user given the JWT and sign the request with it.See the guide on user owners and signers for more details.
AuthorizationContext authorizationContext = AuthorizationContext.builder()
    .addUserJwt("user-jwt")
    .build();
In case you are not able to pass an authorization private key or user JWT to the authorization context directly, you can instead pass a custom signing function that the SDK will invoke to automatically sign requests. As an example, you might implement a custom signing function that calls out to a KMS where your authorization keys are secured and returns the necessary signature.The sign functions should perform an ECDSA P-256 signature on the payload received, and return the base64-encoded signature.
// This feature is not yet supported in the Java SDK.
The binary payload received by the sign function is already formatted and ready to be signed. There is no need to canonicalize or serialize the payload before signing when using this method.
You may combine the different signing mechanisms in the authorization context to produce a fully customizable key quorum.For instance:
  • You may want to keep a wallet under control of both a user and an authorization key, requiring both signatures to authorize an action. This would be a 2-of-2 key quorum, and can be built by combining both the “user jwt” and “authorization private key” properties, as shown below.
  • You may want to keep a wallet under control of several authorization keys. You can build the required authorization context by passing all authorization private keys into the “authorization private key” property.
// Example: A 2-of-2 key quorum, of a user and an authorization private key
AuthorizationContext authorizationContext = AuthorizationContext.builder()
    .addUserJwt("user-jwt")
    .addAuthorizationPrivateKey("authorization-key")
    .build();
If your application computes the signature directly separately from the SDK, you can pass signatures directly into the authorization context.
AuthorizationContext authorizationContext = AuthorizationContext.builder()
    .addSignature("signature-you-produced")
    .build();

2. Pass the authorization context to SDK methods

Once you have built your authorization context, pass the context as a parameter to the SDK method that requires request signing. As an example, to send a request to sign a message that needs to be signed by an authorization context:
String message = "Hello, Ethereum.";

// Example: If wallet's owner is an authorization private key
AuthorizationContext authorizationContext = AuthorizationContext.builder()
    .addAuthorizationPrivateKey("authorization-key")
    .build();

EthereumPersonalSignRpcResponseData response = privyClient
    .wallets()
    .ethereum()
    .signMessage(
        walletId,
        message.getBytes(StandardCharsets.UTF_8),
        authorizationContext
    );

String signature = response.signature();
The SDK will sign the request given the authorization context and automatically include the signature in the underlying request to the Privy API.
I