Flutter插件singularity_flutter的使用方法详解
Flutter插件singularity_flutter的使用方法详解
您可以将singularity sdk集成到Flutter应用中,以轻松实现登录流程和钱包集成。
SigularitySDKProtocol
实现此协议以获取回调。
onGetSingularityUserInfo
此回调在成功登录后触发。参数中会以json字符串的形式返回登录用户的详细信息。
您还可以随时从SharedPreferences中获取用户详细信息,使用SingularityUser
作为键。
[@override](/user/override)
onGetSingularityUserInfo(Map user) {
}
从SharedPreferences中获取用户详细信息:
final prefs = await SharedPreferences.getInstance();
final Map user = prefs.getString('SingularityUser'); // 对于iOS返回的是map,对于Android返回的是Json字符串
onSingularityClose
当点击关闭图标或按下返回按钮时会触发此回调。
[@override](/user/override)
onSingularityClose() {
}
onSingularityLogout
成功注销后会触发此回调,并且会从SharedPreferences中删除用户详细信息。
[@override](/user/override)
onSingularityLogout() {
}
onSingularityError
发生任何错误时会触发此回调。
[@override](/user/override)
onSingularityError(String msg) {
}
openLoginScreen
您可以调用此函数来开始登录流程或打开个人资料页面。
参数:
key
- 提供用户密钥作为字符串singularityConfig
- 提供配置详情作为map
_gamepay.openLoginScreen(key: '<your_key>', singularityConfig: {'environment': 0}); // 将'environment'设置为0表示测试环境,1表示生产环境
完整示例代码
以下是一个完整的示例代码,展示了如何使用singularity_flutter
插件。
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hex/hex.dart';
import 'package:singularity_flutter/SingularityFlutter.dart';
import 'package:uuid/uuid.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> implements SigularitySDKProtocol, SingularityInitCallback {
/// 初始化SingularityFlutter变量
late SingularityFlutter _gamepay;
late TextEditingController _controller;
late TextEditingController _personalMessageController;
late TextEditingController _transactionAmountController;
late TextEditingController _signTransactionController;
late TextEditingController _signAndSendTransactionController;
String selectedValue = '800011'; // 存储选择的值
[@override](/user/override)
void initState() {
super.initState();
_controller = TextEditingController();
_personalMessageController = TextEditingController();
_transactionAmountController = TextEditingController();
_signTransactionController = TextEditingController();
_signAndSendTransactionController = TextEditingController();
_controller.text = "2";
_personalMessageController.text = "Some message";
_transactionAmountController.text = "0.001";
_signTransactionController.text = '{"value":100000000000000,"to":"0xCA4511435F99dcbf3Ab7cba04C8A16721eB7b894"}';
_signAndSendTransactionController.text = '{"value":100000000000000,"to":"0xCA4511435F99dcbf3Ab7cba04C8A16721eB7b894"}';
/// 初始化SingularityFlutter
_gamepay = SingularityFlutter(this);
}
[@override](/user/override)
void dispose() {
_controller.dispose();
_personalMessageController.dispose();
_transactionAmountController.dispose();
_signTransactionController.dispose();
_signAndSendTransactionController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
final List<Map<String, dynamic>> dropdownItems = [
{ 'value': '800011', 'label': 'USDC Mumbai' },
{ 'value': '800010', 'label': 'MATIC Mumbai' },
{ 'value': '970', 'label': 'BNB BSC Testnet' },
{ 'value': '973', 'label': 'BUSD BSC Testnet' },
{ 'value': '560', 'label': 'BNB BSC Mainnet' },
{ 'value': '563', 'label': 'BUSD BSC Mainnet' },
{ 'value': '564', 'label': 'RPG BSC Mainnet' },
{ 'value': '50', 'label': 'ETH on Goerli' },
{ 'value': '51', 'label': 'USDC on Goerli' },
{ 'value': '4200', 'label': 'ETH on Optimism Testnet' },
{ 'value': '4201', 'label': 'USDC on Optimism Testnet' },
{ 'value': '99810', 'label': 'ETH on Caldera Goerli Appchain' },
{ 'value': '99811', 'label': 'USDC on Caldera Goerli Appchain' },
{ 'value': '2220', 'label': 'ETH on Conduit Goerli Appchain' },
{ 'value': '2221', 'label': 'USDC on Conduit Goerli Appchain' },
{ 'value': '93720', 'label': 'OAS on Oasys Testnet' },
{ 'value': '93721', 'label': 'USDC on Oasys Testnet' },
{ 'value': '295480', 'label': 'OAS on MCH Verse Mainnet' },
{ 'value': '295481', 'label': 'USDC on MCH Verse Mainnet' },
{ 'value': '201970', 'label': 'OAS on SAND Verse' },
{ 'value': '201971', 'label': 'USDC on SAND Verse' },
{ 'value': '408750', 'label': 'OAS on Home Verse Testnet' },
{ 'value': '408751', 'label': 'USDC on Home Verse Testnet' },
{ 'value': '431130', 'label': 'Avax on Avalanche Fuji testnet' },
{ 'value': '431131', 'label': 'USDC on Avalanche Fuji testnet' },
{ 'value': '431140', 'label': 'Avax on Avalanche Mainnet' },
{ 'value': '431141', 'label': 'USDC on Avalanche Mainnet' },
{ 'value': '431147', 'label': 'LODE on Avalanche Mainnet' },
{ 'value': '431148', 'label': 'AGX on Avalanche Mainnet' },
{ 'value': '431149', 'label': 'AUX on Avalanche Mainnet' },
{ 'value': '1370', 'label': 'MATIC Mainnet' },
{ 'value': '1371', 'label': 'USDC Mainnet' },
{ 'value': '974', 'label': 'RPG BSC Testnet' },
{ 'value': '539350', 'label': 'JEWEL on DFK Mainnet' },
{ 'value': '539351', 'label': 'USDC on DFK Mainnet' },
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Neobrix'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Enter api key ", style: TextStyle(fontSize: 16),),
],
),
TextField(
controller: _controller,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
ElevatedButton(onPressed: () async {
// 初始化SingularityFlutter
var apiKey = _controller.text;
try{
_gamepay.initializeSingularity(apiKey, this);
}
catch(e){
Fluttertoast.showToast(
msg: "Invalid Input",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
textColor: Colors.white,
fontSize: 16.0
);
}
}, child: Text("Initialize Singularity")),
ElevatedButton(onPressed: () async {
_gamepay.openDrawer();
}, child: Text("Open Drawer")),
ElevatedButton(onPressed: () async {
_gamepay.closeDrawer();
}, child: Text("Close Drawer")),
ElevatedButton(onPressed: () async {
_gamepay.logoutUser();
}, child: Text("Logout User")),
ElevatedButton(onPressed: () async {
var userInfo = await _gamepay.getUserInfo();
showAlertDialog(context, "onGetSingularityUserInfo", userInfo.toString());
}, child: Text("Get User Info")),
const Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Enter Message", style: TextStyle(fontSize: 16),),
],
),
TextField(
controller: _personalMessageController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
ElevatedButton(onPressed: () async {
// 请求个人签名
var message = _personalMessageController.text;
try{
var sign = await _gamepay.requestPersonalSignature(message);
showAlertDialog(context, "Personal Message Signed", sign.toString());
}
catch(e){
Fluttertoast.showToast(
msg: "Invalid Input",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
textColor: Colors.white,
fontSize: 16.0
);
}
}, child: Text("Request personal sign")),
ElevatedButton(onPressed: () async {
String domainString = '{"name":"GamePay","version":"1","chainId":97,"verifyingContract":"0xED975dB5192aB41713f0080E7306E08188e53E7f"}';
String typesString = '{"bid":[{"name":"bidder","type":"address"},{"name":"collectableId","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"nounce","type":"uint"}]}';
String messageString = '{"bidder":"0xAa81f641d4b3546F05260F49DEc69Eb0314c47De","collectableId":1,"amount":100,"nounce":1}';
String primaryType = 'bid';
Map<String, dynamic> domain = json.decode(domainString);
Map<String, dynamic> types = json.decode(typesString);
Map<String, dynamic> message = json.decode(messageString);
try{
var sign = await _gamepay.requestTypedSignature(domain, primaryType, types, message);
showAlertDialog(context, "Typed Message Signed", sign.toString());
}
catch(e){ }
}, child: Text("Handle Typed Message Sign")),
DropdownButton<String>(
value: selectedValue, // 当前选中的值
onChanged: (String? newValue) {
setState(() {
selectedValue = newValue!; // 更新选中的值
});
},
items: dropdownItems.map((item) {
return DropdownMenuItem<String>(
value: item['value'],
child: Text(item['label']), // 显示标签
);
}).toList(),
),
const Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Enter Amount", style: TextStyle(fontSize: 16),),
],
),
TextField(
controller: _transactionAmountController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
ElevatedButton(onPressed: () async {
// 开始交易
var amount = _transactionAmountController.text;
try{
var uuid = Uuid();
var uuidv4 = uuid.v4();
var txnObject = {
'clientReferenceId': uuidv4,
'singularityTransactionType': 'RECEIVE',
'transactionLabel': 'Demo flutter label',
'transactionDescription': 'Description',
'transactionIconLink': 'https://singularity-icon-assets.s3.ap-south-1.amazonaws.com/currency/lode.svg',
'clientReceiveObject': {
'clientRequestedAssetQuantity': amount,
'clientRequestedAssetId': selectedValue
}
};
const secret = 'SSk49aq1/kQ1eKH7Sg+u4JsisvrycRcLopHdM6lNEMVe/p7lsSVoRiY0neFYNJkHoWVEK30bPAV2pNU2WwOJXQ==';
var requestString = jsonEncode(txnObject);
final hmacSha512 = Hmac(sha512, utf8.encode(secret)); // 创建一个带有秘钥的HMAC-SHA512对象
final signatureBytes = hmacSha512.convert(utf8.encode(requestString)).bytes; // 计算HMAC-SHA512哈希
final signature = HEX.encode(signatureBytes); // 将哈希转换为十六进制字符串
_gamepay.transactionFlow(requestString, signature);
// const signature = Hex.stringify(hmacSHA512(requestString, secret));
// window.SingularityEvent.transactionFlow(requestString, signature);
}
catch(e){
Fluttertoast.showToast(
msg: "Invalid Input",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
textColor: Colors.white,
fontSize: 16.0
);
}
}, child: Text("Start transaction")),
TextField(
controller: _signAndSendTransactionController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
ElevatedButton(onPressed: () async {
try{
var txnDataString = _signAndSendTransactionController.text;
var userData = await _gamepay.getUserInfo();
var publicAddress = userData['metaData']['wallet']['accounts']['evmPublicAddress'][0]['publicAddress'];
var signature = await _gamepay.signAndSendTransaction(txnDataString);
showAlertDialog(context, 'Sign and send result', signature.toString());
}
catch(e){
debugPrint('Error: ' + e.toString());
}
}, child: Text("Test Sign and send transaction")),
TextField(
controller: _signTransactionController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
ElevatedButton(onPressed: () async {
try{
var txnDataString = _signTransactionController.text;
var userData = await _gamepay.getUserInfo();
var publicAddress = userData['metaData']['wallet']['accounts']['evmPublicAddress'][0]['publicAddress'];
var signature = await _gamepay.signTransaction(txnDataString);
showAlertDialog(context, 'Sign result', signature.toString());
}
catch(e){
debugPrint('Error: ' + e.toString());
}
}, child: Text("Test Sign transaction")),
],
)
),
);
}
showAlertDialog(BuildContext context, String title, String content) {
Widget okButton = TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.pop(context);
},
);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(content),
),
actions: [okButton],
);
});
}
/// 登录成功后的Sigularity委托方法
[@override](/user/override)
onGetSingularityUserInfo(Map user) {
showAlertDialog(context, "onGetSingularityUserInfo", user.toString());
}
/// 用户点击关闭或返回按钮时的Sigularity委托方法
[@override](/user/override)
onSingularityClose() {
showAlertDialog(context, "Alert", "Drawer Closed");
}
/// 注销成功后的Sigularity委托方法
[@override](/user/override)
onSingularityLogout() {
showAlertDialog(context, "Alert", "User logged out");
}
[@override](/user/override)
onSingularityInitialized() {
showAlertDialog(context, "Alert", "Singularity Initialized");
}
[@override](/user/override)
onSingularityError(String message) {
}
}
更多关于Flutter插件singularity_flutter的使用方法详解的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter插件singularity_flutter的使用方法详解的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
singularity_flutter
是一个 Flutter 插件,它可能提供了一些未知的或实验性的功能,帮助开发者在 Flutter 应用中实现某些特定的需求。由于这个插件的知名度不高,或者可能是某个开发者或团队创建的自定义插件,因此使用它之前需要仔细阅读其文档和源代码。
以下是一个探索和使用 singularity_flutter
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 singularity_flutter
插件的依赖。假设你已经找到了这个插件的包名和版本号,可以像这样添加依赖:
dependencies:
flutter:
sdk: flutter
singularity_flutter: ^1.0.0 # 假设版本号为 1.0.0
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 singularity_flutter
插件:
import 'package:singularity_flutter/singularity_flutter.dart';
3. 探索插件的功能
由于 singularity_flutter
是一个未知的插件,你可能需要查看其文档或源代码来了解它提供的功能。通常,插件会提供一些类、方法或 Widget,你可以通过这些来实现特定的功能。
假设 singularity_flutter
提供了一个名为 SingularityWidget
的 Widget,你可以这样使用它:
class MyHomePage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Singularity Flutter Example'),
),
body: Center(
child: SingularityWidget(
// 传递必要的参数
onEvent: (event) {
print('Event received: $event');
},
),
),
);
}
}