Skip to content

Commit

Permalink
support ethereum dapp
Browse files Browse the repository at this point in the history
  • Loading branch information
duanyytop committed Jul 17, 2018
1 parent a3b959c commit 4555b10
Show file tree
Hide file tree
Showing 37 changed files with 399 additions and 361 deletions.
3 changes: 2 additions & 1 deletion app/build.gradle
Expand Up @@ -100,6 +100,8 @@ dependencies {
// implementation 'org.web3j:core:3.3.1-android'
implementation 'com.yanzhenjie:permission:2.0.0-rc5'
implementation 'io.reactivex:rxjava:1.2.4'
implementation 'com.github.TrustWallet:trust-web3-provider:0.2.1'
api 'com.github.TrustWallet:TrustCoreAndroid:0.01.6'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
Expand All @@ -115,7 +117,6 @@ dependencies {
implementation files('libs/rlp-3.3.2-android.jar')
implementation files('libs/tuples-3.3.2-android.jar')
implementation files('libs/utils-3.3.2-android.jar')
implementation project(path: ':lib')
}

def getVersionName(boolean isDebug) {
Expand Down
199 changes: 89 additions & 110 deletions app/src/main/java/org/nervos/neuron/activity/AppWebActivity.java
Expand Up @@ -7,7 +7,6 @@
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
Expand All @@ -19,29 +18,26 @@

import org.nervos.neuron.R;
import org.nervos.neuron.dialog.SimpleDialog;
import org.nervos.neuron.item.AppItem;
import org.nervos.neuron.item.WalletItem;
import org.nervos.neuron.service.SignService;
import org.nervos.neuron.util.Blockies;
import org.nervos.neuron.util.ConstUtil;
import org.nervos.neuron.util.LogUtil;
import org.nervos.neuron.util.NumberUtil;
import org.nervos.neuron.util.crypto.AESCrypt;
import org.nervos.neuron.util.web.WebAppUtil;
import org.nervos.neuron.util.db.DBWalletUtil;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Sign;
import org.web3j.utils.Numeric;

import java.security.GeneralSecurityException;
import java.util.concurrent.Callable;

import de.hdodenhof.circleimageview.CircleImageView;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import trust.core.entity.Address;
import trust.web3.Web3View;
import trust.web3.item.Transaction;
import org.nervos.neuron.webview.OnSignMessageListener;
import org.nervos.neuron.webview.Web3View;
import org.nervos.neuron.webview.item.Message;
import org.nervos.neuron.webview.item.Transaction;

public class AppWebActivity extends BaseActivity {

Expand All @@ -60,14 +56,15 @@ public class AppWebActivity extends BaseActivity {
private BottomSheetDialog sheetDialog;

private WalletItem walletItem;
private Transaction transaction;
private Transaction signTransaction;
private String url;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_web);

String url = getIntent().getStringExtra(EXTRA_URL);
url = getIntent().getStringExtra(EXTRA_URL);
walletItem = DBWalletUtil.getCurrentWallet(mActivity);

initView();
Expand Down Expand Up @@ -142,22 +139,37 @@ private void initInjectWebView() {

webView.setOnSignTransactionListener(transaction -> {
Toast.makeText(mActivity,
"transaction information: payload: " + transaction.data
+ " gasPrice: " + transaction.gasPrice, Toast.LENGTH_LONG).show();
this.transaction = transaction;
if (walletItem == null) {
Toast.makeText(mActivity, R.string.no_wallet_suggestion, Toast.LENGTH_SHORT).show();
startActivity(new Intent(mActivity, AddWalletActivity.class));
} else {
Intent intent = new Intent(mActivity, PayTokenActivity.class);
intent.putExtra(EXTRA_PAYLOAD, new Gson().toJson(transaction));
intent.putExtra(EXTRA_CHAIN, WebAppUtil.getAppItem());
startActivityForResult(intent, REQUEST_CODE);
}
"transaction information: payload: " + transaction.data, Toast.LENGTH_LONG).show();
signTxAction(transaction);
});

webView.setOnSignMessageListener(new OnSignMessageListener() {
@Override
public void onSignMessage(Message<Transaction> message) {
Toast.makeText(mActivity,
"transaction information: message: " + message.url + " "
+ message.value + " " + message.leafPosition, Toast.LENGTH_LONG).show();
showSignMessageDialog(message);
}
});
}


private void signTxAction(Transaction transaction) {
this.signTransaction = transaction;
if (walletItem == null) {
Toast.makeText(mActivity, R.string.no_wallet_suggestion, Toast.LENGTH_SHORT).show();
startActivity(new Intent(mActivity, AddWalletActivity.class));
} else {
Intent intent = new Intent(mActivity, PayTokenActivity.class);
intent.putExtra(EXTRA_PAYLOAD, new Gson().toJson(transaction));
intent.putExtra(EXTRA_CHAIN, WebAppUtil.getAppItem() == null?
new AppItem(url):WebAppUtil.getAppItem());
startActivityForResult(intent, REQUEST_CODE);
}
}


private void initWebView() {
webView.setWebChromeClient(new WebChromeClient(){
@Override
Expand Down Expand Up @@ -189,19 +201,6 @@ public void onPageFinished(WebView view, String url) {
});
}

private class Nervos {

@JavascriptInterface
public void signTransaction(String tx) {
if (walletItem == null) {
Toast.makeText(mActivity, R.string.no_wallet_suggestion, Toast.LENGTH_SHORT).show();
startActivity(new Intent(mActivity, AddWalletActivity.class));
} else {
showSignMessageDialog(tx);
}
}
}

@Override
public void onDestroy() {
if (sheetDialog != null && sheetDialog.isShowing()) {
Expand All @@ -210,14 +209,14 @@ public void onDestroy() {
super.onDestroy();
}

private void showSignMessageDialog(String tx) {
private void showSignMessageDialog(Message<Transaction> message) {
sheetDialog = new BottomSheetDialog(mActivity);
sheetDialog.setCanceledOnTouchOutside(true);
sheetDialog.setContentView(getSignMessageView(tx));
sheetDialog.setContentView(getSignMessageView(message));
sheetDialog.show();
}

private View getSignMessageView(String tx) {
private View getSignMessageView(Message<Transaction> message) {
View view = getLayoutInflater().inflate(R.layout.dialog_sign_message, null);
TextView walletNameText = view.findViewById(R.id.wallet_name);
TextView walletAddressText = view.findViewById(R.id.wallet_address);
Expand All @@ -228,19 +227,19 @@ private View getSignMessageView(String tx) {

walletNameText.setText(walletItem.name);
walletAddressText.setText(walletItem.address);
payOwnerText.setText(WebAppUtil.getAppItem().entry);
payDataText.setText(tx);
payOwnerText.setText(WebAppUtil.getAppItem() == null?
url:WebAppUtil.getAppItem().entry);
payDataText.setText(message.value.data);
photoImage.setImageBitmap(Blockies.createIcon(walletItem.address));
if (WebAppUtil.getAppItem() != null) {
payOwnerText.setText(WebAppUtil.getAppItem().provider);
payDataText.setText(tx);
}
view.findViewById(R.id.sign_hex_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.findViewById(R.id.pay_data_left_line).setVisibility(View.VISIBLE);
view.findViewById(R.id.pay_data_right_line).setVisibility(View.GONE);
payDataText.setText(tx);
payDataText.setText(message.value.data);
}
});

Expand All @@ -249,30 +248,31 @@ public void onClick(View v) {
public void onClick(View v) {
view.findViewById(R.id.pay_data_left_line).setVisibility(View.GONE);
view.findViewById(R.id.pay_data_right_line).setVisibility(View.VISIBLE);
if (Numeric.containsHexPrefix(tx)) {
payDataText.setText(NumberUtil.hexToUtf8(tx));
if (Numeric.containsHexPrefix(message.value.data)) {
payDataText.setText(NumberUtil.hexToUtf8(message.value.data));
}
}
});
view.findViewById(R.id.pay_reject).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sheetDialog.dismiss();
webView.onSignCancel(message);
}
});
view.findViewById(R.id.pay_approve).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPasswordConfirmView(progressBar, tx);
showPasswordConfirmView(progressBar, message);
}
});
return view;
}

