Wallet Configuration
Auth makes use of a server-side wallet to sign and verify JWTs, as covered in the how auth works section. You can configure this wallet using a variety of wallet management options, giving you the freedom to choose the most convenient and secure setup for your project.
Simple Wallets
The easiest way to get started with Auth would be to use a simple private key or signer wallet directly. It's easy to use such a setup with just the core @thirdweb-dev/auth
package.
Given that private key and signer wallets for EVM and Solana depend on different packages underneath, they are accessible via separate @thirdweb-dev/auth/evm
and @thirdweb-dev/auth/solana
entrypoints, which each have their own peerDependencies
.
EVM
Use the following installation to get started with Auth using a simple EVM private key or signer wallet:
- npm
- Yarn
npm install @thirdweb-dev/auth ethers@5
yarn add @thirdweb-dev/auth ethers@5
Private Key Wallet
You can use an EVM private key (a 64 character hex-string) as your wallet by using the PrivateKeyWallet
class from the @thirdweb-dev/auth/evm
entrypoint.
Never hardcode your private key into your codebase or commit it to version control! Instead, use an environment variable or other secure method to pass your private key in indirectly.
import { PrivateKeyWallet } from "@thirdweb-dev/auth/evm";
// Pass private key from environment variables directly
const wallet = new PrivateKeyWallet(
process.env.THIRDWEB_AUTH_PRIVATE_KEY || "",
);
// Pass the wallet to your auth configuration...
Signer Wallet
You can also use any signer wallet compatible with the ethers.Signer
interface, such as the ethers.Wallet
class.
import { SignerWallet } from "@thirdweb-dev/auth/evm";
import { ethers } from "ethers";
// Create a new ethers signer or use an existing one
const signer = new ethers.Wallet(...);
const wallet = new SignerWallet(signer);
// Pass the wallet to your auth configuration...
Solana
Use the following installation to get started with Auth using a simple Solana private key or signer wallet:
- npm
- Yarn
npm install @thirdweb-dev/auth @noble/ed25519 @solana/web3.js bs58 tweetnacl
yarn add @thirdweb-dev/auth @noble/ed25519 @solana/web3.js bs58 tweetnacl
Private Key Wallet
You can use a Solana private key (a 64 character base58-string) as your wallet by using the PrivateKeyWallet
class from the @thirdweb-dev/auth/solana
entrypoint.
Never hardcode your private key into your codebase or commit it to version control! Instead, use an environment variable or other secure method to pass your private key in indirectly.
import { PrivateKeyWallet } from "@thirdweb-dev/auth/solana";
// Pass private key from environment variables directly
const wallet = new PrivateKeyWallet(
process.env.THIRDWEB_AUTH_PRIVATE_KEY || "",
);
// Pass the wallet to your auth configuration...
Signer Wallet
You can also use any Solana Keypair
signer as your wallet.
import { SignerWallet } from "@thirdweb-dev/auth/solana";
import { Keypair } from "@solana/web3.js";
// Get a solana keypair from somewhere
const keypair = Keypair.generate();
const wallet = new SignerWallet(keypair);
// Pass the wallet to your auth configuration...
Advanced Wallets
For more advanced wallet setups like cloud wallets, managed private keys, and more, we have a variety of options available in our @thirdweb-dev/wallets
package. The package is an optional peerDependency
of @thirdweb-dev/auth
, so you'll need to install it separately, along with any peer depenencis of the specific wallet you want to use.
- npm
- Yarn
npm install @thirdweb-dev/auth @thirdweb-dev/wallets
yarn add @thirdweb-dev/auth @thirdweb-dev/wallets
For more information on the available wallets and the specific of their setup, see the @thirdweb-dev/wallets
documentation
For example, here's how you would use a signing key from AWS Secrets Manager as your Auth wallet using the @thirdweb-dev/wallets
package (you would need to install its @aws-sdk/client-secrets-manager
peer dependency as well):
import { AwsSecretsManagerWallet } from "@thirdweb-dev/wallets/evm/wallets/aws-secrets-manager";
// Pass in your AWS configuration
const wallet = new AwsSecretsManagerWallet({
secretName: "my-secret",
secretKeyName: "private-key",
awsConfig: {
region: "us-east-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
},
},
});
// Pass the wallet to your auth configuration...
Custom Wallets
If none of the above methods are suitable for your project, you can also create your own custom wallet class by implementing the GenericAuthWallet
interface from the @thirdweb-dev/wallets
package for a completely custom setup.
Auth only requires the following simple wallet interface to facilitate signing and verification of JWTs:
interface GenericAuthWallet {
// Whether your wallet is an "evm" or "solana" wallet
type: Ecosystem;
// Get the address of your wallet
getAddress(): Promise<string>;
// Optionally get the chain ID of your wallet (important for EIP1271 wallets)
getChainId?(): Promise<number>;
// Sign a message with your wallet
signMessage(message: string): Promise<string>;
// Verify a signature
verifySignature(
message: string,
signature: string,
address: string,
): Promise<boolean>;
}
You can see how this interface is chain agnostic, and can be used across different blockchain ecosystems.
For example, here is a minimal implementation of the basic SignerWallet
class from the @thirdweb-dev/auth/evm
entrypoing, which follows the GenericAuthWallet
interface:
import type { Ecosystem, GenericAuthWallet } from "@thirdweb-dev/wallets";
class SignerWallet implements GenericAuthWallet {
type: Ecosystem = "evm";
#signer: ethers.Signer;
constructor(signer: ethers.Signer) {
this.#signer = signer;
}
public async getAddress(): Promise<string> {
return this.#signer.getAddress();
}
public async signMessage(message: string): Promise<string> {
return await this.#signer.signMessage(message);
}
public async verifySignature(
message: string,
signature: string,
address: string,
): Promise<boolean> {
const messageHash = ethers.utils.hashMessage(message);
const messageHashBytes = ethers.utils.arrayify(messageHash);
const recoveredAddress = ethers.utils.recoverAddress(
messageHashBytes,
signature,
);
return recoveredAddress === address;
}
}