Motivation for v2
- Simplify the Wallets SDK and reduce web3-specific jargon
- Unify wallet types and signer configs across chains
- Provide better defaults for common use cases
- Make wallet integration faster and less error-prone
- Enable advanced features via optional parameters when needed
Wallets SDK
Signer types and locators
Signer types and locators have been consolidated and simplified:
Before | Now |
---|
evm-keypair solana-keypair | external-wallet |
evm-passkey | passkey |
solana-fireblocks-custodial evm-fireblocks-custodial | api-key |
// Before
const wallet = await crossmintWallets.getOrCreateWallet("evm-smart-wallet", {
chain: "base-sepolia",
adminSigner: {
type: "evm-passkey",
},
});
// Now
const wallet = await crossmintWallets.getOrCreateWallet({
chain: "base", // base-sepolia will be inferred by the api key being from staging
signer: {
type: "passkey",
},
});
Change #1: Wallet type
Wallet type is not an argument anymore. All wallets are smart wallets and type is inferred from the chain passed
Change #2: Signers configs
Signers configs are now a single argument.
//////////////////////
// Passkey signer
//////////////////////
// Before
{
type: "evm-passkey";
name?: string;
signingCallback?: PasskeySigningCallback;
creationCallback?: PasskeyCreationCallback;
};
// Now
{
type: "passkey";
name?: string;
onCreatePasskey?: (name: string) => Promise<{ id: string; publicKey: { x: string; y: string } }>;
onSignWithPasskey?: (message: string) => Promise<PasskeySignResult>;
};
//////////////////////
// Keypair signer
//////////////////////
// Before
{
type: "evm-keypair";
address: string;
signer:
| {
type: "provider";
provider: EIP1193Provider; // From viem
}
| {
type: "viem_v2";
account: Account; // From viem
};
}
{
type: "solana-keypair";
address: SolanaAddress;
signer: {
signMessage: (message: Uint8Array) => Promise<Uint8Array>;
signTransaction: (transaction: VersionedTransaction) => Promise<VersionedTransaction>;
};
}
// Now
export type BaseExternalWalletSignerConfig = {
type: "external-wallet";
address: string;
};
export type EvmExternalWalletSignerConfig = BaseExternalWalletSignerConfig & {
provider?: GenericEIP1193Provider | ViemEIP1193Provider;
viemAccount?: Account;
};
export type SolanaExternalWalletSignerConfig = BaseExternalWalletSignerConfig & {
onSignTransaction: (transaction: VersionedTransaction) => Promise<VersionedTransaction>;
};
//////////////////////
// Fireblocks
//////////////////////
// Before
{
type: "solana-fireblocks-custodial";
};
// Now
{ type: "api-key" } // works for both EVM and Solana
Change #3: LinkedUser is now owner
LinkedUser field is now called owner.
// Before
const wallet = await crossmintWallets.getOrCreateWallet("evm-smart-wallet", {
chain: "base-sepolia",
linkedUser: "email:dev@company.com",
adminSigner: {
type: "evm-passkey",
},
});
// Now
const wallet = await crossmintWallets.getOrCreateWallet({
chain: "base-sepolia",
owner: "email:dev@company.com",
signer: {
type: "passkey",
},
});
SolanaSmartWallet and EVMSmartWallet get consolidated into Wallet
Change #1: getOrCreateWallet just returns a Wallet object
// Before
const wallet: SolanaSmartWallet = await crossmintWallets.getOrCreateWallet("solana-smart-wallet", {
adminSigner: {
type: "solana-fireblocks-custodial",
},
});
const wallet: EVMSmartWallet = await crossmintWallets.getOrCreateWallet("evm-smart-wallet", {
chain: "base",
adminSigner: {
type: "evm-passkey",
},
});
// Now
const wallet: Wallet = await crossmintWallets.getOrCreateWallet({
chain: "base", // or "solana"
signer: {
type: "passkey",
},
});
The Wallet object has common methods for all chains including checking the balance,
adding delegated signers and sending any kind of token.
Change #2: Balances
Balances now return an object with nativeToken, usdc and tokens. USDC and nativeToken balances are always fetched.
// Before
await wallet.getBalances(["sol", "usdc"]);
// Now
await wallet.balances();
Change #3: Sending transactions and signing messages
To create transactions that are not transferring any kind of token you now need to do the following:
// Before
wallet.sendTransaction({});
// Now
// EVM
const wallet: Wallet = // ...
const evmWallet: EVMWallet = EVMWallet.from(wallet);
evmWallet.sendTransaction(...);
evmWallet.signMessage(...);
evmWallet.signTypedData(...);
// Solana
const wallet: Wallet = // ...
const solanaWallet: SolanaWallet = SolanaWallet.from(wallet);
solanaWallet.sendTransaction(...);
Change #4: Delegated signer type
Delegated signer type is now a method on the Wallet object.
// Before
wallet.getDelegatedSigners();
await wallet.addDelegatedSigner(`solana-keypair:${newSigner}`);
wallet.send("email@gmail.com", "usdc", "1.2");
// Now
wallet.delegatedSigners();
await wallet.addDelegatedSigner({ signer: `external-wallet:${newSigner}` });