Local Wallet
Allow users to connect to your app by generating a Local Wallet directly in your application.
A local wallet is a low-level wallet that allows you to create wallets within your application or project. It is a non-custodial solution that simplifies the onboarding process and improves the user experience for web3 apps in two ways:
- It enables non-web3 native users to get started easily without having to create a wallet.
- It hides transaction confirmations from users.
After generating wallets for your users, your can offer multiple persistance and backup options.
Usage
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { LocalWallet } from "@thirdweb-dev/wallets";
const wallet = new LocalWallet();
// generate a random wallet
await wallet.generate();
// connect the wallet to the application
await wallet.connect();
// at any point, you can save the wallet to persistent storage
await wallet.save(config);
// and load it back up
await wallet.load(config);
// you can also export the wallet out of the application
const exportedWallet = await wallet.export(config);
// and import it back in
await wallet.import(exportedWallet, config);
// You can then use this wallet to perform transactions via the SDK
const sdk = await ThirdwebSDK.fromWallet(wallet, "goerli");
Local Wallet Backup
Local wallets can be persisted on disk, or backed up to the cloud. Currently 3 formats are supported:
encryptedJSON
- a standard format for encrypted wallets, this requires a password to encrypt/decrypt the wallet. Recommended for safe backups.privateKey
- the raw private key. This can be stored encrypted or un-encrypted. If not encrypted, make sure you store it somewhere safe.mnemonic
- the raw seed phrase. This can be stored encrypted or un-encrypted. If not encrypted, make sure you store it somewhere safe.
We provide encryption capabilities out of the box, but you can customize the type of encryption, and also turn it off completely.
The type of storage can also be overridden, allowing you to store wallets anywhere you want, including remote locations.
By default, wallets will be stored on the browser's storage for web (React), and on the secure storage of the device for mobile (React Native).
On Node.js, you can use LocalWalletNode
which by default will save to the local file system of the machine.
import { LocalWalletNode } from "@thirdweb-dev/wallets/evm/wallets/local-wallet-node";
// wallet data will be saved in 'wallet.json' by default
// you can also pass a different file path by specifying 'storageJsonFile' in the constructor
const wallet = new LocalWalletNode();
await localWallet.loadOrCreate({
strategy: "privateKey",
encryption: false,
});
Customizing where the wallet data is persisted only requires implementing a simple interface. Here's an example of a Local Wallet with custom storage:
class MyStorage implements AsyncStorage {
getItem(key: string): Promise<string | null> { ... }
setItem(key: string, value: string): Promise<void> { ... }
removeItem(key: string): Promise<void> { ... }
}
const wallet = new LocalWallet({
storage: new MyStorage(),
})
You can implement this any way you like, file persistance, remote cloud storage, etc.
Encryption examples
Here's some examples of different encryption configurations:
- Save an encrypted privateKey with default encryption a password as the encryption key:
localWallet.save({
strategy: "privateKey",
encryption: {
password: "your-encryption-password", // uses default encryption
},
});
- Import a raw private key or mnemonic (seed phrase) with no encryption:
// privateKey
localWallet.import({
privateKey: "your-raw-privateKey",
encryption: false, // no encryption
});
// mnemonic
localWallet.import({
mnemonic: "your-raw-mnemonic",
encryption: false, // no encryption
});
- Save an encrypted mnemonic with a custom encryption:
// privateKey
localWallet.save({
strategy: "mnemonic",
encryption: {
encrypt: (message: string, password: string) => {
return yourCustomEncryption(message, password);
},
password: "your-encryption-password",
},
});
Configuration
Optionally, provide a configuration object when instantiating the LocalWallet
class.
clientId or secretKey (recommended)
Provide clientId
or secretKey
to use the thirdweb RPCs for given chains
If you are using the LocalWallet
in a in frontend - provide a clientId
, If you are using the LocalWallet
in backend - you can provide a secretKey
.
You can create a clientId
/ secretKey
from thirdweb dashboard.
chain (optional)
The active chain to connect to.
Must be a Chain
object, from the @thirdweb-dev/chains
package.
Defaults to Ethereum
.
import { LocalWallet } from "@thirdweb-dev/wallets";
import { Goerli } from "@thirdweb-dev/chains";
const walletWithOptions = new LocalWallet(
{
chain: Goerli,
},
);
chains (optional)
Provide an array of chains you want to support.
Must be an array of Chain
objects, from the @thirdweb-dev/chains
package.
Defaults to our default chains.
import { LocalWallet } from "@thirdweb-dev/wallets";
import { BaseGoerli, Goerli } from "@thirdweb-dev/chains";
const walletWithOptions = new LocalWallet(
{
chains: [BaseGoerli, Goerli],
},
);
storage (optional)
This is the default storage for storing the private key, mnemonic or encrypted JSON. This can be implemented in any way you want, as long as it conforms to the AsyncStorage
interface:
If omitted, defaults to browser storage.
export interface AsyncStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
Example:
import { LocalWallet } from "@thirdweb-dev/wallets";
const walletWithOptions = new LocalWallet(
{
storage: {
getItem: (key) => {
// Implement your own storage logic here
},
removeItem: (key) => {
// Implement your own storage logic here
},
setItem: (key, value) => {
// Implement your own storage logic here
},
},
},
);
walletStorage (optional)
This storage is only used for state persistance, allowing for auto connect.
Must be an object conforming to the AsyncStorage
interface:
export interface AsyncStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
Example:
import { LocalWallet } from "@thirdweb-dev/wallets";
const walletWithOptions = new LocalWallet(
{
walletStorage: {
getItem: (key) => {
// Implement your own storage logic here
},
removeItem: (key) => {
// Implement your own storage logic here
},
setItem: (key, value) => {
// Implement your own storage logic here
},
},
},
);
walletId (optional)
An ID for the wallet used to store the wallet in the walletStorage
.
import { LocalWallet } from "@thirdweb-dev/wallets";
const walletWithOptions = new LocalWallet(
{
walletId: "wallet-id",
},
);
Methods
Inherits all the public methods from the AbstractClientWallet
class.
Also provides wallet specific public methods:
generate
Creates a new random wallet.
const address = await wallet.generate();
Configuration
Return Value
Returns a Promise
which resolves to a string
containing the wallet address.
Promise<string>;
save
Save the wallet data to storage
wallet.save({
strategy: "encryptedJson",
password: "password",
});
Configuration
options
Must be a SaveOptions
object:
type SaveOptions =
| {
strategy: "encryptedJson",
password: string,
storage?: AsyncStorage,
}
| {
strategy: "privateKey",
encryption?: EncryptOptions,
storage?: AsyncStorage,
}
| {
strategy: "mnemonic",
encryption: EncryptOptions,
storage?: AsyncStorage,
};
Example:
wallet.save({
strategy: "encryptedJson",
password: "your-password",
});
Return Value
Returns a Promise
which resolves to a string
containing the wallet address.
Promise<string>;
getSavedData
Get the saved wallet data from storage.
const wallet = wallet.getSaved();
Configuration
storage
Optional AsyncStorage
object to get the data from instead of the default storage.
export interface AsyncStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
Example:
wallet.getSaved({
getItem: (key) => {
// Implement your own storage logic here
},
removeItem: (key) => {
// Implement your own storage logic here
},
setItem: (key, value) => {
// Implement your own storage logic here
},
});
Return Value
Returns a Promise
which resolves to a WalletData
object containing the wallet data.
Promise<WalletData | null>;
isSaved
Get an array of the events for which the emitter has registered listeners.
const isSaved = wallet.isSaved();
Configuration
Return Value
Returns a Promise
which resolves to a boolean
- true
if wallet data is saved in storage, false
otherwise.
Promise<boolean>;
deleteSaved
Delete the saved wallet from storage. This action is irreversible, use with caution.
await wallet.deleteSaved();
load
Initialize the wallet from saved data on storage
await wallet.load({
strategy: "encryptedJson",
password: "your-password",
});
Configuration
options
Must be a LoadOptions
object:
type LoadOptions =
| {
strategy: "encryptedJson";
password: string;
storage?: AsyncStorage;
}
| {
strategy: "privateKey";
storage?: AsyncStorage;
encryption: DecryptOptions;
}
| {
strategy: "mnemonic";
storage?: AsyncStorage;
encryption: DecryptOptions;
};
Example:
wallet.load({
strategy: "encryptedJson",
password: "your-password",
});
Return Value
Returns a Promise
which resolves to a string
containing the wallet address.
Promise<string>;
loadOrCreate
Load the saved wallet data from storage, if it exists, or generate a new one and save it.
password = "your-password";
wallet.loadOrCreate({
strategy: "encryptedJson",
password: password,
});
Configuration
options
Must be a LoadOrCreateOptions
object:
type LoadOptions =
| {
strategy: "encryptedJson";
password: string;
storage?: AsyncStorage;
}
| {
strategy: "privateKey";
storage?: AsyncStorage;
encryption: DecryptOptions;
};
Example:
wallet.loadOrCreate({
strategy: "encryptedJson",
password: "password",
});
export
Encrypts the wallet with given password and returns the encrypted wallet.
await wallet.export({
strategy: "encryptedJson",
password: "password",
});
Configuration
options
Must be a ExportOptions
object:
type ExportOptions =
| {
strategy: "encryptedJson";
password: string;
}
| {
strategy: "privateKey";
encryption: EncryptOptions;
}
| {
strategy: "mnemonic";
encryption: EncryptOptions;
};
Example:
wallet.export({
strategy: "privateKey",
encryption: false,
});
Return Value
Returns a Promise
which resolves to a string
containing the encrypted wallet.
Promise<string>;
import
Create a local wallet from an "encryptedJson", "privateKey" or "mnemonic"
localWallet.import({
privateKey: "...",
encryption: false,
});
Configuration
options
Must be a ImportOptions
object:
type ImportOptions =
| {
privateKey: string;
encryption: DecryptOptions;
}
| {
mnemonic: string;
encryption: DecryptOptions;
}
| {
encryptedJson: string;
password: string;
};
Example:
wallet.import({
encryptedJson: "...",
password: "password",
});
Return Value
Returns a Promise
which resolves to a string
containing the wallet address.
Promise<string>;