keyringEth.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import 'dart:convert';
  2. import 'package:polkawallet_sdk/api/types/addressIconData.dart';
  3. import 'package:polkawallet_sdk/ethers/apiEthers.dart';
  4. import 'package:polkawallet_sdk/service/index.dart';
  5. import 'package:polkawallet_sdk/storage/keyringEVM.dart';
  6. const default_derive_path = "m/44'/60'/0'/0/0";
  7. class ServiceKeyringEth {
  8. ServiceKeyringEth(this.serviceRoot);
  9. final SubstrateService serviceRoot;
  10. Future<void> injectKeyPairsToWebView(KeyringEVM keyring) async {
  11. if (keyring.store.list.length > 0) {
  12. final String pairs = jsonEncode(keyring.store.list);
  13. serviceRoot.webView!.evalJavascript('eth.keyring.initKeys($pairs)');
  14. }
  15. }
  16. /// Generate a set of new mnemonic.
  17. Future<AddressIconDataWithMnemonic> generateMnemonic(
  18. {int? index, String? mnemonic}) async {
  19. final dynamic acc = await serviceRoot.webView!
  20. .evalJavascript('eth.keyring.gen("$mnemonic",$index)');
  21. return AddressIconDataWithMnemonic.fromJson(acc);
  22. }
  23. /// get address and avatar from mnemonic.
  24. Future<dynamic> addressFromMnemonic(
  25. {String? derivePath, required String mnemonic}) async {
  26. final dynamic acc = await serviceRoot.webView!.evalJavascript(
  27. 'eth.keyring.addressFromMnemonic("$mnemonic","${derivePath ?? default_derive_path}")');
  28. return acc;
  29. }
  30. /// get address and avatar from privateKey.privateKey: string
  31. Future<dynamic> addressFromPrivateKey({required String privateKey}) async {
  32. final dynamic acc = await serviceRoot.webView!
  33. .evalJavascript('eth.keyring.addressFromPrivateKey("$privateKey")');
  34. return acc;
  35. }
  36. /// Import keyPair from mnemonic, privateKey or keystore.
  37. /// keyType: string, key: string, derivePath: string, password: string
  38. Future<Map> importAccount({
  39. required EVMKeyType keyType,
  40. required String key,
  41. required String name,
  42. required String password,
  43. String derivePath = default_derive_path,
  44. }) async {
  45. // generate json from js-api
  46. final String type = keyType.toString().split('.')[1];
  47. if (type == "keystore") {
  48. key = key.replaceAll("\"", "\\\"");
  49. }
  50. String code =
  51. 'eth.keyring.recover("$type", "$key", "$derivePath", "$password")';
  52. code = code.replaceAll(RegExp(r'\t|\n|\r'), '');
  53. final Map acc = _formatAccountData(
  54. (await serviceRoot.webView!.evalJavascript(code)) ?? {});
  55. return {...acc, type: key, 'name': name};
  56. }
  57. /// check password of account
  58. Future<bool> checkPassword(
  59. {required String address, required String pass}) async {
  60. final res = await serviceRoot.webView!
  61. .evalJavascript('eth.keyring.checkPassword("$address", "$pass")');
  62. //An error Message is displayed if it fails :{ success: false, error: err.message }
  63. return res["success"];
  64. }
  65. /// change password of account
  66. Future<Map> changePassword(
  67. {required String address,
  68. required String passOld,
  69. required String passNew}) async {
  70. final res = await serviceRoot.webView!.evalJavascript(
  71. 'eth.keyring.changePassword("$address", "$passOld", "$passNew")');
  72. return _formatAccountData(res ?? {});
  73. }
  74. /// sign message with private key of an account.
  75. Future<dynamic> signMessage(
  76. {required String message,
  77. required String address,
  78. required String pass}) async {
  79. final res = await serviceRoot.webView!.evalJavascript(
  80. 'eth.keyring.signMessage("$message", "$address", "$pass")');
  81. return res;
  82. }
  83. /// get signer of a signature. so we can verify the signer.
  84. Future<Map> verifySignature(
  85. {required String message, required String signature}) async {
  86. final res = await serviceRoot.webView!.evalJavascript(
  87. 'eth.keyring.verifySignature("$message", "$signature")');
  88. return res;
  89. }
  90. Future<Map> transfer(
  91. {required String token,
  92. required double amount,
  93. required String to,
  94. required String sender,
  95. required String pass,
  96. required Map gasOptions,
  97. required Function(Map) onStatusChange}) async {
  98. final code =
  99. 'eth.keyring.transfer("$token", $amount, "$to", "$sender", "$pass", ${jsonEncode(gasOptions)})';
  100. print('send evm transfer:');
  101. print(code);
  102. final res = await serviceRoot.webView!.evalJavascript(code);
  103. if (res != null && res['hash'] != null) {
  104. serviceRoot.webView!.addMsgHandler(res['hash'], (Map res) {
  105. onStatusChange(res);
  106. if ((res['confirmNumber'] ?? -1) > 1) {
  107. serviceRoot.webView!.removeMsgHandler(res['hash']);
  108. }
  109. });
  110. }
  111. return res;
  112. }
  113. Future<int> estimateTransferGas(
  114. {required String token,
  115. required double amount,
  116. required String to,
  117. required String from}) async {
  118. final res = await serviceRoot.webView!.evalJavascript(
  119. 'eth.keyring.estimateTransferGas("$token", $amount, "$to", "$from")');
  120. return res ?? 200000;
  121. }
  122. Future<String?> getGasPrice() async {
  123. final res =
  124. await serviceRoot.webView!.evalJavascript('eth.keyring.getGasPrice()');
  125. return res;
  126. }
  127. Map _formatAccountData(Map acc) {
  128. final keystore = jsonDecode(acc['keystore'] ?? '{}');
  129. return {
  130. 'error': acc['error'],
  131. 'address': acc['address'],
  132. 'id': keystore['id'],
  133. 'version': keystore['version'],
  134. 'crypto': keystore['Crypto'] ?? keystore['crypto'],
  135. };
  136. }
  137. Future<List> renderEthRequest(Map payload) async {
  138. final List res = await serviceRoot.webView!.evalJavascript(
  139. 'eth.keyring.renderEthRequest(${jsonEncode(payload)})',
  140. wrapPromise: false);
  141. return res;
  142. }
  143. Future<Map> signEthRequest(
  144. Map payload, String address, String pass, Map gasOptions) async {
  145. final Map res = await serviceRoot.webView!.evalJavascript(
  146. 'eth.keyring.signEthRequest(${jsonEncode(payload)}, "$address", "$pass", ${jsonEncode(gasOptions)})');
  147. return res;
  148. }
  149. }