From 0ffe703c9e94666cf49d9f29469f33206dfc49af Mon Sep 17 00:00:00 2001 From: ciripel <37701673+ciripel@users.noreply.github.com> Date: Thu, 15 Sep 2022 17:48:29 +0300 Subject: [PATCH] Subtask/11 implement ethereum signing (#12) --- CHANGELOG.md | 2 + .../integration_tests/on_emulator_test.dart | 48 ++++++++++++ example/pubspec.lock | 73 ++++++++++++------- lib/sio_core_light.dart | 1 + lib/src/signing.dart | 53 ++++++++++++++ pubspec.yaml | 3 +- 6 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 lib/src/signing.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index a0262fd..fced33f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.3 +* Implement Ethereum message signing ## 1.1.2 * Fix: `Transaction` arguments non null-able ## 1.1.1 diff --git a/example/integration_tests/on_emulator_test.dart b/example/integration_tests/on_emulator_test.dart index 119ce5e..7affd45 100644 --- a/example/integration_tests/on_emulator_test.dart +++ b/example/integration_tests/on_emulator_test.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:bs58/bs58.dart'; import 'package:convert/convert.dart'; @@ -439,4 +440,51 @@ void main() { }); }); }); + + group('Ethereum Signing - ', () { + test('Test typeData return correct signature', () { + expect( + EthSign.typedData( + wallet: wallet, + networkId: TWCoinType.TWCoinTypeEthereum, + jsonData: + '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"verifyingContract","type":"address"}],"RelayRequest":[{"name":"target","type":"address"},{"name":"encodedFunction","type":"bytes"},{"name":"gasData","type":"GasData"},{"name":"relayData","type":"RelayData"}],"GasData":[{"name":"gasLimit","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"pctRelayFee","type":"uint256"},{"name":"baseRelayFee","type":"uint256"}],"RelayData":[{"name":"senderAddress","type":"address"},{"name":"senderNonce","type":"uint256"},{"name":"relayWorker","type":"address"},{"name":"paymaster","type":"address"}]},"domain":{"name":"GSN Relayed Transaction","version":"1","chainId":42,"verifyingContract":"0x6453D37248Ab2C16eBd1A8f782a2CBC65860E60B"},"primaryType":"RelayRequest","message":{"target":"0x9cf40ef3d1622efe270fe6fe720585b4be4eeeff","encodedFunction":"0xa9059cbb0000000000000000000000002e0d94754b348d208d64d52d78bcd443afa9fa520000000000000000000000000000000000000000000000000000000000000007","gasData":{"gasLimit":"39507","gasPrice":"1700000000","pctRelayFee":"70","baseRelayFee":"0"},"relayData":{"senderAddress":"0x22d491bde2303f2f43325b2108d26f1eaba1e32b","senderNonce":"3","relayWorker":"0x3baee457ad824c94bd3953183d725847d023a2cf","paymaster":"0x957F270d45e9Ceca5c5af2b49f1b5dC1Abb0421c"}}}', + ), + equals( + '0x6ee63a1fcfcd81c6d8c168a63e27eda62bf663495729fb3b2ad59ded9c1e41703a3f3597c4d1564c4ef0f56acef83b024af4a13099f4ebf1c608714736af4b5c1b')); + }); + test('Test personalTypeData return correct signature', () { + expect( + EthSign.personalTypedData( + wallet: wallet, + networkId: TWCoinType.TWCoinTypeEthereum, + jsonData: + '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"verifyingContract","type":"address"}],"RelayRequest":[{"name":"target","type":"address"},{"name":"encodedFunction","type":"bytes"},{"name":"gasData","type":"GasData"},{"name":"relayData","type":"RelayData"}],"GasData":[{"name":"gasLimit","type":"uint256"},{"name":"gasPrice","type":"uint256"},{"name":"pctRelayFee","type":"uint256"},{"name":"baseRelayFee","type":"uint256"}],"RelayData":[{"name":"senderAddress","type":"address"},{"name":"senderNonce","type":"uint256"},{"name":"relayWorker","type":"address"},{"name":"paymaster","type":"address"}]},"domain":{"name":"GSN Relayed Transaction","version":"1","chainId":42,"verifyingContract":"0x6453D37248Ab2C16eBd1A8f782a2CBC65860E60B"},"primaryType":"RelayRequest","message":{"target":"0x9cf40ef3d1622efe270fe6fe720585b4be4eeeff","encodedFunction":"0xa9059cbb0000000000000000000000002e0d94754b348d208d64d52d78bcd443afa9fa520000000000000000000000000000000000000000000000000000000000000007","gasData":{"gasLimit":"39507","gasPrice":"1700000000","pctRelayFee":"70","baseRelayFee":"0"},"relayData":{"senderAddress":"0x22d491bde2303f2f43325b2108d26f1eaba1e32b","senderNonce":"3","relayWorker":"0x3baee457ad824c94bd3953183d725847d023a2cf","paymaster":"0x957F270d45e9Ceca5c5af2b49f1b5dC1Abb0421c"}}}', + ), + equals( + '0xe742241a8d26e68ba86b854783bba9e8898996776788945a6ebbc6173a741ebb553ce9f41805b7815041dda4587c374591291a07473b9ae7050254ce2f7464ce1c')); + }); + test('Test message return correct signature', () { + expect( + EthSign.message( + wallet: wallet, + networkId: TWCoinType.TWCoinTypeEthereum, + message: Uint8List.fromList(hex.decode( + 'f737d8ba29fa34adf29b88785edca25c873d6fb2eaa4e77394cab27131fa3284')), + ), + equals( + '0xce929bf4483308f0e23752d43cb45def3bfafefdaba1b328d8121969ac303fd955acc4dd5520f585ee3691e04e0917f99360fa24a8280805ff25aa879fb83ae81c')); + }); + test('Test personalMessage return correct signature', () { + expect( + EthSign.personalMessage( + wallet: wallet, + networkId: TWCoinType.TWCoinTypeEthereum, + message: Uint8List.fromList(hex.decode( + '4d7920656d61696c206973206a6f686e40646f652e636f6d202d205468752c2031352053657020323032322031333a30383a313520474d54')), + ), + equals( + '0x2913768a701ea3bea19b5d61d4b70758bf6b805869dea9425edc18e2efa2aa5c61add9bef273d29b4633972a1f35cc5efec23d7c8aeab358efedc2024d555bb01b')); + }); + }); } diff --git a/example/pubspec.lock b/example/pubspec.lock index b5a3689..353010d 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -21,7 +21,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.11" + version: "3.3.0" args: dependency: transitive description: @@ -35,7 +35,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" base_x: dependency: transitive description: @@ -57,27 +57,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" - characters: + buffer: dependency: transitive description: - name: characters + name: buffer url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: + version: "1.1.1" + characters: dependency: transitive description: - name: charcode + name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.2.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -98,14 +98,14 @@ packages: name: coverage url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.5.0" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.0.2" cupertino_icons: dependency: "direct main" description: @@ -113,13 +113,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.5" + equatable: + dependency: transitive + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + eth_sig_util: + dependency: transitive + description: + name: eth_sig_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.9" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: transitive description: @@ -235,21 +249,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -277,7 +291,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" platform: dependency: transitive description: @@ -292,6 +306,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + pointycastle: + dependency: transitive + description: + name: pointycastle + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.2" pool: dependency: transitive description: @@ -354,7 +375,7 @@ packages: path: ".." relative: true source: path - version: "1.1.2" + version: "1.1.3" sky_engine: dependency: transitive description: flutter @@ -380,7 +401,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -401,42 +422,42 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" sync_http: dependency: transitive description: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test: dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.21.1" + version: "1.21.4" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.13" + version: "0.4.16" trust_wallet_core_lib: dependency: "direct main" description: @@ -450,7 +471,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: @@ -464,7 +485,7 @@ packages: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "8.2.2" + version: "9.0.0" watcher: dependency: transitive description: diff --git a/lib/sio_core_light.dart b/lib/sio_core_light.dart index 7b128aa..cc43863 100644 --- a/lib/sio_core_light.dart +++ b/lib/sio_core_light.dart @@ -2,4 +2,5 @@ export 'src/build_transaction.dart'; export 'src/exceptions.dart'; export 'src/mnemonic.dart'; export 'src/networks_groups.dart'; +export 'src/signing.dart'; export 'src/utils.dart'; diff --git a/lib/src/signing.dart b/lib/src/signing.dart new file mode 100644 index 0000000..4794918 --- /dev/null +++ b/lib/src/signing.dart @@ -0,0 +1,53 @@ +import 'dart:typed_data'; + +import 'package:eth_sig_util/eth_sig_util.dart'; +import 'package:trust_wallet_core_lib/trust_wallet_core_lib.dart'; + +class EthSign { + static String typedData({ + required HDWallet wallet, + required int networkId, + required String jsonData, + TypedDataVersion version = TypedDataVersion.V4, + }) { + return EthSigUtil.signTypedData( + privateKeyInBytes: wallet.getKeyForCoin(networkId).data(), + jsonData: jsonData, + version: version); + } + + static String personalTypedData({ + required HDWallet wallet, + required int networkId, + required String jsonData, + TypedDataVersion version = TypedDataVersion.V4, + }) { + return EthSigUtil.signPersonalTypedData( + privateKeyInBytes: wallet.getKeyForCoin(networkId).data(), + jsonData: jsonData, + version: version, + ); + } + + static String message({ + required HDWallet wallet, + required int networkId, + required Uint8List message, + }) { + return EthSigUtil.signMessage( + privateKeyInBytes: wallet.getKeyForCoin(networkId).data(), + message: message, + ); + } + + static String personalMessage({ + required HDWallet wallet, + required int networkId, + required Uint8List message, + }) { + return EthSigUtil.signPersonalMessage( + privateKeyInBytes: wallet.getKeyForCoin(networkId).data(), + message: message, + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 00e66fa..749cf0b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: sio_core_light description: Simplio wallet core library for building blockchain transactions, developed in Dart, can be used in Flutter framework. -version: 1.1.2 +version: 1.1.3 repository: https://github.com/SimplioOfficial/sio_core_light environment: @@ -9,6 +9,7 @@ environment: dependencies: convert: ^3.0.2 + eth_sig_util: ^0.0.9 fixnum: ^1.0.1 flutter: sdk: flutter