Compare commits
1 Commits
master
...
external-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7b1654e39 |
10
build.gradle
10
build.gradle
@ -4,7 +4,7 @@ plugins {
|
||||
}
|
||||
|
||||
group 'com.sparrowwallet.nightjar'
|
||||
version '0.2.40'
|
||||
version '0.2.36'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -17,11 +17,11 @@ file("publish.properties").withInputStream {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation ('org.bouncycastle:bcprov-jdk18on:1.77') {
|
||||
implementation ('org.bouncycastle:bcprov-jdk15on:1.64') {
|
||||
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
||||
}
|
||||
implementation ('com.google.protobuf:protobuf-java:2.6.1')
|
||||
implementation ('com.google.guava:guava:33.0.0-jre')
|
||||
implementation ('com.google.guava:guava:31.1-jre')
|
||||
implementation ('com.lambdaworks:scrypt:1.4.0')
|
||||
implementation ('org.springframework:spring-websocket:5.2.2.RELEASE')
|
||||
implementation ('org.springframework:spring-messaging:5.2.2.RELEASE')
|
||||
@ -34,10 +34,10 @@ dependencies {
|
||||
implementation ('com.fasterxml.jackson.core:jackson-databind:2.13.2')
|
||||
implementation ('org.json:json:20180130')
|
||||
implementation ('io.reactivex.rxjava2:rxjava:2.2.15')
|
||||
implementation ('org.slf4j:slf4j-api:2.0.12')
|
||||
implementation ('org.slf4j:slf4j-api:1.7.30')
|
||||
implementation ('com.auth0:java-jwt:3.8.1')
|
||||
implementation('org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.20')
|
||||
implementation ('ch.qos.logback:logback-classic:1.4.14') {
|
||||
implementation ('ch.qos.logback:logback-classic:1.2.8') {
|
||||
exclude group: 'org.hamcrest', module: 'hamcrest-core'
|
||||
exclude group: 'org.slf4j'
|
||||
}
|
||||
|
||||
@ -9,5 +9,4 @@ public interface IBackendClient {
|
||||
<T> T getJson(String url, Class<T> responseType, Map<String,String> headers, boolean async) throws HttpException;
|
||||
|
||||
<T> T postUrlEncoded(String url, Class<T> responseType, Map<String,String> headers, Map<String, String> body) throws HttpException;
|
||||
String postString(String url, Map<String,String> headers, String contentType, String content) throws HttpException;
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ package com.samourai.wallet.bip47.rpc.java;
|
||||
import com.samourai.wallet.bip47.BIP47UtilGeneric;
|
||||
import com.samourai.wallet.bip47.rpc.secretPoint.ISecretPoint;
|
||||
import com.samourai.wallet.bip47.rpc.secretPoint.ISecretPointFactory;
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
@ -27,6 +29,11 @@ public class Bip47UtilJava extends BIP47UtilGeneric {
|
||||
InvalidKeyException {
|
||||
return new SecretPointJava(dataPrv, dataPub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISecretPoint newSecretPoint(HD_Address address, byte[] dataPub) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException {
|
||||
return new SecretPointJava(address.getECKey().getPrivKeyBytes(), dataPub);
|
||||
}
|
||||
};
|
||||
|
||||
private Bip47UtilJava() {
|
||||
|
||||
@ -2,6 +2,8 @@ package com.samourai.wallet.bip47.rpc.java;
|
||||
|
||||
import com.samourai.wallet.bip47.rpc.secretPoint.ISecretPoint;
|
||||
import com.samourai.wallet.bip47.rpc.secretPoint.ISecretPointFactory;
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
@ -17,11 +19,14 @@ public class SecretPointFactoryJava implements ISecretPointFactory {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private SecretPointFactoryJava() {}
|
||||
public SecretPointFactoryJava() {}
|
||||
|
||||
@Override
|
||||
public ISecretPoint newSecretPoint(byte[] dataPrv, byte[] dataPub) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException {
|
||||
return new SecretPointJava(dataPrv, dataPub);
|
||||
}
|
||||
|
||||
public ISecretPoint newSecretPoint(HD_Address address, byte[] dataPub) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException {
|
||||
return new SecretPointJava(address.getECKey().getPrivKeyBytes(), dataPub);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.samourai.wallet.bip47.rpc.secretPoint;
|
||||
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
@ -8,5 +10,5 @@ import java.security.spec.InvalidKeySpecException;
|
||||
public interface ISecretPointFactory {
|
||||
|
||||
ISecretPoint newSecretPoint(byte[] dataPrv, byte[] dataPub) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException;
|
||||
|
||||
ISecretPoint newSecretPoint(HD_Address address, byte[] dataPub) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ public class BipWallet {
|
||||
IIndexHandler indexChangeHandler,
|
||||
AddressType addressType) {
|
||||
this.account = account;
|
||||
this.bipWallet = new HD_Wallet(addressType.getPurpose(), bip44w);
|
||||
this.bipWallet = bip44w.getSeed() == null ? new HD_Wallet(bip44w.getParams(), bip44w.getAccounts()) : new HD_Wallet(addressType.getPurpose(), bip44w);
|
||||
this.indexHandler = indexHandler;
|
||||
this.indexChangeHandler = indexChangeHandler;
|
||||
}
|
||||
|
||||
@ -120,4 +120,8 @@ public class HD_Address {
|
||||
public static String getPathFull(int purpose, int coinType, int account, int chain, int address) {
|
||||
return "m/"+purpose+"'/"+coinType+"'/"+account+"'/"+chain+"/"+address;
|
||||
}
|
||||
|
||||
public NetworkParameters getParams() {
|
||||
return mParams;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,10 +10,7 @@ import org.bitcoinj.crypto.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class HD_Wallet {
|
||||
private byte[] mSeed = null;
|
||||
@ -75,6 +72,21 @@ public class HD_Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
public HD_Wallet(NetworkParameters params, Map<Integer, HD_Account> xpub) throws AddressFormatException {
|
||||
mParams = params;
|
||||
|
||||
// initialize mAccounts and xpubs
|
||||
mAccounts = new LinkedHashMap<>();
|
||||
xpubs = new String[xpub.size()];
|
||||
List<Integer> indexList = new ArrayList<>(xpub.keySet());
|
||||
for(int i = 0; i < indexList.size(); i++) {
|
||||
Integer accountIndex = indexList.get(i);
|
||||
HD_Account account = new HD_Account(mParams, xpub.get(accountIndex).strXPUB, accountIndex);
|
||||
mAccounts.put(accountIndex, account);
|
||||
xpubs[i] = account.xpubstr();
|
||||
}
|
||||
}
|
||||
|
||||
private static DeterministicKey computeRootKey(int purpose, List<String> mWordList, String strPassphrase, NetworkParameters params) {
|
||||
byte[] hd_seed = MnemonicCode.toSeed(mWordList, strPassphrase);
|
||||
DeterministicKey mKey = HDKeyDerivation.createMasterPrivateKey(hd_seed);
|
||||
@ -104,6 +116,10 @@ public class HD_Wallet {
|
||||
return mParams;
|
||||
}
|
||||
|
||||
public Map<Integer, HD_Account> getAccounts() {
|
||||
return mAccounts;
|
||||
}
|
||||
|
||||
public HD_Account getAccount(int accountIdx) {
|
||||
HD_Account hdAccount = mAccounts.get(accountIdx);
|
||||
if (hdAccount == null) {
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
package com.samourai.wallet.send.provider;
|
||||
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
public abstract class AbstractUtxoKeyProvider implements UtxoKeyProvider {
|
||||
@Override
|
||||
public ECKey _getPrivKey(String utxoHash, int utxoIndex) throws Exception {
|
||||
return getAddress(utxoHash, utxoIndex).getECKey();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.samourai.wallet.send.provider;
|
||||
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.core.TransactionOutPoint;
|
||||
|
||||
@ -17,4 +18,9 @@ public class SimpleUtxoKeyProvider implements UtxoKeyProvider {
|
||||
public ECKey _getPrivKey(String utxoHash, int utxoIndex) throws Exception {
|
||||
return keys.get(utxoHash + ":" + utxoIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HD_Address getAddress(String utxoHash, int utxoIndex) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package com.samourai.wallet.send.provider;
|
||||
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
public interface UtxoKeyProvider {
|
||||
|
||||
ECKey _getPrivKey(String utxoHash, int utxoIndex) throws Exception;
|
||||
HD_Address getAddress(String utxoHash, int utxoIndex) throws Exception;
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
package com.samourai.whirlpool.client.mix.handler;
|
||||
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
import com.samourai.wallet.segwit.SegwitAddress;
|
||||
import com.samourai.wallet.send.SendFactoryGeneric;
|
||||
import com.samourai.wallet.send.exceptions.SignTxException;
|
||||
import com.samourai.wallet.send.provider.UtxoKeyProvider;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
|
||||
public class DefaultSigningHandler implements SigningHandler {
|
||||
@Override
|
||||
public String signMessage(HD_Address hdAddress, String message) {
|
||||
return hdAddress.getECKey().signMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction signTx0Transaction(Transaction transaction, UtxoKeyProvider utxoKeyProvider) throws SignTxException {
|
||||
byte[] signedTx = signTx0Transaction(transaction.bitcoinSerialize(), utxoKeyProvider);
|
||||
if(signedTx != null) {
|
||||
return new Transaction(transaction.getParams(), signedTx);
|
||||
}
|
||||
|
||||
SendFactoryGeneric.getInstance().signTransaction(transaction, getUtxoKeyProvider(utxoKeyProvider));
|
||||
return transaction;
|
||||
}
|
||||
|
||||
protected byte[] signTx0Transaction(byte[] transactionBytes, UtxoKeyProvider utxoKeyProvider) throws SignTxException {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected UtxoKeyProvider getUtxoKeyProvider(UtxoKeyProvider utxoKeyProvider) {
|
||||
return utxoKeyProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] signMixTransaction(byte[] transaction, int inputIndex, HD_Address hdAddress, long spendAmount) {
|
||||
final SegwitAddress segwitAddress = new SegwitAddress(hdAddress.getECKey(), hdAddress.getParams());
|
||||
final Script redeemScript = segwitAddress.segWitRedeemScript();
|
||||
final Script scriptCode = redeemScript.scriptCode();
|
||||
|
||||
Transaction tx = new Transaction(hdAddress.getParams(), transaction);
|
||||
TransactionSignature sig = tx.calculateWitnessSignature(inputIndex, hdAddress.getECKey(), scriptCode, Coin.valueOf(spendAmount), Transaction.SigHash.ALL, false);
|
||||
return sig.encodeToBitcoin();
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,21 @@
|
||||
package com.samourai.whirlpool.client.mix.handler;
|
||||
|
||||
import com.samourai.wallet.segwit.SegwitAddress;
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
import com.samourai.whirlpool.client.utils.ClientUtils;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
|
||||
public class PremixHandler implements IPremixHandler {
|
||||
private UtxoWithBalance utxo;
|
||||
private ECKey utxoKey;
|
||||
private HD_Address utxoAddress;
|
||||
private String userPreHash;
|
||||
private SigningHandler signingHandler;
|
||||
|
||||
public PremixHandler(UtxoWithBalance utxo, ECKey utxoKey, String userPreHash) {
|
||||
public PremixHandler(UtxoWithBalance utxo, HD_Address utxoAddress, String userPreHash, SigningHandler signingHandler) {
|
||||
this.utxo = utxo;
|
||||
this.utxoKey = utxoKey;
|
||||
this.utxoAddress = utxoAddress;
|
||||
this.userPreHash = userPreHash;
|
||||
this.signingHandler = signingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -27,19 +28,14 @@ public class PremixHandler implements IPremixHandler {
|
||||
throws Exception {
|
||||
// TODO SendFactoryGeneric.getInstance().signInput(utxoKey, params, tx, inputIndex);
|
||||
long spendAmount = utxo.getBalance();
|
||||
signInputSegwit(tx, inputIndex, utxoKey, spendAmount, params);
|
||||
signInputSegwit(tx, inputIndex, utxoAddress.getECKey(), spendAmount, params);
|
||||
}
|
||||
|
||||
// TODO
|
||||
protected void signInputSegwit(
|
||||
Transaction tx, int inputIdx, ECKey ecKey, long spendAmount, NetworkParameters params) {
|
||||
final SegwitAddress segwitAddress = new SegwitAddress(ecKey, params);
|
||||
final Script redeemScript = segwitAddress.segWitRedeemScript();
|
||||
final Script scriptCode = redeemScript.scriptCode();
|
||||
|
||||
TransactionSignature sig =
|
||||
tx.calculateWitnessSignature(
|
||||
inputIdx, ecKey, scriptCode, Coin.valueOf(spendAmount), Transaction.SigHash.ALL, false);
|
||||
byte[] sigBytes = signingHandler.signMixTransaction(tx.bitcoinSerialize(), inputIdx, utxoAddress, spendAmount);
|
||||
TransactionSignature sig = TransactionSignature.decodeFromBitcoin(sigBytes, false, false);
|
||||
final TransactionWitness witness = new TransactionWitness(2);
|
||||
witness.setPush(0, sig.encodeToBitcoin());
|
||||
witness.setPush(1, ecKey.getPubKey());
|
||||
@ -48,7 +44,7 @@ public class PremixHandler implements IPremixHandler {
|
||||
|
||||
@Override
|
||||
public String signMessage(String message) {
|
||||
return utxoKey.signMessage(message);
|
||||
return signingHandler.signMessage(utxoAddress, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.samourai.whirlpool.client.mix.handler;
|
||||
|
||||
import com.samourai.wallet.hd.HD_Address;
|
||||
import com.samourai.wallet.send.exceptions.SignTxException;
|
||||
import com.samourai.wallet.send.provider.UtxoKeyProvider;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
public interface SigningHandler {
|
||||
String signMessage(HD_Address hdAddress, String message);
|
||||
Transaction signTx0Transaction(Transaction transaction, UtxoKeyProvider utxoKeyProvider) throws SignTxException;
|
||||
byte[] signMixTransaction(byte[] transaction, int inputIndex, HD_Address hdAddress, long spendAmount);
|
||||
}
|
||||
@ -36,14 +36,12 @@ public class Tx0Service {
|
||||
|
||||
private final Bech32UtilGeneric bech32Util = Bech32UtilGeneric.getInstance();
|
||||
private final FormatsUtilGeneric formatsUtilGeneric = FormatsUtilGeneric.getInstance();
|
||||
private final XorMask xorMask;
|
||||
private final FeeUtil feeUtil = FeeUtil.getInstance();
|
||||
|
||||
private WhirlpoolWalletConfig config;
|
||||
|
||||
public Tx0Service(WhirlpoolWalletConfig config) {
|
||||
this.config = config;
|
||||
xorMask = XorMask.getInstance(config.getSecretPointFactory());
|
||||
}
|
||||
|
||||
private int computeNbPremixMax(
|
||||
@ -275,12 +273,19 @@ public class Tx0Service {
|
||||
ECKey firstInputKey = utxoKeyProvider._getPrivKey(firstInput.tx_hash, firstInput.tx_output_n);
|
||||
String feePaymentCode = tx0Data.getFeePaymentCode();
|
||||
byte[] feePayload = tx0Data.getFeePayload();
|
||||
byte[] feePayloadMasked =
|
||||
XorMask xorMask = XorMask.getInstance(config.getSecretPointFactory());
|
||||
byte[] feePayloadMasked = firstInputKey.hasPrivKey() ?
|
||||
xorMask.mask(
|
||||
feePayload,
|
||||
feePaymentCode,
|
||||
params,
|
||||
firstInputKey.getPrivKeyBytes(),
|
||||
firstInput.computeOutpoint(params)) :
|
||||
xorMask.mask(
|
||||
feePayload,
|
||||
feePaymentCode,
|
||||
params,
|
||||
utxoKeyProvider.getAddress(firstInput.tx_hash, firstInput.tx_output_n),
|
||||
firstInput.computeOutpoint(params));
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("feePayloadHex=" + Hex.toHexString(feePayload));
|
||||
@ -533,15 +538,15 @@ public class Tx0Service {
|
||||
}
|
||||
}
|
||||
|
||||
signTx0(tx, utxoKeyProvider);
|
||||
tx = signTx0(tx, utxoKeyProvider);
|
||||
tx.verify();
|
||||
|
||||
Tx0 tx0 = new Tx0(tx0Preview, tx, premixOutputs, changeOutputs);
|
||||
return tx0;
|
||||
}
|
||||
|
||||
protected void signTx0(Transaction tx, UtxoKeyProvider utxoKeyProvider) throws Exception {
|
||||
SendFactoryGeneric.getInstance().signTransaction(tx, utxoKeyProvider);
|
||||
protected Transaction signTx0(Transaction tx, UtxoKeyProvider utxoKeyProvider) throws Exception {
|
||||
return config.getSigningHandler().signTx0Transaction(tx, utxoKeyProvider);
|
||||
}
|
||||
|
||||
protected Collection<Tx0Data> fetchTx0Data(String partnerId) throws Exception {
|
||||
|
||||
@ -51,7 +51,7 @@ public class PostmixIndexService {
|
||||
}
|
||||
HD_Address hdAddress = walletPostmix.getAddressAt(Chain.RECEIVE.getIndex(), postmixIndex);
|
||||
String outputAddress = bech32Util.toBech32(hdAddress, config.getNetworkParameters());
|
||||
String signature = hdAddress.getECKey().signMessage(outputAddress);
|
||||
String signature = config.getSigningHandler().signMessage(hdAddress, outputAddress);
|
||||
CheckOutputRequest checkOutputRequest = new CheckOutputRequest(outputAddress, signature);
|
||||
return config.getServerApi().checkOutput(checkOutputRequest);
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ import com.samourai.wallet.bip47.rpc.java.SecretPointFactoryJava;
|
||||
import com.samourai.wallet.bip47.rpc.secretPoint.ISecretPointFactory;
|
||||
import com.samourai.wallet.util.FormatsUtilGeneric;
|
||||
import com.samourai.whirlpool.client.exception.NotifiableException;
|
||||
import com.samourai.whirlpool.client.mix.handler.DefaultSigningHandler;
|
||||
import com.samourai.whirlpool.client.mix.handler.SigningHandler;
|
||||
import com.samourai.whirlpool.client.tx0.ITx0ParamServiceConfig;
|
||||
import com.samourai.whirlpool.client.utils.ClientUtils;
|
||||
import com.samourai.whirlpool.client.wallet.beans.IndexRange;
|
||||
@ -31,6 +33,7 @@ public class WhirlpoolWalletConfig extends WhirlpoolClientConfig implements ITx0
|
||||
|
||||
private DataSourceFactory dataSourceFactory;
|
||||
private DataPersisterFactory dataPersisterFactory;
|
||||
private SigningHandler signingHandler = new DefaultSigningHandler();
|
||||
private boolean mobile;
|
||||
|
||||
private int maxClients;
|
||||
@ -371,6 +374,14 @@ public class WhirlpoolWalletConfig extends WhirlpoolClientConfig implements ITx0
|
||||
this.secretPointFactory = secretPointFactory;
|
||||
}
|
||||
|
||||
public SigningHandler getSigningHandler() {
|
||||
return signingHandler;
|
||||
}
|
||||
|
||||
public void setSigningHandler(SigningHandler signingHandler) {
|
||||
this.signingHandler = signingHandler;
|
||||
}
|
||||
|
||||
public Map<String, String> getConfigInfo() {
|
||||
Map<String, String> configInfo = new LinkedHashMap<String, String>();
|
||||
configInfo.put("dataSourceFactory", dataSourceFactory.getClass().getSimpleName());
|
||||
|
||||
@ -185,6 +185,16 @@ public abstract class BasicUtxoSupplier extends BasicSupplier<UtxoData>
|
||||
return premixAddress.getECKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HD_Address getAddress(String utxoHash, int utxoIndex) throws Exception {
|
||||
WhirlpoolUtxo whirlpoolUtxo = findUtxo(utxoHash, utxoIndex);
|
||||
if (whirlpoolUtxo == null) {
|
||||
throw new Exception("Utxo not found: " + utxoHash + ":" + utxoIndex);
|
||||
}
|
||||
|
||||
return getAddress(whirlpoolUtxo);
|
||||
}
|
||||
|
||||
protected byte[] _getPrivKeyBytes(WhirlpoolUtxo whirlpoolUtxo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ public class MixOrchestratorImpl extends MixOrchestrator {
|
||||
String premix00Bech32 = Bech32UtilGeneric.getInstance().toBech32(premix00, params);
|
||||
String userPreHash = ClientUtils.sha256Hash(premix00Bech32);
|
||||
|
||||
return new PremixHandler(utxoWithBalance, premixKey, userPreHash);
|
||||
return new PremixHandler(utxoWithBalance, premixAddress, userPreHash, whirlpoolWallet.getConfig().getSigningHandler());
|
||||
}
|
||||
|
||||
private IPostmixHandler computePostmixHandler(WhirlpoolUtxo whirlpoolUtxo) {
|
||||
|
||||
@ -45,6 +45,24 @@ public class XorMask {
|
||||
return dataMasked;
|
||||
}
|
||||
|
||||
public byte[] mask(
|
||||
byte[] dataToMask,
|
||||
String paymentCodeOfSecretAccount,
|
||||
NetworkParameters params,
|
||||
HD_Address address,
|
||||
TransactionOutPoint input0OutPoint)
|
||||
throws Exception {
|
||||
HD_Address notifAddressCli =
|
||||
new PaymentCode(paymentCodeOfSecretAccount).notificationAddress(params);
|
||||
ISecretPoint secretPointMask =
|
||||
secretPointFactory.newSecretPoint(address, notifAddressCli.getPubKey());
|
||||
byte[] dataMasked = PaymentCode.xorMask(dataToMask, secretPointMask, input0OutPoint);
|
||||
if (dataMasked == null) {
|
||||
throw new Exception("xorMask failed");
|
||||
}
|
||||
return dataMasked;
|
||||
}
|
||||
|
||||
public byte[] unmask(
|
||||
byte[] dataMasked,
|
||||
BIP47Account secretAccount,
|
||||
|
||||
@ -77,7 +77,7 @@ public class JavaHttpClient extends JacksonHttpClient {
|
||||
protected String requestJsonGet(String urlStr, Map<String, String> headers, boolean async) throws Exception {
|
||||
log.debug("GET " + urlStr);
|
||||
Request req = computeHttpRequest(urlStr, HttpMethod.GET, headers);
|
||||
return makeRequest(req);
|
||||
return requestJson(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,7 +85,7 @@ public class JavaHttpClient extends JacksonHttpClient {
|
||||
log.debug("POST " + urlStr);
|
||||
Request req = computeHttpRequest(urlStr, HttpMethod.POST, headers);
|
||||
req.content(new StringContentProvider(MediaType.APPLICATION_JSON_VALUE, jsonBody, StandardCharsets.UTF_8));
|
||||
return makeRequest(req);
|
||||
return requestJson(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -93,30 +93,7 @@ public class JavaHttpClient extends JacksonHttpClient {
|
||||
log.debug("POST " + urlStr);
|
||||
Request req = computeHttpRequest(urlStr, HttpMethod.POST, headers);
|
||||
req.content(new FormContentProvider(computeBodyFields(body)));
|
||||
return makeRequest(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String postString(String urlStr, Map<String, String> headers, String contentType, String content) throws HttpException {
|
||||
try {
|
||||
return requestPostString(urlStr, headers, contentType, content);
|
||||
} catch (Exception e) {
|
||||
onRequestError(e);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.error("postString failed: " + urlStr + ":" + e.getMessage());
|
||||
}
|
||||
if (!(e instanceof HttpException)) {
|
||||
e = new HttpException(e, null);
|
||||
}
|
||||
throw (HttpException) e;
|
||||
}
|
||||
}
|
||||
|
||||
protected String requestPostString(String urlStr, Map<String, String> headers, String contentType, String content) throws Exception {
|
||||
log.debug("POST " + urlStr);
|
||||
Request req = computeHttpRequest(urlStr, HttpMethod.POST, headers);
|
||||
req.content(new StringContentProvider(content), contentType);
|
||||
return makeRequest(req);
|
||||
return requestJson(req);
|
||||
}
|
||||
|
||||
private Fields computeBodyFields(Map<String, String> body) {
|
||||
@ -127,14 +104,12 @@ public class JavaHttpClient extends JacksonHttpClient {
|
||||
return fields;
|
||||
}
|
||||
|
||||
private String makeRequest(Request req) throws Exception {
|
||||
private String requestJson(Request req) throws Exception {
|
||||
ContentResponse response = req.send();
|
||||
if(response.getStatus() != HttpStatus.OK_200 && response.getStatus() != HttpStatus.CREATED_201 && response.getStatus() != HttpStatus.ACCEPTED_202) {
|
||||
String responseBody = response.getContentAsString();
|
||||
if(log.isDebugEnabled()) {
|
||||
log.error("Http query failed: status=" + response.getStatus() + ", responseBody=" + responseBody);
|
||||
}
|
||||
throw new JavaHttpException(new Exception("Http query failed: status=" + response.getStatus()), responseBody, response.getStatus());
|
||||
log.error("Http query failed: status=" + response.getStatus() + ", responseBody=" + responseBody);
|
||||
throw new HttpException(new Exception("Http query failed: status=" + response.getStatus()), responseBody);
|
||||
}
|
||||
return response.getContentAsString();
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ public class JavaHttpClientService implements IHttpClientService {
|
||||
jettyHttpClient.setScheduler(new ScheduledExecutorScheduler(name + "-scheduler", true));
|
||||
|
||||
// prevent user-agent tracking
|
||||
jettyHttpClient.setUserAgentField(null);
|
||||
// jettyHttpClient.setUserAgentField(new HttpField(HttpHeader.USER_AGENT, userAgent));
|
||||
|
||||
// proxy
|
||||
if(proxy != null) {
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
package com.sparrowwallet.nightjar.http;
|
||||
|
||||
import com.samourai.wallet.api.backend.beans.HttpException;
|
||||
|
||||
public class JavaHttpException extends HttpException {
|
||||
private final int statusCode;
|
||||
|
||||
public JavaHttpException(Exception cause, String responseBody, int statusCode) {
|
||||
super(cause, responseBody);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public JavaHttpException(String message, String responseBody, int statusCode) {
|
||||
super(message, responseBody);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
}
|
||||
@ -785,7 +785,7 @@ public class ECKey implements EncryptableItem {
|
||||
|
||||
ASN1TaggedObject pubkey = (ASN1TaggedObject) seq.getObjectAt(3);
|
||||
checkArgument(pubkey.getTagNo() == 1, "Input has 'publicKey' with bad tag number");
|
||||
byte[] pubbits = ((DERBitString)pubkey.getBaseObject()).getBytes();
|
||||
byte[] pubbits = ((DERBitString)pubkey.getObject()).getBytes();
|
||||
checkArgument(pubbits.length == 33 || pubbits.length == 65, "Input has 'publicKey' with invalid length");
|
||||
int encoding = pubbits[0] & 0xFF;
|
||||
// Only allow compressed(2,3) and uncompressed(4), not infinity(0) or hybrid(6,7)
|
||||
|
||||
@ -30,7 +30,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.Normalizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -145,7 +144,7 @@ public class MnemonicCode {
|
||||
// derived key is 512 bits (= 64 bytes).
|
||||
//
|
||||
String pass = Utils.join(words);
|
||||
String salt = "mnemonic" + Normalizer.normalize(passphrase, Normalizer.Form.NFKD);
|
||||
String salt = "mnemonic" + passphrase;
|
||||
|
||||
final Stopwatch watch = Stopwatch.createStarted();
|
||||
byte[] seed = PBKDF2SHA512.derive(pass, salt, PBKDF2_ROUNDS, 64);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user