LocalWallet
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, you can offer multiple persistence and backup options.
import { ThirdwebSDK } from "@thirdweb-dev/sdk";import { LocalWallet } from "@thirdweb-dev/wallets"; const wallet = new LocalWallet(); // generate a random walletawait wallet.generate(); // connect the wallet to the applicationawait wallet.connect(); // at any point, you can save the wallet to persistent storageawait wallet.save(config);// and load it back upawait wallet.load(config); // you can also export the wallet out of the applicationconst exportedWallet = await wallet.export(config);// and import it back inawait wallet.import(exportedWallet, config); // You can then use this wallet to perform transactions via the SDKconst 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 constructorconst 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
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:
// privateKeylocalWallet.import({ privateKey: "your-raw-privateKey", encryption: false, // no encryption}); // mnemoniclocalWallet.import({ mnemonic: "your-raw-mnemonic", encryption: false, // no encryption});
Save an encrypted mnemonic with a custom encryption:
// privateKeylocalWallet.save({ strategy: "mnemonic", encryption: { encrypt: (message: string, password: string) => { return yourCustomEncryption(message, password); }, password: "your-encryption-password", },});
> {}
Initialize the LocalWallet
with the given options
function constructor(
The options
object contains the following properties:
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)
Must be a Chain
object, from the @thirdweb-dev/chains
package.
Defaults to Ethereum
.
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 .
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 local storage.
import { LocalWallet } from "@thirdweb-dev/wallets"; const customStorage = { 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 },}; const walletWithOptions = new LocalWallet({ storage: customStorage,});
Delete the saved wallet from storage. This action is irreversible, use with caution.
await wallet.deleteSaved();
function deleteSaved(): Promise<void>;
Disconnect the wallet
function disconnect(): Promise<void>;
Encrypts the wallet with a password in various formats and return it.
const data = await wallet.export({ strategy: "encryptedJson", password: "password",});
The options
object must be of type LocalWalletExportOptions
. It takes a strategy
and other properties depending on the strategy.
strategy - "encryptedJson"
Export wallet in encryptedJson format. The options
object takes the following properties:
strategy
- must be "encryptedJson"password
- the password to encrypt the wallet data
strategy - "privateKey"
Encrypt the private key of the wallet. The options
object takes the following properties:
strategy
- must be "privateKey"encryption
- encryption object of typeEncryptOptions
to encrypt the private key. It takes apassword
property to encrypt the private key and an optionalencrypt
function to encrypt the private key. Ifencrypt
function is not provided, it uses the default encryption.
strategy - "mnemonic"
Encrypt the mnemonic (seed phrase) of the wallet. The options
object takes the following properties:
strategy
- must be "mnemonic"encryption
- encryption object of typeEncryptOptions
to encrypt the mnemonic. It takes apassword
property to encrypt the mnemonic and an optionalencrypt
function to encrypt the mnemonic. Ifencrypt
function is not provided, it uses the default encryption.
Creates a new random wallet and returns the wallet address.
const address = await wallet.generate();
function generate(): Promise<string>;
Get the saved wallet data from storage
const someStorage = { 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 },}; wallet.getSaved(someStorage);
function getSavedData(
Promise
which resolves to a WalletData
object containing the wallet data. It returns null
if no wallet data is found in storage.
{ address: string; strategy: "mnemonic" | "privateKey" | "encryptedJson"; data: string; isEncrypted: boolean;}
Create local wallet by importing a private key, mnemonic or encrypted JSON.
const address = await localWallet.import({ privateKey: "...", encryption: false,});
The options
object must be of type LocalWalletImportOptions
which can have either privateKey
, mnemonic
or encryptedJson
as a property.
They all can be encrypted or un-encrypted. If encrypted, the encryption
property must be provided with password
property to decrypt the data.
privateKey
The Private Key of the wallet.
mnemonic
The mnemonic (seed phrase) of the wallet.
encryptedJson
The encrypted JSON of the wallet.
encryption
This is only required if the given privateKey
, mnemonic
or encryptedJson
is encrypted.
The encryption
object of type DecryptOptions
can be provided to decrypt the data. It is an object with the following properties:
password
The password to decrypt the data.
decrypt
A custom decrypt function that takes the encrypted data and password as arguments and returns the decrypted data.
Check if the wallet data is saved in storage.
function isSaved(): Promise<boolean>;
Initialize the wallet from saved data on storage
await wallet.load({ strategy: "encryptedJson", password: "your-password",});
The options
object must be of type LocalWalletLoadOptions
which contains a strategy
property and other properties depending on the strategy.
strategy "encryptedJson"
Initialize the wallet from encrypted JSON. The options
object takes the following properties:
strategy
- must be "encryptedJson"password
- the password to decrypt the encrypted JSONstorage
- optional storage to get the wallet data from. Must be of typeAsyncStorage
strategy "privateKey"
Initialize the wallet from a private key. The options
object takes the following properties:
strategy
- must be "privateKey"encryption
- optional encryption object of typeDecryptOptions
to decrypt the private key. This is only required if the private key is encrypted.storage
- optional storage to get the wallet data from. Must be of typeAsyncStorage
strategy "mnemonic"
Initialize the wallet from a mnemonic (seed phrase). The options
object takes the following properties:
strategy
- must be "mnemonic"encryption
- optional encryption object of typeDecryptOptions
to decrypt the mnemonic. This is only required if the mnemonic is encrypted.storage
- optional storage to get the wallet data from. Must be of typeAsyncStorage
Load the saved wallet data from storage, if it exists, or generate a new one and save it.
wallet.loadOrCreate({ strategy: "encryptedJson", password: password,});
function loadOrCreate(): Promise<void>;
The options
object must be of type LocalWalletLoadOrCreateOptions
. It takes a strategy
property and other properties depending on the strategy.
strategy "encryptedJson"
Load the wallet from encrypted JSON. The options
object takes the following properties:
strategy
- must be "encryptedJson"password
- the password to decrypt the encrypted JSONstorage
- optional storage to get the wallet data from. Must be of typeAsyncStorage
strategy "privateKey"
Load the wallet from a private key. The options
object takes the following properties:
strategy
- must be "privateKey"encryption
- optional encryption object of typeDecryptOptions
to decrypt the private key. This is only required if the saved private key is encrypted.
Save the wallet data to storage
wallet.save({ strategy: "encryptedJson", password: "password",});
The options
object must be of type LocalWalletSaveOptions
. It takes a strategy
property and other properties depending on the strategy.
strategy "encryptedJson"
Save the wallet data as encrypted JSON. The options
object takes the following properties:
strategy
- must be "encryptedJson"password
- the password to encrypt the wallet datastorage
- optional storage to save the wallet data to. Must be of typeAsyncStorage
strategy "privateKey"
Save the wallet data as a private key. The options
object takes the following properties:
strategy
- must be "privateKey"encryption
- optional encryption object of typeEncryptOptions
to encrypt the private key. This is only required if you want to encrypt the private key.storage
- optional storage to save the wallet data to. Must be of typeAsyncStorage
strategy "mnemonic"
Save the wallet data as a mnemonic (seed phrase). The options
object takes the following properties:
strategy
- must be "mnemonic"encryption
- optional encryption object of typeEncryptOptions
to encrypt the mnemonic. This is only required if you want to encrypt the mnemonic.storage
- optional storage to save the wallet data to. Must be of typeAsyncStorage
AbstractClientWallet.addListener
event: T, fn: ( ) => void, context?: any,): this;
let fn: () => void;
AbstractClientWallet.autoConnect
auto-connect the wallet if possible
function autoConnect(connectOptions?: { chainId?: number;}): Promise<string>;
AbstractClientWallet.connect
Connect wallet
function connect(connectOptions?: { chainId?: number;}): Promise<string>;
AbstractClientWallet.emit
Calls each of the listeners registered for a given event.
event: T,): boolean;
AbstractClientWallet.eventNames
Return an array listing the events for which the emitter has registered listeners.
AbstractClientWallet.getAddress
Returns the account address of the connected wallet
function getAddress(): Promise<string>;
AbstractClientWallet.getBalance
Returns the balance of the connected wallet for the specified token address. If no token address is specified, it returns the balance of the native token
function getBalance( tokenAddress: string,): Promise<{ decimals: number; displayValue: string; name: string; symbol: string; value: BigNumber;}>;
AbstractClientWallet.getChainId
Returns the chain id of the network that the wallet is connected to
function getChainId(): Promise<number>;
AbstractClientWallet.getPersonalWallet
If the wallet uses another "personal wallet" under the hood, return it
This is only useful for wallets like Safe or Smart Wallet uses a "personal wallet" under the hood to sign transactions. This method returns that wallet
AbstractClientWallet.getSigner
Get ethers Signer object of the connected wallet
function getSigner(): Promise<Signer>;
AbstractClientWallet.listenerCount
Return the number of listeners listening to a given event.
AbstractClientWallet.listeners
Return the listeners registered for a given event.
event: T,): Array< ( ) => void>;
let returnType: Array< ( ) => void>;
AbstractClientWallet.off
event: T, fn?: ( ) => void, context?: any, once?: boolean,): this;
let fn: () => void;
AbstractClientWallet.on
Add a listener for a given event.
event: T, fn: ( ) => void, context?: any,): this;
let fn: () => void;
AbstractClientWallet.once
Add a one-time listener for a given event.
event: T, fn: ( ) => void, context?: any,): this;
let fn: () => void;
AbstractClientWallet.removeListener
Remove the listeners of a given event.
event: T, fn?: ( ) => void, context?: any, once?: boolean,): this;
let fn: () => void;
AbstractClientWallet.signMessage
Sign a message with the connected wallet and return the signature
function signMessage(message: string | Bytes): Promise<string>;
AbstractClientWallet.switchChain
Switch to different Network/Blockchain in the connected wallet
function switchChain(chainId: number): Promise<void>;
AbstractClientWallet.transfer
Transfers some amount of tokens to the specified address
function transfer( to: string, amount: string | number, currencyAddress: string,): Promise<Omit<TransactionResultWithMetadata<unknown>, "data">>;
AbstractClientWallet.updateChains
Update the chains supported by the wallet. This is useful if wallet was initialized with some chains and this needs to be updated without re-initializing the wallet
function updateChains(chains: Array<Chain>): Promise<void>;
AbstractClientWallet.verifySignature
Verify the signature of a message. It returns true
if the signature is valid, false
otherwise
function verifySignature( message: string, signature: string, address: string, _chainId?: number,): Promise<boolean>;
let walletId: string;
let prefixed: string | boolean;