Browse Source

Electrum (#9)

* modify strings

* move update public to android app

* modify tx list UI

* modify UI

* fix read firmware version code timeout

* modify version code

* fix some UI issue

* fix some UI issue
V1.1.0-release
JunZhang 5 years ago
committed by GitHub
parent
commit
3412f499fb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/build.gradle
  2. 19
      app/src/main/java/com/cobo/cold/callables/FirmwareParameterCallable.java
  3. 47
      app/src/main/java/com/cobo/cold/callables/GetUpdateKeyCallable.java
  4. 2
      app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java
  5. 7
      app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java
  6. 7
      app/src/main/java/com/cobo/cold/ui/fragment/main/electrum/ElectrumTxnListFragment.java
  7. 5
      app/src/main/java/com/cobo/cold/ui/views/MenuHidingEditText.java
  8. 6
      app/src/main/java/com/cobo/cold/update/Checking.java
  9. 4
      app/src/main/java/com/cobo/cold/update/Updating.java
  10. 12
      app/src/main/java/com/cobo/cold/viewmodel/AboutViewModel.java
  11. 2
      app/src/main/res/layout/electrum_export.xml
  12. 2
      app/src/main/res/layout/electrum_tx_detail.xml
  13. 13
      app/src/main/res/layout/tx_list_item.xml
  14. 8
      app/src/main/res/values-zh-rCN/strings.xml
  15. 8
      app/src/main/res/values/strings.xml
  16. 2
      app/version.properties
  17. 19
      encryption-core/src/main/java/com/cobo/cold/encryptioncore/base/Packet.java
  18. 3
      encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java

3
app/build.gradle

@ -109,6 +109,7 @@ android {
}
manifestPlaceholders = ["sharedUserId": 'android.uid.system']
buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\""
buildConfigField "String", "UPDATE_PUBLIC_KEY", "\"308201a2300d06092a864886f70d01010105000382018f003082018a0282018100df75e9c2f82e9113e93cf5cf1739436694f12b9009c6bc37156f3cc30f259f3a0661bdd223a833d39a468161751c58a870f25022c619a4010b49058ae23c2b67dab4d6e3cb92a119a0de326303dbad67b33c79a8a1643db6f1a5e955bc7d4de6e9080780df37ac0bc8ad32e9b013e467f04bf0ab158059f5bd728b822456b728b7ec0ba894433f309a7f17fda5df463b09ecc8af5dfbb1159127aaee393696bfb5291353522a5428897824904f25f0b61453d295fd920303e2f72928e17212cbb11d0c701e13029761c570cc46c6fa1ddbbc973864595d860ebbca03bdb9e70136f09210e94e614df988a2dac7bfcc9acb997ed01ab4f75cbf02336c6a753a4ec6b517e0ec84f260d61a4e00ee56d9e152bd8b9a2f0a48846993bd95e2db308c23aedc2e527b532228661c6fb63e2b0dd0900b2a1a36a6d046d64a3a59fef9c566771fd541b5cdb074effd02574a6b5eaa1194e8fc1f2f835657ac9a72a20412e446b3a47105ee65745e6b816b906ef34545fe6fb4aaadc37703e6f599dc6d370203010001\""
signingConfig signingConfigs.vault_v2
}
}
@ -216,7 +217,7 @@ def getVersionProperties() {
}
def versionMajor = 1
def versionMinor = 0
def versionMinor = 1
def versionPatch = versionProps.getProperty('patch', '0').toInteger()
def isVaultRelease = false

19
app/src/main/java/com/cobo/cold/callables/FirmwareParameterCallable.java