private void showPasswordConfirmView(ProgressBar progressBar, String tx) {
private void showPasswordConfirmView(ProgressBar progressBar, Message<Transaction> message) {
SimpleDialog simpleDialog = new SimpleDialog(mActivity);
simpleDialog.setTitle(R.string.input_password_hint);
simpleDialog.setMessageHint("password");
simpleDialog.setMessageHint(R.string.input_password_hint);
simpleDialog.setEditInputType(SimpleDialog.PASSWORD);
simpleDialog.setOnOkClickListener(new SimpleDialog.OnOkClickListener() {
@Override
Expand All @@ -286,77 +286,56 @@ public void onOkClick() {
return;
}
progressBar.setVisibility(View.VISIBLE);
actionSignNervos(password, tx);
simpleDialog.dismiss();

if (Transaction.TYPE_ETH.equals(message.value.chainType)) {
actionSignEth(password, message);
} else if (Transaction.TYPE_APPCHAIN.equals(message.value.chainType)){
actionSignNervos(password, message);
}
}
});
simpleDialog.setOnCancelClickListener(() -> simpleDialog.dismiss());
simpleDialog.show();
}

private void actionSignEth(String password, String tx) {
Observable.fromCallable(new Callable<Sign.SignatureData>() {
@Override
public Sign.SignatureData call() {
try {
String privateKey = AESCrypt.decrypt(password, walletItem.cryptPrivateKey);
return Sign.signMessage(tx.getBytes(),
ECKeyPair.create(Numeric.toBigInt(privateKey)));
} catch (GeneralSecurityException e) {
private void actionSignEth(String password, Message<Transaction> message) {
SignService.signEthMessage(mActivity, message.value.data, password).
subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
sheetDialog.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
sheetDialog.dismiss();
webView.onSignError(message, e.getMessage());
}
return null;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Sign.SignatureData>() {
@Override
public void onCompleted() {
sheetDialog.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
sheetDialog.dismiss();
}
@Override
public void onNext(Sign.SignatureData signatureData) {
LogUtil.d("signatureData: " + new String(signatureData.getR()));
}
});
@Override
public void onNext(String hexSign) {
webView.onSignMessageSuccessful(message, hexSign);
}
});
}

private void actionSignNervos(String password, String tx) {
Observable.fromCallable(new Callable<org.nervos.web3j.crypto.Sign.SignatureData>() {
@Override
public org.nervos.web3j.crypto.Sign.SignatureData call() {
try {
String privateKey = AESCrypt.decrypt(password, walletItem.cryptPrivateKey);
return org.nervos.web3j.crypto.Sign.signMessage(tx.getBytes(),
org.nervos.web3j.crypto.ECKeyPair.create(Numeric.toBigInt(privateKey)));
} catch (GeneralSecurityException e) {
private void actionSignNervos(String password, Message<Transaction> message) {
SignService.signNervosMessage(mActivity, message.value.data, password)
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
sheetDialog.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
sheetDialog.dismiss();
webView.onSignError(message, e.getMessage());
}
return null;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<org.nervos.web3j.crypto.Sign.SignatureData>() {
@Override
public void onCompleted() {
sheetDialog.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
sheetDialog.dismiss();
}
@Override
public void onNext(org.nervos.web3j.crypto.Sign.SignatureData signatureData) {
LogUtil.d("signatureData: " + new String(signatureData.get_signature()));
}
});
@Override
public void onNext(String hexSign) {
webView.onSignMessageSuccessful(message, hexSign);
}
});
}

@Override
Expand All @@ -365,14 +344,14 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
switch (resultCode) {
case RESULT_CODE_CANCEL:
webView.onSignCancel(transaction);
webView.onSignCancel(signTransaction);
break;
case RESULT_CODE_SUCCESS:
webView.onSignTransactionSuccessful(transaction,
webView.onSignTransactionSuccessful(signTransaction,
data.getStringExtra(PayTokenActivity.EXTRA_HEX_HASH));
break;
case RESULT_CODE_FAIL:
webView.onSignError(transaction,
webView.onSignError(signTransaction,
data.getStringExtra(PayTokenActivity.EXTRA_PAY_ERROR));
break;
default:
Expand Down

0 comments on commit 4555b10

Please sign in to comment.