diff --git a/app/build.gradle b/app/build.gradle index 11851f6..ea1ced4 100644 --- a/app/build.gradle +++ b/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 diff --git a/app/src/main/java/com/cobo/cold/callables/FirmwareParameterCallable.java b/app/src/main/java/com/cobo/cold/callables/FirmwareParameterCallable.java index 67b8d10..b8c4120 100644 --- a/app/src/main/java/com/cobo/cold/callables/FirmwareParameterCallable.java +++ b/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 { +public class FirmwareParameterCallable implements Callable { @Override - public String[] call() { + public String call() { try { - String[] res = new String[2]; final Callable 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(); } diff --git a/app/src/main/java/com/cobo/cold/callables/GetUpdateKeyCallable.java b/app/src/main/java/com/cobo/cold/callables/GetUpdateKeyCallable.java deleted file mode 100644 index ff64edc..0000000 --- a/app/src/main/java/com/cobo/cold/callables/GetUpdateKeyCallable.java +++ /dev/null @@ -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 . - */ - -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 { - @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 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; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java b/app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java index cf2987f..fe3e7b5 100644 --- a/app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java +++ b/app/src/main/java/com/cobo/cold/ui/fragment/PassphraseFragment.java @@ -89,7 +89,7 @@ public class PassphraseFragment extends SetupVaultBaseFragment= 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); diff --git a/app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java b/app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java index a403fc2..55c8b19 100644 --- a/app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java +++ b/app/src/main/java/com/cobo/cold/ui/fragment/main/TxListFragment.java @@ -152,6 +152,13 @@ public class TxListFragment extends BaseFragment { 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); } diff --git a/app/src/main/java/com/cobo/cold/ui/fragment/main/electrum/ElectrumTxnListFragment.java b/app/src/main/java/com/cobo/cold/ui/fragment/main/electrum/ElectrumTxnListFragment.java index 16508ed..acb51c0 100644 --- a/app/src/main/java/com/cobo/cold/ui/fragment/main/electrum/ElectrumTxnListFragment.java +++ b/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 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); } }); } diff --git a/app/src/main/java/com/cobo/cold/ui/views/MenuHidingEditText.java b/app/src/main/java/com/cobo/cold/ui/views/MenuHidingEditText.java index 62321b6..7085710 100644 --- a/app/src/main/java/com/cobo/cold/ui/views/MenuHidingEditText.java +++ b/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) { diff --git a/app/src/main/java/com/cobo/cold/update/Checking.java b/app/src/main/java/com/cobo/cold/update/Checking.java index 859ad7b..0a7e0ef 100644 --- a/app/src/main/java/com/cobo/cold/update/Checking.java +++ b/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 { 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 { return null; } - String updateKey = new GetUpdateKeyCallable().call(); + String updateKey = BuildConfig.UPDATE_PUBLIC_KEY; if (TextUtils.isEmpty(updateKey)) { return null; diff --git a/app/src/main/java/com/cobo/cold/update/Updating.java b/app/src/main/java/com/cobo/cold/update/Updating.java index dc35a98..eb56536 100644 --- a/app/src/main/java/com/cobo/cold/update/Updating.java +++ b/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 { @Override public Boolean call() throws Exception { - String updateKey = new GetUpdateKeyCallable().call(); + String updateKey = BuildConfig.UPDATE_PUBLIC_KEY; if (TextUtils.isEmpty(updateKey)) { return false; diff --git a/app/src/main/java/com/cobo/cold/viewmodel/AboutViewModel.java b/app/src/main/java/com/cobo/cold/viewmodel/AboutViewModel.java index a6d16fb..ccb92c5 100644 --- a/app/src/main/java/com/cobo/cold/viewmodel/AboutViewModel.java +++ b/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); }); } diff --git a/app/src/main/res/layout/electrum_export.xml b/app/src/main/res/layout/electrum_export.xml index 42e0f3c..81101f8 100644 --- a/app/src/main/res/layout/electrum_export.xml +++ b/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" /> diff --git a/app/src/main/res/layout/electrum_tx_detail.xml b/app/src/main/res/layout/electrum_tx_detail.xml index cffcef5..f59f416 100644 --- a/app/src/main/res/layout/electrum_tx_detail.xml +++ b/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"/> diff --git a/app/src/main/res/layout/tx_list_item.xml b/app/src/main/res/layout/tx_list_item.xml index 832aa46..c90d558 100644 --- a/app/src/main/res/layout/tx_list_item.xml +++ b/app/src/main/res/layout/tx_list_item.xml @@ -100,6 +100,19 @@ app:time="@{tx.timeStamp}" tools:text="2018/06/01" /> + 请再次输入密码 请输入密码 两次输入不一致 + 两次输入不一致 必须同时包含大、小写字母和数字 1. 助记词为恢复资产的唯一途径,请按顺序正确记录,并妥善保管到安全的脱网环境中。

2. 请勿将助记词拍照、储存在联网设备上或泄露给他人!助记词丢失或泄露将意味着资产丢失!

3.您可访问 https://cobo.com/hardware-wallet/cobo-tablet 购买 Cobo 金刚匣安全方便保存您的助记词。]]>
生成助记词 @@ -275,7 +276,7 @@ 导出成功 读取TF卡 未检测到TF卡 - 请先插入TF卡(仅支持FAT32格式,容量不能超过32GB),再前往签名记录里导出文件。 + 请先插入TF卡(仅支持FAT32格式,容量不能超过32GB) 未检测到待签文件 请检查TF卡中是否存有待签文件 Electrum 广播指引 @@ -289,12 +290,12 @@ 请先插入TF卡(仅支持FAT32格式,容量不能超过32G) 在 Electrum 输入主公钥页面打开该文件 热端钱包 - 请用 Electrum 扫描二维码进行广播 + 请用 Electrum 扫描二维码广播 该笔交易热端来源于Electrum 添加地址 请用 Electrum 扫描主公钥二维码 导出已签名文件 - 导出后,用 Electrum 进行广播\n前往【Electrum--工具--加载交易--从文件】,打开该文件。 + 导出后,用 Electrum 进行广播\n前往【Electrum--工具--加载交易--从文件】打开该文件 导出 导出主公钥文件 该文件的文件名为: @@ -306,4 +307,5 @@ 找零 适配 Electrum 交易识别失败 + 来自Electrum diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 08e53af..182e207 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,7 +41,7 @@ www.cobo.com Serial Number: %s \n Firmware Version: %s\n System Version:%s\n App Version:%s addr. - Please go to \"Menu - Add / Hide Assets\" to add assets you need + Please go to Menu - Add / Hide Assets to add assets you need "The recovery phrase is used to restore your wallet. Use a Cobo Tablet to record your 24 recovery phrase words and store them securely." Do not share your recovery phrase with anyone or take a picture of it. If it is lost or stolen, all assets are irretrievable. Recovery Phrase Saved @@ -113,6 +113,7 @@ Confirm password Please enter your password Passwords do not match. + Passphrase do not match. Must include upper and lower case letters and numbers. 1. The recovery phrase is the only way retrieve your assets. Please use record your recovery phrase carefully and store in a safe location.

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.

3. Visit https://cobo.com/hardware-wallet/cobo-tablet to purchase a Cobo Tablet to store your recovery phrase with a higher degree of security.]]>
Generate Recovery Phrase @@ -299,7 +300,7 @@ Export Successful MicroSD card MicroSD Card Not Found - 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. + Please make sure you have inserted a FAT32 format microSD card with capacity 32GB or less File Not Found Please make sure the file you wish to sign was successfully saved to your microSD card. How to Broadcast @@ -323,11 +324,12 @@ Export Master Public Key File File name: Master Public Key (Nested SegWit) - or \"touch here to export via microSD.\"]]> + or touch here to export via microSD.]]> Difficulty scanning Electrum? You can export the pending transactions as a file using a microSD card (Menu > MicroSD Card) Files Awaiting Signature This transaction can\'t be recognized, your Cobo Vault doesn’t match the watch-only wallet. Change Electrum Compatibility Identification Failed + From Electrum diff --git a/app/version.properties b/app/version.properties index 97035e8..cb6cd2d 100644 --- a/app/version.properties +++ b/app/version.properties @@ -16,4 +16,4 @@ # #Fri Feb 21 13:33:46 CST 2020 -patch=5 +patch=0 diff --git a/encryption-core/src/main/java/com/cobo/cold/encryptioncore/base/Packet.java b/encryption-core/src/main/java/com/cobo/cold/encryptioncore/base/Packet.java index 3f151d9..07fd82f 100644 --- a/encryption-core/src/main/java/com/cobo/cold/encryptioncore/base/Packet.java +++ b/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 payloads; - private Packet(int id, @NonNull SparseArrayCompat payloads, int retryTimes) { + private Packet(int id, @NonNull SparseArrayCompat 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 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); } } } diff --git a/encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java b/encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java index c1002d6..8cf6a8e 100644 --- a/encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java +++ b/encryption-core/src/main/java/com/cobo/cold/encryptioncore/job/Workshop.java @@ -79,7 +79,8 @@ class Workshop implements Callable { mPort.write(ByteBuffer.wrap(outputBytes), outputBytes.length); final Future 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);