Solana Wallet Kit
solana_wallet_kit is a Flutter plugin for adding self-custodial Solana wallet
creation, restore, local storage, backup, and address management to a host
application.
The package gives you ready-made, theme-aware wallet screens and injectable
services. It keeps the security boundary small: recovery phrases and private
keys are generated, validated, and stored on the device; host callbacks receive
only public WalletInfo.
This package is an early preview. Version
0.1.0supports and verifies Android only. Review the security model and test your complete host flow before using it with real funds.
What This Package Does
- Creates Solana wallets from BIP39 recovery phrases.
- Restores Solana wallets from recovery phrases.
- Restores a known Solana address from a matching private key.
- Stores public wallet metadata, per-address private keys, and mnemonic roots separately in secure local storage.
- Groups derived addresses by mnemonic root id.
- Lets users add another derived address from a locally saved mnemonic root.
- Exports and imports verified JSON backup files.
- Shows locally saved wallet secrets when the user needs to recover them.
- Obscures wallet UI while the app is inactive.
- Lets host apps customize copy, theme, backup import/export, clipboard, and storage behavior.
Why It Exists
Most apps that need an embedded wallet have the same hard parts:
- generating and validating wallet material correctly;
- keeping recovery phrases and private keys out of backend and app state;
- persisting secrets locally without exposing them through app callbacks;
- restoring existing backend wallet addresses without guessing ownership;
- giving users a backup and recovery path that is not tied to one host app.
solana_wallet_kit owns those wallet-specific concerns. The host app remains
responsible for app-specific work such as account creation, backend wallet
registration, selected-wallet state, navigation, analytics boundaries, and
product copy.
Package Boundary
The package handles:
- recovery phrase generation, restore, import, export, and secure persistence;
- private-key validation and secure persistence;
- wallet setup, create, restore, address-list, and secrets screens;
- Solana derivation metadata and root-scoped local address indexes.
The host app handles:
- sending public wallet addresses to a backend;
- choosing where wallet setup appears in the app;
- deciding which saved wallet is active in host state;
- app-specific authentication and user-account rules;
- protecting logs, analytics, crash reporting, and network payloads from secrets.
The completion callbacks intentionally return WalletInfo only. They never
return the recovery phrase or private key.
Installation
From pub.dev:
flutter pub add solana_wallet_kit
Until the first pub.dev release, use the Git repository:
dependencies:
solana_wallet_kit:
git:
url: https://github.com/ReyAlexandr/solana_wallet_kit.git
Import the package:
import 'package:solana_wallet_kit/solana_wallet_kit.dart';
Requirements
- Dart SDK
^3.12.1. - Flutter
>=3.38.0. - Android minimum SDK 23 or newer.
- Android cloud backup and device transfer disabled for the host app.
The plugin currently declares Android support. Some Dart-only services may run
elsewhere, and the default backup gateway includes desktop file pickers, but
the package is only verified as an Android Flutter plugin in 0.1.0.
Quick Start
Use WalletSetupScreen when you want the package to provide the complete entry
flow:
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => WalletSetupScreen(
existingWalletsByRootId: savedWalletAddressesByRootId,
onWalletReady: (walletInfo) async {
await api.saveWalletAddress(walletInfo.address);
if (!context.mounted) return;
Navigator.of(context).pushReplacementNamed('/home');
},
),
),
);
onWalletReady is called after the package saves the wallet material locally.
The callback receives public WalletInfo only. Make the callback idempotent:
if the host backend or navigation fails, the user can retry after the wallet is
already saved on the device.
existingWalletsByRootId is a map of:
{
rootWalletAddress: [
rootWalletAddress,
anotherDerivedAddress,
],
}
When this map is empty, the setup screen shows only Create and Restore. When it contains saved wallet families, root wallet cards expand into address cards:
- root-card import opens recovery-phrase restore with that root id and strict root verification;
- address-card import opens private-key restore with the selected address prefilled and locked;
- the normal Restore button stays a plain mnemonic restore and does not verify against a supplied root id.
For separate screens, service-level usage, backup customization, and storage details, read doc/USAGE.md.
Main Screens
WalletSetupScreen: full Create/Restore entry flow, optional saved wallet groups, root-wallet mnemonic import, and address private-key import.CreateSolanaWalletScreen: generates a new wallet, shows address, private key, and recovery phrase, supports JSON export, and saves only after backup confirmation.RestoreSolanaWalletScreen: restores from a recovery phrase, optionally under a suppliedrootId, with optionalverifyRoot.PkRestoreScreen: restores a supplied or user-entered address from a matching base58 private key and stores no mnemonic root.AddressListScreen: lists locally saved addresses in the selected wallet's root family, selects existing addresses, and derives/saves the next address.WalletSecretsScreen: shows a locally saved address, private key, and recovery phrase when available.
Main Models
WalletInfo: public wallet metadata returned to host callbacks. Containschain,address,rootId,label,source, and optionalderivationPath.WalletSecret: per-address private-key material. It wrapsWalletInfoandprivateKeyBase58.MnemonicSecret: mnemonic root secret stored once byrootId.WalletMaterial: internal bundle used by create/restore/backup flows. It containsWalletInfo,WalletSecret, and optionalMnemonicSecret.SolanaDerivation: hardened Solana derivation path helper. The primary path ism/44'/501'/0'/0'.WalletUiText: screen copy and tooltip customization.WalletPhraseFile: file name and contents for backup import/export.
Main Services
WalletRegistryService: creates, restores, saves, reads, derives, and deletes local wallet material. UsehasLocalWallet(address: ...)when a host app only needs to know whether this package has saved usable material for a public address.
Root Id and Address Families
For mnemonic wallets, WalletInfo.rootId is the primary Solana address derived
from the recovery phrase. Additional accounts from the same phrase share that
root id and have their own address, private key, and derivation path.
For private-key-only wallets, there is no mnemonic root. The address itself is
used as rootId, and address derivation is not available.
This distinction matters because a user can prove a known saved address in two different ways:
- root wallet import: enter the recovery phrase for the known root id;
- address import: enter the private key for the exact saved address.
Security Model
- Recovery phrases and private keys are generated and validated locally.
- Default storage uses
flutter_secure_storage. - Secure storage entries are separated:
wallet.solana.info.<address>;wallet.solana.pk.<address>;wallet.solana.mnemonic.<rootId>;wallet.solana.addresses.<rootId>.
- Host callbacks receive only
WalletInfo. - Private-key restore validates that the key controls the supplied address.
- JSON backups are unencrypted and contain both recovery phrase and private key.
protectSensitiveContenthides wallet screens while the app is inactive. It is not a universal foreground screenshot blocker.- Web secure storage is intentionally unsupported by the default store.
Never send recovery phrases or private keys to a backend, logs, analytics, crash reports, screenshots, or user-profile records.
Report vulnerabilities privately as described in SECURITY.md.
Android Configuration
The host application must prevent wallet secrets from entering Android backup or device-to-device transfer.
Configure the host app's <application> element:
<application
android:allowBackup="false"
android:fullBackupContent="false"
android:dataExtractionRules="@xml/data_extraction_rules">
Copy
example/android/app/src/main/res/xml/data_extraction_rules.xml
into the host application.
Backup export uses Android's ACTION_CREATE_DOCUMENT flow through the package
plugin channel solana_wallet_kit/backup. It requires no broad storage
permission because Android grants write access only to the destination selected
by the user.
After first adding the plugin, perform a full rebuild:
flutter clean
flutter pub get
flutter run
Backup Format
Exported JSON uses format id solana-wallet-backup and version 2. It
includes:
- recovery phrase;
- base58 private key;
- chain;
- address;
- root id;
- derivation path;
- plaintext warning.
Import validates the format, version, chain, mnemonic, root id, address, derivation path, and private key before returning data to the restore screen.
Example and Development
The example app demonstrates the complete setup screen and the
required Android security configuration.
Common commands:
flutter pub get
dart format lib test example/lib
flutter analyze
flutter test
cd example
flutter build apk --debug
Before publishing:
dart pub publish --dry-run
Current Limitations
- Android is the only verified plugin platform for
0.1.0. - iOS support is planned but not yet claimed.
- Web builds require a reviewed custom
WalletStore. - JSON backups are not encrypted.
- The package targets Solana only.
- Lifecycle obscuring does not block every possible screenshot path.
Built With
solana: Solana key generation, account derivation, and address utilities.bip39: recovery-phrase generation and validation.flutter_secure_storage: protected local storage for wallet material.file_selector: backup-file import and desktop file dialogs.
License
MIT. See LICENSE.
Libraries
- solana_wallet_kit
- wallet/models/imported_wallet_backup
- wallet/models/mnemonic_secret
- wallet/models/mnemonic_strength
- wallet/models/solana_derivation
- wallet/models/wallet_exception
- wallet/models/wallet_info
- wallet/models/wallet_material
- wallet/models/wallet_phrase_file
- wallet/models/wallet_secret
- wallet/models/wallet_ui_text
- wallet/screens/address_list_screen
- wallet/screens/create_solana_wallet_screen
- wallet/screens/pk_restore_screen
- wallet/screens/restore_solana_wallet_screen
- wallet/screens/wallet_secrets_screen
- wallet/screens/wallet_setup_screen
- wallet/services/wallet_backup_gateway
- wallet/services/wallet_clipboard_service
- wallet/services/wallet_phrase_export_service
- wallet/services/wallet_phrase_import_service
- wallet/services/wallet_registry_service
- wallet/solana/solana_wallet_creation_service
- wallet/solana/solana_wallet_creation_service_01
- wallet/solana/solana_wallet_validator
- wallet/storage/secure_wallet_secret_store
- wallet/storage/wallet_store
- wallet/wallet
- wallet/widgets/mnemonic_grid
- wallet/widgets/mnemonic_input_grid
- wallet/widgets/mnemonic_strength_selector
- wallet/widgets/wallet_security_notice
- wallet/widgets/wallet_sensitive_content