Updated on 2026-08-14
This commit is contained in:
commit
0b3b83e71c
13 changed files with 197 additions and 27 deletions
|
|
@ -10,12 +10,12 @@ static def generateVersionName() {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.tangem.wallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 27
|
||||
versionCode 94
|
||||
targetSdkVersion 28
|
||||
versionCode 95
|
||||
versionName "0.810.1." + generateVersionName()
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
|
@ -44,11 +44,11 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support:design:27.1.1'
|
||||
implementation 'com.android.support:support-compat:27.1.1'
|
||||
implementation 'com.android.support:cardview-v7:27.1.1'
|
||||
implementation 'com.android.support:support-v4:27.1.1'
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
implementation 'com.android.support:support-compat:28.0.0'
|
||||
implementation 'com.android.support:cardview-v7:28.0.0'
|
||||
implementation 'com.android.support:support-v4:28.0.0'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||
implementation 'com.google.zxing:core:3.3.3'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package com.tangem;
|
|||
import android.app.Application;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
|
||||
import com.tangem.di.AppComponent;
|
||||
import com.tangem.di.DaggerAppComponent;
|
||||
import com.tangem.di.DaggerNetworkComponent;
|
||||
import com.tangem.di.NetworkComponent;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ public class App extends Application {
|
|||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
||||
}
|
||||
|
||||
private static AppComponent component;
|
||||
private static NetworkComponent networkComponent;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
@ -29,7 +29,7 @@ public class App extends Application {
|
|||
// initialize the singleton
|
||||
sInstance = this;
|
||||
|
||||
component = DaggerAppComponent.create();
|
||||
networkComponent = DaggerNetworkComponent.create();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -39,8 +39,8 @@ public class App extends Application {
|
|||
return sInstance;
|
||||
}
|
||||
|
||||
public static AppComponent getComponent() {
|
||||
return component;
|
||||
public static NetworkComponent getNetworkComponent() {
|
||||
return networkComponent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ public class ServerApiHelper {
|
|||
}
|
||||
|
||||
public void estimateFee(int blockCount) {
|
||||
EstimatefeeApi estimatefeeApi = App.getComponent().getRetrofitEstimatefee().create(EstimatefeeApi.class);
|
||||
EstimatefeeApi estimatefeeApi = App.getNetworkComponent().getRetrofitEstimatefee().create(EstimatefeeApi.class);
|
||||
|
||||
Call<String> call;
|
||||
switch (blockCount) {
|
||||
|
|
@ -114,7 +114,7 @@ public class ServerApiHelper {
|
|||
}
|
||||
|
||||
public void infura(String method, int id, String wallet, String contract, String tx) {
|
||||
InfuraApi infuraApi = App.getComponent().getRetrofitInfura().create(InfuraApi.class);
|
||||
InfuraApi infuraApi = App.getNetworkComponent().getRetrofitInfura().create(InfuraApi.class);
|
||||
|
||||
InfuraBody infuraBody;
|
||||
switch (method) {
|
||||
|
|
@ -179,7 +179,7 @@ public class ServerApiHelper {
|
|||
}
|
||||
|
||||
public void cardVerifyAndGetInfo(TangemCard card) {
|
||||
TangemApi tangemApi = App.getComponent().getRetrofitTangem().create(TangemApi.class);
|
||||
TangemApi tangemApi = App.getNetworkComponent().getRetrofitTangem().create(TangemApi.class);
|
||||
|
||||
List<CardVerifyAndGetInfo.Request.Item> requests = new ArrayList<>();
|
||||
requests.add(new CardVerifyAndGetInfo.Request.Item(Util.bytesToHex(card.getCID()), Util.bytesToHex(card.getCardPublicKey())));
|
||||
|
|
@ -224,7 +224,7 @@ public class ServerApiHelper {
|
|||
}
|
||||
|
||||
public void requestArtwork(String artworkId, Date updateDate, TangemCard card) {
|
||||
TangemApi tangemApi = App.getComponent().getRetrofitTangem().create(TangemApi.class);
|
||||
TangemApi tangemApi = App.getNetworkComponent().getRetrofitTangem().create(TangemApi.class);
|
||||
|
||||
Call<ResponseBody> call = tangemApi.getArtwork(artworkId, Util.bytesToHex(card.getCID()), Util.bytesToHex(card.getCardPublicKey()));
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
|
|
@ -267,7 +267,7 @@ public class ServerApiHelper {
|
|||
|
||||
@SuppressLint("CheckResult")
|
||||
public void rateInfoData(String cryptoId) {
|
||||
CoinmarketApi coinmarketApi = App.getComponent().getRetrofitCoinmarketcap().create(CoinmarketApi.class);
|
||||
CoinmarketApi coinmarketApi = App.getNetworkComponent().getRetrofitCoinmarketcap().create(CoinmarketApi.class);
|
||||
|
||||
coinmarketApi.getRateInfoList()
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
@ -302,7 +302,7 @@ public class ServerApiHelper {
|
|||
}
|
||||
|
||||
public void requestLastVersion() {
|
||||
UpdateVersionApi updateVersionApi = App.getComponent().getRetrofitGithubusercontent().create(UpdateVersionApi.class);
|
||||
UpdateVersionApi updateVersionApi = App.getNetworkComponent().getRetrofitGithubusercontent().create(UpdateVersionApi.class);
|
||||
|
||||
Call<ResponseBody> call = updateVersionApi.getLastVersion();
|
||||
call.enqueue(new Callback<ResponseBody>() {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.domain.wallet.Blockchain;
|
|||
import com.tangem.domain.wallet.TangemCard;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
|
|
@ -22,6 +23,15 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.observers.DefaultObserver;
|
||||
|
|
@ -41,6 +51,7 @@ public class ServerApiHelperElectrum {
|
|||
|
||||
public interface ElectrumRequestDataListener {
|
||||
void onSuccess(ElectrumRequest electrumRequest);
|
||||
|
||||
void onFail(String method);
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +63,7 @@ public class ServerApiHelperElectrum {
|
|||
Observable<ElectrumRequest> checkElectrumDataObserver = Observable.just(electrumRequest)
|
||||
|
||||
.doOnNext(electrumRequest1 -> doElectrumRequest(card, electrumRequest))
|
||||
// .doOnNext(electrumRequest1 -> testSslSocket(card, electrumRequest))
|
||||
|
||||
.flatMap(electrumRequest1 -> {
|
||||
if (electrumRequest1.answerData == null) {
|
||||
|
|
@ -94,7 +106,61 @@ public class ServerApiHelperElectrum {
|
|||
});
|
||||
}
|
||||
|
||||
private List<ElectrumRequest> doElectrumRequest(TangemCard card, ElectrumRequest electrumRequest) throws ConnectException {
|
||||
private List<ElectrumRequest> testSslSocket(TangemCard card, ElectrumRequest electrumRequest) {
|
||||
SocketFactory sf = SSLSocketFactory.getDefault();
|
||||
SSLSocket socket;
|
||||
|
||||
List<ElectrumRequest> result = new ArrayList<>();
|
||||
Collections.addAll(result, electrumRequest);
|
||||
|
||||
try {
|
||||
// socket = (SSLSocket) sf.createSocket("gmail.com", 443);
|
||||
socket = (SSLSocket) sf.createSocket("electrum.hsmiths.com", 50002);
|
||||
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
|
||||
SSLSession s = socket.getSession();
|
||||
|
||||
// if (!hv.verify("mail.google.com", s)) {
|
||||
// throw new SSLHandshakeException("Expected mail.google.com, found " + s.getPeerPrincipal());
|
||||
// }
|
||||
|
||||
|
||||
try {
|
||||
OutputStream os = socket.getOutputStream();
|
||||
OutputStreamWriter out = new OutputStreamWriter(os, "UTF-8");
|
||||
InputStream is = socket.getInputStream();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(is));
|
||||
electrumRequest.setID(1);
|
||||
|
||||
out.write(electrumRequest.getAsString() + "\n");
|
||||
out.flush();
|
||||
|
||||
electrumRequest.answerData = in.readLine();
|
||||
// electrumRequest.host = host;
|
||||
// electrumRequest.port = port;
|
||||
if (electrumRequest.answerData != null) {
|
||||
Log.i(TAG, ">> " + electrumRequest.answerData);
|
||||
} else {
|
||||
electrumRequest.error = "No answer from server";
|
||||
Log.i(TAG, ">> <NULL>");
|
||||
}
|
||||
|
||||
} catch (ConnectException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "electrumRequestData " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
|
||||
} finally {
|
||||
// Log.i(TAG, "electrumRequestData " + electrumRequest.getMethod() + " CLOSE");
|
||||
socket.close();
|
||||
}
|
||||
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<ElectrumRequest> doElectrumRequest(TangemCard card, ElectrumRequest electrumRequest) {
|
||||
BitcoinNode bitcoinNode = BitcoinNode.values()[new Random().nextInt(BitcoinNode.values().length)];
|
||||
|
||||
if (card.getBlockchain() == Blockchain.BitcoinTestNet || card.getBlockchain() == Blockchain.BitcoinCashTestNet) {
|
||||
|
|
@ -111,8 +177,8 @@ public class ServerApiHelperElectrum {
|
|||
Collections.addAll(result, electrumRequest);
|
||||
|
||||
try {
|
||||
Socket socket = App.getComponent().getSocket();
|
||||
socket.connect(new InetSocketAddress(InetAddress.getByName(host), port));
|
||||
Socket socket = App.getNetworkComponent().getSocket();
|
||||
socket.connect(new InetSocketAddress(InetAddress.getByName(host), port));
|
||||
Log.i(TAG, host + " " + port);
|
||||
try {
|
||||
OutputStream os = socket.getOutputStream();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
|
||||
*
|
||||
* 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 com.dmmatrix.epro.core.exception
|
||||
|
||||
/**
|
||||
* Base Class for handling errors/failures/exceptions.
|
||||
* Every feature specific failure should extend [FeatureFailure] class.
|
||||
*/
|
||||
sealed class Failure {
|
||||
class ApplicationError(val message: String) : Failure()
|
||||
class NotFound : FeatureFailure()
|
||||
class NetworkConnection : Failure()
|
||||
class ServerError : Failure()
|
||||
class Unauthorized : Failure() // 401
|
||||
|
||||
/** * Extend this class for feature specific failures.*/
|
||||
abstract class FeatureFailure : Failure()
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import retrofit2.Retrofit;
|
|||
|
||||
@Singleton
|
||||
@Component(modules = {NetworkModule.class})
|
||||
public interface AppComponent {
|
||||
public interface NetworkComponent {
|
||||
|
||||
@Named(Server.ApiInfura.URL_INFURA)
|
||||
Retrofit getRetrofitInfura();
|
||||
|
|
@ -12,5 +12,6 @@ enum class BitcoinNode(val host: String, val port: Int) {
|
|||
n9("electrumx.nmdps.net", 50001),
|
||||
n10("kirsche.emzy.de", 50001),
|
||||
n11("electrum.petrkr.net", 50001),
|
||||
n12("electrum.dk", 50001)
|
||||
n12("electrum.dk", 50001),
|
||||
// n13("electrum.hsmiths.com", 50002)
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import com.tangem.data.network.ServerApiHelperElectrum
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_logo.*
|
||||
|
|
@ -17,6 +18,8 @@ class LogoActivity : AppCompatActivity() {
|
|||
const val MILLIS_AUTO_HIDE = 1000
|
||||
}
|
||||
|
||||
private var serverApiHelperElectrum: ServerApiHelperElectrum = ServerApiHelperElectrum()
|
||||
|
||||
private val hideRunnable = Runnable { this.hide() }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
|
||||
const val EXTRA_LAST_DISCOVERED_TAG = "extra_last_tag"
|
||||
|
||||
fun callingIntent(context: Context) = Intent(context, MainActivity::class.java)
|
||||
|
||||
fun commonInit(context: Context) {
|
||||
if (PINStorage.needInit())
|
||||
PINStorage.Init(context)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class SignPaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
|
|||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_CODE_SEND_PAYMENT) {
|
||||
setResult(resultCode, data)
|
||||
finish()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
|
||||
*
|
||||
* 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 com.tangem.presentation.viewmodel
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData
|
||||
import android.arch.lifecycle.ViewModel
|
||||
import com.dmmatrix.epro.core.exception.Failure
|
||||
|
||||
/**
|
||||
* Base ViewModel class with default Failure handling.
|
||||
* @see ViewModel
|
||||
* @see Failure
|
||||
*/
|
||||
abstract class BaseViewModel : ViewModel() {
|
||||
|
||||
var failure: MutableLiveData<Failure> = MutableLiveData()
|
||||
|
||||
protected fun handleFailure(failure: Failure) {
|
||||
this.failure.value = failure
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.presentation.viewmodel
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData
|
||||
import com.dmmatrix.epro.core.exception.Failure
|
||||
|
||||
class LoadedWalletViewModel : BaseViewModel() {
|
||||
|
||||
private val state: MutableLiveData<State> = MutableLiveData()
|
||||
|
||||
fun getState() = state
|
||||
|
||||
enum class State {
|
||||
ServerError,
|
||||
Failed,
|
||||
Success
|
||||
}
|
||||
|
||||
fun connectToken(data: String, data2: String) {
|
||||
|
||||
}
|
||||
|
||||
private fun handleTokensSaveFailure(failure: Failure) {
|
||||
state.value = State.Success
|
||||
handleFailure(failure)
|
||||
}
|
||||
|
||||
private fun handleLoginFailure(failure: Failure) {
|
||||
when (failure) {
|
||||
is Failure.ServerError -> state.value = State.ServerError
|
||||
}
|
||||
handleFailure(failure)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.2.71'
|
||||
ext.kotlin_version = '1.3.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue