zetrix_connect_wallet_sdk 1.0.1 copy "zetrix_connect_wallet_sdk: ^1.0.1" to clipboard
zetrix_connect_wallet_sdk: ^1.0.1 copied to clipboard

A Flutter package for integrating Zetrix blockchain wallet connectivity and operations.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:zetrix_connect_wallet_sdk/zetrix_connect_wallet_sdk.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Zetrix SDK Dapp Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late ZetrixWalletConnect _walletConnect;
  String _sessionId = 'Not connected';
  String _deviceInfo = 'Unknown';
  String _address = 'Unknown';
  String _lastResult = 'No operation performed yet';
  bool _useCustomQrUi = false; // Toggle for custom QR UI

  @override
  void initState() {
    super.initState();
    _initializeWallet();
    _loadDeviceInfo();
    _loadSession();
  }

  /// Initialize wallet based on custom QR toggle
  void _initializeWallet() {
    _walletConnect = ZetrixWalletConnect(
      testnet: false,
      qrcode: true,
      appType: 'zetrix',
      isCustomQrUi: _useCustomQrUi,
      qrDataCallback: _useCustomQrUi ? _showCustomQrDialog : null,
    );
  }

  /// Show custom QR code dialog
  void _showCustomQrDialog(String qrContent) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => _CustomQrDialog(
        qrContent: qrContent,
        onClose: () => Navigator.of(context).pop(),
      ),
    );
  }

  Future<void> _loadDeviceInfo() async {
    try {
      final info = await DeviceUtils.getDeviceInfo();
      final appInfo = await DeviceUtils.getAppInfo();
      setState(() {
        _deviceInfo = '${info['model']} (${info['platform']}) - App: ${appInfo['appName']} (${appInfo['packageName']})';
      });
    } catch (e) {
      setState(() {
        _deviceInfo = 'Error: $e';
      });
    }
  }

  Future<void> _loadSession() async {
    final sessionId = await StorageUtils.getSessionId();
    final address = await StorageUtils.getAddress();
    setState(() {
      _sessionId = sessionId ?? 'Not connected';
      _address = address ?? 'Unknown';
    });
  }

  Future<void> _connectWallet() async {
    try {
      final connectResult = await _walletConnect.connect();
      final storedSessionId = await StorageUtils.getSessionId();
      final storedAddress = await StorageUtils.getAddress();

      setState(() {
        if (storedSessionId != null && storedAddress != null) {
          _sessionId = storedSessionId;
          _address = storedAddress;
        } else {
          _sessionId = 'Connected (ready for auth)';
        }
      });
    } catch (e) {
      setState(() {
        _sessionId = 'Connection failed: $e';
      });
    }
  }

  Future<void> _authWallet() async {
    try {
      final authResult = await _walletConnect.auth(context);
      if (authResult['code'] == 0) {
        // Close custom QR dialog if it's open
        if (_useCustomQrUi && Navigator.canPop(context)) {
          Navigator.of(context).pop();
        }

        setState(() {
          _sessionId = authResult['data']['sessionId'] ?? 'Authenticated (no session ID)';
          _address = authResult['data']['address'] ?? 'No address returned';
        });
      } else {
        setState(() {
          _sessionId = 'Auth failed: ${authResult['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _sessionId = 'Auth failed: $e';
      });
    }
  }

  Future<void> _authAndSignMessage() async {
    try {
      final result = await _walletConnect.authAndSignMessage(
        context,
        {'message': 'Auth and sign in one step!'},
      );

      if (result['code'] == 0) {
        // Close custom QR dialog if it's open
        if (_useCustomQrUi && Navigator.canPop(context)) {
          Navigator.of(context).pop();
        }

        setState(() {
          _sessionId = result['data']['sessionId'] ?? 'Authenticated';
          _address = result['data']['address'] ?? 'No address returned';
          _lastResult = 'AuthAndSignMessage Success:\nSessionId: ${result['data']['sessionId']}\nAddress: ${result['data']['address']}\nPublicKey: ${result['data']['publicKey']}\nSignData: ${result['data']['signData']}';
        });
      } else {
        setState(() {
          _lastResult = 'AuthAndSignMessage Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'AuthAndSignMessage Error: $e';
      });
    }
  }

  Future<void> _disconnectWallet() async {
    _walletConnect.closeConnect();
    _walletConnect.disconnect();
    setState(() {
      _sessionId = 'Not connected';
      _address = 'Unknown';
      _lastResult = 'Disconnected';
    });
  }

  Future<void> _signMessage() async {
    try {
      final result = await _walletConnect.signMessage({
        'message': 'Hello from Zetrix SDK Flutter!',
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'SignMessage Success:\nAddress: ${result['data']['address']}\nPublicKey: ${result['data']['publicKey']}\nSignData: ${result['data']['signData']}';
        });
      } else {
        setState(() {
          _lastResult = 'SignMessage Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'SignMessage Error: $e';
      });
    }
  }

  Future<void> _signBlob() async {
    try {
      final result = await _walletConnect.signBlob({
        'message': 'AAAAAAbcdef',
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'SignBlob Success:\nAddress: ${result['data']['address']}\nPublicKey: ${result['data']['publicKey']}\nSignData: ${result['data']['signData']}';
        });
      } else {
        setState(() {
          _lastResult = 'SignBlob Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'SignBlob Error: $e';
      });
    }
  }

  Future<void> _getNonce() async {
    try {
      if (_address == 'Unknown' || _address.isEmpty) {
        setState(() {
          _lastResult = 'GetNonce Failed: Please authenticate first';
        });
        return;
      }

      final result = await _walletConnect.getNonce({
        'address': _address,
        'chainId': '1',
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'GetNonce Success:\nNonce: ${result['data']['nonce']}';
        });
      } else {
        setState(() {
          _lastResult = 'GetNonce Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'GetNonce Error: $e';
      });
    }
  }

  Future<void> _sendTransaction() async {
    try {
      if (_address == 'Unknown' || _address.isEmpty) {
        setState(() {
          _lastResult = 'SendTransaction Failed: Please authenticate first';
        });
        return;
      }

      // First get nonce
      final nonceResult = await _walletConnect.getNonce({
        'address': _address,
        'chainId': '1',
      });

      if (nonceResult['code'] != 0) {
        setState(() {
          _lastResult = 'SendTransaction Failed: Could not get nonce';
        });
        return;
      }

      final nonce = nonceResult['data']['nonce'];

      final result = await _walletConnect.sendTransaction({
        'from': _address,
        'to': 'ZTX3QkbTjJsc7xDbwRtuHn826cAYF79uKR3rt', // Example recipient
        'amount': '1', // 1 ZTX (in smallest unit)
        'gasFee': '0.0001',
        'nonce': nonce,
        'data': '',
        'chainId': '1',
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'SendTransaction Success:\nHash: ${result['data']['hash']}';
        });
      } else {
        setState(() {
          _lastResult = 'SendTransaction Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'SendTransaction Error: $e';
      });
    }
  }

  Future<void> _verifyVC() async {
    try {
      if (_address == 'Unknown' || _address.isEmpty) {
        setState(() {
          _lastResult = 'VerifyVC Failed: Please authenticate first';
        });
        return;
      }

      final result = await _walletConnect.verifyVC({
        'templateId': 'example-template-id-123',
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'VerifyVC Success:\nStatus: ${result['data']['status']}\nDetails: ${result['data']['details']}';
        });
      } else {
        setState(() {
          _lastResult = 'VerifyVC Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'VerifyVC Error: $e';
      });
    }
  }

  Future<void> _getVP() async {
    try {
      if (_address == 'Unknown' || _address.isEmpty) {
        setState(() {
          _lastResult = 'GetVP Failed: Please authenticate first';
        });
        return;
      }

      final result = await _walletConnect.getVP({
        'templateId': 'example-template-id-456',
        'attributes': ['name', 'email', 'phone'],
      });

      if (result['code'] == 0) {
        setState(() {
          _lastResult = 'GetVP Success:\nUUID: ${result['data']['uuid']}';
        });
      } else {
        setState(() {
          _lastResult = 'GetVP Failed: ${result['message']}';
        });
      }
    } catch (e) {
      setState(() {
        _lastResult = 'GetVP Error: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Zetrix SDK Example'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Custom QR UI Toggle
            Card(
              color: Colors.deepPurple.shade50,
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Row(
                  children: [
                    Container(
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: Colors.deepPurple,
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: const Icon(
                        Icons.qr_code_2,
                        color: Colors.white,
                        size: 24,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: const [
                          Text(
                            'Custom QR Code UI',
                            style: TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                              color: Colors.deepPurple,
                            ),
                          ),
                          SizedBox(height: 4),
                          Text(
                            'Toggle to use custom QR code display',
                            style: TextStyle(fontSize: 12),
                          ),
                        ],
                      ),
                    ),
                    Switch(
                      value: _useCustomQrUi,
                      activeColor: Colors.deepPurple,
                      onChanged: (value) {
                        setState(() {
                          _useCustomQrUi = value;
                          // Reinitialize wallet with new settings
                          _initializeWallet();
                        });
                      },
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 24),

            Text('Device: $_deviceInfo'),
            const SizedBox(height: 16),
            Text('Session: $_sessionId'),
            const SizedBox(height: 16),
            Text('Address: $_address'),
            const SizedBox(height: 32),

            // Connection Section
            const Text(
              'Connection:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _connectWallet,
                    child: const Text('Connect'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: _authWallet,
                    child: const Text('Auth'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: _disconnectWallet,
                    child: const Text('Disconnect'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: _authAndSignMessage,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.orange,
                ),
                child: const Text('Auth & Sign Message'),
              ),
            ),
            const SizedBox(height: 24),

            // Signing Section
            const Text(
              'Signing Operations:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _signMessage,
                    child: const Text('Sign Message'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: _signBlob,
                    child: const Text('Sign Blob'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Transaction Section
            const Text(
              'Transaction Operations:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _getNonce,
                    child: const Text('Get Nonce'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: _sendTransaction,
                    child: const Text('Send Transaction'),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Verifiable Credentials Section
            const Text(
              'Verifiable Credentials:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _verifyVC,
                    child: const Text('Verify VC'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: _getVP,
                    child: const Text('Get VP'),
                  ),
                ),
              ],
            ),

            const SizedBox(height: 32),

            // Last Result Section
            const Text(
              'Last Result:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Container(
              width: double.infinity,
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[200],
                borderRadius: BorderRadius.circular(8),
              ),
              child: Text(
                _lastResult,
                style: const TextStyle(fontSize: 12, fontFamily: 'monospace'),
              ),
            ),

            const SizedBox(height: 32),
            const Text(
              'SDK Features:',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            const Text('• Wallet Connection via WebSocket'),
            const Text('• Secure Storage'),
            const Text('• Device Information'),
            const Text('• QR Code Generation (Built-in & Custom)'),
            const Text('• App Linking'),
            const Text('• Cryptographic Utilities'),
          ],
        ),
      ),
    );
  }
}

/// Custom QR Code Dialog Widget
///
/// This widget demonstrates a custom-styled QR code dialog
/// that you can customize to match your app's branding.
class _CustomQrDialog extends StatelessWidget {
  final String qrContent;
  final VoidCallback onClose;

  const _CustomQrDialog({
    required this.qrContent,
    required this.onClose,
  });

  @override
  Widget build(BuildContext context) {
    return Dialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(20),
      ),
      child: Container(
        padding: const EdgeInsets.all(24),
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [Colors.deepPurple.shade50, Colors.white],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
          borderRadius: BorderRadius.circular(20),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // Custom branding icon
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.deepPurple,
                borderRadius: BorderRadius.circular(50),
              ),
              child: const Icon(
                Icons.account_balance_wallet,
                size: 32,
                color: Colors.white,
              ),
            ),
            const SizedBox(height: 16),

            // Title
            const Text(
              'Connect Your Wallet',
              style: TextStyle(
                fontSize: 22,
                fontWeight: FontWeight.bold,
                color: Colors.deepPurple,
              ),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 8),

            // Instructions
            const Text(
              'Scan this QR code with your Zetrix Wallet app to connect',
              style: TextStyle(
                fontSize: 14,
                color: Colors.grey,
              ),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 20),

            // QR Code
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(12),
                boxShadow: [
                  BoxShadow(
                    color: Colors.grey.withOpacity(0.2),
                    spreadRadius: 2,
                    blurRadius: 5,
                  ),
                ],
              ),
              child: QrImageView(
                data: qrContent,
                version: QrVersions.auto,
                size: 220.0,
                backgroundColor: Colors.white,
              ),
            ),
            const SizedBox(height: 16),

            // Waiting text
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(
                  width: 16,
                  height: 16,
                  child: CircularProgressIndicator(
                    strokeWidth: 2,
                    color: Colors.deepPurple.withOpacity(0.5),
                  ),
                ),
                const SizedBox(width: 8),
                Text(
                  'Waiting for wallet to scan...',
                  style: TextStyle(
                    fontSize: 12,
                    color: Colors.grey.withOpacity(0.7),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 20),

            // Cancel button
            SizedBox(
              width: double.infinity,
              child: OutlinedButton(
                onPressed: onClose,
                style: OutlinedButton.styleFrom(
                  side: const BorderSide(color: Colors.deepPurple),
                  padding: const EdgeInsets.symmetric(vertical: 12),
                ),
                child: const Text(
                  'Cancel',
                  style: TextStyle(color: Colors.deepPurple),
                ),
              ),
            ),

            const SizedBox(height: 12),

            // QR Data format info
            Container(
              padding: const EdgeInsets.all(8),
              decoration: BoxDecoration(
                color: Colors.grey.shade100,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Text(
                'QR Data Format: {rms}&{sessionId}&{type}',
                style: TextStyle(
                  fontSize: 10,
                  color: Colors.grey.shade600,
                  fontFamily: 'monospace',
                ),
                textAlign: TextAlign.center,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
12
downloads

Documentation

API reference

Publisher

verified publisherdev.zetrix.com

Weekly Downloads

A Flutter package for integrating Zetrix blockchain wallet connectivity and operations.

Homepage

License

MIT (license)

Dependencies

crypto, device_info_plus, dio, flutter, flutter_secure_storage, logging, package_info_plus, qr_flutter, url_launcher

More

Packages that depend on zetrix_connect_wallet_sdk