DeterministicKeyChain implements EncryptableKeyChain { @Override public List<DeterministicKey> getKeys(KeyPurpose purpose, int numberOfKeys) { checkArgument(numberOfKeys > 0); lock.lock(); try { DeterministicKey parentKey; int index; switch (purpose) { case RECEIVE_FUNDS: case REFUND: issuedExternalKeys += numberOfKeys; index = issuedExternalKeys; parentKey = externalParentKey; break; case AUTHENTICATION: case CHANGE: issuedInternalKeys += numberOfKeys; index = issuedInternalKeys; parentKey = internalParentKey; break; default: throw new UnsupportedOperationException(); } List<DeterministicKey> lookahead = maybeLookAhead(parentKey, index, 0, 0); basicKeyChain.importKeys(lookahead); List<DeterministicKey> keys = new ArrayList<DeterministicKey>(numberOfKeys); for (int i = 0; i < numberOfKeys; i++) { ImmutableList<ChildNumber> path = HDUtils.append(parentKey.getPath(), new ChildNumber(index - numberOfKeys + i, false)); DeterministicKey k = hierarchy.get(path, false, false); checkForBitFlip(k); keys.add(k); } return keys; } finally { lock.unlock(); } } DeterministicKeyChain(SecureRandom random);  DeterministicKeyChain(SecureRandom random, int bits);  DeterministicKeyChain(SecureRandom random, int bits, String passphrase, long seedCreationTimeSecs);  DeterministicKeyChain(byte[] entropy, String passphrase, long seedCreationTimeSecs); protected  DeterministicKeyChain(DeterministicSeed seed);  DeterministicKeyChain(DeterministicSeed seed, ImmutableList<ChildNumber> accountPath);  DeterministicKeyChain(DeterministicKey watchingKey); protected  DeterministicKeyChain(DeterministicKey watchKey, boolean isFollowing); protected  DeterministicKeyChain(DeterministicSeed seed, @Nullable KeyCrypter crypter); protected  DeterministicKeyChain(DeterministicSeed seed, @Nullable KeyCrypter crypter,
                                    ImmutableList<ChildNumber> accountPath); protected  DeterministicKeyChain(KeyCrypter crypter, KeyParameter aesKey, DeterministicKeyChain chain); static Builder<?> builder(); static DeterministicKeyChain watchAndFollow(DeterministicKey watchKey); static DeterministicKeyChain watch(DeterministicKey accountKey); @Override DeterministicKey getKey(KeyPurpose purpose); @Override List<DeterministicKey> getKeys(KeyPurpose purpose, int numberOfKeys); DeterministicKey markKeyAsUsed(DeterministicKey k); DeterministicKey findKeyFromPubHash(byte[] pubkeyHash); DeterministicKey findKeyFromPubKey(byte[] pubkey); @Nullable DeterministicKey markPubHashAsUsed(byte[] pubkeyHash); @Nullable DeterministicKey markPubKeyAsUsed(byte[] pubkey); @Override boolean hasKey(ECKey key); DeterministicKey getKeyByPath(List<ChildNumber> path, boolean create); DeterministicKey getWatchingKey(); boolean isWatching(); @Override int numKeys(); int numLeafKeysIssued(); @Override long getEarliestKeyCreationTime(); @Override void addEventListener(KeyChainEventListener listener); @Override void addEventListener(KeyChainEventListener listener, Executor executor); @Override boolean removeEventListener(KeyChainEventListener listener); @Nullable List<String> getMnemonicCode(); boolean isFollowing(); @Override List<Protos.Key> serializeToProtobuf(); static List<DeterministicKeyChain> fromProtobuf(List<Protos.Key> keys, @Nullable KeyCrypter crypter, KeyChainFactory factory); @Override DeterministicKeyChain toEncrypted(CharSequence password); @Override DeterministicKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey); @Override DeterministicKeyChain toDecrypted(CharSequence password); @Override DeterministicKeyChain toDecrypted(KeyParameter aesKey); @Override boolean checkPassword(CharSequence password); @Override boolean checkAESKey(KeyParameter aesKey); @Nullable @Override KeyCrypter getKeyCrypter(); @Override int numBloomFilterEntries(); @Override BloomFilter getFilter(int size, double falsePositiveRate, long tweak); int getLookaheadSize(); void setLookaheadSize(int lookaheadSize); void setLookaheadThreshold(int num); int getLookaheadThreshold(); void maybeLookAhead(); void maybeLookAheadScripts(); int getIssuedExternalKeys(); int getIssuedInternalKeys(); @Nullable DeterministicSeed getSeed(); List<ECKey> getIssuedReceiveKeys(); List<DeterministicKey> getLeafKeys(); int getKeyLookaheadEpoch(); boolean isMarried(); RedeemData getRedeemData(DeterministicKey followedKey); Script freshOutputScript(KeyPurpose purpose); String toString(boolean includePrivateKeys, NetworkParameters params); void setSigsRequiredToSpend(int sigsRequiredToSpend); int getSigsRequiredToSpend(); @Nullable RedeemData findRedeemDataByScriptHash(ByteString bytes); static final String DEFAULT_PASSPHRASE_FOR_MNEMONIC; static final ImmutableList<ChildNumber> ACCOUNT_ZERO_PATH; static final ImmutableList<ChildNumber> BIP44_ACCOUNT_ZERO_PATH; static final ImmutableList<ChildNumber> BIP44_ACCOUNT_ZERO_PATH_TESTNET; static final ImmutableList<ChildNumber> EXTERNAL_SUBPATH; static final ImmutableList<ChildNumber> INTERNAL_SUBPATH; }
@Test public void getKeys() throws Exception { chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS); chain.getKey(KeyChain.KeyPurpose.CHANGE); chain.maybeLookAhead(); assertEquals(2, chain.getKeys(false).size()); }