Flutter数字货币钱包管理插件lightspark_wallet的使用
Flutter数字货币钱包管理插件lightspark_wallet的使用
这是Lightspark Wallet Flutter SDK!查看示例项目以了解如何使用它,或者阅读以下内容开始使用。
注意: 目前尚未准备好用于生产环境。但您可以自由地在内部进行测试!
开始使用
要使用钱包SDK,首先需要将其作为依赖项安装到您的应用中:
注意: 这个命令在SDK的第一个版本发布之前无法工作!目前还未上线。
flutter pub add lightspark_wallet
然后,导入它并构造一个钱包客户端:
import 'package:lightspark_wallet/lightspark_wallet.dart';
final client = LightsparkWalletClient();
通过JWT进行身份验证
当前版本的SDK支持JWT(JSON Web Token)身份验证,适用于客户端使用。要进行身份验证,您需要使用您的Lightspark账户ID和由您自己的服务器分配给用户的JWT进行登录。
首先,您需要将您的账户公钥注册到Lightspark。您可以通过Lightspark账户设置页面完成此操作。您需要提供您想要用来签署JWT的账户的公钥。您可以使用以下命令生成密钥对:
openssl genrsa -out private.key 2048
这将生成一个名为private.key的私钥文件。然后,您可以使用以下命令生成公钥文件:
openssl rsa -in private.key -pubout -out public.key
接下来,您可以将公钥文件的内容复制到API令牌页面的“JWT公钥”字段中。同时,您还需要将私钥复制到您的服务器代码中(或存储在安全的密钥库或环境变量中),以便能够使用它来签署JWT。
接下来,您需要为用户创建一个JWT。您应该从后端暴露一个端点来创建这些令牌。例如,使用typescript+node服务器创建JWT:
import * as jwt from "jsonwebtoken";
// 创建包含JWT声明的JSON对象。
const claims = {
aud: "https://api.lightspark.com",
// 用户的唯一标识符。
sub: "511c7eb8-9afe-4f69-989a-8d1113a33f3d",
// 使用测试环境还是生产环境。
test: true,
iat: 1516239022,
// JWT的过期时间。
exp: 1799393363,
};
// 调用`jsonwebtoken`库的`sign()`方法,传入JSON对象和您的私钥。
const token = jwt.sign(claims, "your private key");
// 现在将token发送回客户端,以便他们可以使用它与Lightspark SDK进行身份验证。
现在在客户端,您可以使用JWT和您公司账户ID从账户设置页面登录:
await client.loginWithJWT(ACCOUNT_ID, jwt, SharedPreferencesJwtStorage());
您会注意到这个请求需要一个实现JwtStorage
的参数。这可以用于保存凭证以便下次启动应用时使用。如果您想使用保存的JWT信息恢复钱包凭证,可以在客户端构造函数中传递一个JWT存储实现。例如,如果您以前使用了SharedPreferencesJwtStorage
实现登录,您可以在应用启动时这样恢复凭证:
import 'package:lightspark_wallet/lightspark_wallet.dart';
final jwtStorage = SharedPreferencesJwtStorage();
final client = LightsparkWalletClient(authProvider: JwtAuthProvider(jwtStorage));
部署和初始化钱包
当用户首次登录时,他们的钱包初始状态为NOT_SETUP
。您可以通过查询当前钱包的状态来识别这种状态:
final wallet = await client.getCurrentWallet();
if (wallet.status == WalletStatus.NOT_SETUP) {
// 钱包未设置,因此我们需要部署它。
}
要部署钱包,您需要调用client.deployWallet()
,然后等待钱包状态更新为DEPLOYED或FAILED。您可以通过轮询钱包或通过订阅钱包更新来实现这一点。
这里是一个每2秒轮询钱包状态的示例:
var wallet = await client.deployWallet();
while (
wallet.status != WalletStatus.DEPLOYED &&
wallet.status != WalletStatus.FAILED
) {
await Future.delayed(const Duration(seconds: 2));
wallet = await client.getCurrentWallet();
}
// 现在钱包要么已部署,要么失败。
另一种方法是使用辅助函数deployWalletAndAwaitDeployed
:
final walletStatus = await client.deployWalletAndAwaitDeployed();
if (walletStatus == WalletStatus.DEPLOYED) {
// 钱包已部署!
} else {
// 钱包部署失败。
}
一旦钱包部署成功,您就可以初始化它了。但是,您首先需要签名密钥才能完成敏感操作。
钱包的密钥生成
初始化钱包时,您需要提供一个公钥供钱包用于签署交易。请注意,这与您上面使用的JWT签名密钥不同。它应该是每个用户的唯一密钥。确保您的应用程序安全地存储该密钥对。丢失私钥会导致用户失去对其钱包的访问权限。目前,钱包SDK仅支持RSA-PSS密钥,但我们计划在未来支持其他类型的密钥。
为了方便起见,钱包SDK提供了一个generateRsaKeyPair()
方法,可用于生成密钥对。然后,您可以按您希望的方式在应用程序代码中存储这些密钥。
import 'package:lightspark_wallet/lightspark_wallet.dart';
final keyPair = await generateRsaKeyPair();
const signingWalletPublicKey = keyPair.publicKey;
const signingWalletPrivateKey = keyPair.privateKey;
// 将密钥安全地存储起来。
初始化钱包
有了密钥之后,您就可以初始化钱包了!就像部署时一样,您可以通过轮询钱包或通过订阅钱包更新来完成。
var wallet = await client.initializeWallet(
KeyType.RSA_OAEP,
serializedPublicKey,
serializedPrivateKey
);
while (
wallet.status != WalletStatus.READY &&
wallet.status != WalletStatus.FAILED
) {
await Future.delayed(const Duration(seconds: 2));
wallet = await client.getCurrentWallet();
}
// 现在钱包要么已准备好,要么失败。
另一种方法是使用辅助函数initializeWalletAndAwaitReady
:
final walletStatus = await client.initializeWalletAndAwaitReady(
KeyType.RSA_OAEP,
serializedPublicKey,
serializedPrivateKey
);
if (walletStatus == WalletStatus.READY) {
// 钱包已初始化!
} else {
// 钱包初始化失败。
}
解锁钱包并发起请求
当钱包处于READY状态时,您可以发起请求。但是,为了完成像发送支付这样的敏感操作,您首先需要使用您之前生成的私钥解锁钱包。
await client.loadWalletSigningKey(serializedPublicKey, serializedPrivateKey);
现在您可以发起请求了!例如,创建一张发票:
final invoiceData = await client.createInvoice(
100_000,
memo: "mmmmm pizza",
);
或者支付发票:
final payment = await client.payInvoice(
/* 编码后的发票 */ invoiceData.encodedPaymentRequest,
/* 最大费用 */ 50_000
);
完整示例Demo
以下是一个完整的示例,展示了如何使用Lightspark Wallet插件:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:lightspark_wallet/lightspark_wallet.dart';
import 'package:lightspark_wallet_example/src/screens/account_screen.dart';
import 'package:lightspark_wallet_example/src/screens/login_screen.dart';
import 'package:provider/provider.dart';
import 'src/model/lightspark_client_notifier.dart';
import 'src/screens/home_screen.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => LightsparkClientNotifier(
LightsparkWalletClient(
authProvider: JwtAuthProvider(SecureStorageJwtStorage()),
),
),
child: const MyApp(),
),
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isLoggedIn = false;
int _selectedTabIndex = 0;
[@override](/user/override)
void didChangeDependencies() {
super.didChangeDependencies();
final client = Provider.of<LightsparkClientNotifier>(
context,
listen: false,
).value;
client.isAuthorized().then((value) {
setState(() {
_isLoggedIn = value;
});
});
}
Future<bool> _loginWithJwt(String accountId, String jwt) async {
final client = Provider.of<LightsparkClientNotifier>(
context,
listen: false,
).value;
final jwtAuthStorage = SecureStorageJwtStorage();
await client.loginWithJwt(
accountId,
jwt,
jwtAuthStorage,
);
final loggedIn = await client.isAuthorized();
setState(() {
_isLoggedIn = loggedIn;
});
return loggedIn;
}
Future<void> _logout() async {
final client = Provider.of<LightsparkClientNotifier>(
context,
listen: false,
).value;
final authProvider = JwtAuthProvider(
SecureStorageJwtStorage(),
);
await authProvider.logout();
client.setAuthProvider(authProvider);
setState(() {
_isLoggedIn = false;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.from(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blueGrey,
primary: Colors.black,
),
).copyWith(
appBarTheme: const AppBarTheme(
elevation: 1,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(minimumSize: const Size(105, 45)),
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(minimumSize: const Size(105, 45)),
),
),
home: _isLoggedIn
? _buildHomeScreen()
: LoginScreen(onLogin: _loginWithJwt),
);
}
Widget _buildHomeScreen() {
return Scaffold(
body: [
HomeScreen(onLogin: _loginWithJwt, onLogout: _logout),
AccountScreen(onLogin: _loginWithJwt, onLogout: _logout)
][_selectedTabIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedTabIndex,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.wallet),
label: 'Wallet',
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'Account',
),
],
onTap: (index) {
setState(() {
_selectedTabIndex = index;
});
},
),
);
}
}
更多关于Flutter数字货币钱包管理插件lightspark_wallet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数字货币钱包管理插件lightspark_wallet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用lightspark_wallet
插件来管理数字货币钱包的示例代码。请注意,实际使用时需要根据lightspark_wallet
插件的具体API文档进行调整,因为插件的接口和功能可能会随时间变化。
首先,确保你已经在pubspec.yaml
文件中添加了lightspark_wallet
依赖项:
dependencies:
flutter:
sdk: flutter
lightspark_wallet: ^最新版本号 # 替换为实际发布的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用lightspark_wallet
插件:
- 初始化插件并创建钱包
import 'package:flutter/material.dart';
import 'package:lightspark_wallet/lightspark_wallet.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String walletAddress = '';
@override
void initState() {
super.initState();
_initializeWallet();
}
Future<void> _initializeWallet() async {
try {
// 初始化LightSpark Wallet插件
await LightSparkWallet.initialize();
// 创建一个新的钱包(注意:这只是一个示例,实际使用中应确保钱包的安全存储和管理)
Wallet? newWallet = await LightSparkWallet.createWallet();
if (newWallet != null) {
setState(() {
walletAddress = newWallet.address;
});
}
} catch (e) {
print('Error initializing wallet: $e');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('LightSpark Wallet Example'),
),
body: Center(
child: Text('Your Wallet Address: $walletAddress'),
),
),
);
}
}
- 发送交易
在实际应用中,发送交易需要用户输入接收地址、金额等信息,并且需要处理私钥的安全问题。这里仅提供一个简化的示例:
Future<void> _sendTransaction(String recipientAddress, double amount) async {
try {
// 假设你已经有了要发送的金额和接收地址
TransactionRequest request = TransactionRequest(
recipient: recipientAddress,
amount: amount, // 注意:这里可能需要转换为最小单位,例如比特币的聪
// 其他参数,如gas费、手续费等,根据具体需求设置
);
// 发送交易
TransactionResult? result = await LightSparkWallet.sendTransaction(request);
if (result != null && result.success) {
print('Transaction sent successfully!');
} else {
print('Failed to send transaction: ${result?.errorMessage}');
}
} catch (e) {
print('Error sending transaction: $e');
}
}
- 查询余额
查询钱包余额同样需要处理网络请求和异步操作:
Future<void> _checkBalance() async {
try {
// 获取当前钱包的余额
BalanceResult? balance = await LightSparkWallet.getBalance();
if (balance != null) {
print('Balance: ${balance.amount}'); // 注意:这里的金额单位可能需要根据具体币种调整
} else {
print('Failed to get balance.');
}
} catch (e) {
print('Error checking balance: $e');
}
}
请注意,以上代码仅作为示例,并未包含完整的错误处理和用户交互逻辑。在实际开发中,你需要确保用户输入的验证、私钥的安全存储、交易的确认等关键步骤得到妥善处理。
此外,由于lightspark_wallet
插件的具体API和功能可能会变化,请参考插件的官方文档和示例代码进行开发。