Flutter XRP协议交互插件xrpl_dart的使用
Flutter XRP协议交互插件xrpl_dart的使用
XRPL Dart Package
这个包提供了全面的功能,用于使用两种主要的加密算法ED25519和SECP256K1对XRP交易进行签名。除了交易签名之外,它还支持各种功能,包括JSON-RPC、socket和HTTP交互。这种多功能性使开发人员能够安全地创建、签署和与XRP交易进行交互。
对于BIP32 HD钱包、BIP39和密钥存储定义,请参考blockchain_utils包。
功能
交易类型
XRP Ledger容纳了多种不同类型的交易,每种类型都有特定的目的。以下是一些示例:
- 支付交易:用于从一个地址向另一个地址发送XRP或发行。
- 托管交易:这些交易在满足某些条件之前锁定XRP,提供了一种无需信任的延迟支付方式。
- 信任线设置交易:用于创建或修改信任线,使用户能够在账本上持有和交易除XRP以外的资产。
- 订单簿交易:用于在XRP Ledger内的去中心化交易所中下单和取消订单。
- 支付通道交易:允许通过支付通道进行链下支付。
- NFT:铸造NFT、取消它们、创建报价并接受NFT报价。
- 发行:发行自定义资产。
- 自动做市商:投标、创建、删除、存款和投票操作。
- 常规密钥:设置或更新账户常规密钥的交易。
- 报价:创建和取消。
- 多重签名交易:需要多个签名进行验证的交易。
- 跨链账户创建提交:在一个桥梁连接的链上创建新账户。
- 跨链添加账户创建证明:交易提供见证服务器证明跨链账户创建提交交易在另一条链上发生。
- 跨链添加索赔证明:交易提供见证服务器证明跨链承诺交易。
- 跨链索赔:完成跨链价值转移的交易。
- 创建跨链桥:创建新的桥账本。
地址
- classAddress:这是XRP Ledger上收件人地址的简单表示形式。
- xAddress:较新的格式,提供额外的功能和互操作性。xAddresses默认包含目标标签,并设计用于简化跨网络交易和提高地址互操作性。
签名
- 使用ED25519和SECP256K1算法对XRP交易进行签名。
JSON-RPC支持
该包简化了使用JSON-RPC协议和WebSocket技术与XRP节点通信的过程。虽然已经努力将所有方法集成到RPC中,但重要的是要认识到目前大多数数据API以JSON格式呈现且尚未完全建模。WebSocket支持的增加增强了包在实时和异步与XRP节点交互方面的多功能性。
示例
密钥和地址
/// 创建随机私钥
final randomPrivate =
XRPPrivateKey.random(algorithm: CryptoAlgorithm.SECP256K1);
final toHex = randomPrivate.toHex();
/// 使用十六进制访问私钥
final private = XRPPrivateKey.fromHex(toHex);
/// 访问公钥
final publicKey = private.getPublic();
final addressClass = publicKey.toAddress();
/// 经典地址 rpjEqWDFtoin7fFxuw6oQG2onkZkf72hhc
final classicAddress = addressClass.address;
/// 新格式地址 X7ZBWLX4XnxEwvQa4sgH11QbhQzuTuGeoZKEb2naE92oNEc
final xAddress = addressClass.toXAddress(isTestNetwork: false);
/// 使用私钥签名
final sig = private.sign(...)
交易
每种交易类型都有专门的类用于交易创建。下面描述了一些这些类。请在examples文件夹中查看每个交易类型的训练示例。
- 简单支付
final transaction = Payment(
destination: destination, // 目标账户
account: ownerAddress, // 发送者账户
amount: amount, // 发送的金额可以是XRP或其他代币。
signingPubKey: ownerPublic); // 发送者的公钥
- NTF,铸造,创建报价,接受报价
// 铸造代币
final transaction = NFTokenMint(
flags: NFTokenMintFlag.TF_TRANSFERABLE.value,
account: ownerAddress,
uri: "...", // 指向与NFT关联的数据和/或元数据
signingPubKey: ownerPublic,
memos: [memo], // 附加到此交易的任意信息
nftokenTaxon: 1); // 表示与此代币关联的分类
// 创建报价
final offer = NFTokenCreateOffer(
amount: CurrencyAmount.xrp(BigInt.from(1000000)),
flags: NFTokenCreateOfferFlag.TF_SELL_NFTOKEN.value,
nftokenId: tokenId, /// 标识NFToken对象的TokenID
account: ownerAddress,
signingPubKey: ownerPublic,
memos: [memo],
);
// 接受报价
final offer = NFTokenAcceptOffer(
nfTokenSellOffer: offerId,
account: ownerAddress,
signingPubKey: ownerPublic,
memos: [memo],
);
- 完全创建、签名和发送交易
// 创建托管创建交易
final escrowCreate = EscrowCreate(
account: ownerAddress,
destination: destination,
cancelAfterTime: cancelAfterOnDay,
finishAfterTime: finishAfterOneHours,
amount: BigInt.from(25000000),
condition:
"A0258020E488CD4C1AC9A7673CA2D2712B47049B87C308181BF3B89D6FBB74FC36836BB5810120",
signingPubKey: ownerPublic,
memos: [memo],
);
// 它接收交易、RPC类,然后完成交易要求,包括费用金额、账户序列号和最后的网络账本序列号。
await autoFill(rpc, escrowCreate);
// 在这一点上,我们需要用发送者账户的私钥对交易进行签名。
// 我们接收交易blob并用发送者的私钥对其进行签名。
final sig = owner.sign(escrowCreate.toBlob());
// 完成签名后,我们将其添加到交易中。
escrowCreate.setSignature(sig);
/// 在最后一步,我们需要将交易发送到网络。
/// 我们接收另一个已包含签名的交易blob。此时不再需要包含签名,并且必须将'forSigning'变量设置为false。
final trBlob = escrowCreate.toBlob(forSigning: false);
// 广播交易
final result = await rpc.submit(trBlob)
// 交易哈希:result.txJson.hash ()
// 引擎结果:result.engineResult result.engineResult
// 引擎结果消息:result.engineResultMessage
JSON-RPC
请查看http_service和socket_service文件,了解如何创建HTTP/WEBSOCKET RPC服务。
- HTTP JSON RPC
/// 访问事件
final rpc = await XRPProvider.devNet((httpUri, websocketUri) async {
service = RPCHttpService(httpUri, http.Client());
return service!;
});
/// 同步
final syncRpc = XRPProvider(RPCHttpService(XRPProviderConst.devFaucetUrl, http.Client()));
await rpc.request(RPCFee());
await rpc.request(RPCServerInfo());
await rpc.request(RPCAccountInfo(account: "..."));
await rpc.request(RPCServerState());
await rpc.request(RPCServerDefinitions());
...
- WEBSOCKET JSON RPC
/// 访问事件
final rpc = await XRPProvider.devNet((httpUri, websocketUri) async {
service = await RPCWebSocketService.connect(websocketUri);
return service!;
});
await rpc.request(RPCFee());
await rpc.request(RPCServerInfo());
await rpc.request(RPCAccountInfo(account: "..."));
await rpc.request(RPCServerState());
await rpc.request(RPCServerDefinitions());
service?.disconnect();
...
- WEBSOCKET 订阅
/// 流事件处理函数
void onEvent(Map<String, dynamic> event) {}
void onClose(Object? err) {}
/// 访问事件
final rpc = await XRPProvider.mainnet((httpUri, websocketUri) async {
service = await RPCWebSocketService.connect(websocketUri,
onClose: onClose, onEvents: onEvent);
return service!;
});
/// 订阅
await rpc.request(RPCSubscribe(streams: [
StreamParameter.ledger,
]));
...
- 将RPC响应定制为您的规格。
/// 创建一个继承自XRPLedgerRequest的类,并根据您的需求定制它以处理账户NFT报价ID。这是一个示例:
class RPCAccountNftOffersIDs extends XRPLedgerRequest<List<String>> {
RPCAccountNftOffersIDs({
required this.account,
this.limit,
this.marker,
XRPLLedgerIndex? ledgerIndex = XRPLLedgerIndex.validated,
});
@override
String get method => XRPRequestMethod.accountNfts;
final String account;
final int? limit;
final dynamic marker;
@override
Map<String, dynamic> toJson() {
return {"account": account, "limit": limit, "marker": marker};
}
/// 覆盖`onResponse`方法以管理和处理来自RPC结果的期望结果。
@override
List<String> onResponse(Map<String, dynamic> result) {
final List<dynamic> nfts = result["account_nfts"];
return nfts.map<String>((e) => e["nft_offer_index"]).toList();
}
}
final syncRpc = XRPProvider(RPCHttpService(XRPProviderConst.devFaucetUrl, http.Client()));
final List<String> nftOfferIds =
await syncRpc.request(RPCAccountNftOffersIDs(account: "..."));
...
参与贡献
欢迎贡献!请遵循以下指南:
- Fork仓库并创建一个新分支。
- 进行更改并确保测试通过。
- 提交带有详细描述的拉取请求。
特性请求和错误
请在问题跟踪器中提交特性请求和错误报告。
示例代码
void main() {}
更多关于Flutter XRP协议交互插件xrpl_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter XRP协议交互插件xrpl_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用xrpl_dart
插件与XRP协议进行交互的代码示例。xrpl_dart
是一个Dart库,用于与XRP Ledger(Ripple协议)进行交互。
首先,确保你已经在pubspec.yaml
文件中添加了xrpl_dart
依赖:
dependencies:
flutter:
sdk: flutter
xrpl_dart: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来获取依赖。
接下来是一个简单的示例,展示如何使用xrpl_dart
来发送一个XRP交易。注意,这只是一个基础示例,实际使用中需要考虑更多的错误处理和安全性问题。
import 'package:flutter/material.dart';
import 'package:xrpl_dart/xrpl_dart.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String result = '';
@override
void initState() {
super.initState();
_sendXrp();
}
Future<void> _sendXrp() async {
// 配置XRPL客户端
final client = XRPLClient(
serverUrl: 'https://s.altnet.rippletest.net:51234/', // 测试网服务器URL
);
// 获取账户信息(假设你已经有一个测试网账户)
final accountInfo = await client.getAccountInfo('rXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); // 替换为你的账户地址
// 准备发送交易的账户信息
final account = Account(
classicAddress: 'rXXXXXXXXXXXXXXXXXXXXXXXXXXXX', // 替换为你的账户地址
secret: 'sXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', // 替换为你的账户密钥
);
// 目标账户地址
final destination = 'rYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'; // 替换为目标账户地址
// 交易详情
final payment = Payment(
account: account,
fee: '12', // 交易费用(drops)
sequence: accountInfo.sequence,
destination: destination,
amount: '1000000', // 发送的XRP数量(drops)
);
// 签名并提交交易
try {
final signedTransaction = await payment.sign();
final resultBlob = await client.submit(signedTransaction);
// 更新UI显示结果
setState(() {
result = 'Transaction submitted with result: $resultBlob';
});
} catch (e) {
// 更新UI显示错误
setState(() {
result = 'Error: ${e.message}';
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('XRPL Dart Example'),
),
body: Center(
child: Text(result),
),
),
);
}
}
注意事项:
- 安全性:在真实应用中,不要将账户密钥硬编码在代码中。应该使用安全存储方式,如Keystore或密钥管理服务。
- 错误处理:示例代码中的错误处理非常基础,实际应用中需要更完善的错误处理和用户反馈机制。
- 网络配置:测试网和生产网的环境配置不同,确保在发布应用前切换到正确的网络环境。
- 费用计算:交易费用可能会随着网络负载而变化,实际使用中应动态计算费用。
这个示例展示了如何使用xrpl_dart
库在Flutter应用中与XRP协议进行交互。希望这对你有所帮助!