Configuration

We offer two options to setup in-app wallets with custom auth, one that is based on the OIDC (Open ID Connect) standard, and a generic option that lets you bring your own auth server. You can also use both options together if needed.

OIDC compatible auth

The OIDC auth set-up is a good option if you use an external auth provider like Auth0, firebase, cognito etc. that publishes the JWK for checking the authenticity of the token.

An OIDC auth system has a public-private keypair, where the private key is used to sign auth tokens.

  • The public key is uploaded to a public URL in JWKS format. The standard location is https://{domain}.com/.well-known/jwks.json
  • When a user logs in, a JWT token called the idToken is generated and signed by the private key. The OIDC spec provides an interface for fields that are used in this token.
  • This JWT is then passed to the in-app wallet to generate a wallet for the user.
  • We will verify the JWT against the public key to verify that the JWT was signed correctly. Upon successful verification, we will proceed to generate a wallet based on the sub (user identifier) value of the idToken.

To setup an OIDC compatible auth, enable the first option in the configuration tab of the in-app wallet dashboard

You will be asked to enter the following values

  • The URL of the JWKS file (public key): This is used to verify the token was signed by you.
  • The aud value of the idToken: This is used to verify that thirdweb is the intended user of the token

Authenticating a user via OIDC-compatible auth

import { inAppWallet } from "thirdweb/wallets";
import { useConnect } from "thirdweb/react";
const { connect } = useConnect();
const handlePostLogin = async (jwt: string) => {
await connect(() => {
const wallet = inAppWallet();
wallet.connect({
client,
strategy: "jwt",
jwt,
encryptionKey: "your-encryption-key",
});
return wallet;
});
};

You can set your encryptionKey in either a secret env variable or ask the user to enter a password for it.

** Do not hardcode the encryptionKey in your code. **

Generic auth

Generic auth is a lower-level option that can be used when you have your own auth server that you use to authenticate users.

Generic auth is good for supporting other auth methods that we don't support today, like Discord, Twitter, Github etc., or something completely custom.

High-level flow and requirement for generic auth via endpoint:

  • When a user logs in, you are able to generate a public identifier that allows you to identify the user.
  • You can pass this identifier to the in-app wallet to generate a wallet for the user.
  • When verifying the user, we will hit an endpoint that you provide to verify the user's identity.
  • We will then generate a wallet for the user if the provided payload is valid.

To use generic auth, enable the second option in the configuration tab of the in-app wallet dashboard

You will be asked to enter an endpoint that we can hit to verify the user's identity. This endpoint should accept a POST request with a JSON body containing the following fields:

  • payload: This will correspond to the public identifier that was generated for your user. Note that this is passed in from the client side via the SDK. See below for an example of how this is used.

The endpoint should return a JSON body containing the following fields:

  • userId: A uid for the user. This will be used to identify the user in the wallet if no email is present.
  • email (optional): If provided, the user will be able to access the same account outside of the platform for things like private key export // using with wallet connect etc.
    • Note: If two different userId values are provided with the same email, both userId values will be able to access the same wallet.
    • Conversely, if the same userId is provided with two different emails across different login sessions, the userId will have two wallets associated with it. Each wallet will be tied to one of the emails.
  • exp (optional): An expiration date for the user's wallet session. By default, a session is 7 days long.

You can also pass a list of headers. These headers will be sent with every request to your verification endpoint. You can use these to authenticate the request.

Authenticating a user via generic auth

Once you've logged in with your own auth, you can pass the user's JWT to the in-app wallet to authenticate and connect.

import { inAppWallet } from "thirdweb/wallets";
import { useConnect } from "thirdweb/react";
const { connect } = useConnect();
const handlePostLogin = async (jwt: string) => {
await connect(() => {
const wallet = inAppWallet();
await wallet.connect({
client,
strategy: "auth_endpoint",
// This is the payload that is sent to the auth endpoint
payload,
encryptionKey: "your-encryption-key",
});
return wallet;
});
};

You can set your encryptionKey in either a secret env variable or ask the user to enter a password for it.

Do not hardcode the encryptionKey in your code. Use environment variables, server returned keys or user derived keys.