Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
Configuration
DynamicSDK Initialization
Configuration for initializing the Dynamic SDK.
await DynamicSDK.instance.initialize(
environmentId: 'YOUR_ENV_ID', // Your Dynamic environment ID (required)
);
Parameters
- environmentId (String) - Your Dynamic environment ID (required)
Example
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await DynamicSDK.instance.initialize(
environmentId: 'YOUR_ENV_ID',
);
runApp(MyApp());
}
Authentication
UserProfile
Represents an authenticated user’s profile.
class UserProfile {
final String? userId;
final String? email;
final String? phoneNumber;
// Additional fields available
}
Properties
- userId (String?) - Unique user identifier
- email (String?) - User’s email address
- phoneNumber (String?) - User’s phone number
Example
final user = sdk.auth.authenticatedUser;
if (user != null) {
print('User ID: ${user.userId}');
print('Email: ${user.email}');
print('Phone: ${user.phoneNumber}');
}
StreamBuilder Example
StreamBuilder<UserProfile?>(
stream: sdk.auth.authenticatedUserChanges,
initialData: sdk.auth.authenticatedUser,
builder: (context, snapshot) {
final user = snapshot.data;
if (user == null) {
return Text('Not logged in');
}
return Column(
children: [
Text('User ID: ${user.userId}'),
if (user.email != null) Text('Email: ${user.email}'),
if (user.phoneNumber != null) Text('Phone: ${user.phoneNumber}'),
],
);
},
)
PhoneData
Phone number data for SMS authentication.
class PhoneData {
final String dialCode; // e.g., "+1"
final String iso2; // e.g., "US"
final String phone; // Phone number without country code
}
Properties
- dialCode (String) - Country dial code with + prefix
- iso2 (String) - ISO 3166-1 alpha-2 country code
- phone (String) - Phone number without country code
Example
final phoneData = PhoneData(
dialCode: '+1',
iso2: 'US',
phone: '5551234567',
);
await sdk.auth.sms.sendOTP(phoneData);
Country Code Examples
// United States
PhoneData(dialCode: '+1', iso2: 'US', phone: '5551234567')
// United Kingdom
PhoneData(dialCode: '+44', iso2: 'GB', phone: '7700900123')
// India
PhoneData(dialCode: '+91', iso2: 'IN', phone: '9876543210')
// Japan
PhoneData(dialCode: '+81', iso2: 'JP', phone: '9012345678')
SocialProvider
Enum for social authentication providers.
enum SocialProvider {
google,
apple,
farcaster,
}
Example
// Google sign-in
await sdk.auth.social.connect(SocialProvider.google);
// Apple sign-in
await sdk.auth.social.connect(SocialProvider.apple);
// Farcaster sign-in
await sdk.auth.social.connect(SocialProvider.farcaster);
Wallets
BaseWallet
Represents a user’s wallet.
class BaseWallet {
final String address; // Wallet address
final String chain; // "EVM" or "SOL"
final String? walletName; // Wallet name (optional)
final String? id; // Wallet ID for API operations (optional)
}
Properties
- address (String) - The wallet’s public address
- chain (String) - Blockchain type: “EVM” for Ethereum-compatible chains or “SOL” for Solana
- walletName (String?) - Human-readable name of the wallet provider (e.g., “MetaMask”, “Phantom”)
- id (String?) - Unique identifier for API operations like setPrimary
Example
final wallets = sdk.wallets.userWallets;
for (final wallet in wallets) {
print('Address: ${wallet.address}');
print('Chain: ${wallet.chain}');
print('Name: ${wallet.walletName}');
print('ID: ${wallet.id}');
}
Checking Wallet Type
final wallet = sdk.wallets.userWallets.first;
if (wallet.chain == 'EVM') {
// This is an Ethereum-compatible wallet
final client = sdk.evm.createPublicClient(chainId: 1);
// Perform EVM operations
} else if (wallet.chain == 'SOL') {
// This is a Solana wallet
final connection = sdk.solana.createConnection();
// Perform Solana operations
}
class WalletCard extends StatelessWidget {
final BaseWallet wallet;
WalletCard({required this.wallet});
@override
Widget build(BuildContext context) {
return Card(
child: ListTile(
leading: Icon(
wallet.chain == 'EVM' ? Icons.link : Icons.circle,
),
title: Text(
wallet.address.length > 20
? '${wallet.address.substring(0, 10)}...${wallet.address.substring(wallet.address.length - 8)}'
: wallet.address,
),
subtitle: Text('${wallet.chain} - ${wallet.walletName ?? "Unknown"}'),
trailing: wallet.id != null
? IconButton(
icon: Icon(Icons.star_border),
onPressed: () async {
await sdk.wallets.setPrimary(wallet.id!);
},
)
: null,
),
);
}
}
GenericNetwork
Represents a blockchain network.
class GenericNetwork {
final String name;
final int? chainId; // For EVM networks
final String? networkId; // For Solana networks
}
Properties
- name (String) - Human-readable network name
- chainId (int?) - Chain ID for EVM networks (null for Solana)
- networkId (String?) - Network ID for Solana networks (null for EVM)
Example
// EVM networks
final evmNetworks = sdk.networks.evm;
final ethereum = evmNetworks.firstWhere((n) => n.chainId == 1);
print('Network: ${ethereum.name}, Chain ID: ${ethereum.chainId}');
// Solana networks
final solanaNetworks = sdk.networks.solana;
final mainnet = solanaNetworks.firstWhere((n) => n.networkId == 'mainnet-beta');
print('Network: ${mainnet.name}, Network ID: ${mainnet.networkId}');
Common EVM Chain IDs
// Ethereum Mainnet
GenericNetwork(name: 'Ethereum', chainId: 1, networkId: null)
// Polygon
GenericNetwork(name: 'Polygon', chainId: 137, networkId: null)
// Arbitrum
GenericNetwork(name: 'Arbitrum', chainId: 42161, networkId: null)
// Optimism
GenericNetwork(name: 'Optimism', chainId: 10, networkId: null)
// Base
GenericNetwork(name: 'Base', chainId: 8453, networkId: null)
Common Solana Network IDs
// Mainnet
GenericNetwork(name: 'Mainnet', chainId: null, networkId: 'mainnet-beta')
// Devnet
GenericNetwork(name: 'Devnet', chainId: null, networkId: 'devnet')
// Testnet
GenericNetwork(name: 'Testnet', chainId: null, networkId: 'testnet')
EVM / Blockchain
EthereumTransaction
Transaction data for EVM chains.
class EthereumTransaction {
final String to; // Recipient address
final String value; // Amount in Wei (as String)
final int gasLimit; // Gas limit
final int? maxFeePerGas; // Max fee per gas (optional)
final int? maxPriorityFeePerGas; // Priority fee (optional)
final String? data; // Contract data (optional)
}
Properties
- to (String) - Recipient address (0x prefixed hex string)
- value (String) - Amount to send in Wei (as String to handle large numbers)
- gasLimit (int) - Maximum gas units allowed for the transaction
- maxFeePerGas (int?) - Maximum total fee per gas unit (optional, for EIP-1559)
- maxPriorityFeePerGas (int?) - Maximum priority fee per gas unit (optional, for EIP-1559)
- data (String?) - Encoded contract call data (optional)
Example
final transaction = EthereumTransaction(
to: '0x1234567890123456789012345678901234567890',
value: '1000000000000000', // 0.001 ETH in Wei
gasLimit: 21000,
maxFeePerGas: 30000000000,
maxPriorityFeePerGas: 2000000000,
);
Converting ETH to Wei
// Helper function to convert ETH to Wei
String ethToWei(double eth) {
final wei = (eth * 1e18).toStringAsFixed(0);
return wei;
}
// Usage
final transaction = EthereumTransaction(
to: recipientAddress,
value: ethToWei(0.001), // 0.001 ETH
gasLimit: 21000,
);
Input for writing to a smart contract.
class WriteContractInput {
final String address; // Contract address
final String functionName; // Function to call
final List<dynamic> args; // Function arguments
final List<Map<String, dynamic>> abi; // Contract ABI
}
Properties
- address (String) - Smart contract address
- functionName (String) - Name of the function to call
- args (
List<dynamic>) - Function arguments in order
- abi (
List<Map<String, dynamic>>) - Contract ABI definition
Example
final input = WriteContractInput(
address: '0x...',
functionName: 'transfer',
args: ['0x...', '1000000000000000000'], // recipient, amount
abi: [
{
'inputs': [
{'name': 'recipient', 'type': 'address'},
{'name': 'amount', 'type': 'uint256'},
],
'name': 'transfer',
'outputs': [
{'name': '', 'type': 'bool'},
],
'stateMutability': 'nonpayable',
'type': 'function',
},
],
);
ERC20 Transfer Example
class Erc20Helper {
static const transferAbi = [
{
'inputs': [
{'name': 'recipient', 'type': 'address'},
{'name': 'amount', 'type': 'uint256'},
],
'name': 'transfer',
'outputs': [
{'name': '', 'type': 'bool'},
],
'stateMutability': 'nonpayable',
'type': 'function',
},
];
static WriteContractInput createTransfer({
required String tokenAddress,
required String recipient,
required String amount,
}) {
return WriteContractInput(
address: tokenAddress,
functionName: 'transfer',
args: [recipient, amount],
abi: transferAbi,
);
}
}
// Usage
final input = Erc20Helper.createTransfer(
tokenAddress: '0x...',
recipient: '0x...',
amount: '1000000000000000000', // 1 token with 18 decimals
);
GasPrice
Current gas price information for EVM chains.
class GasPrice {
final int maxFeePerGas;
final int maxPriorityFeePerGas;
}
Properties
- maxFeePerGas (int) - Maximum total fee per gas unit (in Wei)
- maxPriorityFeePerGas (int) - Maximum priority fee per gas unit (in Wei)
Example
final client = sdk.evm.createPublicClient(chainId: 1);
final gasPrice = await client.getGasPrice();
print('Max fee: ${gasPrice.maxFeePerGas}');
print('Priority fee: ${gasPrice.maxPriorityFeePerGas}');
Converting Gas Price to Gwei
double weiToGwei(int wei) {
return wei / 1e9;
}
// Usage
final gasPrice = await client.getGasPrice();
print('Max fee: ${weiToGwei(gasPrice.maxFeePerGas)} Gwei');
print('Priority fee: ${weiToGwei(gasPrice.maxPriorityFeePerGas)} Gwei');
BlockhashResult
Solana blockhash information.
class BlockhashResult {
final String blockhash;
final int lastValidBlockHeight;
}
Properties
- blockhash (String) - Recent blockhash for transaction creation
- lastValidBlockHeight (int) - Last block height at which the blockhash is valid
Example
final connection = sdk.solana.createConnection();
final result = await connection.getLatestBlockhash();
print('Blockhash: ${result.blockhash}');
print('Valid until block: ${result.lastValidBlockHeight}');
MFA
MfaDevice
Represents an MFA device.
class MfaDevice {
final String? id;
final MfaDeviceType? type;
}
enum MfaDeviceType {
totp,
}
Properties
- id (String?) - Unique device identifier
- type (MfaDeviceType?) - Type of MFA device (currently only TOTP)
Example
final devices = await sdk.mfa.getUserDevices();
for (final device in devices) {
print('Device ID: ${device.id}');
print('Type: ${device.type?.name}');
}
MfaAddDevice
Response when adding an MFA device.
class MfaAddDevice {
final String secret; // Secret for QR code generation
final String? id;
}
Properties
- secret (String) - Secret key for TOTP QR code generation
- id (String?) - Device identifier
Example
final device = await sdk.mfa.addDevice('totp');
print('Secret for QR code: ${device.secret}');
// Generate QR code with the secret
// Format: otpauth://totp/YourApp:user@example.com?secret=${device.secret}&issuer=YourApp
final qrData = 'otpauth://totp/MyApp:user@example.com?secret=${device.secret}&issuer=MyApp';
QR Code Generation Example
import 'package:qr_flutter/qr_flutter.dart';
class MfaQrCode extends StatelessWidget {
final MfaAddDevice device;
final String userEmail;
MfaQrCode({required this.device, required this.userEmail});
@override
Widget build(BuildContext context) {
final qrData = 'otpauth://totp/MyApp:$userEmail?secret=${device.secret}&issuer=MyApp';
return Column(
children: [
QrImageView(
data: qrData,
version: QrVersions.auto,
size: 200.0,
),
SizedBox(height: 16),
Text('Scan with your authenticator app'),
SizedBox(height: 8),
SelectableText(
device.secret,
style: TextStyle(fontFamily: 'monospace'),
),
],
);
}
}
MfaCreateToken
Parameters for MFA token creation.
class MfaCreateToken {
final bool singleUse;
}
Properties
- singleUse (bool) - Whether the token should be single-use
Example
final createToken = MfaCreateToken(singleUse: true);
final token = await sdk.mfa.authenticateDevice(
code: '123456',
deviceId: deviceId,
createMfaToken: createToken,
);
Passkeys
UserPasskey
Represents a user’s passkey.
class UserPasskey {
final String id;
final String createdAt; // ISO format
final String? lastUsedAt; // ISO format (optional)
final bool? isDefault;
}
Properties
- id (String) - Unique passkey identifier
- createdAt (String) - Creation timestamp in ISO 8601 format
- lastUsedAt (String?) - Last usage timestamp in ISO 8601 format (optional)
- isDefault (bool?) - Whether this is the default passkey
Example
final passkeys = await sdk.passkeys.getPasskeys();
for (final passkey in passkeys) {
print('ID: ${passkey.id}');
print('Created: ${passkey.createdAt}');
print('Last used: ${passkey.lastUsedAt}');
print('Is default: ${passkey.isDefault}');
}
import 'package:intl/intl.dart';
String formatPasskeyDate(String isoDate) {
final date = DateTime.parse(isoDate);
final formatter = DateFormat('MMM dd, yyyy HH:mm');
return formatter.format(date);
}
// Usage
final passkey = passkeys.first;
print('Created: ${formatPasskeyDate(passkey.createdAt)}');
if (passkey.lastUsedAt != null) {
print('Last used: ${formatPasskeyDate(passkey.lastUsedAt!)}');
}
class PasskeyListItem extends StatelessWidget {
final UserPasskey passkey;
final VoidCallback onDelete;
PasskeyListItem({required this.passkey, required this.onDelete});
String formatDate(String isoDate) {
final date = DateTime.parse(isoDate);
final formatter = DateFormat('MMM dd, yyyy');
return formatter.format(date);
}
@override
Widget build(BuildContext context) {
return Card(
child: ListTile(
leading: Icon(
Icons.fingerprint,
color: passkey.isDefault == true ? Colors.blue : Colors.grey,
),
title: Text('Passkey ${passkey.id.substring(0, 8)}...'),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Created: ${formatDate(passkey.createdAt)}'),
if (passkey.lastUsedAt != null)
Text('Last used: ${formatDate(passkey.lastUsedAt!)}'),
if (passkey.isDefault == true)
Text(
'Default',
style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
),
],
),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: onDelete,
),
),
);
}
}
PasskeyAuthenticationResponse
Response from passkey MFA authentication.
class PasskeyAuthenticationResponse {
final String? jwt; // MFA token
}
Properties
- jwt (String?) - JWT token for MFA operations
Example
final response = await sdk.passkeys.authenticatePasskeyMFA(
createMfaToken: MfaCreateToken(singleUse: true),
relatedOriginRpId: null,
);
print('MFA Token: ${response.jwt}');
Error Handling
All SDK methods that can fail will throw exceptions. Use standard Dart error handling:
try {
await sdk.auth.email.verifyOTP(code);
} catch (e) {
print('Error: $e');
}
For async operations in widgets:
Future<void> performOperation() async {
try {
final wallets = sdk.wallets.userWallets;
// Process wallets
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed: $e')),
);
}
}
Common Error Patterns
class ErrorHandler {
static void handle(BuildContext context, dynamic error) {
String message = 'An error occurred';
if (error is TimeoutException) {
message = 'Request timed out';
} else if (error is FormatException) {
message = 'Invalid data format';
} else if (error.toString().contains('network')) {
message = 'Network error';
} else if (error.toString().contains('auth')) {
message = 'Authentication failed';
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
),
);
}
}
// Usage
try {
await sdk.auth.email.verifyOTP(code);
} catch (e) {
ErrorHandler.handle(context, e);
}