/*
* Copyright 2014 http://Bither.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bither.runnable;
import net.bither.bitherj.core.Address;
import net.bither.bitherj.core.HDMAddress;
import net.bither.bitherj.core.Tx;
import net.bither.bitherj.crypto.SecureCharSequence;
import net.bither.bitherj.exception.PasswordException;
import net.bither.bitherj.exception.TxBuilderException;
import net.bither.bitherj.utils.Utils;
import net.bither.utils.LocaliserUtils;
import net.bither.utils.WalletUtils;
public class CompleteTransactionRunnable extends BaseRunnable {
private Address wallet;
private SecureCharSequence password;
private long amount;
private String toAddress;
private String changeAddress;
private boolean toSign = false;
private HDMAddress.HDMFetchOtherSignatureDelegate sigFetcher1;
private HDMAddress.HDMFetchOtherSignatureDelegate sigFetcher2;
static {
WalletUtils.initTxBuilderException();
}
public CompleteTransactionRunnable(Address a, long amount, String toAddress,
SecureCharSequence password) throws Exception {
this(a, amount, toAddress, toAddress, password, null);
}
public CompleteTransactionRunnable(Address a, long amount, String toAddress,
String changeAddress, SecureCharSequence password) throws Exception {
this(a, amount, toAddress, changeAddress, password, null);
}
public CompleteTransactionRunnable(Address a, long amount, String toAddress,
String changeAddress, SecureCharSequence password,
HDMAddress.HDMFetchOtherSignatureDelegate
otherSigFetcher1) throws Exception {
this(a, amount, toAddress, changeAddress, password, otherSigFetcher1, null);
}
public CompleteTransactionRunnable(Address a, long amount, String toAddress,
String changeAddress, SecureCharSequence password,
HDMAddress.HDMFetchOtherSignatureDelegate
otherSigFetcher1,
HDMAddress.HDMFetchOtherSignatureDelegate
otherSigFetcher2) throws Exception {
boolean isHDM = otherSigFetcher1 != null || otherSigFetcher2 != null;
this.amount = amount;
this.toAddress = toAddress;
this.password = password;
sigFetcher1 = otherSigFetcher1;
sigFetcher2 = otherSigFetcher2;
if (isHDM) {
wallet = a;
toSign = true;
} else if (password == null || password.length() == 0) {
wallet = a;
toSign = false;
} else {
if (a.hasPrivKey()) {
wallet = a;
} else {
throw new Exception("address not with private key");
}
toSign = true;
}
if (!Utils.isEmpty(changeAddress)) {
this.changeAddress = changeAddress;
} else {
this.changeAddress = wallet.getAddress();
}
}
@Override
public void run() {
prepare();
try {
Tx tx = wallet.buildTx(amount, toAddress, changeAddress);
if (tx == null) {
error(0, LocaliserUtils.getString("send_failed"));
return;
}
if (toSign) {
if (wallet.isHDM()) {
if (sigFetcher1 != null && sigFetcher2 != null) {
((HDMAddress) wallet).signTx(tx, password, sigFetcher1, sigFetcher2);
} else if (sigFetcher1 != null || sigFetcher2 != null) {
((HDMAddress) wallet).signTx(tx, password,
sigFetcher1 != null ? sigFetcher1 : sigFetcher2);
} else {
throw new RuntimeException("need sig fetcher to sign hdm tx");
}
} else {
wallet.signTx(tx, password);
}
if (password != null) {
password.wipe();
}
if (!tx.verifySignatures()) {
error(0, getMessageFromException(null));
return;
}
}
success(tx);
} catch (Exception e) {
if (password != null) {
password.wipe();
}
if (e instanceof HDMSignUserCancelExcetion) {
error(0, null);
return;
}
e.printStackTrace();
String msg = getMessageFromException(e);
error(0, msg);
}
}
public String getMessageFromException(Exception e) {
if (e != null && e instanceof TxBuilderException) {
return e.getMessage();
} else if (e != null && e instanceof PasswordException) {
return LocaliserUtils.getString("password_wrong");
} else {
return LocaliserUtils.getString("send_failed");
}
}
public static final class HDMServerSignException extends RuntimeException {
public HDMServerSignException(String msg) {
super(msg);
}
}
public static final class HDMSignUserCancelExcetion extends RuntimeException {
}
}