uos.dart 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:polkawallet_sdk/service/index.dart';
  4. /// Steps to complete offline-signature as a cold-wallet:
  5. /// 1. parseQrCode: parse raw data of QR code, and get signer address from it.
  6. /// 2. signAsync: sign the extrinsic with password, get signature.
  7. /// 3. addSignatureAndSend: send tx with address of step1 & signature of step2.
  8. ///
  9. /// Support offline-signature as a hot-wallet: makeQrCode
  10. class ServiceUOS {
  11. ServiceUOS(this.serviceRoot);
  12. final SubstrateService serviceRoot;
  13. /// parse data of QR code.
  14. /// @return: { signer: <pubKey>, genesisHash: <genesisHash> } [Map]
  15. Future<Map<String, dynamic>> parseQrCode(List keyPairs, String data) async {
  16. final res = await serviceRoot.webView!
  17. .evalJavascript('keyring.parseQrCode("$data")');
  18. if (res['error'] != null) {
  19. throw Exception(res['error']);
  20. }
  21. final pubKeyAddressMap = await (serviceRoot.account
  22. .decodeAddress([res['signer']]) as FutureOr<Map<dynamic, dynamic>>);
  23. final pubKey = pubKeyAddressMap.keys.toList()[0];
  24. final accIndex = keyPairs.indexWhere((e) => e['pubKey'] == pubKey);
  25. if (accIndex < 0) {
  26. throw Exception('signer: ${res['signer']} not found.');
  27. }
  28. return Map<String, dynamic>.from({
  29. ...res,
  30. 'signer': pubKey,
  31. });
  32. }
  33. /// this function must be called after parseQrCode.
  34. /// @return: signature [String]
  35. Future<String?> signAsync(String chain, password) async {
  36. final res = await serviceRoot.webView!
  37. .evalJavascript('keyring.signAsync("$chain", "$password")');
  38. if (res['error'] != null) {
  39. throw Exception(res['error']);
  40. }
  41. return res['signature'];
  42. }
  43. Future<Map?> addSignatureAndSend(
  44. String address,
  45. signed,
  46. Function(String) onStatusChange,
  47. ) async {
  48. final msgId =
  49. "onStatusChange${serviceRoot.webView!.getEvalJavascriptUID()}";
  50. serviceRoot.webView!.addMsgHandler(msgId, onStatusChange);
  51. final dynamic res = await serviceRoot.webView!.evalJavascript(
  52. 'keyring.addSignatureAndSend(api, "$address", "$signed")');
  53. serviceRoot.webView!.removeMsgHandler(msgId);
  54. return res;
  55. }
  56. Future<Map?> makeQrCode(Map txInfo, List params,
  57. {String? rawParam, int? ss58}) async {
  58. String param = rawParam != null ? rawParam : jsonEncode(params);
  59. final dynamic res = await serviceRoot.webView!.evalJavascript(
  60. 'keyring.makeTx(api, ${jsonEncode(txInfo)}, $param, $ss58)',
  61. );
  62. return res;
  63. }
  64. }