Prerequisites
- API Key: Ensure you have an API key with the scopes:
wallets.create.
Try it Live
Experience wallet creation in action with this interactive demo. Create a Solana testnet wallet using just your email address:Creating a Wallet
Wallet creation requires a recovery signer — used for account recovery and adding new signers. On client-side SDKs, a device signer is automatically added as the default operational signer.- React
- Node.js
- React Native
- Kotlin
- Swift
- Flutter
- REST
import { useWallet } from '@crossmint/client-sdk-react-ui';
const { createWallet } = useWallet();
const wallet = await createWallet({
chain: "base-sepolia",
recovery: {
type: "email",
email: "user@example.com",
},
});
import { CrossmintWallets, createCrossmint } from "@crossmint/wallets-sdk";
const crossmint = createCrossmint({
apiKey: "<your-server-api-key>",
});
const crossmintWallets = CrossmintWallets.from(crossmint);
const wallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
recovery: {
type: "server",
secret: process.env.RECOVERY_SIGNER_SECRET,
},
signers: [
{ type: "server", secret: process.env.WALLET_SIGNER_SECRET },
],
});
import { useWallet } from '@crossmint/client-sdk-react-native-ui';
const { createWallet } = useWallet();
const wallet = await createWallet({
chain: "base-sepolia",
recovery: {
type: "email",
email: "user@example.com",
},
});
import com.crossmint.kotlin.Crossmint
import com.crossmint.kotlin.types.EVMChain
import com.crossmint.kotlin.signers.SignerType
val sdk = Crossmint.instance
val result = sdk.crossmintWallets.createWallet(
chain = EVMChain.BaseSepolia,
recovery = SignerType.Email("user@example.com")
)
val wallet = result.getOrThrow()
println("Wallet address: ${wallet.address}")
import CrossmintClient
let sdk = CrossmintSDK.shared(
apiKey: crossmintApiKey,
authManager: crossmintAuthManager
)
let wallet = try await sdk.crossmintWallets.createWallet(
chain: EVMChain.baseSepolia,
recovery: EVMSigners.email("user@example.com")
)
print("Wallet address:", wallet.address)
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';
final controller = CrossmintWalletContext.of(context).requireWalletController;
final wallet = await controller.createWallet(
const CrossmintWalletCreateRequest(
chain: 'base-sepolia',
recovery: CrossmintEmailSignerConfig(email: 'user@example.com'),
),
);
CrossmintWalletProvider + createOnLogin, the wallet is created
automatically after login. See the
Flutter SDK reference
for all parameters.curl --request POST \
--url https://staging.crossmint.com/api/2025-06-09/wallets \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <x-api-key>' \
--data '{
"chainType": "evm",
"config": {
"adminSigner": {
"type": "email",
"email": "user@example.com"
}
},
"owner": "email:user@example.com"
}'
const url = 'https://staging.crossmint.com/api/2025-06-09/wallets';
const payload = {
chainType: "evm",
config: {
adminSigner: {
type: "email",
email: "user@example.com"
}
},
owner: "email:user@example.com"
};
const options = {
method: 'POST',
headers: {
'X-API-KEY': '<x-api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
};
try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
import requests
url = "https://staging.crossmint.com/api/2025-06-09/wallets"
payload = {
"chainType": "evm",
"config": {
"adminSigner": {
"type": "email",
"email": "user@example.com"
}
},
"owner": "email:user@example.com"
}
headers = {
"X-API-KEY": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
The REST API uses
adminSigner (recovery role) and delegatedSigners (operational signers). These map to recovery and signers in the SDK.Retrieving an Existing Wallet
UsegetWallet() to retrieve a wallet that was previously created. If the wallet does not exist, it throws a WalletNotAvailableError.
- React
- Node.js
- React Native
- Kotlin
- Swift
- Flutter
- REST
import { useWallet } from '@crossmint/client-sdk-react-ui';
const { getWallet } = useWallet();
const wallet = await getWallet({ chain: "base-sepolia" });
import { CrossmintWallets, createCrossmint } from "@crossmint/wallets-sdk";
const crossmint = createCrossmint({
apiKey: "<your-server-api-key>",
});
const crossmintWallets = CrossmintWallets.from(crossmint);
const wallet = await crossmintWallets.getWallet(
"<wallet-address>",
{ chain: "base-sepolia" }
);
await wallet.useSigner({
type: "server",
secret: process.env.WALLET_SIGNER_SECRET!,
});
import { useWallet } from '@crossmint/client-sdk-react-native-ui';
const { getWallet } = useWallet();
const wallet = await getWallet({ chain: "base-sepolia" });
import com.crossmint.kotlin.Crossmint
import com.crossmint.kotlin.types.EVMChain
val sdk = Crossmint.instance
val result = sdk.crossmintWallets.getWallet(chain = EVMChain.BaseSepolia)
val wallet = result.getOrThrow()
println("Wallet address: ${wallet.address}")
import CrossmintClient
let sdk = CrossmintSDK.shared(
apiKey: crossmintApiKey,
authManager: crossmintAuthManager
)
let wallet = try await sdk.crossmintWallets.getWallet(
chain: EVMChain.baseSepolia,
recovery: EVMSigners.email("user@example.com")
)
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';
final controller = CrossmintWalletContext.of(context).requireWalletController;
final wallet = await controller.getWallet(
const CrossmintWalletLookupRequest(chain: 'base-sepolia'),
);
curl --request GET \
--url https://staging.crossmint.com/api/2025-06-09/wallets/<wallet-locator> \
--header 'X-API-KEY: <x-api-key>'
const url = 'https://staging.crossmint.com/api/2025-06-09/wallets/<wallet-locator>';
const options = {
method: 'GET',
headers: {
'X-API-KEY': '<x-api-key>'
}
};
try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
import requests
url = "https://staging.crossmint.com/api/2025-06-09/wallets/<wallet-locator>"
headers = {"X-API-KEY": "<x-api-key>"}
response = requests.get(url, headers=headers)
print(response.json())
Get-or-Create Pattern
If you want to retrieve an existing wallet or create one if it does not exist, useWalletNotAvailableError to implement the pattern:
- React
- Node.js
- React Native
- Kotlin
- Swift
- Flutter
import { useWallet, WalletNotAvailableError } from '@crossmint/client-sdk-react-ui';
const { getWallet, createWallet } = useWallet();
let wallet;
try {
wallet = await getWallet({ chain: "base-sepolia" });
} catch (error) {
if (error instanceof WalletNotAvailableError) {
wallet = await createWallet({
chain: "base-sepolia",
recovery: {
type: "email",
email: "user@example.com",
},
});
} else {
throw error;
}
}
import {
CrossmintWallets,
WalletNotAvailableError,
createCrossmint,
} from "@crossmint/wallets-sdk";
const crossmint = createCrossmint({
apiKey: "<your-server-api-key>",
});
const crossmintWallets = CrossmintWallets.from(crossmint);
let wallet;
try {
wallet = await crossmintWallets.getWallet(
"<wallet-address>",
{ chain: "base-sepolia" }
);
await wallet.useSigner({
type: "server",
secret: process.env.WALLET_SIGNER_SECRET!,
});
} catch (error) {
if (error instanceof WalletNotAvailableError) {
wallet = await crossmintWallets.createWallet({
chain: "base-sepolia",
recovery: {
type: "server",
secret: process.env.RECOVERY_SIGNER_SECRET,
},
signers: [
{
type: "server",
secret: process.env.WALLET_SIGNER_SECRET,
},
],
});
} else {
throw error;
}
}
import { useWallet, WalletNotAvailableError } from '@crossmint/client-sdk-react-native-ui';
const { getWallet, createWallet } = useWallet();
let wallet;
try {
wallet = await getWallet({ chain: "base-sepolia" });
} catch (error) {
if (error instanceof WalletNotAvailableError) {
wallet = await createWallet({
chain: "base-sepolia",
recovery: {
type: "email",
email: "user@example.com",
},
});
} else {
throw error;
}
}
import com.crossmint.kotlin.Crossmint
import com.crossmint.kotlin.types.EVMChain
import com.crossmint.kotlin.signers.SignerType
val sdk = Crossmint.instance
val wallet = sdk.crossmintWallets.getWallet(chain = EVMChain.BaseSepolia)
.getOrNull()
?: sdk.crossmintWallets.createWallet(
chain = EVMChain.BaseSepolia,
recovery = SignerType.Email("user@example.com")
).getOrThrow()
import CrossmintClient
let sdk = CrossmintSDK.shared(
apiKey: crossmintApiKey,
authManager: crossmintAuthManager
)
let wallet: EVMWallet
if let existing = try await sdk.crossmintWallets.getWallet(
chain: EVMChain.baseSepolia,
recovery: EVMSigners.email("user@example.com")
) {
wallet = existing
} else {
wallet = try await sdk.crossmintWallets.createWallet(
chain: EVMChain.baseSepolia,
recovery: EVMSigners.email("user@example.com")
)
}
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';
final controller = CrossmintWalletContext.of(context).requireWalletController;
// Controller.getWallet returns null when the wallet does not exist.
var wallet = await controller.getWallet(
const CrossmintWalletLookupRequest(chain: 'base-sepolia'),
);
wallet ??= await controller.createWallet(
const CrossmintWalletCreateRequest(
chain: 'base-sepolia',
recovery: CrossmintEmailSignerConfig(email: 'user@example.com'),
),
);
On client-side SDKs (React, React Native), if you use
CrossmintWalletProvider with the createOnLogin prop, the wallet is created automatically when the user logs in — no manual createWallet call is needed.Next Steps
Transfer tokens
Send tokens between wallets
Add signers
Register operational signers on your wallet
Fund your wallet
Get testnet tokens to start testing

