bridge.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:polkawallet_sdk/service/bridgeRunner.dart';
  4. import 'package:polkawallet_sdk/service/index.dart';
  5. class ServiceBridge {
  6. ServiceBridge(this.serviceRoot);
  7. final SubstrateService serviceRoot;
  8. BridgeRunner? _runner;
  9. ///For multiple use at the same time
  10. int _retainCount = 0;
  11. Future<void> init({String? jsCode}) async {
  12. final c = Completer();
  13. if (_runner == null) {
  14. _runner = BridgeRunner();
  15. await _runner?.launch(() {
  16. if (!c.isCompleted) c.complete();
  17. }, jsCode: jsCode);
  18. } else {
  19. await _runner?.reload();
  20. if (!c.isCompleted) c.complete();
  21. }
  22. _retainCount++;
  23. return c.future;
  24. }
  25. Future<void> dispose() async {
  26. _retainCount--;
  27. if (_retainCount > 0) return;
  28. _runner?.dispose();
  29. _runner = null;
  30. }
  31. Future<List<String>> getFromChainsAll() async {
  32. assert(_runner != null, 'bridge not init');
  33. final res = await _runner?.evalJavascript('bridge.getFromChainsAll()');
  34. return List<String>.from(res);
  35. }
  36. Future<List<Map>> getRoutes() async {
  37. assert(_runner != null, 'bridge not init');
  38. final res = await _runner?.evalJavascript('bridge.getRoutes()');
  39. return List<Map>.from(res);
  40. }
  41. Future<Map> getChainsInfo() async {
  42. assert(_runner != null, 'bridge not init');
  43. final Map res = await _runner?.evalJavascript('bridge.getChainsInfo()');
  44. return res;
  45. }
  46. Future<String?> _checkConnection(String chain) async {
  47. final api = await _runner?.evalJavascript(
  48. 'Promise.all([bridge.getApi("$chain")&&bridge.getApi("$chain").isConnected])')
  49. as List;
  50. return api[0] == true ? chain : null;
  51. }
  52. Future<List<String>> connectFromChains(List<String> chains,
  53. {Map<String, List<String>>? nodeList}) async {
  54. assert(_runner != null, 'bridge not init');
  55. final list =
  56. await Future.wait(chains.map((e) => _checkConnection(e)).toList());
  57. final nonNullList =
  58. list.where((element) => element != null).toList() as List<String>;
  59. chains.removeWhere((element) => nonNullList.contains(element));
  60. if (chains.isEmpty) {
  61. return nonNullList;
  62. }
  63. final res = await _runner?.evalJavascript(
  64. 'bridge.connectFromChains(${jsonEncode(chains)}, ${nodeList == null ? 'undefined' : jsonEncode(nodeList)})');
  65. return List<String>.from(res) + nonNullList;
  66. }
  67. Future<void> disconnectFromChains() async {
  68. assert(_runner != null, 'bridge not init');
  69. if (_retainCount > 0) return;
  70. await _runner?.evalJavascript('bridge.disconnectFromChains()');
  71. }
  72. Future<Map> getNetworkProperties(String chain) async {
  73. assert(_runner != null, 'bridge not init');
  74. final Map res =
  75. await _runner?.evalJavascript('bridge.getNetworkProperties("$chain")');
  76. return res;
  77. }
  78. Future<void> subscribeBalances(
  79. String chain, String address, Function(Map) callback) async {
  80. assert(_runner != null, 'bridge not init');
  81. final msgChannel = '${chain}BridgeTokenBalances$address';
  82. final code =
  83. 'bridge.subscribeBalances("$chain", "$address", "$msgChannel")';
  84. _runner?.subscribeMessage(code, msgChannel, callback);
  85. }
  86. Future<void> unsubscribeBalances(String chain, String address) async {
  87. assert(_runner != null, 'bridge not init');
  88. _runner?.unsubscribeMessage('${chain}BridgeTokenBalances$address');
  89. }
  90. Future<Map> getAmountInputConfig(String from, String to, String token,
  91. String address, String signer) async {
  92. assert(_runner != null, 'bridge not init');
  93. final Map res = await _runner?.evalJavascript(
  94. 'bridge.getInputConfig("$from", "$to", "$token", "$address", "$signer")');
  95. return res;
  96. }
  97. Future<Map> getTxParams(String from, String to, String token, String address,
  98. String amount, int decimals, String signer) async {
  99. assert(_runner != null, 'bridge not init');
  100. final Map res = await _runner?.evalJavascript(
  101. 'bridge.getTxParams("$from", "$to", "$token", "$address", "$amount", $decimals, "$signer")');
  102. return res;
  103. }
  104. Future<String> estimateTxFee(
  105. String chainFrom, String txHex, String sender) async {
  106. assert(_runner != null, 'bridge not init');
  107. final String res = await _runner?.evalJavascript(
  108. 'bridge.estimateTxFee("$chainFrom", "$txHex", "$sender")');
  109. return res;
  110. }
  111. Future<Map?> sendTx(String chainFrom, Map txInfo, String password,
  112. String msgId, Map keyring) async {
  113. assert(_runner != null, 'bridge not init');
  114. final String pairs = jsonEncode(keyring);
  115. final dynamic res = await _runner?.evalJavascript(
  116. 'bridge.sendTx("$chainFrom", ${jsonEncode(txInfo)},"$password","$msgId",$pairs)');
  117. if (res?['error'] != null) {
  118. throw Exception(res?['error']);
  119. }
  120. return res;
  121. }
  122. void subscribeReloadAction(String reloadKey, Function reloadAction) {
  123. _runner?.subscribeReloadAction(reloadKey, reloadAction);
  124. }
  125. void unsubscribeReloadAction(String reloadKey) {
  126. _runner?.unsubscribeReloadAction(reloadKey);
  127. }
  128. int getEvalJavascriptUID() {
  129. return _runner?.getEvalJavascriptUID() ?? 0;
  130. }
  131. void addMsgHandler(String channel, Function onMessage) {
  132. _runner?.addMsgHandler(channel, onMessage);
  133. }
  134. void removeMsgHandler(String channel) {
  135. _runner?.removeMsgHandler(channel);
  136. }
  137. Future<bool> checkPassword(Map keyring, String? pubKey, pass) async {
  138. final String pairs = jsonEncode(keyring);
  139. final res = await _runner
  140. ?.evalJavascript('bridge.checkPassword($pairs,"$pubKey", "$pass")');
  141. if (res == null) {
  142. return false;
  143. }
  144. return true;
  145. }
  146. Future<bool> checkAddressFormat(String address, int ss58) async {
  147. final bool? res = await _runner
  148. ?.evalJavascript('bridge.checkAddressFormat("$address", $ss58)');
  149. return res ?? true;
  150. }
  151. Future<void> reload() async {
  152. return _runner?.reload();
  153. }
  154. Future<dynamic> evalJavascript(String code) async {
  155. return await _runner?.evalJavascript(code);
  156. }
  157. }