From cd96a345ad36682f5ae5b5151cd61e20a0637790 Mon Sep 17 00:00:00 2001 From: vjrj <vjrj@comunes.org> Date: Sat, 27 Apr 2024 16:59:23 +0200 Subject: [PATCH] More v2 methods and tests --- lib/g1/g1_v2_helper.dart | 37 ++++++++++++++++-- test/g1_v2_test.dart | 84 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 8 deletions(-) diff --git a/lib/g1/g1_v2_helper.dart b/lib/g1/g1_v2_helper.dart index daf04fb3..ffca0fa6 100644 --- a/lib/g1/g1_v2_helper.dart +++ b/lib/g1/g1_v2_helper.dart @@ -42,6 +42,13 @@ String addressFromV1Pubkey(String pubkey) { return address; } +String v1pubkeyFromAddress(String address) { + final Keyring keyring = Keyring(); + final Uint8List publicKeyBytes = keyring.decodeAddress(address); + final String publicKey = Base58Encode(publicKeyBytes); + return publicKey; +} + Keyring keyringFromV1Seed(Uint8List seed) { final Keyring keyring = Keyring(); final KeyPair keypair = KeyPair.ed25519.fromSeed(seed); @@ -79,9 +86,10 @@ class AuthData { Future<KeyPair> createPair(AuthData data, Keyring keyring) async { if (data.v1 != null) { - final Uint8List passwordU8a = - Uint8List.fromList(data.v1!.password.codeUnits); - final Uint8List saltU8a = Uint8List.fromList(data.v1!.salt.codeUnits); + final List<int> password = data.v1!.password.codeUnits; + final String salt = data.v1!.salt; + final Uint8List passwordU8a = Uint8List.fromList(password); + final Uint8List saltU8a = Uint8List.fromList(salt.codeUnits); final Scrypt scrypt = Scrypt() ..init(ScryptParameters(4096, 16, 1, 32, saltU8a)); final Uint8List seedBytes = scrypt.process(passwordU8a); @@ -98,11 +106,34 @@ Future<KeyPair> createPair(AuthData data, Keyring keyring) async { } } +// From durt String mnemonicGenerate({String lang = 'english'}) { + final List<String> supportedLanguages = <String>[ + 'english', + 'french', + 'italian', + 'spanish' + ]; + if (!supportedLanguages.contains(lang)) { + throw ArgumentError('Unsupported language'); + } final String mnemonic = generateMnemonic(lang: lang); return mnemonic; } +// From: +// https://polkadot.js.org/docs/keyring/start/create +Future<KeyPair> addPair() async { + final String mnemonic = mnemonicGenerate(); + final Keyring keyring = Keyring(); + // create & add the pair to the keyring with the type + // TODOAdd some additional metadata as in polkadot-js + + final KeyPair pair = + await keyring.fromUri(mnemonic, keyPairType: KeyPairType.sr25519); + + return pair; +} /* Future<Map<String, dynamic>> createAccount( AuthData data, Keyring keyring) async { diff --git a/test/g1_v2_test.dart b/test/g1_v2_test.dart index 771faac4..d3915cc8 100644 --- a/test/g1_v2_test.dart +++ b/test/g1_v2_test.dart @@ -1,5 +1,12 @@ +import 'dart:typed_data'; + +import 'package:bip39_multi_nullsafety/src/wordlists/spanish.dart' as spanish; +import 'package:durt/src/crypto/cesium_wallet.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ginkgo/g1/g1_v2_helper.dart'; +import 'package:ginkgo/ui/logger.dart'; +import 'package:polkadart_keyring/polkadart_keyring.dart'; +import 'package:substrate_bip39/substrate_bip39.dart'; void main() { group('isValidAddress', () { @@ -27,7 +34,7 @@ void main() { }); }); - test('v1PubKeyToV2', () { + test('v1PubKeyToV2 and back', () { final List<List<String>> keyPairs = <List<String>>[ <String>[ '6DrGg8cftpkgffv4Y4Lse9HSjgc8coEQor3yvMPHAnVH', @@ -36,10 +43,77 @@ void main() { ]; for (final List<String> keyPair in keyPairs) { - final String v1Key = keyPair[0]; - final String expectedV2Key = keyPair[1]; - expect(addressFromV1Pubkey(v1Key), equals(expectedV2Key)); - expect(isValidV2Address(expectedV2Key), true); + final String v1pubkey = keyPair[0]; + final String expectedV2Address = keyPair[1]; + expect(addressFromV1Pubkey(v1pubkey), equals(expectedV2Address)); + expect(isValidV2Address(expectedV2Address), true); + expect(addressFromV1Pubkey(v1pubkey), equals(expectedV2Address)); + expect(v1pubkeyFromAddress(expectedV2Address), equals(v1pubkey)); + } + }); + + test('generate a v1 wallet and convert to a keypair and back', () async { + const String secret = 'test'; + const String password = 'test'; + final CesiumWallet wallet = CesiumWallet(secret, password); + final String v1PubKey = wallet.pubkey; + final String v2Address = addressFromV1Pubkey(v1PubKey); + final Uint8List seed = wallet.seed; + final Keyring keyring = Keyring(); + final KeyPair keypair = + await keyring.fromSeed(seed, keyPairType: KeyPairType.ed25519); + expect(keypair.address, equals(v2Address)); + }); + + test( + 'generate a keypair via mnemonic and do test with addresses and v1 pubkeys ', + () async { + //const String devMnemonic = + // 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'; + const String devMnemonic = + 'drama dream insane parrot train corn steak latin voice extend fragile concert'; + final Keyring devKeyring = Keyring(); + final KeyPair devKeyPairEd = await devKeyring.fromMnemonic(devMnemonic, + keyPairType: KeyPairType.ed25519); + final KeyPair devKeyPairSr = await devKeyring.fromMnemonic(devMnemonic, + keyPairType: KeyPairType.sr25519); + const String expectedV2DevAddressSr = + '5GTy25GQxWinyhAafiwfVqNV3qFCwJkpbcpzkwKu3qk8HoJN'; + const String expectedV2DevAddressEd = + '5HEwSt1D87Hx161vrqmuCy975y2TFMRqpbja6DcQUNkBLL5b'; + expect(devKeyPairEd.address, equals(expectedV2DevAddressEd)); + expect(devKeyPairSr.address, equals(expectedV2DevAddressSr)); + expect(isValidV2Address(expectedV2DevAddressEd), true); + const String expectedV1PubKeySr = + 'E6xXZNFciyNfdgqcY7QUm1vQcBgPP3dQZegcj8GGSYgV'; + const String expectedV1PubKeyEd = + 'GQrGV3TeEVvA22jtaEUseyEUMajxgsbGPbE5kNpGi3wi'; + expect(v1pubkeyFromAddress(expectedV2DevAddressEd), + equals(expectedV1PubKeyEd)); + expect(v1pubkeyFromAddress(expectedV2DevAddressSr), + equals(expectedV1PubKeySr)); + + // No sr25519 seed support yet + // https://github.com/leonardocustodio/polkadart/issues/448 + final List<int> devSeed = + await SubstrateBip39.ed25519.seedFromUri(devMnemonic); + final Uint8List devSeedU8a = Uint8List.fromList(devSeed); + final CesiumWallet wallet2 = CesiumWallet.fromSeed(devSeedU8a); + expect(wallet2.pubkey, equals(expectedV1PubKeyEd)); + }); + + // Disabled as polkadot does not support spanish mnemonics + test('Spanish bit39', skip: true, () async { + final List<String> esMnemonicList = + mnemonicGenerate(lang: 'spanish').split(' '); + + final Keyring keyring = Keyring(); + final String mnemonic = esMnemonicList.join(' '); + loggerDev(mnemonic); + await keyring.fromMnemonic(mnemonic, keyPairType: KeyPairType.sr25519); + + for (final String esWord in esMnemonicList) { + expect(spanish.WORDLIST.contains(esWord), true); } }); } -- GitLab