ethWithJS.dart 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:polkawallet_sdk/api/types/addressIconData.dart';
  4. import 'package:polkawallet_sdk/ethers/apiEthers.dart';
  5. import 'package:polkawallet_sdk/polkawallet_sdk.dart';
  6. import 'package:polkawallet_sdk/storage/keyringEVM.dart';
  7. import 'package:polkawallet_sdk/storage/types/ethWalletData.dart';
  8. import 'package:polkawallet_sdk_example/pages/keyring.dart';
  9. class EthWithJSPage extends StatefulWidget {
  10. EthWithJSPage(this.sdk, this.keyring, this.showResult);
  11. final WalletSDK sdk;
  12. final KeyringEVM keyring;
  13. final Function(BuildContext, String, String) showResult;
  14. static const String route = '/keyring/eth/js';
  15. @override
  16. _EthWithJSPageState createState() => _EthWithJSPageState();
  17. }
  18. class _EthWithJSPageState extends State<EthWithJSPage> {
  19. final String _testJson = '''{
  20. "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "3be45c336ce8cd771061e3b5ec9460ec"}, "ciphertext": "b4e181f629e480d4073edfe6f0ad7bc8c201ac3975eb0232150e4550f59af1c0", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 8192, "r": 8, "p": 1, "salt": "4771ff99bf695bab6d292330678a800f8acb1831134678df45b6911fab94f38c"}, "mac": "ed5cec3eed91ab251650657cff87c693a2672413658ff7da4c2f38598f21984a"},
  21. "id": "3228f3c9-dfee-4e65-9569-5c8a7afc3921",
  22. "version": 3,
  23. "address": "0x4b248f45dfbea07de1bbd69180f6695b78250caf"
  24. }''';
  25. final String _testPass = 'a123456';
  26. final _testMsg = 'hello message for signing';
  27. EthWalletData? _testAcc;
  28. bool _submitting = false;
  29. Future<void> _generateMnemonic() async {
  30. setState(() {
  31. _submitting = true;
  32. });
  33. final AddressIconDataWithMnemonic seed =
  34. await widget.sdk.api.eth.keyring.generateMnemonic();
  35. widget.showResult(context, 'generateMnemonic', seed.mnemonic!);
  36. setState(() {
  37. _submitting = false;
  38. });
  39. }
  40. Future<void> _getAccountList() async {
  41. final List<EthWalletData> ls = widget.keyring.keyPairs;
  42. widget.showResult(
  43. context,
  44. 'getAccountList',
  45. JsonEncoder.withIndent(' ')
  46. .convert(ls.map((e) => '${e.name}: ${e.address}').toList()),
  47. );
  48. }
  49. Future<void> _getDecryptedSeed() async {
  50. if (_testAcc == null) {
  51. widget.showResult(
  52. context,
  53. 'getDecryptedSeeds',
  54. 'should import keyPair to init test account.',
  55. );
  56. return;
  57. }
  58. setState(() {
  59. _submitting = true;
  60. });
  61. final seed = await widget.sdk.api.eth.keyring
  62. .getDecryptedSeed(widget.keyring, _testPass);
  63. // await widget.sdk.evm.getDecryptedSeed(widget.keyring, 'a654321');
  64. widget.showResult(
  65. context,
  66. 'getDecryptedSeeds',
  67. seed == null
  68. ? 'null'
  69. : JsonEncoder.withIndent(' ').convert({
  70. 'address': _testAcc?.address,
  71. 'type': seed.type,
  72. 'seed': seed.seed,
  73. 'error': seed.error,
  74. }),
  75. );
  76. setState(() {
  77. _submitting = false;
  78. });
  79. }
  80. Future<void> _importFromMnemonic() async {
  81. setState(() {
  82. _submitting = true;
  83. });
  84. final json = await widget.sdk.api.eth.keyring.importAccount(
  85. keyType: EVMKeyType.mnemonic,
  86. key:
  87. 'wing know chapter eight shed lens mandate lake twenty useless bless glory',
  88. name: 'testName01',
  89. password: _testPass,
  90. );
  91. print(json);
  92. final acc = await widget.sdk.api.eth.keyring.addAccount(
  93. widget.keyring,
  94. keyType: EVMKeyType.mnemonic,
  95. acc: json!,
  96. password: _testPass,
  97. );
  98. widget.showResult(
  99. context,
  100. 'importFromMnemonic',
  101. JsonEncoder.withIndent(' ').convert(acc.toJson()),
  102. );
  103. setState(() {
  104. _submitting = false;
  105. _testAcc = acc;
  106. });
  107. }
  108. Future<void> _importFromPrivateKey() async {
  109. setState(() {
  110. _submitting = true;
  111. });
  112. final json = await widget.sdk.api.eth.keyring.importAccount(
  113. keyType: EVMKeyType.privateKey,
  114. key: '0x2defc5ff7c700eb3a39a702e9b38534e8ea3419b93b1836dc6ccc891ce359290',
  115. name: 'testName02',
  116. password: _testPass,
  117. );
  118. print(json);
  119. final acc = await widget.sdk.api.eth.keyring.addAccount(
  120. widget.keyring,
  121. keyType: EVMKeyType.privateKey,
  122. acc: json!,
  123. password: _testPass,
  124. );
  125. widget.showResult(
  126. context,
  127. 'importFromPrivateKey',
  128. JsonEncoder.withIndent(' ').convert(acc.toJson()),
  129. );
  130. setState(() {
  131. _submitting = false;
  132. _testAcc = acc;
  133. });
  134. }
  135. Future<void> _importFromKeystore() async {
  136. setState(() {
  137. _submitting = true;
  138. });
  139. final json = await widget.sdk.api.eth.keyring.importAccount(
  140. keyType: EVMKeyType.keystore,
  141. key: _testJson,
  142. name: 'testName03',
  143. password: _testPass,
  144. );
  145. final acc = await widget.sdk.api.eth.keyring.addAccount(
  146. widget.keyring,
  147. keyType: EVMKeyType.keystore,
  148. acc: json!,
  149. password: _testPass,
  150. );
  151. widget.showResult(
  152. context,
  153. 'importFromKeystore',
  154. JsonEncoder.withIndent(' ').convert(acc.toJson()),
  155. );
  156. setState(() {
  157. _submitting = false;
  158. _testAcc = acc;
  159. });
  160. }
  161. Future<void> _deleteAccount() async {
  162. if (_testAcc == null) {
  163. widget.showResult(
  164. context,
  165. 'deleteAccount',
  166. 'should import keyPair to init test account.',
  167. );
  168. return;
  169. }
  170. setState(() {
  171. _submitting = true;
  172. });
  173. await widget.sdk.api.eth.keyring.deleteAccount(widget.keyring, _testAcc!);
  174. widget.showResult(
  175. context,
  176. 'deleteAccount',
  177. 'ok',
  178. );
  179. setState(() {
  180. _submitting = false;
  181. });
  182. }
  183. Future<void> _checkPassword() async {
  184. if (_testAcc == null) {
  185. widget.showResult(
  186. context,
  187. 'checkPassword',
  188. 'should import keyPair to init test account.',
  189. );
  190. return;
  191. }
  192. setState(() {
  193. _submitting = true;
  194. });
  195. final bool passed = await widget.sdk.api.eth.keyring
  196. .checkPassword(_testAcc?.address ?? '', _testPass);
  197. // await widget.sdk.evm.checkPassword(_testAcc, 'a654321');
  198. widget.showResult(
  199. context,
  200. 'checkPassword',
  201. passed.toString(),
  202. );
  203. setState(() {
  204. _submitting = false;
  205. });
  206. }
  207. Future<void> _changePassword() async {
  208. if (_testAcc == null) {
  209. widget.showResult(
  210. context,
  211. 'changePassword',
  212. 'should import keyPair to init test account.',
  213. );
  214. return;
  215. }
  216. setState(() {
  217. _submitting = true;
  218. });
  219. final res = await widget.sdk.api.eth.keyring
  220. .changePassword(widget.keyring, _testPass, 'a654321');
  221. // .changePassword(widget.keyring, 'a654321', _testPass);
  222. widget.showResult(
  223. context,
  224. 'changePassword',
  225. res == null ? 'null' : JsonEncoder.withIndent(' ').convert(res.toJson()),
  226. );
  227. setState(() {
  228. _submitting = false;
  229. _testAcc = res;
  230. });
  231. }
  232. Future<void> _changeName() async {
  233. if (_testAcc == null) {
  234. widget.showResult(
  235. context,
  236. 'changeName',
  237. 'should import keyPair to init test account.',
  238. );
  239. return;
  240. }
  241. setState(() {
  242. _submitting = true;
  243. });
  244. final res =
  245. await widget.sdk.api.eth.keyring.changeName(widget.keyring, 'newName');
  246. widget.showResult(
  247. context,
  248. 'changeName', JsonEncoder.withIndent(' ').convert(res.toJson()),
  249. );
  250. setState(() {
  251. _submitting = false;
  252. });
  253. }
  254. Future<void> _signMessage() async {
  255. if (_testAcc == null) {
  256. widget.showResult(
  257. context,
  258. 'signMessage',
  259. 'should import keyPair to init test account.',
  260. );
  261. return;
  262. }
  263. setState(() {
  264. _submitting = true;
  265. });
  266. final res = await widget.sdk.api.eth.keyring
  267. .signMessage(_testPass, _testMsg, _testAcc?.address ?? '');
  268. widget.showResult(
  269. context,
  270. 'signMessage',
  271. res == null ? 'null' : JsonEncoder.withIndent(' ').convert(res.toJson()),
  272. );
  273. setState(() {
  274. _submitting = false;
  275. });
  276. }
  277. Future<void> _signatureVerify() async {
  278. if (_testAcc == null) {
  279. widget.showResult(
  280. context,
  281. 'signMessage',
  282. 'should import keyPair to init test account.',
  283. );
  284. return;
  285. }
  286. setState(() {
  287. _submitting = true;
  288. });
  289. final res = await widget.sdk.api.eth.keyring.signatureVerify(_testMsg,
  290. '0xded97a9a203f794a042bb71107523d685258a27f9df00634d782ba0bdb70be3808bff9ac1ef9bbfff474ef69fc2b613b6ae7b1956a83e2286136f8814993e8491c');
  291. widget.showResult(
  292. context,
  293. 'signatureVerify', JsonEncoder.withIndent(' ').convert(res),
  294. );
  295. setState(() {
  296. _submitting = false;
  297. });
  298. }
  299. @override
  300. void initState() {
  301. super.initState();
  302. WidgetsBinding.instance.addPostFrameCallback((_) {
  303. if (widget.keyring.keyPairs.length > 0) {
  304. setState(() {
  305. _testAcc = widget.keyring.keyPairs[0];
  306. });
  307. }
  308. });
  309. }
  310. @override
  311. Widget build(BuildContext context) {
  312. return Scaffold(
  313. appBar: AppBar(
  314. title: Text('keyring API'),
  315. ),
  316. body: SafeArea(
  317. child: ListView(
  318. children: [
  319. // Padding(
  320. // padding: EdgeInsets.all(16),
  321. // child: Column(
  322. // crossAxisAlignment: CrossAxisAlignment.start,
  323. // children: [
  324. // Text('address ss58Format: ${widget.keyring.ss58}'),
  325. // Row(
  326. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  327. // children: [
  328. // RaisedButton(
  329. // child: Text('Polkadot: 0'),
  330. // color:
  331. // _ss58 == 0 ? Theme.of(context).primaryColor : null,
  332. // onPressed: () => _setSS58(0),
  333. // ),
  334. // RaisedButton(
  335. // child: Text('Kusama: 2'),
  336. // color:
  337. // _ss58 == 2 ? Theme.of(context).primaryColor : null,
  338. // onPressed: () => _setSS58(2),
  339. // ),
  340. // RaisedButton(
  341. // child: Text('Substrate: 42'),
  342. // color:
  343. // _ss58 == 42 ? Theme.of(context).primaryColor : null,
  344. // onPressed: () => _setSS58(42),
  345. // )
  346. // ],
  347. // )
  348. // ],
  349. // ),
  350. // ),
  351. // Divider(),
  352. ListTile(
  353. title: Text('getAccountList'),
  354. subtitle: Text('''
  355. sdk.api.eth.keyring.accountList'''),
  356. trailing: SubmitButton(
  357. submitting: _submitting,
  358. call: _getAccountList,
  359. ),
  360. ),
  361. Divider(),
  362. ListTile(
  363. title: Text('generateMnemonic'),
  364. subtitle: Text('sdk.api.keyring.generateMnemonic()'),
  365. trailing: SubmitButton(
  366. submitting: _submitting,
  367. call: _generateMnemonic,
  368. ),
  369. ),
  370. Divider(),
  371. ListTile(
  372. title: Text('importFromMnemonic'),
  373. subtitle: Text('''
  374. sdk.api.eth.keyring.importAccount(
  375. keyType: KeyType.mnemonic,
  376. key: 'wing know chapter eight shed lens mandate lake twenty useless bless glory',
  377. name: 'testName01',
  378. password: 'a123456',
  379. )'''),
  380. trailing: SubmitButton(
  381. submitting: _submitting,
  382. call: _importFromMnemonic,
  383. ),
  384. ),
  385. Divider(),
  386. ListTile(
  387. title: Text('importFromPrivateKey'),
  388. subtitle: Text('''
  389. sdk.api.eth.keyring.importAccount(
  390. keyType: KeyType.privateKey,
  391. key: 'Alice',
  392. name: 'testName02',
  393. password: 'a123456',
  394. )'''),
  395. trailing: SubmitButton(
  396. submitting: _submitting,
  397. call: _importFromPrivateKey,
  398. ),
  399. ),
  400. Divider(),
  401. ListTile(
  402. title: Text('importFromKeystore'),
  403. subtitle: Text('''
  404. sdk.api.eth.keyring.importAccount(
  405. keyType: KeyType.keystore,
  406. key: '{xxx...xxx}',
  407. name: 'testName03',
  408. password: 'a123456',
  409. )'''),
  410. trailing: SubmitButton(
  411. submitting: _submitting,
  412. call: _importFromKeystore,
  413. ),
  414. ),
  415. Divider(),
  416. ListTile(
  417. title: Text('getDecryptedSeed'),
  418. subtitle: Text('''
  419. sdk.api.eth.keyring.getDecryptedSeed(
  420. '${_testAcc?.toString()}',
  421. 'a123456',
  422. )'''),
  423. trailing: SubmitButton(
  424. submitting: _submitting,
  425. call: _getDecryptedSeed,
  426. ),
  427. ),
  428. Divider(),
  429. ListTile(
  430. title: Text('deleteAccount'),
  431. subtitle: Text('''
  432. sdk.api.eth.keyring.deleteAccount'''),
  433. trailing: SubmitButton(
  434. submitting: _submitting,
  435. call: _deleteAccount,
  436. ),
  437. ),
  438. Divider(),
  439. ListTile(
  440. title: Text('checkPassword'),
  441. subtitle: Text('''
  442. sdk.api.eth.keyring.checkPassword(
  443. '${_testAcc?.toString()}',
  444. 'a123456',
  445. )'''),
  446. trailing: SubmitButton(
  447. submitting: _submitting,
  448. call: _checkPassword,
  449. ),
  450. ),
  451. Divider(),
  452. ListTile(
  453. title: Text('changePassword'),
  454. subtitle: Text('''
  455. sdk.api.eth.keyring.changePassword(
  456. '${_testAcc?.toString()}',
  457. 'a123456',
  458. 'a654321',
  459. )'''),
  460. trailing: SubmitButton(
  461. submitting: _submitting,
  462. call: _changePassword,
  463. ),
  464. ),
  465. Divider(),
  466. ListTile(
  467. title: Text('changeName'),
  468. subtitle: Text('''
  469. sdk.api.eth.keyring.changeName(
  470. '${_testAcc?.toString()}',
  471. 'newName',
  472. )'''),
  473. trailing: SubmitButton(
  474. submitting: _submitting,
  475. call: _changeName,
  476. ),
  477. ),
  478. Divider(),
  479. ListTile(
  480. title: Text('signMessage'),
  481. subtitle: Text('''
  482. sdk.api.eth.keyring.signMessage(
  483. '$_testPass',
  484. '$_testMsg',
  485. '${_testAcc?.toString()}'
  486. )'''),
  487. trailing: SubmitButton(
  488. submitting: _submitting,
  489. call: _signMessage,
  490. ),
  491. ),
  492. Divider(),
  493. ListTile(
  494. title: Text('signatureVerify'),
  495. subtitle: Text('''
  496. sdk.api.eth.keyring.signatureVerify(
  497. '$_testMsg',
  498. 'test signature',
  499. )'''),
  500. trailing: SubmitButton(
  501. submitting: _submitting,
  502. call: _signatureVerify,
  503. ),
  504. ),
  505. Divider(),
  506. ],
  507. ),
  508. ), // This trailing comma makes auto-formatting nicer for build methods.
  509. );
  510. }
  511. }