@ -23,23 +23,20 @@ import com.cobo.cold.encryptioncore.base.Payload;
import java.util.concurrent.Callable;
public class FirmwareParameterCallable implements Callable<String[]> {
public class FirmwareParameterCallable implements Callable<String> {
@Override
public String[] call() {
public String call() {
try {
String[] res = new String[2];
final Callable<Packet> callable = new BlockingCallable(
new Packet.Builder(CONSTANTS.METHODS.GET_FIRMWARE_PARAMETER).build());
new Packet.Builder(CONSTANTS.METHODS.GET_FIRMWARE_PARAMETER)
.setRetryTimes(5)
.setTimeout(3)
.build());
final Packet result = callable.call();
Payload payload = result.getPayload(CONSTANTS.TAGS.FIRMWARE_SN);
Payload payload = result.getPayload(CONSTANTS.TAGS.FIRMWARE_APP_VERSION);
if (payload != null) {
res[0] = payload.toUtf8();
return payload.toUtf8();
}
payload = result.getPayload(CONSTANTS.TAGS.FIRMWARE_APP_VERSION);
if (payload != null) {
res[1] = payload.toUtf8();
}
return res;
} catch (Exception e) {
e.printStackTrace();
}

47
app/src/main/java/com/cobo/cold/callables/GetUpdateKeyCallable.java

@ -1,47 +0,0 @@
/*
* Copyright (c) 2020 Cobo
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* in the file COPYING. If not, see <http://www.gnu.org/licenses/>.
*/
package com.cobo.cold.callables;
import com.cobo.cold.encryption.interfaces.CONSTANTS;
import com.cobo.cold.encryptioncore.base.Packet;
import com.cobo.cold.encryptioncore.base.Payload;
import java.util.concurrent.Callable;
public class GetUpdateKeyCallable implements Callable<String> {
@Override
public String call() {
try {
final Packet packet = new Packet.Builder(CONSTANTS.METHODS.GET_UPDATE_KEY)
.addBytePayload(CONSTANTS.TAGS.UPDATE_KEY_OPERATION, CONSTANTS.VALS.READ_UPDATE_KEY)
.build();
final Callable<Packet> callable = new BlockingCallable(packet);
final Packet result = callable.call();
final Payload payload = result.getPayload(CONSTANTS.TAGS.UPDATE_KEY);
if (payload != null) {
return payload.toHex();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

2
app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java

@ -89,7 +89,7 @@ public class PassphraseFragment extends SetupVaultBaseFragment<PassphraseBinding
String input1 = passphrase1.get();
String input2 = passphrase2.get();
if (input2.length() >= input1.length() && !input1.equals(input2)) {
mBinding.inputHint.setText(R.string.password_verify_wrong);
mBinding.inputHint.setText(R.string.passphrase_not_match);
mBinding.inputHint.setTextColor(Color.RED);
} else {
mBinding.inputHint.setText(R.string.passphrase_hint3);

7
app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java

@ -152,6 +152,13 @@ public class TxListFragment extends BaseFragment<TxListBinding> {
protected void onBindItem(TxListItemBinding binding, TxEntity item) {
binding.setTx(item);
binding.setTxCallback(txCallback);
if (ELECTRUM_SIGN_ID.equals(item.getSignId())) {
binding.fromWallet.setText(R.string.from_electrum);
binding.fromWallet.setVisibility(View.VISIBLE);
binding.amount.setVisibility(View.GONE);
} else {
binding.fromWallet.setVisibility(View.GONE);
}
updateFrom(binding, item);
updateTo(binding, item);
}

7
app/src/main/java/com/cobo/cold/ui/fragment/main/electrum/ElectrumTxnListFragment.java

@ -33,6 +33,7 @@ import com.cobo.cold.databinding.TxnListBinding;
import com.cobo.cold.ui.MainActivity;
import com.cobo.cold.ui.common.BaseBindingAdapter;
import com.cobo.cold.ui.fragment.BaseFragment;
import com.cobo.cold.ui.modal.ModalDialog;
import com.cobo.cold.viewmodel.ElectrumViewModel;
import java.util.concurrent.atomic.AtomicBoolean;
@ -108,7 +109,11 @@ public class ElectrumTxnListFragment extends BaseFragment<TxnListBinding>
bundle.putBoolean("is_file", true);
navigate(R.id.action_to_ElectrumTxConfirmFragment, bundle);
} else {
Toast.makeText(mActivity, R.string.error_txn_file, Toast.LENGTH_SHORT).show();
ModalDialog.showCommonModal(mActivity,
getString(R.string.electrum_decode_txn_fail),
getString(R.string.error_txn_file),
getString(R.string.confirm),
null);
}
});
}

5
app/src/main/java/com/cobo/cold/ui/views/MenuHidingEditText.java

@ -23,13 +23,14 @@ import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatEditText;
import java.lang.reflect.Field;
@SuppressLint("AppCompatCustomView")
public class MenuHidingEditText extends EditText {
public class MenuHidingEditText extends AppCompatEditText {
private final Context mContext;
public MenuHidingEditText(Context context) {

6
app/src/main/java/com/cobo/cold/update/Checking.java

@ -26,10 +26,10 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.cobo.cold.BuildConfig;
import com.cobo.cold.MainApplication;
import com.cobo.cold.callables.CheckBootModeCallable;
import com.cobo.cold.callables.CheckUpdateFirmwareCallable;
import com.cobo.cold.callables.GetUpdateKeyCallable;
import com.cobo.cold.encryptioncore.utils.ByteFormatter;
import com.cobo.cold.encryptioncore.utils.Preconditions;
import com.cobo.cold.update.data.FileInfo;
@ -215,7 +215,7 @@ public class Checking implements Callable<UpdateManifest> {
private boolean checkSerialUpdate(FileInfo serial) {
String serialFile = serial.fileName;
final File updateFile = mStorage.getUpdateZipFile();
String updateKey = new GetUpdateKeyCallable().call();
String updateKey = BuildConfig.UPDATE_PUBLIC_KEY;
File serialBin = null;
@ -273,7 +273,7 @@ public class Checking implements Callable<UpdateManifest> {
return null;
}
String updateKey = new GetUpdateKeyCallable().call();
String updateKey = BuildConfig.UPDATE_PUBLIC_KEY;
if (TextUtils.isEmpty(updateKey)) {
return null;

4
app/src/main/java/com/cobo/cold/update/Updating.java

@ -26,7 +26,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.cobo.cold.callables.GetUpdateKeyCallable;
import com.cobo.cold.BuildConfig;
import com.cobo.cold.callables.UpdateCallable;
import com.cobo.cold.encryptioncore.utils.ByteFormatter;
import com.cobo.cold.encryptioncore.utils.Preconditions;
@ -195,7 +195,7 @@ public class Updating implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
String updateKey = new GetUpdateKeyCallable().call();
String updateKey = BuildConfig.UPDATE_PUBLIC_KEY;
if (TextUtils.isEmpty(updateKey)) {
return false;

12
app/src/main/java/com/cobo/cold/viewmodel/AboutViewModel.java

@ -22,7 +22,6 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.SystemProperties;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
@ -61,18 +60,13 @@ public class AboutViewModel extends AndroidViewModel {
}
private void getFirmwareInfo() {
sn.set(SystemProperties.get("persist.sys.serialno"));
AppExecutors.getInstance().diskIO().execute(() -> {
String[] res = new FirmwareParameterCallable().call();
String res = new FirmwareParameterCallable().call();
if (res == null) {
return;
}
if (TextUtils.isEmpty(res[0])) {
sn.set(SystemProperties.get("persist.sys.serialno"));
} else {
sn.set(res[0]);
}
firmwareAppVersion.set(res[1]);
firmwareAppVersion.set(res);
});
}

2
app/src/main/res/layout/electrum_export.xml

@ -45,7 +45,7 @@
android:layout_marginEnd="20dp"
android:ellipsize="middle"
android:singleLine="true"
android:text="@string/export_to_electrum"
android:text="@string/electrum_compatibility"
android:textColor="@android:color/white"
android:textSize="15sp" />
</androidx.appcompat.widget.Toolbar>

2
app/src/main/res/layout/electrum_tx_detail.xml

@ -329,6 +329,7 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:text="@string/electrum_qrcode_hint"
android:textColor="@color/white"
@ -354,6 +355,7 @@
android:paddingHorizontal="16dp"
android:textColor="@color/white"
android:text="@string/export_signed_txn_action_guide"
android:textSize="12sp"
android:gravity="center"/>
</LinearLayout>

13
app/src/main/res/layout/tx_list_item.xml

@ -100,6 +100,19 @@
app:time="@{tx.timeStamp}"
tools:text="2018/06/01" />
<TextView
android:id="@+id/from_wallet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="16dp"
android:gravity="end"
android:layout_centerVertical="true"
android:textStyle="bold"
android:textColor="@color/white40"
android:textSize="12sp"
android:visibility="gone"
tools:text="@string/from_electrum" />
<include
layout="@layout/divider"

8
app/src/main/res/values-zh-rCN/strings.xml

@ -76,6 +76,7 @@
<string name="pwd_again_hint">请再次输入密码</string>
<string name="pwd_hint">请输入密码</string>
<string name="password_verify_wrong">两次输入不一致</string>
<string name="passphrase_not_match">两次输入不一致</string>
<string name="password_input_wrong">必须同时包含大、小写字母和数字</string>
<string name="mnemonic_hint"><![CDATA[提示:<br>1. 助记词为恢复资产的唯一途径,请按顺序正确记录,并妥善保管到安全的脱网环境中。 <br><br>2. 请勿将助记词拍照、储存在联网设备上或泄露给他人!助记词丢失或泄露将意味着资产丢失! <br><br>3.您可访问 <font color="#00cdc3">https://cobo.com/hardware-wallet/cobo-tablet<font/> 购买 Cobo 金刚匣安全方便保存您的助记词。]]></string>
<string name="generate_mnemonic">生成助记词</string>
@ -275,7 +276,7 @@
<string name="export_success">导出成功</string>
<string name="read_sdcard">读取TF卡</string>
<string name="no_sdcard">未检测到TF卡</string>
<string name="no_sdcard_hint">请先插入TF卡(仅支持FAT32格式,容量不能超过32GB),再前往签名记录里导出文件。</string>
<string name="no_sdcard_hint">请先插入TF卡(仅支持FAT32格式,容量不能超过32GB)</string>
<string name="no_unsigned_txn">未检测到待签文件</string>
<string name="no_unsigned_txn_hint">请检查TF卡中是否存有待签文件</string>
<string name="electrum_broadcast_guide">Electrum 广播指引</string>
@ -289,12 +290,12 @@
<string name="insert_sdcard_hint">请先插入TF卡(仅支持FAT32格式,容量不能超过32G)</string>
<string name="electrum_import_xpub_action">在 Electrum 输入主公钥页面打开该文件</string>
<string name="transaction_source_label">热端钱包</string>
<string name="use_electrum_to_broadcast">请用 Electrum 扫描二维码进行广播</string>
<string name="use_electrum_to_broadcast">请用 Electrum 扫描二维码广播</string>
<string name="transaction_from_electrum">该笔交易热端来源于Electrum</string>
<string name="add_address">添加地址</string>
<string name="use_electrum_scan_xpub">请用 Electrum 扫描主公钥二维码</string>
<string name="export_signed_txn_file">导出已签名文件</string>
<string name="export_signed_txn_action_guide">导出后,用 Electrum 进行广播\n前往【Electrum--工具--加载交易--从文件】打开该文件</string>
<string name="export_signed_txn_action_guide">导出后,用 Electrum 进行广播\n前往【Electrum--工具--加载交易--从文件】打开该文件</string>
<string name="export">导出</string>
<string name="export_xpub_text_file">导出主公钥文件</string>
<string name="file_name_label">该文件的文件名为:</string>
@ -306,4 +307,5 @@
<string name="change">找零</string>
<string name="electrum_compatibility">适配 Electrum</string>
<string name="identification_failed">交易识别失败</string>
<string name="from_electrum">来自Electrum</string>
</resources>

8
app/src/main/res/values/strings.xml

@ -41,7 +41,7 @@
<string name="www_cobo_com" translatable="false">www.cobo.com</string>
<string name="device_info">Serial Number: %s \n Firmware Version: %s\n System Version:%s\n App Version:%s</string>
<string name="addr" translatable="false">addr.</string>
<string name="asset_list_empty">Please go to \"Menu - Add / Hide Assets\" to add assets you need</string>
<string name="asset_list_empty">Please go to Menu - Add / Hide Assets to add assets you need</string>
<string name="mnemonic_hint1">"The recovery phrase is used to restore your wallet. Use a Cobo Tablet to record your 24 recovery phrase words and store them securely."</string>
<string name="mnemonic_hint2">Do not share your recovery phrase with anyone or take a picture of it. If it is lost or stolen, all assets are irretrievable.</string>
<string name="saved">Recovery Phrase Saved</string>
@ -113,6 +113,7 @@
<string name="pwd_again_hint">Confirm password</string>
<string name="pwd_hint">Please enter your password</string>
<string name="password_verify_wrong">Passwords do not match.</string>
<string name="passphrase_not_match">Passphrase do not match.</string>
<string name="password_input_wrong">Must include upper and lower case letters and numbers.</string>
<string name="mnemonic_hint"><![CDATA[Important Information: <br>1. The recovery phrase is the only way retrieve your assets. Please use record your recovery phrase carefully and store in a safe location. <br><br>2. Do not take photos of your recovery phrase or store on a device connected to the Internet. Do not share the recovery phrase with others. <br><br>3. Visit <font color="#00cdc3">https://cobo.com/hardware-wallet/cobo-tablet<font/> to purchase a Cobo Tablet to store your recovery phrase with a higher degree of security.]]></string>
<string name="generate_mnemonic">Generate Recovery Phrase</string>
@ -299,7 +300,7 @@
<string name="export_success">Export Successful</string>
<string name="read_sdcard">MicroSD card</string>
<string name="no_sdcard">MicroSD Card Not Found</string>
<string name="no_sdcard_hint">Please make sure you have inserted a FAT32 format microSD card with capacity 32GB or less, and that the signed transaction information has been uploaded to it.</string>
<string name="no_sdcard_hint">Please make sure you have inserted a FAT32 format microSD card with capacity 32GB or less</string>
<string name="no_unsigned_txn">File Not Found</string>
<string name="no_unsigned_txn_hint">Please make sure the file you wish to sign was successfully saved to your microSD card.</string>
<string name="electrum_broadcast_guide">How to Broadcast</string>
@ -323,11 +324,12 @@
<string name="export_xpub_text_file">Export Master Public Key File</string>
<string name="file_name_label">File name:</string>
<string name="master_xpub">Master Public Key (Nested SegWit)</string>
<string name="electrum_qrcode_hint"><![CDATA[Difficulty scanning?Tap the QR code to enlarge<br>or <u>\"touch here to export via microSD.\"</u>]]></string>
<string name="electrum_qrcode_hint"><![CDATA[Difficulty scanning?Tap the QR code to enlarge<br>or <u>touch here to export via microSD.</u>]]></string>
<string name="scan_electrum_hint">Difficulty scanning Electrum? You can export the pending transactions as a file using a microSD card (Menu > MicroSD Card)</string>
<string name="sign_txn_in_sdcard">Files Awaiting Signature</string>
<string name="master_pubkey_not_match">This transaction can\'t be recognized, your Cobo Vault doesn’t match the watch-only wallet. </string>
<string name="change">Change</string>
<string name="electrum_compatibility">Electrum Compatibility</string>
<string name="identification_failed">Identification Failed</string>
<string name="from_electrum">From Electrum</string>
</resources>

2
app/version.properties

@ -16,4 +16,4 @@
#
#Fri Feb 21 13:33:46 CST 2020
patch=5
patch=0

19
encryption-core/src/main/java/com/cobo/cold/encryptioncore/base/Packet.java

@ -33,13 +33,17 @@ import org.json.JSONObject;
public class Packet {
private final int id;
private final int retryTimes;
private final int timeout;
@NonNull
private final SparseArrayCompat<Payload> payloads;
private Packet(int id, @NonNull SparseArrayCompat<Payload> payloads, int retryTimes) {
private Packet(int id, @NonNull SparseArrayCompat<Payload> payloads,
int retryTimes,
int timeout) {
this.id = id;
this.payloads = payloads;
this.retryTimes = retryTimes;
this.timeout = timeout;
}
public int getId() {
@ -61,6 +65,11 @@ public class Packet {
return retryTimes;
}
@IntRange(from = 0)
public int getTimeout() {
return timeout;
}
@NonNull
@Override
public String toString() {
@ -97,6 +106,7 @@ public class Packet {
private final int id;
private final SparseArrayCompat<Payload> payloads;
private int retryTimes;
private int timeout;
public Builder(int id) {
this.id = id;
@ -109,6 +119,11 @@ public class Packet {
return this;
}
public Builder setTimeout(@IntRange(from = 0) int timeout) {
this.timeout = timeout;
return this;
}
public Builder addBytePayload(int payloadId, int i) {
final byte[] value = new byte[]{(byte) i};
payloads.append(payloadId, new Payload(value));
@ -154,7 +169,7 @@ public class Packet {
}
public Packet build() {
return new Packet(id, payloads, retryTimes);
return new Packet(id, payloads, retryTimes, timeout);
}
}
}

3
encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java

@ -79,7 +79,8 @@ class Workshop implements Callable<Packet> {
mPort.write(ByteBuffer.wrap(outputBytes), outputBytes.length);
final Future<byte[]> future = sExecutor.submit(new SerialReader(mPort));
final byte[] inputBytes = future.get(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
int timeout = mPacket.getTimeout() == 0 ? DEFAULT_TIMEOUT : mPacket.getTimeout();
final byte[] inputBytes = future.get(timeout, TimeUnit.SECONDS);
logBytes(false, id, inputBytes);
Packet packet = mPacker.deserialize(inputBytes);

Loading…
Cancel
Save