Updated on 2026-08-14

This commit is contained in:
Tangem 2020-01-14 18:57:45 +03:00
parent 161bf4ab5c
commit d35dc8a87b
10 changed files with 784 additions and 5 deletions

View file

@ -23,11 +23,12 @@ public enum Blockchain {
BinanceTestNet("BINANCE/test", "BNB", 100000000.0, R.drawable.tangem2, "Binance Testnet"),
Matic("MATIC", "MTX", 1.0, R.drawable.tangem2, "Matic"),
MaticTestNet("MATIC/test", "MTX", 1.0, R.drawable.tangem2, "Matic Testnet"),
Stellar("XLM", "XLM", 1000000.0, R.drawable.ic_logo_stellar, "Stellar"),
StellarTestNet("XLM/test", "XLM", 1000000.0, R.drawable.ic_logo_stellar, "Stellar Testnet"),
Stellar("XLM", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar"),
StellarTestNet("XLM/test", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar Testnet"),
StellarAsset("Asset", "XLM", 10000000.0, R.drawable.ic_logo_stellar, "Stellar"),
Eos("EOS", "EOS", 10000.0, R.drawable.tangem2, "EOS"),
Ducatus("DUC", "DUC", 100000000.0, R.drawable.tangem2, "Ducatus");
Ducatus("DUC", "DUC", 100000000.0, R.drawable.tangem2, "Ducatus"),
Tezos("TEZOS", "XTZ", 10000000.0, R.drawable.tangem2, "Tezos");
Blockchain(String ID, String currency, double multiplier, int imageResource, String officialName) {
mID = ID;

View file

@ -0,0 +1,139 @@
package com.tangem.data.network;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.tangem.data.network.model.TezosAccountResponse;
import com.tangem.data.network.model.TezosForgeBody;
import com.tangem.data.network.model.TezosHeaderResponse;
import com.tangem.data.network.model.TezosPreapplyBody;
import com.tangem.tangem_card.util.Log;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public class ServerApiTezos {
private static String TAG = ServerApiTezos.class.getSimpleName();
private final String letzbakeURI = "https://teznode.letzbake.com";
private final String tezrpcURI = "https://mainnet.tezrpc.me";
static final String TEZOS_ADDRESS = "chains/main/blocks/head/context/contracts/{address}";
static final String TEZOS_HEADER = "chains/main/blocks/head/header";
static final String TEZOS_MANAGER_KEY = "chains/main/blocks/head/context/contracts/{address}/manager_key";
static final String TEZOS_FORGE_OPERATIONS = "chains/main/blocks/head/helpers/forge/operations";
static final String TEZOS_PREAPPLY_OPERATIONS = "chains/main/blocks/head/helpers/preapply/operations";
static final String TEZOS_RUN_OPERATION = "chains/main/blocks/head/helpers/scripts/run_operation";
static final String TEZOS_INJECT_OPERATIONS = "injection/operation";
private Retrofit retrofitTezos = new Retrofit.Builder()
.baseUrl(letzbakeURI)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//logging for testing
.client(new OkHttpClient.Builder().addInterceptor(
new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
).build())
.build();
private TezosApi tezosApi = retrofitTezos.create(TezosApi.class);
private int requestsCount = 0;
public boolean isRequestsSequenceCompleted() {
Log.i(TAG, String.format("isRequestsSequenceCompleted: %s (%d requests left)", String.valueOf(requestsCount <= 0), requestsCount));
return requestsCount <= 0;
}
public void getAddress(String wallet, SingleObserver<TezosAccountResponse> accountObserver) {
requestsCount++;
Log.i(TAG, "new getAddress request");
Single<TezosAccountResponse> accountSingle = tezosApi.getAccount(wallet)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnEvent((object, throwable) -> requestsCount--);
accountSingle.subscribe(accountObserver);
}
public void getMangerKey(String wallet, SingleObserver<String> accountObserver) {
requestsCount++;
Log.i(TAG, "new getManagerKey request");
Single<String> managerKeySingle = tezosApi.getManagerKey(wallet)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnEvent((object, throwable) -> requestsCount--);
managerKeySingle.subscribe(accountObserver);
}
public TezosHeaderResponse getHeader() throws Exception { // TODO? not async
requestsCount++;
Log.i(TAG, "new getHeader request");
Response<TezosHeaderResponse> headerResponse = tezosApi.getHeader().execute();
requestsCount--;
if (headerResponse.code() == 200) {
return headerResponse.body();
} else {
throw new Exception("Wrong header response, code: " + headerResponse.code());
}
}
public String forgeOperations(TezosForgeBody tezosForgeBody) throws Exception { // TODO? not async
requestsCount++;
Log.i(TAG, "new forgeOperations request");
Response<String> forgeResponse = tezosApi.forgeOperations(tezosForgeBody).execute();
requestsCount--;
if (forgeResponse.code() == 200) {
return forgeResponse.body();
} else {
throw new Exception("Wrong forge response, code: " + forgeResponse.code());
}
}
public void peapplyOperations(TezosPreapplyBody tezosPreapplyBody) throws Exception {
Log.i(TAG, "new peapplyOperations request");
List<TezosPreapplyBody> tezosPreapplyBodyList = new ArrayList<>();
tezosPreapplyBodyList.add(tezosPreapplyBody);
Response<Void> preapplyResponse = tezosApi.preapplyOperations(tezosPreapplyBodyList).execute();
if (preapplyResponse.code() != 200) {
String error = "Preapply error: unknown error";
if (preapplyResponse.errorBody() != null) {
error = "Preapply error: " + preapplyResponse.errorBody().string();
}
Log.e(TAG, error);
throw new Exception(error);
}
}
public void injectOperations(String txForSend, SingleObserver<Object> injectObserver) {
requestsCount++;
Log.i(TAG, "new injectOperations request");
Single<Object> injectSingle = tezosApi.injectOperations(txForSend)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnEvent((object, throwable) -> requestsCount--);
injectSingle.subscribe(injectObserver);
}
}

View file

@ -0,0 +1,35 @@
package com.tangem.data.network;
import com.tangem.data.network.model.TezosAccountResponse;
import com.tangem.data.network.model.TezosForgeBody;
import com.tangem.data.network.model.TezosHeaderResponse;
import com.tangem.data.network.model.TezosPreapplyBody;
import java.util.List;
import io.reactivex.Single;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
public interface TezosApi {
@GET(ServerApiTezos.TEZOS_ADDRESS)
Single<TezosAccountResponse> getAccount(@Path("address") String address);
@GET(ServerApiTezos.TEZOS_HEADER)
Call<TezosHeaderResponse> getHeader();
@GET(ServerApiTezos.TEZOS_MANAGER_KEY)
Single<String> getManagerKey(@Path("address") String address);
@POST(ServerApiTezos.TEZOS_FORGE_OPERATIONS)
Call<String> forgeOperations(@Body TezosForgeBody tezosForgeBody);
@POST(ServerApiTezos.TEZOS_PREAPPLY_OPERATIONS)
Call<Void> preapplyOperations(@Body List<TezosPreapplyBody> tezosPreapplyBodyList);
@POST(ServerApiTezos.TEZOS_INJECT_OPERATIONS)
Single<Object> injectOperations(@Body String txForSend);
}

View file

@ -0,0 +1,25 @@
package com.tangem.data.network.model
data class TezosForgeBody(
val branch: String,
val contents: List<TezosOperationContent>
)
data class TezosOperationContent(
val kind: String,
val source: String,
val fee: String,
val counter: String,
val gas_limit: String,
val storage_limit: String,
val public_key: String? = null,
val destination: String? = null,
val amount: String? = null
)
data class TezosPreapplyBody(
val protocol: String,
val branch: String,
val contents: List<TezosOperationContent>,
val signature: String
)

View file

@ -0,0 +1,19 @@
package com.tangem.data.network.model
import com.google.gson.annotations.SerializedName
data class TezosAccountResponse(
@SerializedName("balance")
var balance: Long? = null,
@SerializedName("counter")
var counter: Long? = null
)
data class TezosHeaderResponse(
@SerializedName("protocol")
var protocol: String? = null,
@SerializedName("hash")
var hash: String? = null
)