/// <summary> /// Unlocks the asynchronous. /// </summary> /// <param name="password">The password.</param> /// <param name="noCheck">if set to <c>true</c> [no check].</param> /// <returns></returns> /// <exception cref="Exception">Public key check failed!</exception> public async Task <bool> UnlockAsync(string password, bool noCheck = false) { if (IsUnlocked || !IsCreated) { Logger.Warn("Wallet is already unlocked or doesn't exist."); return(IsUnlocked && IsCreated); } Logger.Info("Unlock new wallet."); try { var pswBytes = Encoding.UTF8.GetBytes(password); pswBytes = SHA256.Create().ComputeHash(pswBytes); var seed = ManagedAes.DecryptStringFromBytes_Aes(_walletFile.EncryptedSeed, pswBytes, _walletFile.Salt); byte[] publicKey = null; byte[] privateKey = null; switch (_walletFile.KeyType) { case KeyType.Ed25519: Ed25519.KeyPairFromSeed(out publicKey, out privateKey, Utils.HexToByteArray(seed)); break; case KeyType.Sr25519: var miniSecret = new MiniSecret(Utils.HexToByteArray(seed), ExpandMode.Ed25519); var getPair = miniSecret.GetPair(); privateKey = getPair.Secret.ToBytes(); publicKey = getPair.Public.Key; break; } if (noCheck || !publicKey.SequenceEqual(_walletFile.PublicKey)) { throw new Exception("Public key check failed!"); } Account = Account.Build(_walletFile.KeyType, privateKey, publicKey); } catch (Exception exception) { Logger.Warn($"Couldn't unlock the wallet with this password. {exception}"); return(false); } if (IsOnline) { _subscriptionAccountInfo = await SubscribeAccountInfoAsync(); } return(true); }
/// <summary> /// Creates the asynchronous. /// </summary> /// <param name="password">The password.</param> /// <param name="walletName">Name of the wallet.</param> /// <returns></returns> public async Task <bool> CreateAsync(string password, string walletName = DefaultWalletName) { if (IsCreated) { Logger.Warn("Wallet already created."); return(true); } if (!IsValidPassword(password)) { Logger.Warn( "Password isn't is invalid, please provide a proper password. Minmimu eight size and must have upper, lower and digits."); return(false); } Logger.Info("Creating new wallet."); var randomBytes = new byte[48]; _random.NextBytes(randomBytes); var memoryBytes = randomBytes.AsMemory(); var pswBytes = Encoding.UTF8.GetBytes(password); var salt = memoryBytes.Slice(0, 16).ToArray(); var seed = memoryBytes.Slice(16, 32).ToArray(); pswBytes = SHA256.Create().ComputeHash(pswBytes); var encryptedSeed = ManagedAes.EncryptStringToBytes_Aes(Utils.Bytes2HexString(seed, Utils.HexStringFormat.Pure), pswBytes, salt); Ed25519.KeyPairFromSeed(out var publicKey, out var privateKey, seed); var keyType = KeyType.Ed25519; _walletFile = new WalletFile(keyType, publicKey, encryptedSeed, salt); Caching.Persist(AddWalletFileType(walletName), _walletFile); Account = Account.Build(keyType, privateKey, publicKey); if (IsOnline) { _subscriptionAccountInfo = await SubscribeAccountInfoAsync(); } return(true); }
/// <summary> /// Creates the asynchronous. /// </summary> /// <param name="password">The password.</param> /// <param name="mnemonic">The mnemonic.</param> /// <param name="walletName">Name of the wallet.</param> /// <returns></returns> public async Task <bool> CreateAsync(string password, string mnemonic, string walletName = DefaultWalletName) { if (IsCreated) { Logger.Warn("Wallet already created."); return(true); } if (!IsValidPassword(password)) { Logger.Warn( "Password isn't is invalid, please provide a proper password. Minmimu eight size and must have upper, lower and digits."); return(false); } Logger.Info("Creating new wallet from mnemonic."); var seed = Mnemonic.GetSecretKeyFromMnemonic(mnemonic, "Substrate", BIP39Wordlist.English); var randomBytes = new byte[48]; _random.NextBytes(randomBytes); var memoryBytes = randomBytes.AsMemory(); var pswBytes = Encoding.UTF8.GetBytes(password); var salt = memoryBytes.Slice(0, 16).ToArray(); pswBytes = SHA256.Create().ComputeHash(pswBytes); var encryptedSeed = ManagedAes.EncryptStringToBytes_Aes(Utils.Bytes2HexString(seed, Utils.HexStringFormat.Pure), pswBytes, salt); var miniSecret = new MiniSecret(seed, ExpandMode.Ed25519); var getPair = miniSecret.GetPair(); var keyType = KeyType.Sr25519; _walletFile = new WalletFile(keyType, getPair.Public.Key, encryptedSeed, salt); Caching.Persist(AddWalletFileType(walletName), _walletFile); Account = Account.Build(keyType, getPair.Secret.ToBytes(), getPair.Public.Key); if (IsOnline) { _subscriptionAccountInfo = await SubscribeAccountInfoAsync(); } return(true); }
/// <summary> /// Unlock a locked wallet. /// </summary> /// <param name="password"></param> /// <returns></returns> public bool Unlock(string password) { if (IsUnlocked || !IsCreated) { Logger.Warn($"Wallet is already unlocked or doesn't exist."); return(IsUnlocked && IsCreated); } Logger.Info($"Unlock new wallet."); var pswBytes = Encoding.UTF8.GetBytes(password); pswBytes = SHA256.Create().ComputeHash(pswBytes); var seed = ManagedAes.DecryptStringFromBytes_Aes(_walletFile.encryptedSeed, pswBytes, _walletFile.salt); Chaos.NaCl.Ed25519.KeyPairFromSeed(out byte[] publicKey, out byte[] privateKey, Utils.HexToByteArray(seed)); Account = new Account(KeyType.ED25519, privateKey, publicKey); return(true); }
/// <summary> /// Create a new wallet with mnemonic /// </summary> /// <param name="password"></param> /// <returns></returns> public bool Create(string password) { if (IsCreated) { Logger.Warn($"Wallet already created."); return(true); } Logger.Info($"Creating new wallet."); byte[] randomBytes = new byte[48]; _random.NextBytes(randomBytes); var memoryBytes = randomBytes.AsMemory(); var pswBytes = Encoding.UTF8.GetBytes(password); var salt = memoryBytes.Slice(0, 16).ToArray(); var seed = memoryBytes.Slice(16, 32).ToArray(); pswBytes = SHA256.Create().ComputeHash(pswBytes); var encryptedSeed = ManagedAes.EncryptStringToBytes_Aes(Utils.Bytes2HexString(seed, Utils.HexStringFormat.PURE), pswBytes, salt); _walletFile = new WalletFile(encryptedSeed, salt); Caching.Persist(_path, _walletFile); Chaos.NaCl.Ed25519.KeyPairFromSeed(out byte[] publicKey, out byte[] privateKey, seed); Account = new Account(KeyType.ED25519, privateKey, publicKey); return(true); }