Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cc.youchain.crypto.WalletUtils Maven / Gradle / Ivy
package cc.youchain.crypto;
import java.io.File;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import cc.youchain.utils.Numeric;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import static cc.youchain.crypto.Hash.sha256;
import static cc.youchain.crypto.Keys.ADDRESS_LENGTH_IN_HEX;
import static cc.youchain.crypto.Keys.PRIVATE_KEY_LENGTH_IN_HEX;
/**
* Utility functions for working with Wallet files.
*/
public class WalletUtils {
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final SecureRandom secureRandom = SecureRandomUtils.secureRandom();
static {
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public static String generateFullNewWalletFile(String password, File destinationDirectory)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException, CipherException, IOException {
return generateNewWalletFile(password, destinationDirectory, true);
}
public static String generateLightNewWalletFile(String password, File destinationDirectory)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException, CipherException, IOException {
return generateNewWalletFile(password, destinationDirectory, false);
}
public static String generateNewWalletFile(String password, File destinationDirectory)
throws CipherException, InvalidAlgorithmParameterException,
NoSuchAlgorithmException, NoSuchProviderException, IOException {
return generateFullNewWalletFile(password, destinationDirectory);
}
public static String generateNewWalletFile(
String password, File destinationDirectory, boolean useFullScrypt)
throws CipherException, IOException, InvalidAlgorithmParameterException,
NoSuchAlgorithmException, NoSuchProviderException {
ECKeyPair ecKeyPair = Keys.createEcKeyPair();
return generateWalletFile(password, ecKeyPair, destinationDirectory, useFullScrypt);
}
public static String generateWalletFile(
String password, ECKeyPair ecKeyPair, File destinationDirectory, boolean useFullScrypt)
throws CipherException, IOException {
WalletFile walletFile;
if (useFullScrypt) {
walletFile = Wallet.createStandard(password, ecKeyPair);
} else {
walletFile = Wallet.createLight(password, ecKeyPair);
}
String fileName = getWalletFileName(walletFile);
File destination = new File(destinationDirectory, fileName);
objectMapper.writeValue(destination, walletFile);
return fileName;
}
/**
* Generates a BIP-39 compatible YOUChain wallet. The private key for the wallet can
* be calculated using following algorithm:
*
* Key = SHA-256(BIP_39_SEED(mnemonic, password))
*
*
* @param password Will be used for both wallet encryption and passphrase for BIP-39 seed
* @param destinationDirectory The directory containing the wallet
* @return A BIP-39 compatible YOUChain wallet
* @throws CipherException if the underlying cipher is not available
* @throws IOException if the destination cannot be written to
*/
public static Bip39Wallet generateBip39Wallet(String password, File destinationDirectory)
throws CipherException, IOException {
byte[] initialEntropy = new byte[16];
secureRandom.nextBytes(initialEntropy);
String mnemonic = MnemonicUtils.generateMnemonic(initialEntropy);
return generateBip39WalletFromMnemonic(password, mnemonic, destinationDirectory);
}
/**
* Generates a BIP-39 compatible YOUChain wallet using a mnemonic passed as argument.
*
* @param password Will be used for both wallet encryption and passphrase for BIP-39 seed
* @param mnemonic The mnemonic that will be used to generate the seed
* @param destinationDirectory The directory containing the wallet
* @return A BIP-39 compatible YOUChain wallet
* @throws CipherException if the underlying cipher is not available
* @throws IOException if the destination cannot be written to
*/
public static Bip39Wallet generateBip39WalletFromMnemonic(
String password, String mnemonic, File destinationDirectory)
throws CipherException, IOException {
byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
ECKeyPair privateKey = ECKeyPair.create(sha256(seed));
String walletFile = generateWalletFile(password, privateKey, destinationDirectory, false);
return new Bip39Wallet(walletFile, mnemonic);
}
public static Credentials loadCredentials(String password, String source)
throws IOException, CipherException {
return loadCredentials(password, new File(source));
}
public static Credentials loadCredentials(String password, File source)
throws IOException, CipherException {
WalletFile walletFile = objectMapper.readValue(source, WalletFile.class);
return Credentials.create(Wallet.decrypt(password, walletFile));
}
public static Credentials loadBip39Credentials(String password, String mnemonic) {
byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
return Credentials.create(ECKeyPair.create(Hash.sha256(seed)));
}
private static String getWalletFileName(WalletFile walletFile) {
DateTimeFormatter format = DateTimeFormatter.ofPattern(
"'UTC--'yyyy-MM-dd'T'HH-mm-ss.nVV'--'");
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
return now.format(format) + walletFile.getAddress() + ".json";
}
public static String getDefaultKeyDirectory() {
return getDefaultKeyDirectory(System.getProperty("os.name"));
}
static String getDefaultKeyDirectory(String osName1) {
String osName = osName1.toLowerCase();
if (osName.startsWith("mac")) {
return String.format("%s%sLibrary%sYOUChain", System.getProperty("user.home"), File.separator, File.separator);
} else if (osName.startsWith("win")) {
return String.format("%s%sYOUChain", System.getenv("APPDATA"), File.separator);
} else {
return String.format("%s%s.YOUChain", System.getProperty("user.home"), File.separator);
}
}
public static String getTestnetKeyDirectory() {
return String.format("%s%stestnet%skeystore", getDefaultKeyDirectory(), File.separator, File.separator);
}
public static String getMainnetKeyDirectory() {
return String.format("%s%skeystore", getDefaultKeyDirectory(), File.separator);
}
public static boolean isValidPrivateKey(String privateKey) {
String cleanPrivateKey = Numeric.cleanHexPrefix(privateKey);
return cleanPrivateKey.length() == PRIVATE_KEY_LENGTH_IN_HEX;
}
public static boolean isValidAddress(String input) {
String cleanInput = Numeric.cleanHexPrefix(input);
try {
Numeric.toBigIntNoPrefix(cleanInput);
} catch (NumberFormatException e) {
return false;
}
return cleanInput.length() == ADDRESS_LENGTH_IN_HEX;
}
}