package com.mygeopay.core.wallet; import com.mygeopay.core.protos.Protos; import org.bitcoinj.core.ECKey; import org.bitcoinj.crypto.EncryptableItem; import org.bitcoinj.crypto.EncryptedData; import org.bitcoinj.crypto.KeyCrypter; import org.bitcoinj.wallet.BasicKeyChain; import com.google.protobuf.ByteString; import java.util.LinkedHashMap; import java.util.Map; import static com.google.common.base.Preconditions.checkState; /** * @author John L. Jegutanis */ public class SimpleKeyChain extends BasicKeyChain { public SimpleKeyChain(KeyCrypter crypter) { super(crypter); } public SimpleKeyChain() { super(); } Map<ECKey, Protos.Key.Builder> toEditableProtobufs() { Map<ECKey, Protos.Key.Builder> result = new LinkedHashMap<ECKey, Protos.Key.Builder>(); for (ECKey ecKey : getKeys()) { Protos.Key.Builder protoKey = serializeKey(ecKey); result.put(ecKey, protoKey); } return result; } /*package*/ static Protos.Key.Builder serializeEncryptableItem(EncryptableItem item) { Protos.Key.Builder proto = Protos.Key.newBuilder(); if (item.isEncrypted() && item.getEncryptedData() != null) { // The encrypted data can be missing for an "encrypted" key in the case of a deterministic wallet for // which the leaf keys chain to an encrypted parent and rederive their private keys on the fly. In that // case the caller in DeterministicKeyChain will take care of setting the type. EncryptedData data = item.getEncryptedData(); proto.getEncryptedDataBuilder() .setEncryptedPrivateKey(ByteString.copyFrom(data.encryptedBytes)) .setInitialisationVector(ByteString.copyFrom(data.initialisationVector)); // We don't allow mixing of encryption types at the moment. checkState(item.getEncryptionType() == org.bitcoinj.wallet.Protos.Wallet.EncryptionType.ENCRYPTED_SCRYPT_AES, "We don't allow mixing of encryption types at the moment"); proto.setType(Protos.Key.Type.ENCRYPTED_SCRYPT_AES); } else { final byte[] secret = item.getSecretBytes(); // The secret might be missing in the case of a watching wallet, or a key for which the private key // is expected to be rederived on the fly from its parent. if (secret != null) proto.setSecretBytes(ByteString.copyFrom(secret)); proto.setType(Protos.Key.Type.ORIGINAL); } return proto; } /*package*/ static Protos.Key.Builder serializeKey(ECKey key) { Protos.Key.Builder protoKey = serializeEncryptableItem(key); protoKey.setPublicKey(ByteString.copyFrom(key.getPubKey())); return protoKey; } }