Browse Source

Merge pull request #144 from kennycud/master

Added Spendable Attribute to Address Info
reticulum
AlphaX-Projects 10 months ago committed by GitHub
parent
commit
1e4d4e178d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/main/java/org/qortal/crosschain/AddressInfo.java
  2. 33
      src/main/java/org/qortal/crosschain/Bitcoiny.java
  3. 5
      src/test/java/org/qortal/test/crosschain/BitcoinTests.java
  4. 18
      src/test/java/org/qortal/test/crosschain/BitcoinyTests.java
  5. 5
      src/test/java/org/qortal/test/crosschain/DigibyteTests.java
  6. 5
      src/test/java/org/qortal/test/crosschain/DogecoinTests.java
  7. 5
      src/test/java/org/qortal/test/crosschain/LitecoinTests.java
  8. 9
      src/test/java/org/qortal/test/crosschain/PirateChainTests.java
  9. 5
      src/test/java/org/qortal/test/crosschain/RavencoinTests.java

14
src/main/java/org/qortal/crosschain/AddressInfo.java

@ -21,15 +21,18 @@ public class AddressInfo {
private int transactionCount;
private boolean isSpendable;
public AddressInfo() {
}
public AddressInfo(String address, List<Integer> path, long value, String pathAsString, int transactionCount) {
public AddressInfo(String address, List<Integer> path, long value, String pathAsString, int transactionCount, boolean isSpendable) {
this.address = address;
this.path = path;
this.value = value;
this.pathAsString = pathAsString;
this.transactionCount = transactionCount;
this.isSpendable = isSpendable;
}
public String getAddress() {
@ -52,17 +55,21 @@ public class AddressInfo {
return transactionCount;
}
public boolean isSpendable() {
return isSpendable;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AddressInfo that = (AddressInfo) o;
return value == that.value && transactionCount == that.transactionCount && Objects.equals(address, that.address) && Objects.equals(path, that.path) && Objects.equals(pathAsString, that.pathAsString);
return value == that.value && transactionCount == that.transactionCount && isSpendable == that.isSpendable && address.equals(that.address) && path.equals(that.path) && pathAsString.equals(that.pathAsString);
}
@Override
public int hashCode() {
return Objects.hash(address, path, value, pathAsString, transactionCount);
return Objects.hash(address, path, value, pathAsString, transactionCount, isSpendable);
}
@Override
@ -73,6 +80,7 @@ public class AddressInfo {
", value=" + value +
", pathAsString='" + pathAsString + '\'' +
", transactionCount=" + transactionCount +
", isSpendable=" + isSpendable +
'}';
}
}

33
src/main/java/org/qortal/crosschain/Bitcoiny.java

@ -335,6 +335,30 @@ public abstract class Bitcoiny implements ForeignBlockchain {
}
}
/**
* Get Spending Candidate Addresses
*
* @param key58 public master key
* @return the addresses this instance will look at when building a spend
* @throws ForeignBlockchainException
*/
public List<String> getSpendingCandidateAddresses(String key58) throws ForeignBlockchainException {
Wallet wallet = Wallet.fromWatchingKeyB58(this.params, key58, DeterministicHierarchy.BIP32_STANDARDISATION_TIME_SECS);
wallet.setUTXOProvider(new WalletAwareUTXOProvider(this, wallet));
// from Wallet.getStoredOutputsFromUTXOProvider()
List<ECKey> spendingKeys = wallet.getImportedKeys();
spendingKeys.addAll(wallet.getActiveKeyChain().getLeafKeys());
List<String> spendingCandidateAddresses
= spendingKeys.stream()
.map(spendingKey -> Address.fromKey(this.params, spendingKey, ScriptType.P2PKH ).toString())
.collect(Collectors.toList());
return spendingCandidateAddresses;
}
/**
* Returns bitcoinj transaction sending <tt>amount</tt> to <tt>recipient</tt> using default fees.
*
@ -478,8 +502,10 @@ public abstract class Bitcoiny implements ForeignBlockchain {
public List<AddressInfo> getWalletAddressInfos(String key58) throws ForeignBlockchainException {
List<AddressInfo> infos = new ArrayList<>();
List<String> candidates = this.getSpendingCandidateAddresses(key58);
for(DeterministicKey key : getWalletKeys(key58)) {
infos.add(buildAddressInfo(key));
infos.add(buildAddressInfo(key, candidates));
}
return infos.stream()
@ -487,7 +513,7 @@ public abstract class Bitcoiny implements ForeignBlockchain {
.collect(Collectors.toList());
}
public AddressInfo buildAddressInfo(DeterministicKey key) throws ForeignBlockchainException {
public AddressInfo buildAddressInfo(DeterministicKey key, List<String> candidates) throws ForeignBlockchainException {
Address address = Address.fromKey(this.params, key, ScriptType.P2PKH);
@ -498,7 +524,8 @@ public abstract class Bitcoiny implements ForeignBlockchain {
toIntegerList( key.getPath()),
summingUnspentOutputs(address.toString()),
key.getPathAsString(),
transactionCount);
transactionCount,
candidates.contains(address.toString()));
}
private static List<Integer> toIntegerList(ImmutableList<ChildNumber> path) {

5
src/test/java/org/qortal/test/crosschain/BitcoinTests.java

@ -32,6 +32,11 @@ public class BitcoinTests extends BitcoinyTests {
return "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ";
}
@Override
protected String getDeterministicPublicKey58() {
return "tpubDCxs3oB9X7XJYkQGU6gfPwd4h3NEiBGA8mfD1aEbZiG5x3BTH4cJqszDP6dtoHPPjZNEj5jPxuSWHCvjg9AHz4dNg6w5vQhv1B8KwWKpxoz";
}
@Override
protected String getRecipient() {
return "2N8WCg52ULCtDSMjkgVTm5mtPdCsUptkHWE";

18
src/test/java/org/qortal/test/crosschain/BitcoinyTests.java

@ -31,6 +31,8 @@ public abstract class BitcoinyTests extends Common {
protected abstract String getDeterministicKey58();
protected abstract String getDeterministicPublicKey58();
protected abstract String getRecipient();
@Before
@ -154,12 +156,24 @@ public abstract class BitcoinyTests extends Common {
@Test
public void testWalletAddressInfos() throws ForeignBlockchainException {
String xprv58 = getDeterministicKey58();
String key58 = getDeterministicPublicKey58();
List<AddressInfo> addressInfos = this.bitcoiny.getWalletAddressInfos(xprv58);
List<AddressInfo> addressInfos = this.bitcoiny.getWalletAddressInfos(key58);
System.out.println("address count = " + addressInfos.size() );
System.out.println( "address infos ..." );
addressInfos.forEach( System.out::println );
}
@Test
public void testWalletSpendingCandidateAddresses() throws ForeignBlockchainException {
String xpub58 = getDeterministicPublicKey58();
List<String> candidateAddresses = this.bitcoiny.getSpendingCandidateAddresses(xpub58);
System.out.println("candidate address count = " + candidateAddresses.size() );
System.out.println( "candidate addresses ..." );
candidateAddresses.forEach( System.out::println );
}
}

5
src/test/java/org/qortal/test/crosschain/DigibyteTests.java

@ -32,6 +32,11 @@ public class DigibyteTests extends BitcoinyTests {
return "xpub661MyMwAqRbcEnabTLX5uebYcsE3uG5y7ve9jn1VK8iY1MaU3YLoLJEe8sTu2YVav5Zka5qf2dmMssfxmXJTqZnazZL2kL7M2tNKwEoC34R";
}
@Override
protected String getDeterministicPublicKey58() {
return "xpub661MyMwAqRbcEnabTLX5uebYcsE3uG5y7ve9jn1VK8iY1MaU3YLoLJEe8sTu2YVav5Zka5qf2dmMssfxmXJTqZnazZL2kL7M2tNKwEoC34R";
}
@Override
protected String getRecipient() {
return "2N8WCg52ULCtDSMjkgVTm5mtPdCsUptkHWE";

5
src/test/java/org/qortal/test/crosschain/DogecoinTests.java

@ -32,6 +32,11 @@ public class DogecoinTests extends BitcoinyTests {
return "dgpv51eADS3spNJh9drNeW1Tc1P9z2LyaQRXPBortsq6yice1k47C2u2Prvgxycr2ihNBWzKZ2LthcBBGiYkWZ69KUTVkcLVbnjq7pD8mnApEru";
}
@Override
protected String getDeterministicPublicKey58() {
return "dgub8rqf3khHiPeYE3cNn3Y4DQQ411nAnFpuSUPt5k5GJZQsydsTLkaf4onaWn4N8pHvrV3oNMEATKoPGTFZwm2Uhh7Dy9gYwA7rkSv6oLofbag";
}
@Override
protected String getRecipient() {
return null;

5
src/test/java/org/qortal/test/crosschain/LitecoinTests.java

@ -32,6 +32,11 @@ public class LitecoinTests extends BitcoinyTests {
return "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ";
}
@Override
protected String getDeterministicPublicKey58() {
return "tpubDCxs3oB9X7XJYkQGU6gfPwd4h3NEiBGA8mfD1aEbZiG5x3BTH4cJqszDP6dtoHPPjZNEj5jPxuSWHCvjg9AHz4dNg6w5vQhv1B8KwWKpxoz";
}
@Override
protected String getRecipient() {
return "2N8WCg52ULCtDSMjkgVTm5mtPdCsUptkHWE";

9
src/test/java/org/qortal/test/crosschain/PirateChainTests.java

@ -43,6 +43,11 @@ public class PirateChainTests extends BitcoinyTests {
return null;
}
@Override
protected String getDeterministicPublicKey58() {
return null;
}
@Override
protected String getRecipient() {
return null;
@ -250,4 +255,8 @@ public class PirateChainTests extends BitcoinyTests {
@Test
@Ignore(value = "Needs adapting for Pirate Chain")
public void testWalletAddressInfos() throws ForeignBlockchainException {}
@Test
@Ignore(value = "Needs adapting for Pirate Chain")
public void testWalletSpendingCandidateAddresses() throws ForeignBlockchainException {}
}

5
src/test/java/org/qortal/test/crosschain/RavencoinTests.java

@ -32,6 +32,11 @@ public class RavencoinTests extends BitcoinyTests {
return "xpub661MyMwAqRbcEt3Ge1wNmkagyb1J7yTQu4Kquvy77Ycg2iPoh7Urg8s9Jdwp7YmrqGkDKJpUVjsZXSSsQgmAVUC17ZVQQeoWMzm7vDTt1y7";
}
@Override
protected String getDeterministicPublicKey58() {
return "xpub661MyMwAqRbcEt3Ge1wNmkagyb1J7yTQu4Kquvy77Ycg2iPoh7Urg8s9Jdwp7YmrqGkDKJpUVjsZXSSsQgmAVUC17ZVQQeoWMzm7vDTt1y7";
}
@Override
protected String getRecipient() {
return null;

Loading…
Cancel
Save